From 22092ce3cc79e0d5543eb7747362a4b3d9f9de9d Mon Sep 17 00:00:00 2001 From: Rendo Date: Tue, 18 Nov 2025 00:21:40 +0500 Subject: [PATCH] Gameover screen --- assets/player.png | Bin 147 -> 150 bytes assets/tileset.png | Bin 653 -> 660 bytes src/asteroid.rs | 3 +- src/main.rs | 14 ++++++++ src/ships/enemy.rs | 5 +-- src/ships/gun.rs | 2 ++ src/ships/mod.rs | 18 ++++++++-- src/ships/player.rs | 3 +- src/ui/game_over.rs | 81 ++++++++++++++++++++++++++++++++++++++++++++ src/ui/mod.rs | 8 ++++- 10 files changed, 127 insertions(+), 7 deletions(-) diff --git a/assets/player.png b/assets/player.png index 3540408fba1c54e66cf04ee39e6bc3024c4413af..0c89e098929431814b3a6513211c17920c319aeb 100644 GIT binary patch delta 121 zcmV-<0EYjQ0hR%fBywFzL_t(IjbmU~^#4D@qW}LH$OMcSn&TK5DKmgXgCL6Vd4YgI z2uVWWfWshEL1F?E%^*xuiH#AcLD>CALbNgws}L8UvKJ@{M2e!3qJ%_YQf47nBc=f) bYJ>p*!bd5$-!Bhl00000NkvXXu0mjfsV6P% delta 118 zcmV-+0Ez#W0h0lcByU#Tbs`;fEXy<2WPNz8B>MZY1t~;njM5^htDK|84d69) YRSQly6I6&n^Z)<=07*qoM6N<$f>ygQj{pDw diff --git a/assets/tileset.png b/assets/tileset.png index ba0e6b12521c987d5b88bb32d29b25bdf893dc4a..bb0e330e8d1dad49f98a9bb98005294e65f12d9c 100644 GIT binary patch delta 618 zcmV-w0+s!Z1(XGlB!62;L_t(|ob8xBa>6hWg?Bw%C80_Y=PJz5(QphXq0a$ALz*zd zS)ia|ILxL&M3%MM^$*54`&GuWjNa4A+7-f<2mk(7_^S^s0`q5{9w z-J^^Y&vZsipns3J6lze80PXBwLu;Ssh3B=iA1;B|R;Lk+C@kAbOF$z&c%g5AMtqnb z5D{_vJSa>k7*Hdd{aXT(c;V%ecrGzQL|m;_&9=#!X*}EvXb?gmh;Oq-2x+4}$dajW z1M%bC2DRd=q_pUv?UQ_8pNgSyDTM3)9u;Au4+z|$9DjBubRiztL@0uvvE6Ghk3c1) z%L9t8NoInn?WvT9KPeg4pea(C6f%9`76C&LQ-=&1ir?osh4ny{_D7SoHS_yCFCBRJ z!ux6hY7Zl0MF}F}c{(TmG$@uCrrPhBDr;arf)f4?;EReKjY;i~BzY{w)#$!>KkP$s zlf!{6oknBrkAO8ms?oU|z=`C5RK}5x|KbLKXW1`I_!XsW@`gdvGHlV1WB7~_BN3pn&xjOk_S2mk;807*qoM6N<$ Ef+(RK_W%F@ delta 628 zcmV-)0*n2W1&sxeB!5&%L_t(|ob8!Aa>6hWhIc(&B}tVc<|@q4(QphX;TEAGO_(89 zF$ERFVUz|jvaEghfo+)mDs1_o|CeO#F6f+d004-H(16Q)=>Pye4!cJ8r|^9WY1%&t zj9*swMcx2U8zWM}J=^WJbi7`#J29kUz`a3fL~MYkt`T*_dw;qxA)|!48`1;L*HiNR zWxjNjIb$LNVYD?yP$s|=7?JrO(v+8s;7kC)2+82pYQ;Vq_Rhgxo~f4h{ z6xZ}dN??e%6n`2}nE~3-_fzkf=cVhlqaQDU)K;evjEKmt|2j)RBR*dHp#d84aeUyM zbJRW$3KL2O2x3#*cL7N}-k{ng@gIjBrh=nRLfi#n6Y=1`0i1YE2RZRw<_Ixen3r*( za2xT|h^MF%(qe%29`<=-N`^L@P3c+j`hP@5h+JT!p?~Xi*qhLYc%TBI6yZ#HRA+`j zC8W;+Mc=TIV7w+nDslLel2Hwspr}nEGZyYM;1$F)A%m9Uk9qFme4tMI(2#*pU5B4GIDl+8S9~mlZAU}c<;SLarN|nZ>_90=*QdEu}iVvrK zEN)g5WNqr4Y99j904YbOVgN6a5+}9yjaU|knx&{&Q6MKyYVRAeBIIWPCH@tnK;UYE zQi=R!4G3xbzu_|=3Tay~F$}{n48t%C!!QiPFbu;m48t%C!!QiP7@B{brE7_jUc$2g O0000) { Transform::from_translation(position), Collider::new(8.), Damagable::new(200), + GameObject, )) .observe(bump); } diff --git a/src/main.rs b/src/main.rs index 317d36e..4063b78 100644 --- a/src/main.rs +++ b/src/main.rs @@ -32,6 +32,9 @@ pub enum GameState { Gameover, } +#[derive(Component)] +pub struct GameObject; + fn main() { App::new() .insert_resource(ClearColor(Color::srgb(0.0, 0.0, 0.0))) @@ -65,5 +68,16 @@ fn main() { .add_systems(Startup, |mut commands: Commands| { commands.spawn(Camera2d); }) + .add_systems(OnExit(GameState::Game), cleanup_gameobjects) .run(); } + +pub fn cleanup_gameobjects(mut commands: Commands, query: Query>) { + for entity in query { + let Ok(mut interface) = commands.get_entity(entity) else { + continue; + }; + + interface.despawn(); + } +} diff --git a/src/ships/enemy.rs b/src/ships/enemy.rs index 496fa3b..74e0cb6 100644 --- a/src/ships/enemy.rs +++ b/src/ships/enemy.rs @@ -1,4 +1,4 @@ -use crate::velocity::Velocity; +use crate::{GameObject, velocity::Velocity}; use bevy::prelude::*; use crate::{ @@ -33,8 +33,9 @@ pub fn spawn_enemy(commands: &mut Commands, sprite: Handle, at: Vec2) { Velocity::moving(256., f32::to_radians(180.)), Sprite::from(sprite), Transform::from_xyz(at.x, at.y, 0.), - Damagable::new(100), + Damagable::new(20), Factions::EnemyFaction, + GameObject, )); } diff --git a/src/ships/gun.rs b/src/ships/gun.rs index 654802f..6bf0b06 100644 --- a/src/ships/gun.rs +++ b/src/ships/gun.rs @@ -2,6 +2,7 @@ use bevy::prelude::*; use rand::random_range; use crate::{ + GameObject, collision::Collider, projectile::{Projectile, ProjectileSprite}, ships::Factions, @@ -45,6 +46,7 @@ pub fn gun_shooting_system( commands.spawn(( Projectile::new(gun.damage, faction.clone()), + GameObject, bullet_transform, Velocity::moving(1024., 0.), Collider::new(8.), diff --git a/src/ships/mod.rs b/src/ships/mod.rs index 3bc2035..51f1204 100644 --- a/src/ships/mod.rs +++ b/src/ships/mod.rs @@ -1,6 +1,10 @@ use bevy::prelude::*; +use rand::{prelude::*, rng}; -use crate::GameState; +use crate::{ + FIRST_CORNER_X, FIRST_CORNER_Y, GameState, SECOND_CORNER_X, SECOND_CORNER_Y, + ships::enemy::spawn_enemy, +}; pub mod enemy; pub mod gun; @@ -51,5 +55,15 @@ fn startup(mut commands: Commands, asset_server: Res) { let enemy_sprite: Handle = asset_server.load("enemy.png"); player::spawn_player(&mut commands, player_sprite, Vec2::new(0., 0.)); - enemy::spawn_enemy(&mut commands, enemy_sprite.clone(), Vec2::new(100., 100.)); + + let mut random = rng(); + + for _ in 0..50 { + let position = Vec2::new( + random.random_range(FIRST_CORNER_X..SECOND_CORNER_X), + random.random_range(FIRST_CORNER_Y..SECOND_CORNER_Y), + ); + + spawn_enemy(&mut commands, enemy_sprite.clone(), position); + } } diff --git a/src/ships/player.rs b/src/ships/player.rs index 4d6240b..74a0539 100644 --- a/src/ships/player.rs +++ b/src/ships/player.rs @@ -1,5 +1,5 @@ use crate::{ - GameState, + GameObject, GameState, collision::Collider, damagable::{Damagable, DamageableKilled}, ships::{Factions, enemy::Enemy, gun::Gun}, @@ -28,6 +28,7 @@ pub fn spawn_player(commands: &mut Commands, sprite: Handle, at: Vec2) { Transform::from_xyz(at.x, at.y, 0.), Factions::PlayerFaction, Damagable::new(150), + GameObject, )); } diff --git a/src/ui/game_over.rs b/src/ui/game_over.rs index e69de29..bdc0d9d 100644 --- a/src/ui/game_over.rs +++ b/src/ui/game_over.rs @@ -0,0 +1,81 @@ +use bevy::{input_focus::InputFocus, prelude::*}; + +use crate::{GameState, score::Score}; + +#[derive(Component)] +pub struct Gameover; + +pub fn setup_gameover(mut commands: Commands, score: Res) { + //setup menu text + commands.spawn(( + Text::new("U DEAD"), + TextFont { + font_size: 32., + ..default() + }, + TextLayout::new_with_justify(Justify::Center), + Gameover, + Node { + position_type: PositionType::Absolute, + align_self: AlignSelf::Center, + justify_self: JustifySelf::Center, + ..default() + }, + )); + //Max score + commands.spawn(( + Text::new("Your score:".to_string() + score.max_score.to_string().as_str()), + TextLayout::new_with_justify(Justify::Center), + Gameover, + Node { + position_type: PositionType::Absolute, + align_self: AlignSelf::Center, + justify_self: JustifySelf::Center, + top: px(32), + ..default() + }, + )); + //setup button + commands.spawn(( + Button, + Node { + align_self: AlignSelf::Center, + justify_self: JustifySelf::Center, + justify_content: JustifyContent::Center, + align_items: AlignItems::Center, + top: px(64), + ..default() + }, + Gameover, + children![(Text::new("Continue"))], + )); +} + +pub fn gameover_button_system( + mut commands: Commands, + mut input_focus: ResMut, + interaction_query: Query<(Entity, &Interaction, &mut Button), Changed>, +) { + for (entity, interaction, mut button) in interaction_query { + match interaction { + Interaction::Pressed => { + input_focus.set(entity); + button.set_changed(); + commands.set_state(GameState::Game); + } + Interaction::Hovered => { + input_focus.set(entity); + button.set_changed(); + } + Interaction::None => { + input_focus.clear(); + } + } + } +} + +pub fn cleanup_gameover(mut commands: Commands, query: Query>) { + for entity in query { + commands.get_entity(entity).unwrap().despawn(); + } +} diff --git a/src/ui/mod.rs b/src/ui/mod.rs index 770f582..96a7f72 100644 --- a/src/ui/mod.rs +++ b/src/ui/mod.rs @@ -23,6 +23,12 @@ impl Plugin for UIPlugin { (update_player_health_display, update_player_score_display) .run_if(in_state(GameState::Game)), ) - .add_systems(OnExit(GameState::Game), cleanup_player_interface); + .add_systems(OnExit(GameState::Game), cleanup_player_interface) + .add_systems(OnEnter(GameState::Gameover), setup_gameover) + .add_systems( + Update, + gameover_button_system.run_if(in_state(GameState::Gameover)), + ) + .add_systems(OnExit(GameState::Gameover), cleanup_gameover); } }