Skip to content

Commit 02bc2d8

Browse files
StarArawnStarArawn
authored andcommitted
Updated player movement code to be smoother, and added camera smoothing.
Used an event to pass data to the battle view. Camera now follows player. Simple Player/Enemy collision detection.
1 parent 7b8d4bc commit 02bc2d8

File tree

15 files changed

+191
-108
lines changed

15 files changed

+191
-108
lines changed

src/game/camera/input.rs

Lines changed: 5 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
use crate::game::{gameplay::scenes, GameState};
2-
use bevy::render::camera::CameraProjection;
1+
use crate::game::GameState;
32
use bevy::{
4-
// input::mouse::{MouseMotion, MouseWheel},
53
prelude::*,
64
render::camera::Camera,
75
};
@@ -29,29 +27,18 @@ impl Default for KeyboardConf {
2927
}
3028

3129
pub fn camera_movement(
32-
asset_server: Res<AssetServer>,
33-
mut commands: Commands,
3430
mut game_state: ResMut<State<GameState>>,
3531
mut keyboard_input: ResMut<Input<KeyCode>>,
36-
mut materials: ResMut<Assets<ColorMaterial>>,
3732
mut query: Query<(
3833
&mut Camera,
3934
&mut Transform,
4035
&mut CustomOrthographicProjection,
4136
)>,
4237
time: Res<Time>,
43-
windows: Res<Windows>,
38+
_windows: Res<Windows>,
4439
) {
4540
if keyboard_input.just_pressed(KeyCode::P) {
46-
if *game_state.current() == GameState::MapView {
47-
game_state.set(GameState::BattleView).unwrap();
48-
scenes::battle::spawn(
49-
scenes::battle::BattleLocation::Mountains,
50-
&mut commands,
51-
&asset_server,
52-
&mut materials,
53-
);
54-
} else if *game_state.current() == GameState::BattleView {
41+
if *game_state.current() == GameState::BattleView {
5542
game_state.set(GameState::MapView).unwrap();
5643
}
5744
keyboard_input.update();
@@ -61,7 +48,7 @@ pub fn camera_movement(
6148
return;
6249
}
6350

64-
for (mut camera, mut transform, mut projection) in query.iter_mut() {
51+
for (mut _camera, mut transform, mut projection) in query.iter_mut() {
6552
let mut direction = Vec3::ZERO;
6653
let scale = projection.scale;
6754

@@ -91,12 +78,7 @@ pub fn camera_movement(
9178
projection.scale = scale;
9279
}
9380

94-
projection.update(
95-
windows.get_primary().unwrap().width(),
96-
windows.get_primary().unwrap().height(),
97-
);
98-
camera.projection_matrix = projection.get_projection_matrix();
99-
camera.depth_calculation = projection.depth_calculation();
81+
10082

10183
transform.translation += time.delta_seconds() * direction * 1000.;
10284
}

src/game/camera/mod.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,10 @@ pub use ortho::{CustomOrthographicCameraBundle, CustomOrthographicProjection};
77
#[derive(Default)]
88
pub struct CurrentCamera {
99
pub camera: Option<Entity>,
10+
}
11+
12+
#[derive(Default)]
13+
pub struct CameraData {
14+
// Used to lerp camera.
15+
pub value: f32,
1016
}

src/game/gameplay/camera/mod.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mod movement;
2+
3+
pub use movement::movement;

src/game/gameplay/camera/movement.rs

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
use bevy::{prelude::*, render::camera::{Camera, CameraProjection}};
2+
3+
use crate::game::{camera::{CameraData, CustomOrthographicProjection}, gameplay::player::PlayerSprite};
4+
5+
pub fn movement(
6+
time: Res<Time>,
7+
windows: Res<Windows>,
8+
player_query: Query<&Transform, (With<PlayerSprite>, Without<Camera>)>,
9+
mut camera_query: Query<(
10+
&mut CameraData,
11+
&mut Camera,
12+
&mut Transform,
13+
&mut CustomOrthographicProjection,
14+
)>,
15+
) {
16+
let mut player_position = Vec3::ZERO;
17+
for player_transform in player_query.iter() {
18+
player_position = player_transform.translation;
19+
}
20+
for (mut camera_data, mut camera, mut camera_transform, mut projection) in camera_query.iter_mut() {
21+
let camera_z = camera_transform.translation.z;
22+
23+
camera_data.value += 0.01 * time.delta_seconds();
24+
25+
camera_transform.translation = camera_transform.translation.truncate().lerp(player_position.truncate(), camera_data.value).extend(camera_z);
26+
27+
projection.update(
28+
windows.get_primary().unwrap().width(),
29+
windows.get_primary().unwrap().height(),
30+
);
31+
camera.projection_matrix = projection.get_projection_matrix();
32+
camera.depth_calculation = projection.depth_calculation();
33+
}
34+
}

src/game/gameplay/enemy/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ pub fn spawn_enemy(
1515
commands
1616
.spawn()
1717
.insert(GlobalTransform::default())
18-
.insert(Transform::from_xyz(position.x, position.y, 12.0))
18+
.insert(Transform::from_xyz(position.x, position.y, 11.0))
1919
.insert(Enemy::default())
2020
.with_children(|child_builder| {
2121
let texture_handle: Handle<Texture> = asset_server.load("textures/spider_sprite.png");

src/game/gameplay/mod.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
pub mod scenes;
1+
pub mod camera;
22
pub mod enemy;
33
pub mod player;
4+
pub mod scenes;

src/game/gameplay/player/collision.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
use bevy::prelude::*;
2+
use crate::game::{GameState, gameplay::{enemy::Enemy, scenes}};
3+
use super::PlayerSprite;
4+
5+
pub fn check(
6+
mut battle_event_writer: EventWriter<scenes::battle::BattleEvent>,
7+
mut game_state: ResMut<State<GameState>>,
8+
player_query: Query<(&PlayerSprite, &Transform)>,
9+
enemy_query: Query<(Entity, &Enemy, &Transform)>,
10+
) {
11+
let mut enemies_within_range = Vec::new();
12+
for (_, player_transform) in player_query.iter() {
13+
for (enemy_entity, _, enemy_transform) in enemy_query.iter() {
14+
let distance = player_transform.translation.distance_squared(enemy_transform.translation);
15+
if distance <= 32.0 {
16+
enemies_within_range.push((distance, enemy_entity, enemy_transform));
17+
}
18+
}
19+
20+
enemies_within_range.sort_by(|a, b| { a.0.partial_cmp(&b.0).unwrap() });
21+
22+
for (distance, enemy_entity, _enemy_transform) in enemies_within_range.iter() {
23+
if *distance < 8.0 {
24+
game_state.set(GameState::BattleView).unwrap();
25+
battle_event_writer.send(scenes::battle::BattleEvent {
26+
battle_location: scenes::battle::BattleLocation::Mountains,
27+
enemy_entity: *enemy_entity,
28+
});
29+
}
30+
}
31+
}
32+
}

src/game/gameplay/player/mod.rs

Lines changed: 35 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,50 @@ use bevy::{prelude::*, render::camera::RenderLayers};
22

33
mod movement;
44
mod player;
5+
pub mod collision;
56
pub use player::Player;
67

78
pub use movement::movement;
89

10+
#[derive(Default)]
11+
pub struct PlayerSprite {
12+
// Current index of the road path position that the player is traveling to.
13+
pub current_position: usize,
14+
}
15+
916
pub fn spawn_player(
1017
mut commands: Commands,
1118
asset_server: Res<AssetServer>,
1219
mut materials: ResMut<Assets<ColorMaterial>>,
1320
mut texture_atlases: ResMut<Assets<TextureAtlas>>,
1421
) {
15-
commands.spawn().insert(Player::default())
16-
.with_children(|child_builder| {
17-
let map_player_texture_handle = asset_server.load("textures/player_sprite.png");
18-
let map_player_sprite_material = materials.add(map_player_texture_handle.into());
19-
child_builder
20-
.spawn_bundle(SpriteBundle {
21-
material: map_player_sprite_material,
22-
transform: Transform::from_xyz(0.0, 0.0, 10.0),
23-
..Default::default()
24-
})
25-
.insert(RenderLayers::layer(0));
22+
commands.spawn()
23+
.insert(Player::default());
24+
25+
let map_player_texture_handle = asset_server.load("textures/player_sprite.png");
26+
let map_player_sprite_material = materials.add(map_player_texture_handle.into());
27+
commands
28+
.spawn_bundle(SpriteBundle {
29+
material: map_player_sprite_material,
30+
transform: Transform::from_xyz(0.0, 0.0, 10.0),
31+
..Default::default()
32+
})
33+
.insert(PlayerSprite::default())
34+
.insert(RenderLayers::layer(0));
35+
2636

27-
let battle_player_texture_handle = asset_server.load("textures/characters/huntress/idle.png");
28-
let texture_atlas =
29-
TextureAtlas::from_grid(battle_player_texture_handle, Vec2::new(150.0, 150.0), 8, 1);
30-
let texture_atlas_handle = texture_atlases.add(texture_atlas);
31-
32-
let mut transform = Transform::from_scale(Vec3::splat(5.0));
33-
transform.translation.z = 12.0;
34-
35-
child_builder
36-
.spawn_bundle(SpriteSheetBundle {
37-
texture_atlas: texture_atlas_handle,
38-
transform,
39-
..Default::default()
40-
})
41-
.insert(RenderLayers::layer(1))
42-
.insert(Timer::from_seconds(0.1, true));
43-
});
37+
let battle_player_texture_handle = asset_server.load("textures/characters/huntress/idle.png");
38+
let texture_atlas =
39+
TextureAtlas::from_grid(battle_player_texture_handle, Vec2::new(150.0, 150.0), 8, 1);
40+
let texture_atlas_handle = texture_atlases.add(texture_atlas);
41+
let mut transform = Transform::from_scale(Vec3::splat(5.0));
42+
transform.translation.z = 2.0;
43+
commands
44+
.spawn_bundle(SpriteSheetBundle {
45+
texture_atlas: texture_atlas_handle,
46+
transform,
47+
..Default::default()
48+
})
49+
.insert(RenderLayers::layer(1))
50+
.insert(Timer::from_seconds(0.1, true));
4451
}

src/game/gameplay/player/movement.rs

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
1-
use crate::game::{map::Map, timing::Timing};
1+
use crate::game::map::Map;
22
use bevy::prelude::*;
33

4-
use super::Player;
4+
use super::PlayerSprite;
55

66
pub fn movement(
7-
mut timing: ResMut<Timing>,
7+
time: Res<Time>,
88
map: Res<Map>,
9-
mut player_query: Query<(&mut Player, &mut Transform)>,
9+
mut player_query: Query<(&mut PlayerSprite, &mut Transform)>,
1010
) {
11-
if !timing.should_update {
12-
return;
13-
}
14-
15-
timing.should_update = false;
16-
1711
if map.road_path.len() > 0 {
1812
for (mut player, mut transform) in player_query.iter_mut() {
19-
player.current_position += 1;
20-
if player.current_position >= map.road_path.len() {
21-
player.current_position = 0;
22-
}
23-
2413
let current_road_position = map.road_path[player.current_position];
25-
transform.translation = Vec3::new(
14+
let current_road_position = Vec2::new(
2615
(current_road_position.0 as f32 * 16.0) + 8.0,
2716
(current_road_position.1 as f32 * 16.0) + 8.0,
28-
10.0,
2917
);
18+
let mut player_position = transform.translation.truncate();
19+
20+
21+
let direction = (current_road_position - player_position).normalize();
22+
player_position += direction * 100.0 * time.delta_seconds();
23+
24+
transform.translation = player_position.extend(10.0);
25+
26+
let distance = current_road_position.distance_squared(player_position);
27+
if distance <= 1.0 {
28+
player.current_position += 1;
29+
if player.current_position >= map.road_path.len() {
30+
player.current_position = 0;
31+
}
32+
}
3033
}
3134
}
3235
}

src/game/gameplay/player/player.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
#[derive(Default, Clone, Debug)]
22
pub struct Player {
3-
pub current_position: usize,
3+
44
}

0 commit comments

Comments
 (0)