1
2
3
4
5
6
7
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
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
use sdl3::event::Event;
use sdl3::pixels::Color;
use sdl3::rect::Rect;
use sdl3::render::{Canvas, Texture, TextureCreator};
use sdl3::ttf::Sdl3TtfContext;
use sdl3::video::{Window, WindowContext};
use sdl3::Sdl;
use crate::sprite::Sprite;
use crate::Vec2d;
/// Frug Instance. Holds the context and the canvas
pub struct Instance {
context: Sdl,
canvas: Canvas<Window>,
}
impl Instance {
/// Creates a new frug instance and a window (given a title, width, and height)
pub fn new(title: &str, width: u32, height: u32) -> Self {
let context = sdl3::init().unwrap();
let video_subsystem = context.video().unwrap();
let window = video_subsystem
.window(title, width, height)
.position_centered()
.build()
.unwrap();
let canvas = window.into_canvas();
Instance { context, canvas }
}
/// Creates a texture creater which we can use to load textures.
pub fn new_texture_creator(&self) -> TextureCreator<WindowContext> {
self.canvas.texture_creator()
}
/// Create a ttf context which we can use to load fonts.
/// Returns an error if the context could not be created.
pub fn new_ttf_context(&self) -> Result<Sdl3TtfContext, String> {
sdl3::ttf::init().map_err(|e| e.to_string())
}
/// Clears the canvas with a given color
pub fn clear(&mut self, color: Color) {
self.canvas.set_draw_color(color);
self.canvas.clear();
}
/// Renders all textures/shapes drawn into the canvas since it was last cleaned.
pub fn present(&mut self) {
self.canvas.present();
}
/// Draws a rectangle given the position, size, and color
/// `pos` - Defines the position of the rectangle
/// `size` - Defines the dimensions of the rectangle (x = width, y = height)
/// `color` - Color
pub fn draw_rect(&mut self, pos: &Vec2d<i32>, size: &Vec2d<u32>, color: Color) {
self.canvas.set_draw_color(color);
let rect = Rect::new(pos.x, pos.y, size.x, size.y);
self.canvas.fill_rect(rect).unwrap();
}
/// Draws a texture
/// `texture` - Defines the texture to use.
/// `pos` - Defines the position of the image to draw.
/// `size` - Defines the dimensions of the image rectangle (x = width, y = height)
pub fn draw_full_texture(&mut self, texture: &Texture, pos: &Vec2d<i32>, size: &Vec2d<u32>) {
let rect = Rect::new(pos.x, pos.y, size.x, size.y);
self.canvas
.copy(texture, None, Some(rect).map(|r| r.into()))
.unwrap();
}
/// Draws from a texture into a destination rectangle in the canvas.
/// `texture` - Defines the texture to use.
/// `src_pos` - Defines the starting point of the rectangular section of the texture to draw onto the canvas.
/// `src_dimensions` - Defines the dimensions of the rectangular section of the texture to draw onto the canvas.
/// `dest_pos` - Defines the starting point of the rectangular section of the canvas where the texture will be drawn.
/// `dest_dimensions` - Defines the dimensions of the rectangular section of the canvas where the texture will be drawn.
pub fn draw_texture(
&mut self,
texture: &Texture,
src_pos: &Vec2d<i32>,
src_dimensions: &Vec2d<u32>,
dest_pos: &Vec2d<i32>,
dest_dimensions: &Vec2d<u32>,
) {
let src_rect = Rect::new(src_pos.x, src_pos.y, src_dimensions.x, src_dimensions.y);
let dest_rect = Rect::new(dest_pos.x, dest_pos.y, dest_dimensions.x, dest_dimensions.y);
if let Err(e) = self.canvas.copy(texture, src_rect, dest_rect) {
eprintln!("Error drawing sprite: {}", e);
}
}
/// Draws a given sprite in its current frame.
/// `sprite` - The sprite object to use.
/// `position` - Defines the position on the canvas where we want to draw the sprite.
/// `scale` - Defines the scale of the sprite to draw.
pub fn draw_sprite(&mut self, sprite: &Sprite, position: &Vec2d<i32>, scale: &Vec2d<u32>) {
self.draw_texture(
&sprite.texture,
&Vec2d {
x: sprite.drawing_rect.x,
y: sprite.drawing_rect.y,
},
&Vec2d {
x: sprite.drawing_rect.width(),
y: sprite.drawing_rect.height(),
},
position,
&Vec2d {
x: sprite.drawing_rect.width() * scale.x,
y: sprite.drawing_rect.height() * scale.y,
},
);
}
/// Returns a vector containing all the events captured during the current call of this method.
pub fn get_events(&mut self) -> Vec<Event> {
let mut event_pump = self.context.event_pump().unwrap();
return event_pump.poll_iter().collect::<Vec<_>>();
}
}