Struct pixel_game_lib::canvas::Canvas
source · pub struct Canvas<'a> { /* private fields */ }
Expand description
Simple wrapper around a pixel buffer that can be passed around to rendering calls.
Implementations§
source§impl<'a> Canvas<'a>
impl<'a> Canvas<'a>
sourcepub fn set_pixel(&mut self, position: Vec2<f64>, color: u32)
pub fn set_pixel(&mut self, position: Vec2<f64>, color: u32)
Set a pixel on the buffer at the coordinate passed.
If the coordinate is out of bounds nothing will be done.
This is quite a slow operation because it needs to calculate the index of the coordinate, if setting multiple pixels it might be more efficient to create a sprite from them.
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn draw_line(&mut self, start: Vec2<f64>, end: Vec2<f64>, color: u32)
pub fn draw_line(&mut self, start: Vec2<f64>, end: Vec2<f64>, color: u32)
Draw a line using Bresenham’s line algorithm.
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn draw_scanline(&mut self, y: usize, x: Range<usize>, color: u32)
pub fn draw_scanline(&mut self, y: usize, x: Range<usize>, color: u32)
Fill a horizontal line, very cheap operation.
sourcepub fn draw_circle_outline(&mut self, circle: Disk<f64, f64>, color: u32)
pub fn draw_circle_outline(&mut self, circle: Disk<f64, f64>, color: u32)
Draw a circle using Bresenham’s circle algorithm.
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn draw_circle(&mut self, circle: Disk<f64, f64>, color: u32)
pub fn draw_circle(&mut self, circle: Disk<f64, f64>, color: u32)
Fill a circle using Bresenham’s circle algorithm.
Based on: https://funloop.org/post/2021-03-15-bresenham-circle-drawing-algorithm.html
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn draw_triangle(&mut self, corners: [Vec2<f64>; 3], color: u32)
pub fn draw_triangle(&mut self, corners: [Vec2<f64>; 3], color: u32)
Fill a triangle.
Based on: https://joshbeam.com/articles/triangle_rasterization/
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn draw_quad(&mut self, corners: [Vec2<f64>; 4], color: u32)
pub fn draw_quad(&mut self, corners: [Vec2<f64>; 4], color: u32)
Fill a polygon with 4 corners.
If any of the 4 points falls inside the triangle of the other three only a single triangle will be drawn.
Based on: https://stackoverflow.com/a/2122620
Examples found in repository?
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn fill(&mut self, color: u32)
pub fn fill(&mut self, color: u32)
Fill the canvas with a single color.
Examples found in repository?
More examples
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
fn main() {
// Window configuration with huge pixels
let window_config = WindowConfig {
buffer_size: Extent2::new(64, 64),
scaling: 8,
..Default::default()
};
// Open the window and start the game-loop
pixel_game_lib::window(
// Keep track of the mouse as our "game state"
Vec2::zero(),
window_config.clone(),
// Update loop exposing input events we can handle, this is where you would handle the game logic
|state, input, mouse, _dt| {
// Set the mouse position as the game state
if let Some(mouse) = mouse {
*state = mouse;
}
// Exit when escape is pressed
input.key_pressed(KeyCode::Escape)
},
// Render loop exposing the pixel buffer we can mutate
move |mouse, canvas, _dt| {
// Reset the canvas with a white color
canvas.fill(0xFFFFFFFF);
// Draw a gray circle with the radius being the distance of the center to the mouse
let circle_center = Vec2::new(50.0, 50.0);
let dist_from_mouse = mouse.as_().distance(circle_center);
canvas.draw_circle(Disk::new(circle_center, dist_from_mouse), 0xFF999999);
// Draw a darker gray circle outline on top of the circle
canvas.draw_circle_outline(Disk::new(circle_center, dist_from_mouse), 0xFF333333);
// Draw a light green blue triangle with one corner being snapped to the mouse
canvas.draw_triangle(
[Vec2::new(45.0, 5.0), Vec2::new(60.0, 8.0), mouse.as_()],
0xFF99FF99,
);
// Draw a light blue quadrilateral with one corner being snapped to the mouse
canvas.draw_quad(
[
Vec2::new(5.0, 5.0),
Vec2::new(20.0, 8.0),
Vec2::new(8.0, 30.0),
mouse.as_(),
],
0xFF9999FF,
);
// Draw a black line from the center of the canvas to our mouse
canvas.draw_line(
(window_config.buffer_size.as_() / 2.0).into(),
mouse.as_(),
0xFF000000,
);
// Draw a red pixel under the mouse
canvas.set_pixel(mouse.as_(), 0xFFFF0000);
},
)
.expect("Error opening window");
}
sourcepub fn raw_buffer(&mut self) -> &mut [u32]
pub fn raw_buffer(&mut self) -> &mut [u32]
Get the raw buffer of pixels.
Auto Trait Implementations§
impl<'a> Freeze for Canvas<'a>
impl<'a> RefUnwindSafe for Canvas<'a>
impl<'a> Send for Canvas<'a>
impl<'a> Sync for Canvas<'a>
impl<'a> Unpin for Canvas<'a>
impl<'a> !UnwindSafe for Canvas<'a>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
source§impl<T> Downcast for Twhere
T: Any,
impl<T> Downcast for Twhere
T: Any,
source§fn into_any(self: Box<T>) -> Box<dyn Any>
fn into_any(self: Box<T>) -> Box<dyn Any>
Box<dyn Trait>
(where Trait: Downcast
) to Box<dyn Any>
. Box<dyn Any>
can
then be further downcast
into Box<ConcreteType>
where ConcreteType
implements Trait
.source§fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>
Rc<Trait>
(where Trait: Downcast
) to Rc<Any>
. Rc<Any>
can then be
further downcast
into Rc<ConcreteType>
where ConcreteType
implements Trait
.source§fn as_any(&self) -> &(dyn Any + 'static)
fn as_any(&self) -> &(dyn Any + 'static)
&Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &Any
’s vtable from &Trait
’s.source§fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)
&mut Trait
(where Trait: Downcast
) to &Any
. This is needed since Rust cannot
generate &mut Any
’s vtable from &mut Trait
’s.source§impl<T> DowncastSync for T
impl<T> DowncastSync for T
source§impl<T> Instrument for T
impl<T> Instrument for T
source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
source§impl<T> IntoEither for T
impl<T> IntoEither for T
source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left
is true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
self
into a Left
variant of Either<Self, Self>
if into_left(&self)
returns true
.
Converts self
into a Right
variant of Either<Self, Self>
otherwise. Read moresource§impl<T> Pointable for T
impl<T> Pointable for T
source§impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
impl<SS, SP> SupersetOf<SS> for SPwhere
SS: SubsetOf<SP>,
source§fn to_subset(&self) -> Option<SS>
fn to_subset(&self) -> Option<SS>
self
from the equivalent element of its
superset. Read moresource§fn is_in_subset(&self) -> bool
fn is_in_subset(&self) -> bool
self
is actually part of its subset T
(and can be converted to it).source§fn to_subset_unchecked(&self) -> SS
fn to_subset_unchecked(&self) -> SS
self.to_subset
but without any property checks. Always succeeds.source§fn from_subset(element: &SS) -> SP
fn from_subset(element: &SS) -> SP
self
to the equivalent element of its superset.