diff --git a/assets/player.png b/assets/player.png index 3540408..0c89e09 100644 Binary files a/assets/player.png and b/assets/player.png differ diff --git a/assets/tileset.png b/assets/tileset.png index ba0e6b1..bb0e330 100644 Binary files a/assets/tileset.png and b/assets/tileset.png differ diff --git a/src/asteroid.rs b/src/asteroid.rs index cb879ab..17f5534 100644 --- a/src/asteroid.rs +++ b/src/asteroid.rs @@ -2,7 +2,7 @@ use bevy::prelude::*; use rand::{prelude::*, rng}; use crate::{ - FIRST_CORNER_X, FIRST_CORNER_Y, GameState, SECOND_CORNER_X, SECOND_CORNER_Y, + FIRST_CORNER_X, FIRST_CORNER_Y, GameObject, GameState, SECOND_CORNER_X, SECOND_CORNER_Y, collision::{Collided, Collider}, damagable::Damagable, projectile::Projectile, @@ -52,6 +52,7 @@ pub fn setup_asteroids(mut commands: Commands, asset_server: Res) { 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); } }