@@ -45,6 +45,7 @@ fn main() {
4545 app_state. add_state_data ( "HIGHSCORE" , Box :: new ( highscore) ) ;
4646 app_state. add_state_data ( "WELL_DONE_TIMER" , Box :: new ( 0i32 ) ) ;
4747 app_state. add_state_data ( "TRY_AGAIN_TIMER" , Box :: new ( 0i32 ) ) ;
48+ app_state. add_state_data ( "SAFE_TIMER" , Box :: new ( 0i32 ) ) ;
4849 app_state. add_state_data ( "LIVES" , Box :: new ( 3i32 ) ) ;
4950 app_state. add_state_data ( "PAUSE" , Box :: new ( false ) ) ;
5051
@@ -305,9 +306,18 @@ fn player_update(app_state: &mut AppState){
305306 } ,
306307 None => { }
307308 }
309+ let timer_value = * app_state. get_state_data_value :: < i32 > ( "SAFE_TIMER" ) . unwrap_or ( & 0 ) ;
310+ let is_safe = timer_value > 0 ;
308311 let player_option = app_state. get_object_mut ( "PLAYER" ) ;
309312 match player_option {
310313 Some ( player) => {
314+ if is_safe {
315+ if ( timer_value / 5 ) % 2 == 0 {
316+ player. transform . set_scale ( [ 2.0 , 2.0 , 2.0 ] ) ;
317+ } else {
318+ player. transform . set_scale ( [ 0.0 , 0.0 , 0.0 ] ) ; // "Hide" the player
319+ }
320+ }
311321 if player. transform . get_position ( ) . y > -5.0 {
312322 player. transform . move_dir_array ( [ 0.0 , -0.05 , 0.0 ] ) ;
313323 player. transform . rotate ( [ 0.0 , 0.0 , -0.7 ] )
@@ -432,20 +442,20 @@ fn update_ui_timers(app_state: &mut AppState) {
432442 * timer -= 1 ;
433443 }
434444 }
445+ if let Some ( timer) = app_state. get_state_data_value_mut :: < i32 > ( "SAFE_TIMER" ) {
446+ if * timer > 0 {
447+ * timer -= 1 ;
448+ }
449+ }
435450}
436451
437452fn check_collision ( app_state : & mut AppState ) {
438453 match app_state. get_state_data_value_mut :: < bool > ( "PAUSE" ) {
439- Some ( p) => {
440- if * p {
441- return ;
442- }
443- } ,
444- None => { }
454+ Some ( p) if * p => return ,
455+ _ => { }
445456 }
446-
457+ let is_safe = app_state . get_state_data_value :: < i32 > ( "SAFE_TIMER" ) . map_or ( false , |t| * t > 0 ) ;
447458 let player_option = app_state. get_object_mut ( "PLAYER" ) ;
448-
449459 // define temp var to store collision
450460 let mut colliding = CollisionState :: None ;
451461
@@ -463,11 +473,11 @@ fn check_collision(app_state: &mut AppState){
463473 continue ;
464474 }
465475 }
466- if object. name . contains ( "PIPE" ) {
476+ if !is_safe && object. name . contains ( "PIPE" ) {
467477 let object_bounds = object. get_bounding_box ( ) ;
468478 if collision_world:: is_colliding ( & player_bounds, & object_bounds) {
469479 colliding = CollisionState :: Pipe ;
470- continue ;
480+ break ;
471481 }
472482 }
473483 }
@@ -477,86 +487,72 @@ fn check_collision(app_state: &mut AppState){
477487
478488 // setting player positions
479489 if colliding == CollisionState :: Pipe {
480- match app_state. get_object_mut ( "PLAYER" ) {
481- Some ( player) => {
482- player. transform . set_position ( [ 0.0 , 0.0 , 0.0 ] ) ;
483- player. transform . set_scale ( [ 2.0 , 2.0 , 2.0 ] ) ;
484- player. transform . set_rotation ( [ 0.0 , 0.0 , 0.0 ] ) ;
485- } ,
486- None => { }
490+ if let Some ( player) = app_state. get_object_mut ( "PLAYER" ) {
491+ player. transform . set_position ( [ 0.0 , 0.0 , 0.0 ] ) ;
492+ player. transform . set_rotation ( [ 0.0 , 0.0 , 0.0 ] ) ;
487493 }
488494 }
489495
496+
490497 // handle lives
491- let mut live_tracker = 0 ;
492- match app_state. get_state_data_value_mut :: < i32 > ( "LIVES" ) {
493- Some ( live) => {
494- if colliding == CollisionState :: Pipe {
495- * live = * live - 1 ;
496- if * live < 0 {
497- * live = 0 ;
498- }
499- live_tracker = * live;
500- }
501- } ,
502- None => { }
498+ let mut live_tracker = app_state. get_state_data_value :: < i32 > ( "LIVES" ) . map_or ( 0 , |l| * l) ;
499+ if colliding == CollisionState :: Pipe {
500+ if let Some ( live) = app_state. get_state_data_value_mut :: < i32 > ( "LIVES" ) {
501+ * live -= 1 ;
502+ live_tracker = * live;
503+ }
503504 }
504505
505506 // now lets set the score
506- let mut score = 0 ;
507- match app_state. get_state_data_value_mut :: < i32 > ( "SCORE" ) {
508- Some ( s) => {
509- if colliding == CollisionState :: Coin {
510- * s = * s + 1 ;
511- score = * s;
512- } else if colliding == CollisionState :: Pipe {
513- if live_tracker <= 0 {
514- * s = 0 ;
515- score = 0 ;
516- }
507+ let mut current_score = app_state. get_state_data_value :: < i32 > ( "SCORE" ) . map_or ( 0 , |s| * s) ;
508+ if let Some ( s) = app_state. get_state_data_value_mut :: < i32 > ( "SCORE" ) {
509+ if colliding == CollisionState :: Coin {
510+ * s += 1 ;
511+ current_score = * s;
512+ } else if colliding == CollisionState :: Pipe {
513+ if live_tracker <= 0 {
514+ * s = 0 ;
515+ current_score = 0 ;
517516 }
518- } ,
519- None => { }
517+ }
520518 }
521519
522520 // let's set the highscore
523- match app_state. get_state_data_value_mut :: < i32 > ( "HIGHSCORE" ) {
524- Some ( hs) => {
525- if colliding == CollisionState :: Coin && score > 0 {
526- if score > * hs {
527- * hs = score;
528- save_highscore ( * hs) ;
529- }
521+ if colliding == CollisionState :: Coin {
522+ if let Some ( hs) = app_state. get_state_data_value_mut :: < i32 > ( "HIGHSCORE" ) {
523+ if current_score > * hs {
524+ * hs = current_score;
525+ save_highscore ( * hs) ;
530526 }
531- } ,
532- None => { }
527+ }
533528 }
534529
535530 // finally set lives
536- match app_state. get_state_data_value_mut :: < i32 > ( "LIVES" ) {
537- Some ( l) => {
538- if * l <= 0 {
539- * l = 3 ;
540- }
541- } ,
542- None => { }
531+ if colliding == CollisionState :: Pipe && live_tracker <= 0 {
532+ if let Some ( l) = app_state. get_state_data_value_mut :: < i32 > ( "LIVES" ) {
533+ * l = 3 ;
534+ }
543535 }
544536
545537 // handling audio
546- if colliding == CollisionState :: Pipe {
547- if live_tracker == 0 {
538+ if colliding == CollisionState :: Pipe {
539+ if live_tracker <= 0 {
548540 app_state. play_audio_once ( "game-over" ) ;
549541 if let Some ( timer) = app_state. get_state_data_value_mut :: < i32 > ( "TRY_AGAIN_TIMER" ) {
550- * timer = 120 ;
542+ * timer = 120 ; // 2 seconds
551543 }
552544 } else {
553545 app_state. play_audio_once ( "hit" ) ;
546+ // Set the safe timer since a life was lost but it's not game over
547+ if let Some ( timer) = app_state. get_state_data_value_mut :: < i32 > ( "SAFE_TIMER" ) {
548+ * timer = 120 ; // 2 seconds of immunity
549+ }
554550 }
555551 } else if colliding == CollisionState :: Coin {
556- if score > 0 && score % 10 == 0 {
552+ if current_score > 0 && current_score % 10 == 0 {
557553 app_state. play_audio_once ( "collect-ten" ) ;
558554 if let Some ( timer) = app_state. get_state_data_value_mut :: < i32 > ( "WELL_DONE_TIMER" ) {
559- * timer = 120 ;
555+ * timer = 120 ; // 2 seconds
560556 }
561557 } else {
562558 app_state. play_audio_once ( "collect" ) ;
0 commit comments