summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhongheng Liu <z.liu@outlook.com.gr>2025-01-26 14:00:40 +0200
committerZhongheng Liu <z.liu@outlook.com.gr>2025-01-26 14:00:40 +0200
commit7e7dccf4324fafdc1814854886075b1f7b9208c0 (patch)
tree26130882fc9daa8b09b6d979da104ecfc08fca25
parent1f356482b692d3b1a86026996f89d65ca82e0678 (diff)
downloadgame-project-rs-7e7dccf4324fafdc1814854886075b1f7b9208c0.tar.gz
game-project-rs-7e7dccf4324fafdc1814854886075b1f7b9208c0.tar.bz2
game-project-rs-7e7dccf4324fafdc1814854886075b1f7b9208c0.zip
feat: benny hill chase simulatorHEADmaster
-rw-r--r--Cargo.lock1
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs155
3 files changed, 156 insertions, 1 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 3c3174d..fd233f2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -2047,6 +2047,7 @@ name = "game-project"
version = "0.1.0"
dependencies = [
"bevy",
+ "bevy_render",
]
[[package]]
diff --git a/Cargo.toml b/Cargo.toml
index fd8c1ff..dbc9d7c 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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
+ );
+ }
}