2023-12-04 21:23:48 +00:00
|
|
|
use bevy::prelude::*;
|
2023-12-04 21:17:34 +00:00
|
|
|
|
|
|
|
// Define the player component
|
|
|
|
#[derive(Component)]
|
|
|
|
pub struct Player {
|
|
|
|
pub movement_speed: f32,
|
|
|
|
pub rotation_speed: f32,
|
2023-12-05 13:51:40 +00:00
|
|
|
|
|
|
|
pub health: f32,
|
|
|
|
pub health_max: f32,
|
|
|
|
pub stamina: f32,
|
|
|
|
pub stamina_max: f32,
|
2023-12-04 21:17:34 +00:00
|
|
|
}
|
|
|
|
|
2024-03-16 00:14:10 +00:00
|
|
|
// Define the attacking component
|
|
|
|
#[derive(Component)]
|
|
|
|
pub struct Attack {
|
|
|
|
pub velocity: f32,
|
|
|
|
pub damage: f32,
|
|
|
|
}
|
|
|
|
|
2023-12-04 21:17:34 +00:00
|
|
|
// Define the player movement system
|
|
|
|
pub fn movement(
|
|
|
|
time: Res<Time>,
|
2024-03-14 20:52:03 +00:00
|
|
|
keys: Res<ButtonInput<KeyCode>>,
|
2023-12-06 22:45:32 +00:00
|
|
|
mut player_query: Query<(&mut Player, &mut Transform), With<Player>>,
|
2023-12-04 21:17:34 +00:00
|
|
|
) {
|
2023-12-06 22:45:32 +00:00
|
|
|
let (mut player, mut transform) = player_query.single_mut();
|
2023-12-04 21:17:34 +00:00
|
|
|
|
|
|
|
let mut rotation_factor = 0.;
|
|
|
|
let mut movement_factor = 0.;
|
2023-12-06 22:45:32 +00:00
|
|
|
|
2024-03-14 20:52:03 +00:00
|
|
|
if keys.pressed(KeyCode::KeyW) {
|
2023-12-04 21:17:34 +00:00
|
|
|
movement_factor += 1.;
|
2024-03-14 20:52:03 +00:00
|
|
|
} else if keys.pressed(KeyCode::KeyS) {
|
2023-12-04 21:17:34 +00:00
|
|
|
movement_factor -= 1.;
|
2023-12-06 13:35:53 +00:00
|
|
|
}
|
2024-03-14 20:52:03 +00:00
|
|
|
if keys.pressed(KeyCode::KeyA) {
|
2023-12-04 21:17:34 +00:00
|
|
|
rotation_factor += 1.;
|
2024-03-14 20:52:03 +00:00
|
|
|
} else if keys.pressed(KeyCode::KeyD) {
|
2023-12-04 21:17:34 +00:00
|
|
|
rotation_factor -= 1.;
|
2023-12-06 13:35:53 +00:00
|
|
|
}
|
2023-12-05 13:51:40 +00:00
|
|
|
|
2023-12-07 13:48:38 +00:00
|
|
|
// Initialise the movement distance variable (to bring it into scope)
|
|
|
|
let mut movement_distance: f32 = 0.;
|
2023-12-07 19:00:18 +00:00
|
|
|
// Player is not dashing by default
|
|
|
|
let mut is_dashing = false;
|
2023-12-07 09:55:41 +00:00
|
|
|
|
2023-12-07 19:00:18 +00:00
|
|
|
// Dash on space key press if the player has the stamina
|
2023-12-07 17:44:17 +00:00
|
|
|
if keys.just_pressed(KeyCode::Space) && player.stamina >= 0.3 {
|
2023-12-07 19:00:18 +00:00
|
|
|
is_dashing = true;
|
2023-12-07 17:44:17 +00:00
|
|
|
player.stamina -= 0.3;
|
|
|
|
movement_distance = 256.;
|
2023-12-07 13:48:38 +00:00
|
|
|
}
|
2023-12-05 13:51:40 +00:00
|
|
|
|
2023-12-04 21:17:34 +00:00
|
|
|
// Get the player's *forward* vector
|
|
|
|
let movement_direction = transform.rotation * Vec3::Y;
|
|
|
|
|
2023-12-07 19:00:18 +00:00
|
|
|
if !is_dashing {
|
2023-12-07 17:44:17 +00:00
|
|
|
movement_distance = movement_factor * player.movement_speed * time.delta_seconds();
|
|
|
|
// Change the player rotation around the Z-axis only if not dashing
|
|
|
|
transform.rotate_z(rotation_factor * player.rotation_speed * time.delta_seconds());
|
2023-12-04 21:17:34 +00:00
|
|
|
}
|
|
|
|
|
2023-12-05 18:49:03 +00:00
|
|
|
// Update the player translation with the translation
|
|
|
|
transform.translation += movement_direction * movement_distance;
|
2023-12-06 13:35:53 +00:00
|
|
|
}
|
2023-12-04 21:17:34 +00:00
|
|
|
|
2024-03-16 00:14:10 +00:00
|
|
|
pub fn attack(
|
|
|
|
keys: Res<ButtonInput<KeyCode>>,
|
|
|
|
mut set: ParamSet<(
|
|
|
|
Query<&mut Transform, With<Attack>>,
|
|
|
|
Query<&Transform, With<Player>>
|
|
|
|
)>,
|
|
|
|
mut commands: Commands,
|
|
|
|
asset_server: Res<AssetServer>,
|
|
|
|
) {
|
2024-03-19 21:04:44 +00:00
|
|
|
|
2024-03-16 00:14:10 +00:00
|
|
|
for player_transform in set.p1().iter_mut() {
|
2024-03-19 21:04:44 +00:00
|
|
|
let attack_position = player_transform.translation + ((player_transform.rotation * Vec3::Y) * 50.);
|
|
|
|
|
2024-03-16 00:14:10 +00:00
|
|
|
if keys.just_pressed(KeyCode::Enter) {
|
|
|
|
commands
|
|
|
|
.spawn(SpriteBundle {
|
2024-03-19 21:04:44 +00:00
|
|
|
texture: asset_server.load("attacks/stone_cannon.png"),
|
2024-03-16 00:14:10 +00:00
|
|
|
transform: Transform {
|
2024-03-19 21:04:44 +00:00
|
|
|
scale: Vec3::splat(0.2),
|
|
|
|
translation: attack_position,
|
2024-03-16 00:14:10 +00:00
|
|
|
rotation: player_transform.rotation,
|
|
|
|
},
|
|
|
|
..default()
|
|
|
|
})
|
|
|
|
.insert(Attack {
|
|
|
|
velocity: 10.,
|
|
|
|
damage: 20.,
|
|
|
|
});
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for mut attack_transform in set.p0().iter_mut() {
|
|
|
|
let direction = attack_transform.rotation * Vec3::Y;
|
2024-03-19 21:04:44 +00:00
|
|
|
attack_transform.translation += direction * 20.;
|
2024-03-16 00:14:10 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-12-06 13:35:53 +00:00
|
|
|
// Function to make the camera follow the plaeyr
|
|
|
|
pub fn camera_follow(
|
|
|
|
mut player: Query<(&Player, &mut Transform)>,
|
|
|
|
mut cameras: Query<&mut Transform, (With<Camera>, Without<Player>)>,
|
|
|
|
) {
|
|
|
|
let (_, transform) = player.single_mut();
|
|
|
|
let pos = transform.translation;
|
|
|
|
|
|
|
|
for mut camera_transform in &mut cameras {
|
|
|
|
camera_transform.translation.x = pos.x;
|
|
|
|
camera_transform.translation.y = pos.y;
|
|
|
|
}
|
2023-12-04 21:17:34 +00:00
|
|
|
}
|
2023-12-06 22:45:32 +00:00
|
|
|
|
|
|
|
pub fn player_regen(mut player_query: Query<&mut Player, With<Player>>, time: Res<Time>) {
|
|
|
|
let mut player = player_query.single_mut();
|
|
|
|
if player.stamina < 1. {
|
2023-12-07 13:48:38 +00:00
|
|
|
player.stamina += 0.1 * time.delta_seconds();
|
2023-12-06 22:45:32 +00:00
|
|
|
}
|
|
|
|
}
|