Mercurial repo for silny-kombat project
Révision | 3704cec45aaa4036fe8382e2c2146a653e285dc4 (tree) |
---|---|
l'heure | 2023-03-10 03:54:12 |
Auteur | SecT <grzegorzstarowicz@gmai...> |
Commiter | SecT |
Merged ref_01
@@ -9,7 +9,6 @@ | ||
9 | 9 | use crate::sprite_rendering::CharacterSprite; |
10 | 10 | |
11 | 11 | use crate::state_enums; |
12 | -use crate::health_bar; | |
13 | 12 | |
14 | 13 | use std::fs::File; |
15 | 14 | use std::io::prelude::*; |
@@ -17,15 +16,15 @@ | ||
17 | 16 | |
18 | 17 | use sfml::{ |
19 | 18 | graphics::{ |
20 | - Color, Transformable, Texture, RenderWindow, RenderTarget, Sprite | |
19 | + Transformable, Texture, RenderWindow, RenderTarget | |
21 | 20 | }, |
22 | - window::{ ContextSettings, Style, Event}, | |
21 | + window::{ Event}, | |
23 | 22 | system::Vector2f, |
24 | 23 | SfBox |
25 | 24 | }; |
26 | 25 | use crate::key_processing::{KeyProcessor, KeyEvents}; |
27 | -use sfml::system::Vector2u; | |
28 | 26 | use sfml::window::{Key}; |
27 | +use crate::controller::Combat_status::A_ATTACKS_B; | |
29 | 28 | |
30 | 29 | use crate::key_processing; |
31 | 30 | use crate::renderer::Renderer; |
@@ -34,13 +33,20 @@ | ||
34 | 33 | pub const TEXTURE_ARRAY_SIZE : usize = 7; |
35 | 34 | pub const SYSTEM_TEXTURE_ARRAY_SIZE : usize = 2; |
36 | 35 | |
37 | -const char_width : f32 = 120.0; | |
36 | +pub const CHAR_WIDTH: f32 = 120.0; | |
38 | 37 | |
39 | -const punch_dmg : i32 = 5; | |
40 | -const punch_range :f32 = 45.0; | |
38 | +pub const PUNCH_DMG: i32 = 5; | |
39 | +pub const PUNCH_RANGE:f32 = 45.0; | |
41 | 40 | |
42 | -const kick_dmg : i32 = 2; | |
43 | -const kick_range :f32 = 70.0; | |
41 | +pub const KICK_DMG: i32 = 2; | |
42 | +pub const KICK_RANGE:f32 = 70.0; | |
43 | + | |
44 | +pub enum Combat_status{ | |
45 | + NONE, | |
46 | + BOTH, | |
47 | + A_ATTACKS_B, | |
48 | + B_ATTACKS_A | |
49 | +} | |
44 | 50 | |
45 | 51 | pub enum Texture_Ids { |
46 | 52 | IDLE_0, |
@@ -58,40 +64,78 @@ | ||
58 | 64 | } |
59 | 65 | |
60 | 66 | pub struct Controller<'a> { |
61 | - character_a : Option<&'a Character<'a>>, | |
62 | - character_b : Option<&'a Character<'a>>, | |
67 | + pub(crate) character_a : Character<'a>, | |
68 | + pub(crate) character_b : Character<'a>, | |
63 | 69 | |
64 | 70 | char_textures: &'a [ SfBox<Texture>; TEXTURE_ARRAY_SIZE], |
65 | 71 | system_textures: &'a [ SfBox<Texture>; SYSTEM_TEXTURE_ARRAY_SIZE], |
66 | 72 | |
67 | - key_processor : KeyProcessor, | |
68 | - myRenderer : Renderer | |
73 | + pub(crate) key_processor : KeyProcessor, | |
74 | + myRenderer : Renderer<'a>, | |
75 | + window : RenderWindow, | |
76 | + | |
69 | 77 | } |
70 | 78 | |
71 | 79 | impl<'a> Controller<'a> { |
72 | 80 | |
73 | - pub fn new(textures: &'a [ SfBox<Texture>;TEXTURE_ARRAY_SIZE] , textures2: &'a [SfBox<Texture>;SYSTEM_TEXTURE_ARRAY_SIZE] ) -> Self { | |
81 | + pub fn new(char_a : Character<'a>, char_b: Character<'a>, textures: &'a [ SfBox<Texture>;TEXTURE_ARRAY_SIZE] , textures2: &'a [SfBox<Texture>;SYSTEM_TEXTURE_ARRAY_SIZE] ) -> Self { | |
82 | + | |
83 | + let rend = Renderer::new(800, | |
84 | + &textures2[System_texture_Ids::BACKGROUND as usize], | |
85 | + &textures2[System_texture_Ids::HEALTH_BAR as usize] | |
86 | + ); | |
87 | + let myWindow = rend.prepare_window(); | |
74 | 88 | |
75 | 89 | Controller { |
76 | - character_a: None, | |
77 | - character_b: None, | |
90 | + character_a: char_a, | |
91 | + character_b: char_b, | |
78 | 92 | char_textures: textures, |
79 | 93 | system_textures: textures2, |
80 | 94 | key_processor : KeyProcessor::new() , |
81 | - myRenderer : Renderer::new() | |
95 | + myRenderer : rend, | |
96 | + window : myWindow | |
82 | 97 | } |
83 | 98 | } |
84 | 99 | |
85 | - pub fn set_character_a(&mut self, new_character: &'a Character){ | |
86 | - self.character_a = Some(new_character); | |
100 | + // pub fn set_character_a(&mut self, new_character: &'a mut Character<'a>){ | |
101 | + // self.character_a = Some(new_character); | |
102 | + // } | |
103 | + // | |
104 | + // pub fn set_character_b(&mut self, new_character: &'a mut Character<'a>){ | |
105 | + // self.character_b = Some(new_character); | |
106 | + // } | |
107 | + | |
108 | + pub fn init(&mut self) { | |
109 | + | |
110 | + println!("{} vs {}", self.character_a.get_name(), self.character_b.get_name()); | |
111 | + | |
112 | + | |
113 | + | |
114 | + //let ground_level = self.window.size().y as f32 - 50.0 - 100.0; | |
115 | + | |
116 | + //let mut background_sprite = Sprite::new(); | |
117 | + //self.myRenderer.background_sprite.set_texture(&self.system_textures[System_texture_Ids::BACKGROUND as usize], true); | |
118 | + | |
119 | + // let mut left_health_bar_sprite = Sprite::new(); | |
120 | + // left_health_bar_sprite.set_texture(&self.textures[Texture_Ids::HEALTH_BAR as usize], true); | |
121 | + //let mut left_health_bar = health_bar::HealthBar::new(&self.system_textures[System_texture_Ids::HEALTH_BAR as usize], true, self.window.size().x); | |
122 | + //let mut right_health_bar = health_bar::HealthBar::new(&self.system_textures[System_texture_Ids::HEALTH_BAR as usize], false, self.window.size().x); | |
123 | + | |
124 | + //let mut right_health_bar_sprite = Sprite::new(); | |
125 | + //right_health_bar_sprite.set_texture(&self.textures[Texture_Ids::HEALTH_BAR as usize], true); | |
126 | + | |
127 | + //let groundLevel = self.window.size().y as f32 - 50.0 - 100.0; | |
128 | + //let groundLevel = getGroundLevel(& self.window); | |
129 | + | |
130 | + | |
131 | + // self.myRenderer.prepareSprites(&mut self.window, &mut self.character_a, &mut self.character_b, groundLevel); | |
132 | + | |
133 | + self.myRenderer.init(& mut self.window, &mut self.character_a, &mut self.character_b); | |
134 | + | |
87 | 135 | } |
88 | 136 | |
89 | - pub fn set_character_b(&mut self, new_character: &'a Character){ | |
90 | - self.character_b = Some(new_character); | |
91 | - } | |
92 | - | |
93 | - //TODO: find a better name | |
94 | - pub fn run(&self) { | |
137 | + // //TODO: find a better name | |
138 | + pub fn run(&mut self) { | |
95 | 139 | |
96 | 140 | // poll event from keyboard E |
97 | 141 | // send E to KeyProcessor |
@@ -102,85 +146,64 @@ | ||
102 | 146 | //If True - queue interaction_event to character (for example "is_hit") |
103 | 147 | //If False - CharacterX.sprite.update() |
104 | 148 | |
105 | - let mut window = self.myRenderer.prepare_window(); | |
106 | - | |
107 | - | |
108 | - let mut character_a: Character = Character ::new("Sub Zero", 100, true, self.char_textures); | |
109 | - let mut character_b: Character = Character ::new("Sub Zero", 100, true, self.char_textures); | |
110 | - | |
111 | - | |
112 | - println!("{} vs {}", character_a.get_name(), character_b.get_name()); | |
113 | - | |
114 | - let ground_level = window.size().y as f32 - 50.0 - 100.0; | |
149 | + //let mut window = self.myRenderer.prepare_window(); | |
115 | 150 | |
116 | - let mut background_sprite = Sprite::new(); | |
117 | - background_sprite.set_texture(&self.system_textures[System_texture_Ids::BACKGROUND as usize], true); | |
118 | - | |
119 | - // let mut left_health_bar_sprite = Sprite::new(); | |
120 | - // left_health_bar_sprite.set_texture(&self.textures[Texture_Ids::HEALTH_BAR as usize], true); | |
121 | - let mut left_health_bar = health_bar::HealthBar::new(&self.system_textures[System_texture_Ids::HEALTH_BAR as usize], true, window.size().x); | |
122 | - let mut right_health_bar = health_bar::HealthBar::new(&self.system_textures[System_texture_Ids::HEALTH_BAR as usize], false, window.size().x); | |
123 | - | |
124 | - //let mut right_health_bar_sprite = Sprite::new(); | |
125 | - //right_health_bar_sprite.set_texture(&self.textures[Texture_Ids::HEALTH_BAR as usize], true); | |
126 | - | |
127 | - self.myRenderer.prepareSprites(& window, &mut character_a, &mut character_b, &mut background_sprite, ground_level); | |
128 | - | |
151 | + //let mut character_a: &Character = self.character_a.unwrap(); | |
152 | + //let mut character_b = self.character_b.unwrap(); | |
153 | + //let mut character_a = self.character_a.unwrap(); | |
129 | 154 | |
130 | 155 | //let key_processor = KeyProcessor::new(); |
131 | 156 | |
157 | + | |
132 | 158 | //loop |
133 | 159 | |
134 | - //let &mut mut stateReference: &mut i32; | |
135 | - while window.is_open() { | |
136 | - for event in window.poll_event() { | |
160 | + while self.window.is_open() { | |
161 | + | |
162 | + // Is this for loop needed now ? We no longer use control by events, we check which keys are pressed in key_processor | |
163 | + for event in self.window.poll_event() { | |
137 | 164 | match event { |
138 | - Event::Closed => window.close(), | |
165 | + Event::Closed => self.window.close(), | |
139 | 166 | _ => { /* do nothing */ } |
140 | 167 | } |
141 | 168 | } |
142 | 169 | |
170 | + //let groundLevel = self.window.size().y as f32 - 50.0 - 100.0; | |
171 | + let ground_level = get_ground_level(& self.window); | |
143 | 172 | |
144 | 173 | //key_processing::processKeyPress(&self.key_processor, &mut window, &mut character_a, &mut character_b, ground_level); |
145 | - self.key_processor.processKeyPress( &mut window, &mut character_a, &mut character_b, ground_level); | |
146 | 174 | |
147 | - left_health_bar.update(character_a.get_hp()); | |
148 | - right_health_bar.update(character_b.get_hp()); | |
149 | - self.myRenderer.displayWindow(&mut window, &background_sprite, &character_a.char_sprite.sprite, &character_b.char_sprite.sprite, &left_health_bar, &right_health_bar); | |
175 | + let key_results = self.key_processor.get_keys_pressed(); | |
176 | + | |
177 | + self.key_processor.process_key_press(&mut self.window, &mut self.character_a, &mut self.character_b, key_results, ground_level); | |
178 | + | |
179 | + self.myRenderer.left_health_bar.update(self.character_a.get_hp()); | |
180 | + self.myRenderer.right_health_bar.update(self.character_b.get_hp()); | |
181 | + self.myRenderer.display_window(&mut self.window, &self.character_a.char_sprite.sprite, &self.character_b.char_sprite.sprite); | |
150 | 182 | |
151 | 183 | //end main loop |
152 | 184 | } |
153 | 185 | |
154 | - | |
155 | 186 | } |
156 | 187 | |
157 | 188 | } |
158 | 189 | |
159 | -pub fn tryUpdatingSprites(character_a: &mut Character, character_b: &mut Character, | |
160 | - output_a: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError>, | |
161 | - output_b: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError> | |
190 | +pub fn get_ground_level(window : & RenderWindow) ->f32 | |
191 | +{ | |
192 | + window.size().y as f32 - 50.0 - 100.0 | |
193 | +} | |
194 | + | |
195 | +pub fn try_updating_sprites(character_a: &mut Character, character_b: &mut Character, | |
196 | + output_a: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError>, | |
197 | + output_b: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError> | |
162 | 198 | ) |
163 | 199 | { |
164 | 200 | |
165 | - let attack_dmg = is_attacking(&character_a, &character_b); | |
201 | + resolve_combat(character_a, character_b); | |
166 | 202 | |
167 | - if attack_dmg > 0 { | |
168 | - //A hit B | |
169 | - println!("A hit B"); | |
170 | - character_b.update_hp(- attack_dmg); | |
171 | - println!("B HP: {}", character_b.get_hp()); | |
172 | - } | |
173 | - if attack_dmg < 0 { | |
174 | - //B hit A | |
175 | - println!("B hit A"); | |
176 | - character_a.update_hp(attack_dmg); | |
177 | - println!("A HP: {}", character_a.get_hp()); | |
178 | - } | |
179 | 203 | |
180 | - if !check_collision(&character_a, &character_b) { | |
181 | - //character_A.update_sprite(); | |
182 | - //character_B.update_sprite(); | |
183 | - | |
204 | + if !check_collision(character_a.char_sprite.sprite.position(), character_b.char_sprite.sprite.position(), | |
205 | + character_a.get_state(), character_b.get_state()) | |
206 | + { | |
184 | 207 | match output_b { |
185 | 208 | Ok(v) => { |
186 | 209 | character_b.update_sprite(v); |
@@ -198,72 +221,158 @@ | ||
198 | 221 | |
199 | 222 | } |
200 | 223 | |
201 | -pub fn is_attacking(character_a: & Character, character_b: & Character) -> i32 | |
224 | +pub fn resolve_combat( character_a: &mut Character, character_b: &mut Character ) | |
202 | 225 | { |
203 | 226 | |
204 | - let pos_a: Vector2f = character_a.char_sprite.sprite.position(); | |
205 | - let pos_b: Vector2f = character_b.char_sprite.sprite.position(); | |
206 | - | |
207 | - | |
208 | - let state_a:i32 = getStateAsInt32(character_a.get_state()); | |
209 | - let state_b:i32 = getStateAsInt32(character_b.get_state()); | |
210 | - | |
227 | + let char_a_pos: Vector2f = character_a.char_sprite.sprite.position(); | |
228 | + let char_b_pos: Vector2f = character_b.char_sprite.sprite.position(); | |
211 | 229 | |
212 | - let mut attack_range = 0.0; | |
230 | + let curr_combat_status = get_combat_status( character_a.get_state(), character_b.get_state() ); | |
213 | 231 | |
214 | - if (state_a == state_enums::States::Punching as i32 || state_b == state_enums::States::Punching as i32) | |
215 | - { | |
216 | - attack_range = punch_range; | |
217 | - } | |
218 | - if (state_a == state_enums::States::Kicking as i32 || state_b == state_enums::States::Kicking as i32) | |
219 | - { | |
220 | - attack_range = kick_range; | |
232 | + match &curr_combat_status { | |
233 | + Combat_status::A_ATTACKS_B => { | |
234 | + if is_chars_in_attack_range( char_a_pos, char_b_pos, character_a.get_state()) | |
235 | + { | |
236 | + let attack_dmg = get_attack_dmg( character_a.get_state()); | |
237 | + println!("A hit B"); | |
238 | + character_b.update_hp(-attack_dmg); | |
239 | + println!("B HP: {}", character_b.get_hp()); | |
240 | + } | |
241 | + } | |
242 | + Combat_status::B_ATTACKS_A => { | |
243 | + if is_chars_in_attack_range( char_a_pos, char_b_pos, character_b.get_state()) | |
244 | + { | |
245 | + let attack_dmg = get_attack_dmg( character_b.get_state() ); | |
246 | + //B hit A | |
247 | + println!("B hit A"); | |
248 | + character_a.update_hp(-attack_dmg); | |
249 | + println!("A HP: {}", character_a.get_hp()); | |
250 | + } | |
251 | + } | |
252 | + Combat_status::BOTH => { | |
253 | + if is_chars_in_attack_range( char_a_pos, char_b_pos, character_a.get_state() ) | |
254 | + { | |
255 | + let attack_dmg = get_attack_dmg( character_a.get_state() ); | |
256 | + println!("A hit B"); | |
257 | + character_b.update_hp(-attack_dmg); | |
258 | + println!("B HP: {}", character_b.get_hp()); | |
259 | + } | |
260 | + | |
261 | + if is_chars_in_attack_range( char_a_pos, char_b_pos, character_b.get_state() ) | |
262 | + { | |
263 | + //B hit A | |
264 | + let attack_dmg = get_attack_dmg( character_b.get_state() ); | |
265 | + println!("B hit A"); | |
266 | + character_a.update_hp(-attack_dmg); | |
267 | + println!("A HP: {}", character_a.get_hp()); | |
268 | + } | |
269 | + } | |
270 | + Combat_status::NONE => {} | |
221 | 271 | } |
222 | 272 | |
223 | - if (pos_a.x + char_width - pos_b.x - 1.0).abs() > attack_range | |
273 | +} | |
274 | + | |
275 | +pub fn get_combat_status(char_a_state: &character_state_machine::CharacterFSMState, | |
276 | + char_b_state: &character_state_machine::CharacterFSMState) -> Combat_status | |
277 | +{ | |
278 | + let state_a:i32 = get_state_as_int32(char_a_state); | |
279 | + let state_b:i32 = get_state_as_int32(char_b_state); | |
280 | + | |
281 | + if ( state_a == state_enums::States::Punching as i32 | |
282 | + || state_a == state_enums::States::Kicking as i32 | |
283 | + ) | |
284 | + && | |
285 | + (state_b != state_enums::States::Punching as i32 | |
286 | + && state_b != state_enums::States::Kicking as i32 | |
287 | + ) | |
224 | 288 | { |
225 | - //too far apart | |
226 | - return 0; | |
227 | - } | |
228 | - | |
229 | - if (state_a == state_enums::States::Punching as i32 && state_b != state_enums::States::Punching as i32) | |
230 | - { | |
231 | - return punch_dmg; | |
289 | + return Combat_status::A_ATTACKS_B; | |
232 | 290 | } |
233 | 291 | |
234 | - if (state_b == state_enums::States::Punching as i32 && state_a != state_enums::States::Punching as i32) | |
292 | + if ( state_b == state_enums::States::Punching as i32 | |
293 | + || state_b == state_enums::States::Kicking as i32 | |
294 | + ) | |
295 | + && | |
296 | + (state_a != state_enums::States::Punching as i32 | |
297 | + && state_a != state_enums::States::Kicking as i32 | |
298 | + ) | |
235 | 299 | { |
236 | - return -punch_dmg; | |
300 | + return Combat_status::B_ATTACKS_A; | |
237 | 301 | } |
238 | 302 | |
239 | - if (state_a == state_enums::States::Kicking as i32 && state_b != state_enums::States::Kicking as i32) | |
303 | + if ( state_a == state_enums::States::Punching as i32 | |
304 | + || state_a == state_enums::States::Kicking as i32 | |
305 | + ) | |
306 | + && | |
307 | + (state_b == state_enums::States::Punching as i32 | |
308 | + || state_b == state_enums::States::Kicking as i32 | |
309 | + ) | |
240 | 310 | { |
241 | - return kick_dmg; | |
311 | + return Combat_status::BOTH; | |
242 | 312 | } |
243 | 313 | |
244 | - if (state_b == state_enums::States::Kicking as i32 && state_a != state_enums::States::Kicking as i32) | |
314 | + return Combat_status::NONE; | |
315 | +} | |
316 | + | |
317 | +pub fn is_chars_in_attack_range(char_a_pos: Vector2f, char_b_pos: Vector2f, | |
318 | + attacking_char_state: &character_state_machine::CharacterFSMState ) -> bool | |
319 | +{ | |
320 | + let mut attack_range = 0.0; | |
321 | + | |
322 | + let state_a:i32 = get_state_as_int32(attacking_char_state); | |
323 | + //let state_b:i32 = get_state_as_int32(defending_char_state); | |
324 | + | |
325 | + if state_a == state_enums::States::Punching as i32 | |
245 | 326 | { |
246 | - return -kick_dmg; | |
327 | + println!("PUNCH!"); | |
328 | + attack_range = PUNCH_RANGE; | |
329 | + } | |
330 | + else if state_a == state_enums::States::Kicking as i32 | |
331 | + { | |
332 | + println!("KICK!"); | |
333 | + attack_range = KICK_RANGE; | |
334 | + } | |
335 | + else { | |
336 | + return false; | |
247 | 337 | } |
248 | 338 | |
249 | - return 0; | |
339 | + //println!("HIT ? {}", ( (char_a_pos.x + CHAR_WIDTH - char_b_pos.x - 1.0).abs() <= attack_range ) ); | |
340 | + | |
341 | + return (char_a_pos.x + CHAR_WIDTH - char_b_pos.x ).abs() <= attack_range ; | |
342 | +} | |
343 | + | |
344 | +pub fn get_attack_dmg(attacking_char_state: &character_state_machine::CharacterFSMState ) -> i32 | |
345 | +{ | |
346 | + let state_a:i32 = get_state_as_int32(attacking_char_state); | |
347 | + | |
348 | + if state_a == state_enums::States::Punching as i32 | |
349 | + { | |
350 | + return PUNCH_DMG; | |
351 | + } | |
352 | + if state_a == state_enums::States::Kicking as i32 | |
353 | + { | |
354 | + return KICK_DMG; | |
355 | + } | |
356 | + | |
357 | + return 0; | |
250 | 358 | } |
251 | 359 | |
252 | 360 | |
253 | -pub fn check_collision(character_a: & Character, character_b: & Character) -> bool | |
361 | +pub fn check_collision(char_a_pos: Vector2f, char_b_pos: Vector2f, char_a_state: &character_state_machine::CharacterFSMState, | |
362 | + char_b_state: &character_state_machine::CharacterFSMState) ->bool | |
254 | 363 | { |
255 | 364 | println!("Check collision Enter"); |
256 | 365 | |
257 | 366 | |
258 | - let pos_a: Vector2f = character_a.char_sprite.sprite.position(); | |
259 | - let pos_b: Vector2f = character_b.char_sprite.sprite.position(); | |
367 | + //let pos_a: Vector2f = character_a.char_sprite.sprite.position(); | |
368 | + //let pos_b: Vector2f = character_b.char_sprite.sprite.position(); | |
260 | 369 | |
261 | 370 | |
262 | 371 | //println!("checkCollision. A.state: {} B.state: {}", characterA.get_num_state(), characterB.get_num_state() ); |
263 | 372 | |
264 | 373 | |
265 | - let state_a:i32 = getStateAsInt32(character_a.get_state()); | |
266 | - let state_b:i32 = getStateAsInt32(character_b.get_state()); | |
374 | + let state_a:i32 = get_state_as_int32(char_a_state); | |
375 | + let state_b:i32 = get_state_as_int32(char_b_state); | |
267 | 376 | |
268 | 377 | |
269 | 378 | println!("checkCollision. A.state: {} B.state: {}", state_a, state_b); |
@@ -286,7 +395,7 @@ | ||
286 | 395 | || state_b == state_enums::States::Punching as i32 |
287 | 396 | || state_b == state_enums::States::Kicking as i32 |
288 | 397 | ) |
289 | - { let val = (pos_a.x - 1.0 + char_width - pos_b.x).abs() ; | |
398 | + { let val = (char_a_pos.x - 1.0 + CHAR_WIDTH - char_b_pos.x).abs() ; | |
290 | 399 | println!("Check collision B : {}", val); |
291 | 400 | |
292 | 401 | //return val < 1.0; |
@@ -301,7 +410,7 @@ | ||
301 | 410 | { |
302 | 411 | println!("Check collision C"); |
303 | 412 | |
304 | - return (pos_a.x + char_width - pos_b.x - 1.0).abs() <= 1.0; | |
413 | + return (char_a_pos.x + CHAR_WIDTH - char_b_pos.x - 1.0).abs() <= 1.0; | |
305 | 414 | } |
306 | 415 | |
307 | 416 | if ( state_a == state_enums::States::Idle as i32 || state_a == state_enums::States::Crouching as i32 |
@@ -319,12 +428,12 @@ | ||
319 | 428 | { |
320 | 429 | println!("Check collision E"); |
321 | 430 | |
322 | - return (pos_a.x + char_width - pos_b.x).abs() <= 10.0; | |
431 | + return (char_a_pos.x + CHAR_WIDTH - char_b_pos.x).abs() <= 10.0; | |
323 | 432 | } |
324 | 433 | |
325 | 434 | if state_a == state_enums::States::MovingLeft as i32 && state_b == state_enums::States::MovingRight as i32 |
326 | 435 | { |
327 | - let val = (pos_a.x + char_width - pos_b.x ).abs() ; | |
436 | + let val = (char_a_pos.x + CHAR_WIDTH - char_b_pos.x ).abs() ; | |
328 | 437 | println!("Check collision F : {}", val); |
329 | 438 | |
330 | 439 | //return val < 1.0; |
@@ -334,7 +443,7 @@ | ||
334 | 443 | return false; |
335 | 444 | } |
336 | 445 | |
337 | -pub fn getStateAsInt32(raw_state: &character_state_machine::CharacterFSMState) -> i32 | |
446 | +pub fn get_state_as_int32(raw_state: &character_state_machine::CharacterFSMState) -> i32 | |
338 | 447 | { |
339 | 448 | match raw_state { |
340 | 449 | character_state_machine::CharacterFSMState::StandMoveBack => state_enums::States::MovingLeft as i32, |
@@ -349,6 +458,7 @@ | ||
349 | 458 | } |
350 | 459 | } |
351 | 460 | |
461 | + | |
352 | 462 | pub fn save_test_data_to_file(ground_level:f32, sprite_a: &CharacterSprite, sprite_b: &CharacterSprite) |
353 | 463 | { |
354 | 464 | let mut data_to_dump: String = "spriteAData\n".to_string(); |
@@ -1,9 +1,8 @@ | ||
1 | 1 | use sfml::{ |
2 | 2 | graphics::{RenderWindow}, |
3 | - window::{Event, Key}, | |
3 | + window::{ Key}, | |
4 | 4 | }; |
5 | 5 | |
6 | -use crate::key_processing::KeyEvents::{CharLeft, CharRight, CharKeyRelease}; | |
7 | 6 | |
8 | 7 | use crate::character::Character; |
9 | 8 |
@@ -12,15 +11,14 @@ | ||
12 | 11 | |
13 | 12 | use crate::controller; |
14 | 13 | |
15 | -use crate::state_enums; | |
16 | 14 | |
17 | 15 | //use crate::sprite_rendering; |
18 | 16 | |
19 | 17 | // pub const KEY_BASE : i32 = 10; |
20 | 18 | |
21 | 19 | pub enum KeyEvents { |
22 | - //None = -1, | |
23 | - //Escape, | |
20 | + None = -1, | |
21 | + Escape, | |
24 | 22 | CharLeft, |
25 | 23 | CharRight, |
26 | 24 | CharDown, |
@@ -33,7 +31,7 @@ | ||
33 | 31 | CharBPunch = 14, |
34 | 32 | CharBKick = 15, |
35 | 33 | //CharBKeyRelease = 13, |
36 | - //KeyTesting = 99 | |
34 | + KeyDump = 99 | |
37 | 35 | } |
38 | 36 | |
39 | 37 |
@@ -54,67 +52,102 @@ | ||
54 | 52 | } |
55 | 53 | |
56 | 54 | |
57 | - pub fn processKeyPress(&self, window : &mut RenderWindow, character_a: &mut Character, character_b: &mut Character, | |
58 | - ground_level: f32, | |
55 | + pub fn get_keys_pressed(&self) -> Vec<KeyEvents> | |
56 | + { | |
57 | + let mut vec:Vec<KeyEvents> = Vec::new(); | |
58 | + | |
59 | + if Key::A.is_pressed() | |
60 | + { | |
61 | + vec.push(KeyEvents::CharBLeft); | |
62 | + } | |
63 | + if Key::D.is_pressed() | |
64 | + { | |
65 | + vec.push(KeyEvents::CharBRight); | |
66 | + } | |
67 | + if Key::S.is_pressed() | |
68 | + { | |
69 | + vec.push(KeyEvents::CharBDown); | |
70 | + } | |
71 | + if Key::Q.is_pressed() | |
72 | + { | |
73 | + vec.push(KeyEvents::CharBPunch); | |
74 | + } | |
75 | + if Key::E.is_pressed() | |
76 | + { | |
77 | + vec.push(KeyEvents::CharBKick); | |
78 | + } | |
79 | + | |
80 | + if Key::F4.is_pressed() | |
81 | + { | |
82 | + //println!("Testing: dump values to check"); | |
83 | + //controller::save_test_data_to_file(ground_level, &character_a.char_sprite, &character_b.char_sprite); | |
84 | + //return KeyEvents:: | |
85 | + vec.push(KeyEvents::KeyDump); | |
86 | + } | |
87 | + if Key::ESCAPE.is_pressed() | |
88 | + { | |
89 | + //window.close(); | |
90 | + vec.push(KeyEvents::Escape); | |
91 | + } | |
92 | + | |
93 | + if Key::LEFT.is_pressed() | |
94 | + { | |
95 | + vec.push(KeyEvents::CharLeft); | |
96 | + } | |
97 | + if Key::RIGHT.is_pressed() | |
98 | + { | |
99 | + vec.push(KeyEvents::CharRight); | |
100 | + } | |
101 | + if Key::DOWN.is_pressed() | |
102 | + { | |
103 | + vec.push(KeyEvents::CharDown); | |
104 | + } | |
105 | + if Key::ENTER.is_pressed() | |
106 | + { | |
107 | + vec.push(KeyEvents::CharPunch); | |
108 | + } | |
109 | + if Key::RSHIFT.is_pressed() | |
110 | + { | |
111 | + vec.push(KeyEvents::CharKick); | |
112 | + } | |
113 | + | |
114 | + | |
115 | + return vec; | |
116 | + } | |
117 | + | |
118 | + pub fn process_key_press(&self, window : &mut RenderWindow, character_a: &mut Character, character_b: &mut Character, key_result :Vec<KeyEvents>, | |
119 | + ground_level: f32, | |
59 | 120 | ) |
60 | 121 | { |
61 | 122 | let mut output_a: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError> = character_a.trigger(character_state_machine::CharacterFSMInput::Released); |
62 | 123 | let mut output_b: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError> = character_b.trigger(character_state_machine::CharacterFSMInput::Released); |
63 | 124 | |
64 | - | |
65 | - //let mut key_result = key_processor.match_key(); | |
66 | - if Key::A.is_pressed() | |
67 | - { | |
68 | - output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBLeft); | |
69 | - } | |
70 | - if Key::D.is_pressed() | |
125 | + for res in key_result | |
71 | 126 | { |
72 | - output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBRight); | |
73 | - } | |
74 | - if Key::S.is_pressed() | |
75 | - { | |
76 | - output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBDown); | |
77 | - } | |
78 | - if Key::Q.is_pressed() | |
79 | - { | |
80 | - output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBPunch); | |
81 | - } | |
82 | - if Key::E.is_pressed() | |
83 | - { | |
84 | - output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBKick); | |
127 | + match res { | |
128 | + KeyEvents::None => { } , | |
129 | + KeyEvents::Escape => { window.close();} , | |
130 | + KeyEvents::KeyDump => {controller::save_test_data_to_file(ground_level, &character_a.char_sprite, &character_b.char_sprite);} | |
131 | + | |
132 | + | |
133 | + KeyEvents::CharBLeft => output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBLeft), | |
134 | + KeyEvents::CharBRight => output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBRight), | |
135 | + KeyEvents::CharBDown => output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBDown), | |
136 | + KeyEvents::CharBPunch => output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBPunch), | |
137 | + KeyEvents::CharBKick => output_b = self.process_key_result_for_character( character_b, KeyEvents::CharBKick), | |
138 | + | |
139 | + KeyEvents::CharKeyRelease => { } , | |
140 | + | |
141 | + KeyEvents::CharLeft => output_a = self.process_key_result_for_character( character_a, KeyEvents::CharLeft), | |
142 | + KeyEvents::CharRight => output_a = self.process_key_result_for_character( character_a, KeyEvents::CharRight), | |
143 | + KeyEvents::CharDown => output_a = self.process_key_result_for_character( character_a, KeyEvents::CharDown), | |
144 | + KeyEvents::CharPunch => output_a = self.process_key_result_for_character( character_a, KeyEvents::CharPunch), | |
145 | + KeyEvents::CharKick => output_a = self.process_key_result_for_character( character_a, KeyEvents::CharKick), | |
146 | + } | |
147 | + | |
85 | 148 | } |
86 | 149 | |
87 | - if Key::F4.is_pressed() | |
88 | - { | |
89 | - println!("Testing: dump values to check"); | |
90 | - controller::save_test_data_to_file(ground_level, &character_a.char_sprite, &character_b.char_sprite); | |
91 | - } | |
92 | - if Key::ESCAPE.is_pressed() | |
93 | - { | |
94 | - window.close(); | |
95 | - } | |
96 | - if Key::LEFT.is_pressed() | |
97 | - { | |
98 | - output_a = self.process_key_result_for_character( character_a, KeyEvents::CharLeft); | |
99 | - } | |
100 | - if Key::RIGHT.is_pressed() | |
101 | - { | |
102 | - output_a = self.process_key_result_for_character( character_a, KeyEvents::CharRight); | |
103 | - } | |
104 | - if Key::DOWN.is_pressed() | |
105 | - { | |
106 | - output_a = self.process_key_result_for_character( character_a, KeyEvents::CharDown); | |
107 | - } | |
108 | - if Key::ENTER.is_pressed() | |
109 | - { | |
110 | - output_a = self.process_key_result_for_character( character_a, KeyEvents::CharPunch); | |
111 | - } | |
112 | - if Key::RSHIFT.is_pressed() | |
113 | - { | |
114 | - output_a = self.process_key_result_for_character( character_a, KeyEvents::CharKick); | |
115 | - } | |
116 | - | |
117 | - controller::tryUpdatingSprites(character_a, character_b, output_a, output_b); | |
150 | + controller::try_updating_sprites(character_a, character_b, output_a, output_b); | |
118 | 151 | |
119 | 152 | |
120 | 153 | } |
@@ -123,6 +156,11 @@ | ||
123 | 156 | { |
124 | 157 | |
125 | 158 | match key_result { |
159 | + KeyEvents::None => character.trigger(character_state_machine::CharacterFSMInput::Released), | |
160 | + KeyEvents::Escape => character.trigger(character_state_machine::CharacterFSMInput::Released), | |
161 | + KeyEvents::KeyDump => character.trigger(character_state_machine::CharacterFSMInput::Released), | |
162 | + | |
163 | + | |
126 | 164 | KeyEvents::CharBLeft => character.trigger(character_state_machine::CharacterFSMInput::FrontPressed), |
127 | 165 | KeyEvents::CharBRight => character.trigger(character_state_machine::CharacterFSMInput::BackPressed), |
128 | 166 | KeyEvents::CharBDown => character.trigger(character_state_machine::CharacterFSMInput::Crouch), |
@@ -1,15 +1,3 @@ | ||
1 | -use sfml::{ | |
2 | - graphics::{ | |
3 | - RenderWindow, Transformable | |
4 | - }, | |
5 | - window::{ ContextSettings, Style}, | |
6 | - | |
7 | -}; | |
8 | -use crate::sprite_rendering::CharacterSprite; | |
9 | - | |
10 | -use std::fs::File; | |
11 | -use std::io::prelude::*; | |
12 | -use std::path::Path; | |
13 | 1 | |
14 | 2 | mod sprite_rendering; |
15 | 3 | mod key_processing; |
@@ -19,32 +7,24 @@ | ||
19 | 7 | mod renderer; |
20 | 8 | mod state_enums; |
21 | 9 | mod health_bar; |
10 | +mod tests; | |
22 | 11 | |
23 | 12 | |
24 | 13 | fn main() { |
25 | 14 | println!("Silny-Kombat!"); |
26 | 15 | |
27 | - let textures = renderer::myTextures::new(); | |
28 | 16 | |
29 | - let controller = controller::Controller::new(&textures.texturesArray, &textures.systemTexturesArray); | |
30 | - controller.run(); | |
31 | -} | |
32 | - | |
33 | - | |
34 | -pub fn add(a: i32, b: i32) -> i32 { | |
35 | - a + b | |
36 | -} | |
17 | + let textures = renderer::myTextures::new(); | |
37 | 18 | |
38 | 19 | |
39 | -#[cfg(test)] | |
40 | -mod tests { | |
41 | - | |
42 | - use super::*; | |
20 | + let mut character_a = character::Character::new("Sub Zero", 100, true, &textures.texturesArray); | |
21 | + let mut character_b = character::Character::new("Sub Zero", 100, true, &textures.texturesArray); | |
43 | 22 | |
44 | - //example test | |
45 | - #[test] | |
46 | - fn test_add() { | |
47 | - assert_eq!(add(1, 2), 3); | |
48 | - } | |
49 | 23 | |
50 | -} | |
\ No newline at end of file | ||
24 | + let mut controller = controller::Controller::new( character_a, character_b, &textures.texturesArray, &textures.systemTexturesArray); | |
25 | + | |
26 | + controller.init(); | |
27 | + | |
28 | + controller.run(); | |
29 | + | |
30 | +} |
@@ -1,21 +1,23 @@ | ||
1 | 1 | |
2 | 2 | use crate::controller; |
3 | 3 | use crate::character::Character; |
4 | +use crate::health_bar; | |
4 | 5 | |
5 | 6 | use sfml::{ |
6 | 7 | graphics::{ |
7 | 8 | Color, Transformable, Texture, RenderWindow, RenderTarget, Sprite |
8 | 9 | }, |
9 | - window::{ ContextSettings, Style, Event}, | |
10 | + window::{ ContextSettings, Style}, | |
10 | 11 | system::Vector2f, |
11 | 12 | SfBox |
12 | 13 | }; |
13 | -use crate::health_bar::HealthBar; | |
14 | + | |
14 | 15 | |
15 | 16 | |
16 | 17 | pub struct myTextures { |
17 | 18 | pub texturesArray: [SfBox<Texture>; controller::TEXTURE_ARRAY_SIZE], |
18 | 19 | pub systemTexturesArray : [SfBox<Texture>; controller::SYSTEM_TEXTURE_ARRAY_SIZE], |
20 | + | |
19 | 21 | } |
20 | 22 | |
21 | 23 | impl myTextures { |
@@ -31,26 +33,45 @@ | ||
31 | 33 | ], |
32 | 34 | systemTexturesArray: [Texture::from_file("backgrounds/01.png").unwrap(), |
33 | 35 | Texture::from_file("sprites//hud//health_bar.gif").unwrap() |
34 | - ] | |
36 | + ], | |
37 | + | |
38 | + | |
35 | 39 | } |
36 | 40 | |
37 | 41 | |
38 | 42 | } |
39 | 43 | } |
40 | 44 | |
41 | -pub struct Renderer { | |
45 | +pub struct Renderer<'a> { | |
42 | 46 | |
47 | + window_width : u32, | |
48 | + | |
49 | + pub background_sprite : Sprite<'a>, | |
50 | + background_texture : &'a Texture, | |
51 | + | |
52 | + pub left_health_bar : health_bar::HealthBar<'a>, | |
53 | + pub right_health_bar : health_bar::HealthBar<'a>, | |
43 | 54 | } |
44 | 55 | |
45 | -impl Renderer{ | |
46 | - pub fn new() -> Self{ | |
56 | +impl<'a> Renderer<'a>{ | |
57 | + pub fn new(window_width: u32, bgTexture : &'a Texture , HpTexture: &'a Texture) -> Self{ | |
58 | + | |
59 | + | |
47 | 60 | Renderer { |
48 | - | |
61 | + window_width, | |
62 | + background_sprite : Sprite::new(), | |
63 | + background_texture : bgTexture, | |
64 | + left_health_bar : health_bar::HealthBar::new(&HpTexture, true, window_width), | |
65 | + right_health_bar : health_bar::HealthBar::new(&HpTexture, false, window_width) | |
49 | 66 | } |
50 | 67 | } |
51 | 68 | |
52 | - pub fn prepareSprites(&self, window : & RenderWindow, character_a: & mut Character, character_b: & mut Character, background_sprite : & mut Sprite, ground_level : f32) | |
69 | + pub fn init(&mut self, window : &mut RenderWindow , character_a: & mut Character, character_b: & mut Character) | |
53 | 70 | { |
71 | + self.background_sprite.set_texture(&self.background_texture, true); | |
72 | + | |
73 | + let ground_level = controller::get_ground_level(window); | |
74 | + | |
54 | 75 | character_a.char_sprite.sprite.set_scale(Vector2f::new(1.0, 1.0)); |
55 | 76 | character_b.char_sprite.sprite.set_scale(Vector2f::new(-1.0, 1.0)); |
56 | 77 |
@@ -59,9 +80,9 @@ | ||
59 | 80 | |
60 | 81 | |
61 | 82 | let target_size: Vector2f = Vector2f::new(window.size().x as f32, window.size().y as f32); |
62 | - let mut scale_vect: Vector2f = Vector2f::new(target_size.x / background_sprite.local_bounds().width, | |
63 | - target_size.y / background_sprite.local_bounds().height); | |
64 | - background_sprite.set_scale(scale_vect); | |
83 | + let mut scale_vect: Vector2f = Vector2f::new(target_size.x / &self.background_sprite.local_bounds().width, | |
84 | + target_size.y / &self.background_sprite.local_bounds().height); | |
85 | + &self.background_sprite.set_scale(scale_vect); | |
65 | 86 | |
66 | 87 | } |
67 | 88 |
@@ -83,14 +104,14 @@ | ||
83 | 104 | window |
84 | 105 | } |
85 | 106 | |
86 | - pub fn displayWindow(&self, window: &mut RenderWindow, background_sprite: &Sprite, char_A_sprite : &Sprite , char_B_sprite : &Sprite, left_health_bar: &HealthBar, right_health_bar: &HealthBar) | |
107 | + pub fn display_window(&self, window: &mut RenderWindow, char_A_sprite : &Sprite, char_B_sprite : &Sprite) | |
87 | 108 | { |
88 | 109 | window.clear(Color::rgb(50, 200, 50)); |
89 | - window.draw(background_sprite); | |
110 | + window.draw(&self.background_sprite); | |
90 | 111 | window.draw(char_A_sprite); |
91 | 112 | window.draw(char_B_sprite); |
92 | - window.draw(left_health_bar); | |
93 | - window.draw(right_health_bar); | |
113 | + window.draw(&self.left_health_bar); | |
114 | + window.draw(&self.right_health_bar); | |
94 | 115 | window.display(); |
95 | 116 | } |
96 | 117 |
@@ -0,0 +1,254 @@ | ||
1 | +use crate::key_processing; | |
2 | +use crate::controller; | |
3 | +use crate::character; | |
4 | +use crate::renderer; | |
5 | +use crate::character_state_machine; | |
6 | + | |
7 | +use sfml::{ | |
8 | + graphics::{ | |
9 | + RenderWindow , Sprite | |
10 | + }, | |
11 | + window::{ ContextSettings, Style, Event}, | |
12 | + | |
13 | +}; | |
14 | + | |
15 | + | |
16 | +// NOTE - to run, use: | |
17 | +// cargo test tests | |
18 | +// or: | |
19 | +// cargo test tests -- --nocapture | |
20 | +// if you want println! to work (otherwise it's not displayed) | |
21 | + | |
22 | +#[cfg(test)] | |
23 | +mod tests { | |
24 | + use sfml::graphics::Transformable; | |
25 | + use sfml::system::Vector2f; | |
26 | + use crate::controller::{CHAR_WIDTH, Combat_status, get_combat_status, is_chars_in_attack_range, KICK_DMG, KICK_RANGE, PUNCH_DMG, PUNCH_RANGE}; | |
27 | + use crate::key_processing::KeyEvents; | |
28 | + use super::*; | |
29 | + | |
30 | + | |
31 | + #[test] | |
32 | + fn test_check_collision() | |
33 | + { | |
34 | + { | |
35 | + //Expected result - no collision | |
36 | + assert!( ! controller::check_collision( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + controller::CHAR_WIDTH * 4.0 , 0.0), | |
37 | + &character_state_machine::CharacterFSMState::StandIdle , | |
38 | + &character_state_machine::CharacterFSMState::StandIdle ) ); | |
39 | + } | |
40 | + | |
41 | + { | |
42 | + //Expected result - no collision | |
43 | + assert!( ! controller::check_collision( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + controller::CHAR_WIDTH, 0.0), | |
44 | + &character_state_machine::CharacterFSMState::StandIdle , | |
45 | + &character_state_machine::CharacterFSMState::StandIdle ) ); | |
46 | + } | |
47 | + | |
48 | + { | |
49 | + //Expected result - collision | |
50 | + assert!( controller::check_collision( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + controller::CHAR_WIDTH, 0.0), | |
51 | + &character_state_machine::CharacterFSMState::StandIdle , | |
52 | + &character_state_machine::CharacterFSMState::StandMoveFront) ); | |
53 | + } | |
54 | + | |
55 | + { | |
56 | + //Expected result - collision | |
57 | + assert!( controller::check_collision( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + controller::CHAR_WIDTH, 0.0), | |
58 | + &character_state_machine::CharacterFSMState::StandMoveBack , | |
59 | + &character_state_machine::CharacterFSMState::StandMoveFront) ); | |
60 | + } | |
61 | + | |
62 | + } | |
63 | + | |
64 | + #[test] | |
65 | + fn test_get_combat_status() | |
66 | + { | |
67 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::StandIdle, | |
68 | + &character_state_machine::CharacterFSMState::StandIdle) as i32 , Combat_status::NONE as i32 ); | |
69 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::StandIdle, | |
70 | + &character_state_machine::CharacterFSMState::Punching) as i32 , Combat_status::B_ATTACKS_A as i32); | |
71 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::Punching, | |
72 | + &character_state_machine::CharacterFSMState::StandIdle) as i32 , Combat_status::A_ATTACKS_B as i32); | |
73 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::Punching, | |
74 | + &character_state_machine::CharacterFSMState::Punching) as i32 , Combat_status::BOTH as i32); | |
75 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::StandIdle, | |
76 | + &character_state_machine::CharacterFSMState::Kicking) as i32 , Combat_status::B_ATTACKS_A as i32); | |
77 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::Kicking, | |
78 | + &character_state_machine::CharacterFSMState::StandIdle) as i32 , Combat_status::A_ATTACKS_B as i32); | |
79 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::Kicking, | |
80 | + &character_state_machine::CharacterFSMState::Kicking) as i32 , Combat_status::BOTH as i32); | |
81 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::Punching, | |
82 | + &character_state_machine::CharacterFSMState::Kicking) as i32 , Combat_status::BOTH as i32); | |
83 | + assert_eq!( get_combat_status(&character_state_machine::CharacterFSMState::Kicking, | |
84 | + &character_state_machine::CharacterFSMState::Punching) as i32 , Combat_status::BOTH as i32); | |
85 | + } | |
86 | + | |
87 | + #[test] | |
88 | + fn test_is_chars_in_attack_range() | |
89 | + { | |
90 | + assert!( is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + PUNCH_RANGE, 0.0), | |
91 | + &character_state_machine::CharacterFSMState::Punching ) ); | |
92 | + assert!( is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + KICK_RANGE, 0.0), | |
93 | + &character_state_machine::CharacterFSMState::Kicking ) ); | |
94 | + | |
95 | + assert!( is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + PUNCH_RANGE - 10.0, 0.0), | |
96 | + &character_state_machine::CharacterFSMState::Punching ) ); | |
97 | + assert!( is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + KICK_RANGE - 10.0, 0.0), | |
98 | + &character_state_machine::CharacterFSMState::Kicking ) ); | |
99 | + | |
100 | + | |
101 | + assert!( ! is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + PUNCH_RANGE, 0.0), | |
102 | + &character_state_machine::CharacterFSMState::StandIdle ) ); | |
103 | + | |
104 | + assert!( ! is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + PUNCH_RANGE+10.0, 0.0), | |
105 | + &character_state_machine::CharacterFSMState::Punching ) ); | |
106 | + assert!( ! is_chars_in_attack_range( Vector2f::new(0.0, 0.0), Vector2f::new(0.0 + CHAR_WIDTH + KICK_RANGE+10.0, 0.0), | |
107 | + &character_state_machine::CharacterFSMState::Kicking ) ); | |
108 | + } | |
109 | + | |
110 | + #[test] | |
111 | + fn test_resolve_combat() | |
112 | + { | |
113 | + ///////Set up test | |
114 | + | |
115 | + let textures = renderer::myTextures::new(); | |
116 | + | |
117 | + | |
118 | + let mut character_a = character::Character::new("Sub Zero", 100, true, &textures.texturesArray); | |
119 | + let mut character_b = character::Character::new("Sub Zero", 100, true, &textures.texturesArray); | |
120 | + | |
121 | + character_a.char_sprite.sprite.set_scale(Vector2f::new(1.0, 1.0)); | |
122 | + character_b.char_sprite.sprite.set_scale(Vector2f::new(-1.0, 1.0)); | |
123 | + | |
124 | + character_a.char_sprite.sprite.set_position(Vector2f::new(0.0, 0.0)); | |
125 | + character_b.char_sprite.sprite.set_position(Vector2f::new(600.0, 0.0)); | |
126 | + | |
127 | + /////end setup | |
128 | + | |
129 | + { | |
130 | + character_b.char_sprite.sprite.set_position(Vector2f::new(CHAR_WIDTH*4.0, 0.0)); | |
131 | + controller::resolve_combat(&mut character_a, &mut character_b); | |
132 | + | |
133 | + assert_eq!( character_a.get_hp(), 100 ); | |
134 | + assert_eq!( character_b.get_hp(), 100 ); | |
135 | + } | |
136 | + | |
137 | + { | |
138 | + character_b.char_sprite.sprite.set_position(Vector2f::new(CHAR_WIDTH*4.0, 0.0)); | |
139 | + character_a.trigger(character_state_machine::CharacterFSMInput::Punch); | |
140 | + controller::resolve_combat(&mut character_a, &mut character_b); | |
141 | + | |
142 | + assert_eq!( character_a.get_hp(), 100 ); | |
143 | + assert_eq!( character_b.get_hp(), 100 ); | |
144 | + | |
145 | + character_a.trigger(character_state_machine::CharacterFSMInput::Released); | |
146 | + } | |
147 | + | |
148 | + { | |
149 | + character_b.char_sprite.sprite.set_position(Vector2f::new(CHAR_WIDTH+PUNCH_RANGE, 0.0)); | |
150 | + character_a.trigger(character_state_machine::CharacterFSMInput::Punch); | |
151 | + controller::resolve_combat(&mut character_a, &mut character_b); | |
152 | + | |
153 | + assert_eq!( character_a.get_hp(), 100 ); | |
154 | + assert_eq!( character_b.get_hp(), 100 - PUNCH_DMG); | |
155 | + | |
156 | + character_a.trigger(character_state_machine::CharacterFSMInput::Released); | |
157 | + character_b.update_hp(PUNCH_DMG); | |
158 | + } | |
159 | + | |
160 | + { | |
161 | + character_b.char_sprite.sprite.set_position(Vector2f::new(CHAR_WIDTH+KICK_RANGE, 0.0)); | |
162 | + character_a.trigger(character_state_machine::CharacterFSMInput::Kick); | |
163 | + controller::resolve_combat(&mut character_a, &mut character_b); | |
164 | + | |
165 | + assert_eq!( character_a.get_hp(), 100 ); | |
166 | + assert_eq!( character_b.get_hp(), 100 - KICK_DMG); | |
167 | + | |
168 | + character_a.trigger(character_state_machine::CharacterFSMInput::Released); | |
169 | + character_b.update_hp(KICK_DMG); | |
170 | + } | |
171 | + } | |
172 | + | |
173 | + #[test] | |
174 | + fn test_integration() | |
175 | + { | |
176 | + | |
177 | + ///////Set up test | |
178 | + let game_width = 800; | |
179 | + let game_height = 600; | |
180 | + let context_settings = ContextSettings::default(); | |
181 | + | |
182 | + let mut window = RenderWindow::new( | |
183 | + (game_width, game_height), | |
184 | + "Silny Kombat", | |
185 | + Style::CLOSE, | |
186 | + &context_settings, | |
187 | + ); | |
188 | + | |
189 | + let groundLevel = controller::get_ground_level(& window); | |
190 | + | |
191 | + let textures = renderer::myTextures::new(); | |
192 | + | |
193 | + | |
194 | + let mut character_a = character::Character::new("Sub Zero", 100, true, &textures.texturesArray); | |
195 | + let mut character_b = character::Character::new("Sub Zero", 100, true, &textures.texturesArray); | |
196 | + | |
197 | + let mut controller = controller::Controller::new( character_a, character_b, &textures.texturesArray, &textures.systemTexturesArray); | |
198 | + | |
199 | + controller.init(); | |
200 | + | |
201 | + /////end setup | |
202 | + | |
203 | + let pos_a: Vector2f = controller.character_a.char_sprite.sprite.position(); | |
204 | + let pos_b: Vector2f = controller.character_b.char_sprite.sprite.position(); | |
205 | + | |
206 | + println!("pos_a_2: {}", pos_a.x); | |
207 | + println!("pos_b_2: {}", pos_b.x); | |
208 | + | |
209 | + for i in 0..50 { | |
210 | + | |
211 | + let mut key_results:Vec<KeyEvents> = Vec::new(); | |
212 | + | |
213 | + key_results.push(KeyEvents::CharBLeft); | |
214 | + | |
215 | + | |
216 | + controller.key_processor.process_key_press(&mut window, &mut controller.character_a, &mut controller.character_b, key_results, groundLevel ); | |
217 | + } | |
218 | + | |
219 | + let pos_a_2: Vector2f = controller.character_a.char_sprite.sprite.position(); | |
220 | + let pos_b_2: Vector2f = controller.character_b.char_sprite.sprite.position(); | |
221 | + | |
222 | + | |
223 | + println!("pos_a_2: {}", pos_a_2.x); | |
224 | + println!("pos_b_2: {}", pos_b_2.x); | |
225 | + | |
226 | + let char_a_pos: Vector2f = controller.character_a.char_sprite.sprite.position(); | |
227 | + let char_b_pos: Vector2f = controller.character_b.char_sprite.sprite.position(); | |
228 | + | |
229 | + //Expected result - collision | |
230 | + //Characters are right next to each other | |
231 | + assert!( controller::check_collision( char_a_pos, char_b_pos, controller.character_a.get_state(), controller.character_b.get_state()) ); | |
232 | + | |
233 | + | |
234 | + ///////////////////////// | |
235 | + | |
236 | + assert_eq!(controller.character_a.get_hp(), 100); | |
237 | + println!("A HP: {}", controller.character_a.get_hp()); | |
238 | + | |
239 | + | |
240 | + { | |
241 | + let mut key_results:Vec<KeyEvents> = Vec::new(); | |
242 | + | |
243 | + key_results.push(KeyEvents::CharBPunch); | |
244 | + | |
245 | + controller.key_processor.process_key_press(&mut window, &mut controller.character_a, &mut controller.character_b, key_results, groundLevel ); | |
246 | + } | |
247 | + | |
248 | + | |
249 | + println!("A HP: {}", controller.character_a.get_hp()); | |
250 | + assert_eq!(controller.character_a.get_hp(), 100 - controller::PUNCH_DMG); | |
251 | + } | |
252 | + | |
253 | + | |
254 | +} | |
\ No newline at end of file |