1use crate::{
2 general::{color::Color, direction::Direction},
3 gl_utils::{
4 gl_texture::LoadableTexture, gl_texture::Texture,
5 shader_creator::ShaderProgram,
6 },
7 math::matrix::{IdentityMatrix, Matrix},
8 shapes::shape::Shape,
9};
10
11use super::drawable::Drawable;
12use std::marker::PhantomData;
13
14#[derive(Debug, Clone)]
15pub struct Sprite<'a, TShape>
17where
18 TShape: Shape + 'a,
19{
20 shape: TShape,
21 pub name: String,
22 texture: Texture,
23 phantom: PhantomData<&'a TShape>,
24 transformation: Matrix<f32>,
25}
26
27impl<'a, TShape: 'a> Sprite<'a, TShape>
28where
29 TShape: Shape + 'a,
30{
31 pub fn new(shape: TShape, texture: Texture) -> Sprite<'a, TShape> {
32 Sprite {
33 shape,
34 name: texture.image_name.to_owned(),
35 texture,
36 phantom: PhantomData,
37 transformation: Matrix::<f32>::generate_identity(4),
38 }
39 }
40
41 pub fn with_transformation(
42 shape: TShape,
43 texture: Texture,
44 trans: Matrix<f32>,
45 ) -> Sprite<'a, TShape> {
46 Sprite {
47 shape,
48 name: texture.image_name.to_owned(),
49 texture,
50 phantom: PhantomData,
51 transformation: trans,
52 }
53 }
54
55 pub fn move_sprite(&mut self, direction: Direction, amount: f32) {
56 match direction {
57 Direction::Right => {
58 self.move_right(amount);
59 }
60 Direction::Left => {
61 self.move_left(amount);
62 }
63 Direction::Up => {
64 self.move_up(amount);
65 }
66 Direction::Down => {
67 self.move_down(amount);
68 }
69 Direction::UpRight => {
70 self.move_right(amount);
71 self.move_up(amount);
72 }
73 Direction::UpLeft => {
74 self.move_left(amount);
75 self.move_up(amount);
76 }
77 Direction::DownRight => {
78 self.move_right(amount);
79 self.move_down(amount);
80 }
81 Direction::DownLeft => {
82 self.move_left(amount);
83 self.move_down(amount);
84 }
85 _ => {}
86 }
87 }
88
89 pub fn flip_vertical(&mut self) {
90 self.shape.flip_texture_corners_y()
91 }
92
93 pub fn flip_horizontal(&mut self) {
94 self.shape.flip_texture_corners_x()
95 }
96
97 pub fn transform(&mut self, transformation_matrix: Matrix<f32>) {
98 assert!(
99 transformation_matrix.get_num_rows() == 4
100 && transformation_matrix.get_num_columns() == 4,
101 "Not a valid transformation_matrix"
102 );
103
104 self.transformation = transformation_matrix;
105 }
106
107 pub fn load_texture(&mut self) {
108 self.texture.load_texture();
109 }
110
111 pub fn set_x(&mut self, x: f32) {
112 self.shape.set_x(x);
113 }
114 pub fn set_y(&mut self, y: f32) {
115 self.shape.set_y(y);
116 }
117
118 pub fn get_x(&self) -> f32 {
119 self.shape.get_x()
120 }
121
122 pub fn get_y(&self) -> f32 {
123 self.shape.get_y()
124 }
125
126 pub fn get_height(&self) -> f32 {
127 self.shape.get_height()
128 }
129
130 pub fn get_width(&self) -> f32 {
131 self.shape.get_width()
132 }
133
134 pub fn move_up(&mut self, amount: f32) -> bool {
135 let new_amount = self.shape.get_y() + amount;
136
137 if new_amount >= 0.8 {
138 return false;
139 }
140
141 self.shape.set_y(new_amount);
142
143 return true;
144 }
145
146 pub fn move_down(&mut self, amount: f32) -> bool {
147 let new_amount = self.shape.get_y() - amount;
148
149 if new_amount <= -0.7 {
150 return false;
151 }
152
153 self.shape.set_y(new_amount);
154
155 return true;
156 }
157
158 pub fn move_right(&mut self, amount: f32) -> bool {
159 let new_amount = self.shape.get_x() + amount;
160
161 if new_amount > 0.7 {
162 return false;
163 }
164
165 self.shape.set_x(new_amount);
166
167 return true;
168 }
169
170 pub fn set_color_overlay(&mut self, color: Color) {
171 self.shape.set_color(color);
172 }
173
174 pub fn move_left(&mut self, amount: f32) -> bool {
175 let new_amount = self.shape.get_x() - amount;
176
177 if new_amount <= -1.0 {
178 return false;
179 }
180
181 self.shape.set_x(new_amount);
182
183 return true;
184 }
185}
186
187impl<'a, TShape> Drawable<'a> for Sprite<'a, TShape>
188where
189 TShape: Shape + 'a,
190{
191 fn set_texture_uniform(&'a self, program: &ShaderProgram) -> () {
192 self.texture.set_uniform(program);
193 }
194
195 fn get_corner_count(&'a self) -> i32 {
196 self.shape.get_coordinate_corners().len() as i32
197 }
198
199 fn get_elements(&self) -> Vec<i32> {
200 return vec![0, 1, 2, 2, 3, 0];
201 }
202
203 fn load_texture(&'a self) -> () {
204 self.texture.load_texture();
205 }
206
207 fn get_vertices(&self) -> Vec<f32> {
208 let mut vertices = Vec::<f32>::new();
209
210 let shape = &self.shape;
211
212 let coordinate_corners = &self.shape.get_coordinate_corners();
213 let texture_corners = &self.shape.get_texture_corners();
214
215 for i in 0..4 {
216 let [x, y] = coordinate_corners[i];
218 vertices.push(x);
219 vertices.push(y);
220
221 vertices.push(shape.get_color().r);
223 vertices.push(shape.get_color().g);
224 vertices.push(shape.get_color().b);
225 vertices.push(shape.get_color().a);
226
227 let [tx, ty] = texture_corners[i];
229 vertices.push(tx);
230 vertices.push(ty);
231
232 vertices.push(self.texture.texture_id as f32);
233
234 for entry in self.transformation.get_inner_ptr() {
235 vertices.push(entry.to_owned());
236 }
237 }
238 return vertices;
239 }
240}
241
242impl<'a, TShape> From<&Sprite<'a, TShape>> for Sprite<'a, TShape>
243where
244 TShape: Shape + Clone,
245{
246 fn from(sprite_ref: &Sprite<'a, TShape>) -> Self {
247 Sprite::new(sprite_ref.shape.to_owned(), sprite_ref.texture.to_owned())
248 }
249}