diff options
author | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-01-26 14:00:40 +0200 |
---|---|---|
committer | Zhongheng Liu <z.liu@outlook.com.gr> | 2025-01-26 14:00:40 +0200 |
commit | 7e7dccf4324fafdc1814854886075b1f7b9208c0 (patch) | |
tree | 26130882fc9daa8b09b6d979da104ecfc08fca25 | |
parent | 1f356482b692d3b1a86026996f89d65ca82e0678 (diff) | |
download | game-project-rs-master.tar.gz game-project-rs-master.tar.bz2 game-project-rs-master.zip |
-rw-r--r-- | Cargo.lock | 1 | ||||
-rw-r--r-- | Cargo.toml | 1 | ||||
-rw-r--r-- | src/main.rs | 155 |
3 files changed, 156 insertions, 1 deletions
@@ -2047,6 +2047,7 @@ name = "game-project" version = "0.1.0" dependencies = [ "bevy", + "bevy_render", ] [[package]] @@ -5,3 +5,4 @@ edition = "2021" [dependencies] bevy = "0.15.1" +bevy_render = "0.15.1" diff --git a/src/main.rs b/src/main.rs index e7a11a9..63b8f4a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,156 @@ +use bevy::window::{PresentMode, WindowResolution}; +use bevy::{prelude::*, winit::WinitSettings}; + +#[derive(Component)] +enum Direction { + Up, + Down, + Left, + Right, + None, +} fn main() { - println!("Hello, world!"); + App::new() + .add_plugins(DefaultPlugins.set(WindowPlugin { + primary_window: Some(Window { + title: "I am a window!".into(), + resolution: WindowResolution::new(500., 300.).with_scale_factor_override(1.0), + present_mode: PresentMode::AutoVsync, + // Tells wasm to resize the window according to the available canvas + fit_canvas_to_parent: true, + // Tells wasm not to override default event handling, like F5, Ctrl+R etc. + prevent_default_event_handling: false, + ..default() + }), + ..default() + })) + .add_plugins(EnemyPlugin) + .insert_resource(ClearColor(Color::srgb(0.5, 0.5, 0.9))) + .insert_resource(WinitSettings::game()) + .add_systems(Startup, setup_player) + .add_systems(Update, player_movements) + .run(); +} +fn offset_to_velocity(abs_v: f32, tr: Vec3, tr_target: Vec3) -> Vec2 { + let dx = tr_target.x - tr.x; + let dy = tr_target.y - tr.y; + let v = Vec2 { x: dx, y: dy }.normalize_or_zero(); + Vec2 { + x: v.x * abs_v, + y: v.y * abs_v, + } +} +fn map_key_to_movement(key: &KeyCode) -> Direction { + match key { + KeyCode::KeyW => Direction::Up, + KeyCode::KeyS => Direction::Down, + KeyCode::KeyA => Direction::Left, + KeyCode::KeyD => Direction::Right, + _ => Direction::None, + } +} + +pub struct EnemyPlugin; +impl Plugin for EnemyPlugin { + fn build(&self, app: &mut App) { + app.add_systems(Startup, setup_enemy) + .add_systems(Update, enemy_follow); + } + fn name(&self) -> &str { + "Enemy plugin" + } +} +#[derive(Debug)] +enum EntityType { + Player, + Enemy, +} +#[derive(Component)] +pub struct Player { + name: String, +} +#[derive(Component)] +pub struct Enemy { + name: String, +} +fn enemy_follow( + time: Res<Time>, + mut enemy: Query<(&Enemy, &Sprite, &mut Transform), (Without<Player>, With<Enemy>)>, + p: Query<(&Player, &Sprite, &Transform), (With<Player>, Without<Enemy>)>, +) { + let ev = 400. * time.delta_secs(); + let (pl, ps, pt) = match p.get_single() { + Ok(p) => p, + Err(e) => return, + }; + for (e, s, mut t) in &mut enemy { + let dv = offset_to_velocity(ev, t.translation, pt.translation); + let (ex, ey) = (t.translation.x, t.translation.y); + t.translation.x = safe_move(ex, dv.x, -500., 500.); + t.translation.y = safe_move(ey, dv.y, -300., 300.); + println!( + "Moving {} with v: {:?}, to translation: {:?}", + e.name, dv, t.translation + ); + } +} +fn setup_enemy(mut commands: Commands) { + let enemy = Sprite::from_color(Color::srgb(0., 0.5, 0.), Vec2 { x: 10., y: 50. }); + commands.spawn(( + Enemy { + name: "Evil guy".to_string(), + }, + enemy, + Transform::from_xyz(0., 0., 0.), + )); +} +fn setup_player(mut commands: Commands) { + let s = Sprite::from_color(Color::srgb(1., 1., 1.), Vec2 { x: 10., y: 50. }); + commands.spawn(Camera2d); + commands.spawn(( + Player { + name: "Person".to_string(), + }, + s, + Transform::from_xyz(0., 0., 0.), + )); +} +fn safe_move(x: f32, v: f32, bl: f32, br: f32) -> f32 { + if x + v > 0. && x + v > br { + return x; + } + if x + v < 0. && x + v < bl { + return x; + } + x + v +} +/// The sprite is animated by changing its translation depending on the time that has passed since +/// the last frame. +fn player_movements( + time: Res<Time>, + input: Res<ButtonInput<KeyCode>>, + mut ps: Query<(&Player, &Sprite, &mut Transform), (With<Player>, Without<Enemy>)>, +) { + let pv = 750. * time.delta_secs(); + let ev = 500. * time.delta_secs(); + let movements: Vec<Direction> = input.get_pressed().map(map_key_to_movement).collect(); + for (p, s, mut transform) in &mut ps { + let mut pvel_vec = Vec2 { x: 0., y: 0. }; + movements.iter().for_each(|m| match m { + Direction::Up => pvel_vec.y = pv, + Direction::Down => pvel_vec.y = -pv, + Direction::Left => pvel_vec.x = -pv, + Direction::Right => pvel_vec.x = pv, + Direction::None => pvel_vec = Vec2 { x: 0., y: 0. }, + }); + let pvv = pvel_vec.normalize_or_zero(); + let nx = safe_move(transform.translation.x, pv * pvv.x, -500., 500.); + let ny = safe_move(transform.translation.y, pv * pvv.y, -300., 300.); + transform.translation.x = nx; + transform.translation.y = ny; + println!( + "Moving {} with v: {:?}, to translation: {:?}", + p.name, pvv, transform.translation + ); + } } |