@@ -88,6 +88,7 @@ pub(super) fn plugin(app: &mut App) {
8888 update_projectiles,
8989 projectile_asteroid_collision,
9090 update_explosions,
91+ shield_regen,
9192 )
9293 . in_set ( GameSystems :: Play )
9394 . run_if ( in_state ( Screen :: Game ) ) ,
@@ -113,13 +114,19 @@ pub(super) fn plugin(app: &mut App) {
113114#[ derive( Component ) ]
114115struct Thruster ;
115116
117+ #[ derive( Component ) ]
118+ struct Shield ;
119+
116120fn spawn_player ( mut commands : Commands , asset_server : Res < AssetServer > ) {
117121 let default_speed = asset_server. load ( "sprites/ships/ship3-default.png" ) ;
118122 commands. spawn ( (
119123 Name :: new ( "Player Ship" ) ,
120124 Player {
121125 can_shoot : true ,
122126 timer : Timer :: from_seconds ( 0.15 , TimerMode :: Once ) ,
127+ shield : 2 ,
128+ shield_regen : Timer :: from_seconds ( 5.0 , TimerMode :: Once ) ,
129+ shield_hit_cooldown : Timer :: from_seconds ( 1.0 , TimerMode :: Once ) ,
123130 } ,
124131 Sprite {
125132 image : asset_server. load ( "sprites/ships/ship3.png" ) ,
@@ -136,15 +143,25 @@ fn spawn_player(mut commands: Commands, asset_server: Res<AssetServer>) {
136143 ..default ( )
137144 } ,
138145 PIXEL_PERFECT_LAYERS ,
139- children ! [ (
140- Name :: new( "Player Ship Thruster" ) ,
141- Thruster ,
142- Sprite {
143- image: default_speed. clone( ) ,
144- custom_size: Some ( Vec2 :: splat( 32.0 ) ) ,
145- ..default ( )
146- }
147- ) ] ,
146+ children ! [
147+ (
148+ Name :: new( "Player Ship Thruster" ) ,
149+ Thruster ,
150+ Sprite {
151+ image: default_speed. clone( ) ,
152+ custom_size: Some ( Vec2 :: splat( 32.0 ) ) ,
153+ ..default ( )
154+ }
155+ ) ,
156+ (
157+ Name :: new( "Player Shield" ) ,
158+ Shield ,
159+ Sprite {
160+ image: asset_server. load( "sprites/shield.png" ) ,
161+ ..default ( )
162+ }
163+ )
164+ ] ,
148165 ) ) ;
149166}
150167
@@ -185,6 +202,9 @@ fn enter_player(
185202pub struct Player {
186203 pub can_shoot : bool ,
187204 pub timer : Timer ,
205+ pub shield : u8 ,
206+ pub shield_regen : Timer ,
207+ pub shield_hit_cooldown : Timer ,
188208}
189209
190210#[ derive( Component ) ]
@@ -454,26 +474,37 @@ fn spawn_asteroid(
454474
455475fn collide_with_asteroid_check (
456476 mut commands : Commands ,
457- player : Query < & Transform , With < Player > > ,
477+ mut player : Single < ( & Transform , & mut Player ) > ,
458478 asteroids : Query < & Transform , With < Asteroid > > ,
459479 mut time : ResMut < Time < Virtual > > ,
460480 mut state : ResMut < NextState < GameState > > ,
461481 asset_server : Res < AssetServer > ,
462482 mut texture_atlases : ResMut < Assets < TextureAtlasLayout > > ,
483+ mut shield : Single < & mut Sprite , With < Shield > > ,
463484) {
464- let player = player. single ( ) ;
465- if player. is_err ( ) {
466- return ;
467- }
468- let player_transform = player. unwrap ( ) ;
485+ let player_transform = player. 0 ;
486+ let player = & mut player. 1 ;
469487 let hitbox_size = 8.0 ;
470488 for asteroid_transform in asteroids. iter ( ) {
471489 let distance = player_transform
472490 . translation
473491 . distance ( asteroid_transform. translation ) ;
474- if distance < ( hitbox_size / 2.0 ) + ( 30.0 / 2.0 ) {
475- time. pause ( ) ;
476- state. set ( GameState :: GameOver ) ;
492+ if distance < ( hitbox_size / 2.0 ) + ( 30.0 / 2.0 ) && player. shield_hit_cooldown . is_finished ( )
493+ {
494+ if player. shield == 0 {
495+ time. pause ( ) ;
496+ state. set ( GameState :: GameOver ) ;
497+ } else {
498+ player. shield -= 1 ;
499+ player. shield_regen . reset ( ) ;
500+ player. shield_hit_cooldown . reset ( ) ;
501+ if player. shield == 0 {
502+ shield. image = asset_server. load ( "sprites/shield-empty.png" ) ;
503+ } else if player. shield == 1 {
504+ shield. image = asset_server. load ( "sprites/shield-low.png" ) ;
505+ }
506+ }
507+
477508 commands. trigger ( PlaySfxEvent {
478509 sfx : SoundEffect :: Explosion ,
479510 } ) ;
@@ -501,6 +532,29 @@ fn collide_with_asteroid_check(
501532 }
502533}
503534
535+ fn shield_regen (
536+ time : Res < Time < Virtual > > ,
537+ mut player : Single < & mut Player > ,
538+ mut shield : Single < & mut Sprite , With < Shield > > ,
539+ asset_server : Res < AssetServer > ,
540+ ) {
541+ player. shield_regen . tick ( time. delta ( ) ) ;
542+ player. shield_hit_cooldown . tick ( time. delta ( ) ) ;
543+ if player. shield_regen . just_finished ( ) {
544+ player. shield_regen . reset ( ) ;
545+ player. shield += 1 ;
546+ if player. shield > 2 {
547+ player. shield = 2 ;
548+ }
549+ match player. shield {
550+ 0 => shield. image = asset_server. load ( "sprites/shield-empty.png" ) ,
551+ 1 => shield. image = asset_server. load ( "sprites/shield-low.png" ) ,
552+ 2 => shield. image = asset_server. load ( "sprites/shield.png" ) ,
553+ _ => { }
554+ }
555+ }
556+ }
557+
504558#[ derive( Component ) ]
505559struct Explosion ;
506560
0 commit comments