diff --git a/game/Cargo.lock b/game/Cargo.lock index 1ee3696e3a1240ca4be8b5d413abd7a754451481..b06f418b7e05548f7e8662ca32c6dfff5f1f8409 100644 --- a/game/Cargo.lock +++ b/game/Cargo.lock @@ -354,7 +354,7 @@ dependencies = [ "fastrand 1.9.0", "js-sys", "notify", - "parking_lot 0.12.1", + "parking_lot", "serde", "thiserror", "wasm-bindgen", @@ -378,7 +378,7 @@ dependencies = [ "bevy_transform", "bevy_utils", "oboe", - "parking_lot 0.12.1", + "parking_lot", "rodio", ] @@ -712,7 +712,7 @@ dependencies = [ "erased-serde", "glam", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "serde", "smallvec", "smol_str", @@ -770,7 +770,7 @@ dependencies = [ "ktx2", "naga", "naga_oil", - "parking_lot 0.12.1", + "parking_lot", "regex", "ruzstd", "serde", @@ -1321,7 +1321,7 @@ dependencies = [ "ndk-context", "oboe", "once_cell", - "parking_lot 0.12.1", + "parking_lot", "wasm-bindgen", "wasm-bindgen-futures", "web-sys", @@ -1485,7 +1485,7 @@ checksum = "d4029edd3e734da6fe05b6cd7bd2960760a616bd2ddd0d59a0124746d6272af0" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "windows-sys 0.48.0", ] @@ -1567,6 +1567,7 @@ name = "game" version = "0.1.0" dependencies = [ "bevy", + "rand", ] [[package]] @@ -2462,7 +2463,7 @@ version = "0.3.46" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8378ac0dfbd4e7895f2d2c1f1345cab3836910baf3a300b000d04250f0c8428f" dependencies = [ - "redox_syscall 0.3.5", + "redox_syscall", ] [[package]] @@ -2486,17 +2487,6 @@ version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e52c774a4c39359c1d1c52e43f73dd91a75a614652c825408eec30c95a9b2067" -[[package]] -name = "parking_lot" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" -dependencies = [ - "instant", - "lock_api", - "parking_lot_core 0.8.6", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2504,21 +2494,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core 0.9.8", -] - -[[package]] -name = "parking_lot_core" -version = "0.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" -dependencies = [ - "cfg-if", - "instant", - "libc", - "redox_syscall 0.2.16", - "smallvec", - "winapi", + "parking_lot_core", ] [[package]] @@ -2529,7 +2505,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall 0.3.5", + "redox_syscall", "smallvec", "windows-targets 0.48.5", ] @@ -2596,6 +2572,12 @@ dependencies = [ "unicode-xid", ] +[[package]] +name = "ppv-lite86" +version = "0.2.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" + [[package]] name = "proc-macro-crate" version = "1.3.1" @@ -2636,6 +2618,36 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17fd96390ed3feda12e1dfe2645ed587e0bea749e319333f104a33ff62f77a0b" +[[package]] +name = "rand" +version = "0.8.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" +dependencies = [ + "libc", + "rand_chacha", + "rand_core", +] + +[[package]] +name = "rand_chacha" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" +dependencies = [ + "ppv-lite86", + "rand_core", +] + +[[package]] +name = "rand_core" +version = "0.6.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" +dependencies = [ + "getrandom", +] + [[package]] name = "range-alloc" version = "0.1.3" @@ -2654,15 +2666,6 @@ version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a0d463f2884048e7153449a55166f91028d5b0ea53c79377099ce4e8cf0cf9bb" -[[package]] -name = "redox_syscall" -version = "0.2.16" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" -dependencies = [ - "bitflags 1.3.2", -] - [[package]] name = "redox_syscall" version = "0.3.5" @@ -3292,7 +3295,7 @@ dependencies = [ "js-sys", "log", "naga", - "parking_lot 0.11.2", + "parking_lot", "profiling", "raw-window-handle", "smallvec", @@ -3317,7 +3320,7 @@ dependencies = [ "codespan-reporting", "log", "naga", - "parking_lot 0.11.2", + "parking_lot", "profiling", "raw-window-handle", "rustc-hash", @@ -3356,7 +3359,7 @@ dependencies = [ "metal", "naga", "objc", - "parking_lot 0.11.2", + "parking_lot", "profiling", "range-alloc", "raw-window-handle", @@ -3642,7 +3645,7 @@ dependencies = [ "orbclient", "percent-encoding", "raw-window-handle", - "redox_syscall 0.3.5", + "redox_syscall", "wasm-bindgen", "wayland-scanner", "web-sys", diff --git a/game/Cargo.toml b/game/Cargo.toml index cf168c635497a9a6a897d4686aa8b177ab411b69..ef923c54957971d33e60e3eb1c5740250877e94b 100644 --- a/game/Cargo.toml +++ b/game/Cargo.toml @@ -7,6 +7,7 @@ edition = "2021" [dependencies] bevy = "0.11.3" +rand = "0.8.5" # Enable a small amount of optimization in debug mode [profile.dev] diff --git a/game/assets/eleve.png b/game/assets/eleve.png new file mode 100644 index 0000000000000000000000000000000000000000..7f0a0676c2003810983da014392052b492860b08 Binary files /dev/null and b/game/assets/eleve.png differ diff --git a/game/assets/enemy.png b/game/assets/enemy.png new file mode 100644 index 0000000000000000000000000000000000000000..263c034500842964567f63c10ac5c96ba9f18812 Binary files /dev/null and b/game/assets/enemy.png differ diff --git a/game/assets/mapdebut.png b/game/assets/mapdebut.png new file mode 100644 index 0000000000000000000000000000000000000000..b79ba97a84ead7173fe31219fcdaa5a637e20897 Binary files /dev/null and b/game/assets/mapdebut.png differ diff --git a/game/src/game.rs b/game/src/game.rs index de6a74140a5e0726b844d06f6dc745ac63340e8c..882f9a3fd4e8e047c93f1cf2715ca6debe9b83a4 100644 --- a/game/src/game.rs +++ b/game/src/game.rs @@ -1,6 +1,10 @@ +use std::collections::btree_map::Keys; + use bevy::prelude::*; +use rand::Rng; + - use super::{despawn_screen, DisplayQuality, GameState, Volume, TEXT_COLOR}; +use super::{despawn_screen, DisplayQuality, GameState, Volume, TEXT_COLOR}; // This plugin will contain the game. In this case, it's just be a screen that will // display the current settings for 5 seconds before returning to the menu @@ -8,117 +12,181 @@ use bevy::prelude::*; impl Plugin for GamePlugin { fn build(&self, app: &mut App) { - app.add_systems(OnEnter(GameState::Game), game_setup) + app.add_systems(OnEnter(GameState::Game), (game_setup ,spawn_enemies)) .add_systems(Update, game.run_if(in_state(GameState::Game))) - .add_systems(OnExit(GameState::Game), despawn_screen::<OnGameScreen>); + .add_systems(OnExit(GameState::Game), ( + despawn_game::<Player>, + despawn_game::<Enemy>, + despawn_game::<OnGameScreen>, + )); } } // Tag component used to tag entities added on the game screen + #[derive(Component)] struct OnGameScreen; #[derive(Resource, Deref, DerefMut)] struct GameTimer(Timer); - fn game_setup( - mut commands: Commands, - display_quality: Res<DisplayQuality>, - volume: Res<Volume>, - ) { + #[derive(Component)] + struct Player; + + #[derive(Component)] + struct Enemy; + + + #[derive(Component)] + struct CollisionBox { + width: f32, + height: f32, + } + + #[derive(Component)] + struct CombatText; + + + fn game_setup(mut commands: Commands, + asset_server: Res<AssetServer>, + mut map_query: Query<&Transform, With<Player>> + ){ + + let map_texture = asset_server.load("mapdebut.png"); commands - .spawn(( - NodeBundle { - style: Style { - width: Val::Percent(100.0), - height: Val::Percent(100.0), - // center children - align_items: AlignItems::Center, - justify_content: JustifyContent::Center, - ..default() - }, + .spawn( + SpriteBundle { + sprite: Sprite { + custom_size: Some(Vec2::new(600.0, 600.0)), + ..default() + }, // Assurez-vous d'ajuster la taille selon votre image + texture: map_texture, + ..default() + }, + //OnGameScreen, + ) + .insert(OnGameScreen); + + let texture = asset_server.load("eleve.png"); + commands + .spawn( + SpriteBundle { + sprite: Sprite { + custom_size: Some(Vec2::new(50.0, 50.0)), + color: Color::WHITE, + flip_x: false, + flip_y: false, + ..default() + }, + texture: texture, + ..default() + }) + .insert(Player); + } + + fn spawn_enemies(mut commands: Commands, asset_server: Res<AssetServer>, mut materials: ResMut<Assets<ColorMaterial>>) { + let enemy_texture = asset_server.load("enemy.png"); + + // Définir le nombre maximum d'ennemis + let max_enemies = 5; + + // Générer une position aléatoire pour chaque ennemi + let mut rng = rand::thread_rng(); + for _ in 0..max_enemies { + let x_position = rng.gen_range(-300.0..300.0); // Assurez-vous d'ajuster ces valeurs en fonction de la taille de votre carte + let y_position = rng.gen_range(-300.0..300.0); + + commands.spawn(SpriteBundle { + sprite: Sprite { + custom_size: Some(Vec2::new(50.0, 50.0)), + ..default() + }, + transform: Transform { + translation: Vec3::new(x_position, y_position, 0.0), ..default() }, - OnGameScreen, - )) - .with_children(|parent| { - // First create a `NodeBundle` for centering what we want to display - parent - .spawn(NodeBundle { - style: Style { - // This will display its children in a column, from top to bottom - flex_direction: FlexDirection::Column, - // `align_items` will align children on the cross axis. Here the main axis is - // vertical (column), so the cross axis is horizontal. This will center the - // children - align_items: AlignItems::Center, - ..default() - }, - background_color: Color::BLACK.into(), - ..default() - }) - .with_children(|parent| { - // Display two lines of text, the second one with the current settings - parent.spawn( - TextBundle::from_section( - "Will be back to the menu shortly...", - TextStyle { - font_size: 80.0, - color: TEXT_COLOR, - ..default() - }, - ) - .with_style(Style { - margin: UiRect::all(Val::Px(50.0)), - ..default() - }), - ); - parent.spawn( - TextBundle::from_sections([ - TextSection::new( - format!("quality: {:?}", *display_quality), - TextStyle { - font_size: 60.0, - color: Color::BLUE, - ..default() - }, - ), - TextSection::new( - " - ", - TextStyle { - font_size: 60.0, - color: TEXT_COLOR, - ..default() - }, - ), - TextSection::new( - format!("volume: {:?}", *volume), - TextStyle { - font_size: 60.0, - color: Color::GREEN, - ..default() - }, - ), - ]) - .with_style(Style { - margin: UiRect::all(Val::Px(50.0)), - ..default() - }), - ); - }); - }); - // Spawn a 5 seconds timer to trigger going back to the menu - commands.insert_resource(GameTimer(Timer::from_seconds(5.0, TimerMode::Once))); + texture: enemy_texture.clone(), + ..default() + }) + .insert(Enemy) + //.insert(Health { current: 100, max: 100 }) + //.insert(Attack { damage: 10 }) + .insert(CollisionBox { width: 75.0, height: 75.0 }); + } } + - // Tick the timer, and change state when finished fn game( + mut characters: Query<(&mut Transform, &Sprite), With<Player>>, + input: Res<Input<KeyCode>>, time: Res<Time>, mut game_state: ResMut<NextState<GameState>>, - mut timer: ResMut<GameTimer>, ) { - if timer.tick(time.delta()).finished() { - game_state.set(GameState::Menu); + for (mut transform, _) in &mut characters { + if input.pressed(KeyCode::W) { + transform.translation.y += 100.0 * time.delta_seconds(); + } + if input.pressed(KeyCode::S) { + transform.translation.y -= 100.0 * time.delta_seconds(); + } + if input.pressed(KeyCode::D) { + transform.translation.x += 100.0 * time.delta_seconds(); + } + if input.pressed(KeyCode::A) { + transform.translation.x -= 100.0 * time.delta_seconds(); + } + if input.pressed(KeyCode::Escape) { + game_state.set(GameState::Menu); + } } } + fn attack_system( + mut commands: Commands, + asset_server: Res<AssetServer>, + mut player_query: Query<&Transform, With<Player>>, + mut enemy_query: Query<&Transform, With<Enemy>>, + combat_text_query: Query<Entity, With<CombatText>>, // Query to handle existing combat texts + ) { + // Check if the player is near an enemy to show the combat text + for (player_transform) in player_query.iter_mut() { + let mut in_combat = false; + for (enemy_transform) in enemy_query.iter_mut() { + if player_transform.translation.distance(enemy_transform.translation) < 60.0 { // Adjust this value based on the size of your collision box + in_combat = true; + break; + } + } + let has_combat_text = combat_text_query.iter().next().is_some(); + + if in_combat && !has_combat_text { + // Display the combat text + commands.spawn(TextBundle { + text: Text { + sections: vec![TextSection { + value: "Combat".to_string(), + style: TextStyle { + font: asset_server.load("FiraSans-Bold.ttf"), // Adjust this font path + font_size: 40.0, + color: Color::WHITE, + }, + }], + ..Default::default() + }, + ..Default::default() + }) + .insert(CombatText); + } else if !in_combat && has_combat_text { + // Remove the combat text + for entity in combat_text_query.iter() { + commands.entity(entity).despawn(); + } + } + } + } + + fn despawn_game<T: Component>(to_despawn: Query<Entity, With<T>>, mut commands: Commands) { + for entity in &to_despawn { + commands.entity(entity).despawn_recursive(); + } + } diff --git a/game/src/main.rs b/game/src/main.rs index 83417e893a7719b41d2148f6d713ea89a2e93b6f..5572ac7154bab77109ead089ece7c756993e4991 100644 --- a/game/src/main.rs +++ b/game/src/main.rs @@ -17,6 +17,7 @@ enum GameState { Splash, Menu, Game, + Fight, } // One of the two settings that can be set through the menu. It will be a resource in the app @@ -27,17 +28,25 @@ enum DisplayQuality { High, } +// Stores the various windows-resolution we can select between. +#[derive(Resource)] +struct ResolutionSettings { + large: Vec2, + medium: Vec2, + small: Vec2, +} + // One of the two settings that can be set through the menu. It will be a resource in the app #[derive(Resource, Debug, Component, PartialEq, Eq, Clone, Copy)] struct Volume(u32); fn main() { - App::new()/* + App::new() .insert_resource(ResolutionSettings { large: Vec2::new(1920.0, 1080.0), - medium: Vec2::new(800.0, 600.0), + medium: Vec2::new(1200.0, 720.0), small: Vec2::new(640.0, 360.0), - })*/ + }) .add_plugins(DefaultPlugins) // Insert as resource the initial value for the settings resources .insert_resource(DisplayQuality::Medium) @@ -55,7 +64,6 @@ fn setup(mut commands: Commands) { commands.spawn(Camera2dBundle::default()); } - mod game; mod menu; diff --git a/game/src/menu.rs b/game/src/menu.rs index a3f023e67bb14a2d822f93cdcd5f79db0549204a..f0349fcf99d6a69454949f73b6688b3ca7562515 100644 --- a/game/src/menu.rs +++ b/game/src/menu.rs @@ -1,7 +1,9 @@ use bevy::{app::AppExit, prelude::*}; +use bevy::{prelude::*, window::WindowResized}; +use bevy::{window::PrimaryWindow}; use super::{despawn_screen, DisplayQuality, GameState, Volume, TEXT_COLOR}; - + use crate::ResolutionSettings; // This plugin manages the menu, with 5 different screens: // - a main menu with "New Game", "Settings", "Quit" // - a settings menu with two submenus and a back button @@ -55,7 +57,8 @@ use bevy::{app::AppExit, prelude::*}; .add_systems( Update, (menu_action, button_system).run_if(in_state(GameState::Menu)), - ); + ) + .add_systems(Update, toggle_resolution); } } @@ -147,7 +150,7 @@ use bevy::{app::AppExit, prelude::*}; menu_state.set(MenuState::Main); } - fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>) { + fn main_menu_setup(mut commands: Commands, asset_server: Res<AssetServer>, window_query: Query<&mut Window, With<PrimaryWindow>>) { // Common style for all buttons on the screen let button_style = Style { width: Val::Px(250.0), @@ -172,6 +175,8 @@ use bevy::{app::AppExit, prelude::*}; ..default() }; + let window = window_query.get_single().unwrap(); + commands .spawn(( NodeBundle { @@ -189,6 +194,7 @@ use bevy::{app::AppExit, prelude::*}; parent .spawn(NodeBundle { style: Style { + width: Val::Px(5000.0), flex_direction: FlexDirection::Column, align_items: AlignItems::Center, ..default() @@ -533,6 +539,29 @@ use bevy::{app::AppExit, prelude::*}; }); } + /// This system shows how to request the window to a new resolution +fn toggle_resolution( + keys: Res<Input<KeyCode>>, + mut windows: Query<&mut Window>, + resolution: Res<ResolutionSettings>, +) { + let mut window = windows.single_mut(); + + if keys.just_pressed(KeyCode::Key1) { + let res = resolution.small; + window.resolution.set(res.x, res.y); + } + if keys.just_pressed(KeyCode::Key2) { + let res = resolution.medium; + window.resolution.set(res.x, res.y); + } + if keys.just_pressed(KeyCode::Key3) { + let res = resolution.large; + window.resolution.set(res.x, res.y); + } +} + + fn menu_action( interaction_query: Query< (&Interaction, &MenuButtonAction), diff --git a/game/src/player.rs b/game/src/player.rs new file mode 100644 index 0000000000000000000000000000000000000000..db1fdf6870c1d5d35b3944e5a7f89ed496902f62 --- /dev/null +++ b/game/src/player.rs @@ -0,0 +1,43 @@ +use bevy::prelude::*; + +pub struct PlayerHistory { + pub target_position: Vec2, + pub new_position: Vec2, + pub timer: Timer, +} + +impl PlayerHistory { + pub fn update_position(&mut self, new_position: Vec3) { + self.target_position = self.new_position; + self.new_position = new_position; + } +} + +#[derive(Component)] +struct Enemy; + + +#[derive(Component)] +struct CollisionBox { + width: f32, + height: f32, +} + + +pub struct PlayerPlugin; + +impl Plugin for PlayerPlugin { + fn build(&self, app: &mut App) { + app.insert_resource(PlayerHistory{ + trarget_position: Vec2::ZERO, + new_position: Vec2::ZERO, + timer: Timer::new(Duration::from_secs_f32(0.2)), + }) + . + .add_systems(Update, character_movement) + .add_systems(Startup,spawn_enemies) + .add_systems(Update,attack_system) + + } + +}