Skip to content

Commit

Permalink
Dog movement
Browse files Browse the repository at this point in the history
  • Loading branch information
ayamaev-se committed Dec 5, 2023
1 parent c66ce41 commit fc42331
Show file tree
Hide file tree
Showing 4 changed files with 217 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

pub mod debug_diagnostic;
pub mod test_level;
pub mod player;
pub mod physics;

use std::f32::consts::PI;

use bevy::app::App;
#[cfg(debug_assertions)]
Expand Down Expand Up @@ -34,6 +38,15 @@ impl Plugin for GamePlugin {
app.add_plugins((FrameTimeDiagnosticsPlugin, LogDiagnosticsPlugin::default()));
}

app.add_plugins((
player::PlayerPlugin,
physics::PhysicsPlugin,
));

app.add_systems(Startup, test_level::setup);
}
}

pub fn get_sprite_rotation() -> Quat {
Quat::from_euler(EulerRot::XYZ, PI / 2.0 - PI / 4.0, 0.0, 0.0)
}
19 changes: 19 additions & 0 deletions src/physics.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
use bevy::prelude::*;


pub struct PhysicsPlugin;

impl Plugin for PhysicsPlugin {
fn build(&self, app: &mut App) {
app.add_systems(Update, apply_velocity);
}
}

#[derive(Component, Default)]
pub struct Velocity(pub Vec3);

fn apply_velocity(mut query: Query<(&Velocity, &mut Transform)>, time: Res<Time>) {
for (velocity, mut transform) in query.iter_mut() {
transform.translation += velocity.0 * time.delta_seconds();
}
}
178 changes: 178 additions & 0 deletions src/player.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
use bevy::{prelude::*, window::PrimaryWindow};

use crate::{get_sprite_rotation, physics::Velocity};

const DOG_PATH: &str = "test/dog.png";

pub struct PlayerPlugin;

#[derive(Default, Hash, PartialEq, Eq, Debug, States, Clone)]
pub enum MovementStyle {
Mouse,
#[default]
WASD
}

impl Plugin for PlayerPlugin {
fn build(&self, app: &mut App) {
app
.add_event::<SpawnPlayer>()

.add_state::<MovementStyle>()

.add_systems(Update, spawn_player_by_event)
.add_systems(Update, player_movemnt_by_wasd.run_if(in_state(MovementStyle::WASD)))
.add_systems(Update, player_movemnt_by_mouse.run_if(in_state(MovementStyle::Mouse)))
.add_systems(Update, change_movement_style);
}
}

fn change_movement_style(
mut next_state: ResMut<NextState<MovementStyle>>,
current_state: Res<State<MovementStyle>>,
keyboard_input: Res<Input<KeyCode>>,
) {
if keyboard_input.just_pressed(KeyCode::Tab) {
if *current_state.get() == MovementStyle::Mouse {
next_state.set(MovementStyle::WASD);
} else {
next_state.set(MovementStyle::Mouse);
}
}
}

#[derive(Component)]
pub struct Player;

#[derive(Component)]
pub struct Dog;

#[derive(Event)]
pub struct SpawnPlayer {
pub position: Vec3,
}

fn spawn_player_by_event(
mut commands : Commands,
mut event_reader : EventReader<SpawnPlayer>,
asset_server: Res<AssetServer>,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
for event in event_reader.read() {
let plane = meshes.add(Mesh::from(shape::Plane { size: 1.0, ..default() }));
let material = materials.add(StandardMaterial {
base_color_texture: Some(asset_server.load(DOG_PATH)),
alpha_mode: AlphaMode::Blend,
..default()
});

info!("Spawn player at {:?}", event.position);

commands.spawn((
PbrBundle {
mesh: plane.clone(),
material: material.clone(),
transform: Transform::from_translation(event.position + Vec3::new(0.0, 2.5, 0.0)).with_rotation(get_sprite_rotation()).with_scale(Vec3::splat(5.0)),
..default()
},
Player,
Dog,
Velocity::default()
));
}
event_reader.clear();
}



fn player_movemnt_by_mouse(
mut player_query: Query<(&Transform, &mut Velocity), With<Player>>,
time : Res<Time>,
q_window: Query<&Window, With<PrimaryWindow>>,
q_camera: Query<(&Camera, &GlobalTransform)>,
) {
let Ok((transform, mut vel)) = player_query.get_single_mut() else {
return;
};

let (camera, camera_transform) = q_camera.single();
let window = q_window.single();

let Some(cursor_position) = window.cursor_position() else {
// if the cursor is not inside the window, we can't do anything
return;
};

let Some(ray) = camera.viewport_to_world(camera_transform, cursor_position) else {
// if it was impossible to compute for whatever reason; we can't do anything
return;
};

let Some(distance) = ray.intersect_plane(Vec3::Y * transform.translation.y, Vec3::Y) else {
return;
};

let globel_cursor = ray.get_point(distance);


let speed : f32 = 25.0;
let accel : f32 = 200.0;

let dir = (globel_cursor - transform.translation).normalize_or_zero();

let max_speed = speed.min(((globel_cursor - transform.translation).length() * 10.0) as f32);
let target_speed = (dir * speed).clamp_length(0.0, max_speed);

let dspeed = target_speed - vel.0;


vel.0 += dspeed.normalize_or_zero() * accel * time.delta_seconds();

vel.0 = vel.0.clamp_length_max(speed);

}

fn player_movemnt_by_wasd(
mut player_query: Query<&mut Velocity, With<Player>>,
input : Res<Input<KeyCode>>,
time : Res<Time>,
) {
let Ok(mut player) = player_query.get_single_mut() else {
return;
};

let speed = 25.0;
let accel = 200.0_f32;

let mut dir = Vec3::ZERO;

if input.pressed(KeyCode::W) {
dir += Vec3::new(0.0, 0.0, -1.0);
}

if input.pressed(KeyCode::S) {
dir += Vec3::new(0.0, 0.0, 1.0);
}

if input.pressed(KeyCode::A) {
dir += Vec3::new(-1.0, 0.0, 0.0);
}

if input.pressed(KeyCode::D) {
dir += Vec3::new(1.0, 0.0, 0.0);
}

dir = dir.normalize_or_zero();

let target_speed = dir * speed;

let dspeed = target_speed - player.0;

let accel = accel.min(dspeed.length() * 10.0);

player.0 += dspeed.normalize_or_zero() * accel * time.delta_seconds();

player.0 = player.0.clamp_length_max(speed);

}
7 changes: 7 additions & 0 deletions src/test_level.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ use bevy::{pbr::CascadeShadowConfigBuilder, prelude::*};
use rand::prelude::*;
use std::f32::consts::PI;

use crate::player::SpawnPlayer;

const TREE_PATH: &str = "test/pine.png";
const SHEEP_PATH: &str = "test/sheep.png";

Expand All @@ -10,6 +12,7 @@ pub fn setup(
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
asset_server: Res<AssetServer>,
mut spawn_player_event: EventWriter<SpawnPlayer>
) {
commands.spawn(Camera3dBundle {
transform: Transform::from_xyz(0.0, 100.0, 100.0)
Expand Down Expand Up @@ -126,4 +129,8 @@ pub fn setup(
..default()
});
}

spawn_player_event.send(SpawnPlayer {
position : Vec3::new(-r - 10.0, 0.0, 0.0)
});
}

0 comments on commit fc42331

Please sign in to comment.