• R/O
  • SSH

silny-kombat: Commit

Mercurial repo for silny-kombat project


Commit MetaInfo

Révision3704cec45aaa4036fe8382e2c2146a653e285dc4 (tree)
l'heure2023-03-10 03:54:12
AuteurSecT <grzegorzstarowicz@gmai...>
CommiterSecT

Message de Log

Merged ref_01

Change Summary

Modification

diff -r b7fea44f138f -r 3704cec45aaa src/controller.rs
--- a/src/controller.rs Wed Feb 15 21:31:37 2023 +0100
+++ b/src/controller.rs Thu Mar 09 19:54:12 2023 +0100
@@ -9,7 +9,6 @@
99 use crate::sprite_rendering::CharacterSprite;
1010
1111 use crate::state_enums;
12-use crate::health_bar;
1312
1413 use std::fs::File;
1514 use std::io::prelude::*;
@@ -17,15 +16,15 @@
1716
1817 use sfml::{
1918 graphics::{
20- Color, Transformable, Texture, RenderWindow, RenderTarget, Sprite
19+ Transformable, Texture, RenderWindow, RenderTarget
2120 },
22- window::{ ContextSettings, Style, Event},
21+ window::{ Event},
2322 system::Vector2f,
2423 SfBox
2524 };
2625 use crate::key_processing::{KeyProcessor, KeyEvents};
27-use sfml::system::Vector2u;
2826 use sfml::window::{Key};
27+use crate::controller::Combat_status::A_ATTACKS_B;
2928
3029 use crate::key_processing;
3130 use crate::renderer::Renderer;
@@ -34,13 +33,20 @@
3433 pub const TEXTURE_ARRAY_SIZE : usize = 7;
3534 pub const SYSTEM_TEXTURE_ARRAY_SIZE : usize = 2;
3635
37-const char_width : f32 = 120.0;
36+pub const CHAR_WIDTH: f32 = 120.0;
3837
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;
4140
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+}
4450
4551 pub enum Texture_Ids {
4652 IDLE_0,
@@ -58,40 +64,78 @@
5864 }
5965
6066 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>,
6369
6470 char_textures: &'a [ SfBox<Texture>; TEXTURE_ARRAY_SIZE],
6571 system_textures: &'a [ SfBox<Texture>; SYSTEM_TEXTURE_ARRAY_SIZE],
6672
67- key_processor : KeyProcessor,
68- myRenderer : Renderer
73+ pub(crate) key_processor : KeyProcessor,
74+ myRenderer : Renderer<'a>,
75+ window : RenderWindow,
76+
6977 }
7078
7179 impl<'a> Controller<'a> {
7280
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();
7488
7589 Controller {
76- character_a: None,
77- character_b: None,
90+ character_a: char_a,
91+ character_b: char_b,
7892 char_textures: textures,
7993 system_textures: textures2,
8094 key_processor : KeyProcessor::new() ,
81- myRenderer : Renderer::new()
95+ myRenderer : rend,
96+ window : myWindow
8297 }
8398 }
8499
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+
87135 }
88136
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) {
95139
96140 // poll event from keyboard E
97141 // send E to KeyProcessor
@@ -102,85 +146,64 @@
102146 //If True - queue interaction_event to character (for example "is_hit")
103147 //If False - CharacterX.sprite.update()
104148
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();
115150
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();
129154
130155 //let key_processor = KeyProcessor::new();
131156
157+
132158 //loop
133159
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() {
137164 match event {
138- Event::Closed => window.close(),
165+ Event::Closed => self.window.close(),
139166 _ => { /* do nothing */ }
140167 }
141168 }
142169
170+ //let groundLevel = self.window.size().y as f32 - 50.0 - 100.0;
171+ let ground_level = get_ground_level(& self.window);
143172
144173 //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);
146174
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);
150182
151183 //end main loop
152184 }
153185
154-
155186 }
156187
157188 }
158189
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>
162198 )
163199 {
164200
165- let attack_dmg = is_attacking(&character_a, &character_b);
201+ resolve_combat(character_a, character_b);
166202
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- }
179203
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+ {
184207 match output_b {
185208 Ok(v) => {
186209 character_b.update_sprite(v);
@@ -198,72 +221,158 @@
198221
199222 }
200223
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 )
202225 {
203226
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();
211229
212- let mut attack_range = 0.0;
230+ let curr_combat_status = get_combat_status( character_a.get_state(), character_b.get_state() );
213231
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 => {}
221271 }
222272
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+ )
224288 {
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;
232290 }
233291
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+ )
235299 {
236- return -punch_dmg;
300+ return Combat_status::B_ATTACKS_A;
237301 }
238302
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+ )
240310 {
241- return kick_dmg;
311+ return Combat_status::BOTH;
242312 }
243313
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
245326 {
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;
247337 }
248338
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;
250358 }
251359
252360
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
254363 {
255364 println!("Check collision Enter");
256365
257366
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();
260369
261370
262371 //println!("checkCollision. A.state: {} B.state: {}", characterA.get_num_state(), characterB.get_num_state() );
263372
264373
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);
267376
268377
269378 println!("checkCollision. A.state: {} B.state: {}", state_a, state_b);
@@ -286,7 +395,7 @@
286395 || state_b == state_enums::States::Punching as i32
287396 || state_b == state_enums::States::Kicking as i32
288397 )
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() ;
290399 println!("Check collision B : {}", val);
291400
292401 //return val < 1.0;
@@ -301,7 +410,7 @@
301410 {
302411 println!("Check collision C");
303412
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;
305414 }
306415
307416 if ( state_a == state_enums::States::Idle as i32 || state_a == state_enums::States::Crouching as i32
@@ -319,12 +428,12 @@
319428 {
320429 println!("Check collision E");
321430
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;
323432 }
324433
325434 if state_a == state_enums::States::MovingLeft as i32 && state_b == state_enums::States::MovingRight as i32
326435 {
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() ;
328437 println!("Check collision F : {}", val);
329438
330439 //return val < 1.0;
@@ -334,7 +443,7 @@
334443 return false;
335444 }
336445
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
338447 {
339448 match raw_state {
340449 character_state_machine::CharacterFSMState::StandMoveBack => state_enums::States::MovingLeft as i32,
@@ -349,6 +458,7 @@
349458 }
350459 }
351460
461+
352462 pub fn save_test_data_to_file(ground_level:f32, sprite_a: &CharacterSprite, sprite_b: &CharacterSprite)
353463 {
354464 let mut data_to_dump: String = "spriteAData\n".to_string();
diff -r b7fea44f138f -r 3704cec45aaa src/key_processing.rs
--- a/src/key_processing.rs Wed Feb 15 21:31:37 2023 +0100
+++ b/src/key_processing.rs Thu Mar 09 19:54:12 2023 +0100
@@ -1,9 +1,8 @@
11 use sfml::{
22 graphics::{RenderWindow},
3- window::{Event, Key},
3+ window::{ Key},
44 };
55
6-use crate::key_processing::KeyEvents::{CharLeft, CharRight, CharKeyRelease};
76
87 use crate::character::Character;
98
@@ -12,15 +11,14 @@
1211
1312 use crate::controller;
1413
15-use crate::state_enums;
1614
1715 //use crate::sprite_rendering;
1816
1917 // pub const KEY_BASE : i32 = 10;
2018
2119 pub enum KeyEvents {
22- //None = -1,
23- //Escape,
20+ None = -1,
21+ Escape,
2422 CharLeft,
2523 CharRight,
2624 CharDown,
@@ -33,7 +31,7 @@
3331 CharBPunch = 14,
3432 CharBKick = 15,
3533 //CharBKeyRelease = 13,
36- //KeyTesting = 99
34+ KeyDump = 99
3735 }
3836
3937
@@ -54,67 +52,102 @@
5452 }
5553
5654
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,
59120 )
60121 {
61122 let mut output_a: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError> = character_a.trigger(character_state_machine::CharacterFSMInput::Released);
62123 let mut output_b: Result<Option<character_state_machine::CharacterFSMOutput>, TransitionImpossibleError> = character_b.trigger(character_state_machine::CharacterFSMInput::Released);
63124
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
71126 {
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+
85148 }
86149
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);
118151
119152
120153 }
@@ -123,6 +156,11 @@
123156 {
124157
125158 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+
126164 KeyEvents::CharBLeft => character.trigger(character_state_machine::CharacterFSMInput::FrontPressed),
127165 KeyEvents::CharBRight => character.trigger(character_state_machine::CharacterFSMInput::BackPressed),
128166 KeyEvents::CharBDown => character.trigger(character_state_machine::CharacterFSMInput::Crouch),
diff -r b7fea44f138f -r 3704cec45aaa src/main.rs
--- a/src/main.rs Wed Feb 15 21:31:37 2023 +0100
+++ b/src/main.rs Thu Mar 09 19:54:12 2023 +0100
@@ -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;
131
142 mod sprite_rendering;
153 mod key_processing;
@@ -19,32 +7,24 @@
197 mod renderer;
208 mod state_enums;
219 mod health_bar;
10+mod tests;
2211
2312
2413 fn main() {
2514 println!("Silny-Kombat!");
2615
27- let textures = renderer::myTextures::new();
2816
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();
3718
3819
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);
4322
44- //example test
45- #[test]
46- fn test_add() {
47- assert_eq!(add(1, 2), 3);
48- }
4923
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+}
diff -r b7fea44f138f -r 3704cec45aaa src/renderer.rs
--- a/src/renderer.rs Wed Feb 15 21:31:37 2023 +0100
+++ b/src/renderer.rs Thu Mar 09 19:54:12 2023 +0100
@@ -1,21 +1,23 @@
11
22 use crate::controller;
33 use crate::character::Character;
4+use crate::health_bar;
45
56 use sfml::{
67 graphics::{
78 Color, Transformable, Texture, RenderWindow, RenderTarget, Sprite
89 },
9- window::{ ContextSettings, Style, Event},
10+ window::{ ContextSettings, Style},
1011 system::Vector2f,
1112 SfBox
1213 };
13-use crate::health_bar::HealthBar;
14+
1415
1516
1617 pub struct myTextures {
1718 pub texturesArray: [SfBox<Texture>; controller::TEXTURE_ARRAY_SIZE],
1819 pub systemTexturesArray : [SfBox<Texture>; controller::SYSTEM_TEXTURE_ARRAY_SIZE],
20+
1921 }
2022
2123 impl myTextures {
@@ -31,26 +33,45 @@
3133 ],
3234 systemTexturesArray: [Texture::from_file("backgrounds/01.png").unwrap(),
3335 Texture::from_file("sprites//hud//health_bar.gif").unwrap()
34- ]
36+ ],
37+
38+
3539 }
3640
3741
3842 }
3943 }
4044
41-pub struct Renderer {
45+pub struct Renderer<'a> {
4246
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>,
4354 }
4455
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+
4760 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)
4966 }
5067 }
5168
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)
5370 {
71+ self.background_sprite.set_texture(&self.background_texture, true);
72+
73+ let ground_level = controller::get_ground_level(window);
74+
5475 character_a.char_sprite.sprite.set_scale(Vector2f::new(1.0, 1.0));
5576 character_b.char_sprite.sprite.set_scale(Vector2f::new(-1.0, 1.0));
5677
@@ -59,9 +80,9 @@
5980
6081
6182 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);
6586
6687 }
6788
@@ -83,14 +104,14 @@
83104 window
84105 }
85106
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)
87108 {
88109 window.clear(Color::rgb(50, 200, 50));
89- window.draw(background_sprite);
110+ window.draw(&self.background_sprite);
90111 window.draw(char_A_sprite);
91112 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);
94115 window.display();
95116 }
96117
diff -r b7fea44f138f -r 3704cec45aaa src/tests.rs
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests.rs Thu Mar 09 19:54:12 2023 +0100
@@ -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
Afficher sur ancien navigateur de dépôt.