haw-gj13-game/src/game/player.rs
2024-11-23 21:53:08 +01:00

175 lines
5.2 KiB
Rust

use std::{hash::Hash, time::Duration};
use animation::{run_animations, AnimBundle, Animation};
use bevy::{ecs::system::SystemId, prelude::*, sprite::MaterialMesh2dBundle, utils::HashMap};
use bevy_rapier2d::prelude::*;
use crate::{AppState, METER};
use super::{scene::PlayerCoords, set::IngameSet};
mod animation;
#[derive(Component)]
struct Player {
move_cooldown: Timer,
}
impl Default for Player {
fn default() -> Self {
Self {
move_cooldown: Timer::from_seconds(0.01, TimerMode::Repeating),
}
}
}
#[derive(Resource)]
pub struct PlayerSpawnOneshot(pub SystemId);
impl FromWorld for PlayerSpawnOneshot {
fn from_world(world: &mut World) -> Self {
Self(world.register_system(add_player))
}
}
pub(super) fn player_plugin(app: &mut App) {
app.add_systems(
Update,
(
move_player,
debug_player_pos,
run_animations::<PlayerAnimations>,
),
)
.init_resource::<PlayerSpawnOneshot>();
}
#[derive(Component, Hash, PartialEq, Eq, Default)]
enum PlayerAnimations {
#[default]
Idle,
Walk,
}
fn debug_player_pos(query: Query<&Transform, With<Player>>) {
let trans = query.single();
}
fn move_player(
kb_input: Res<ButtonInput<KeyCode>>,
mut query: Query<(
&mut Velocity,
&Transform,
&mut Player,
&mut KinematicCharacterController,
)>,
mut camera_query: Query<&mut Transform, (With<Camera2d>, Without<Player>)>,
phys: Query<&KinematicCharacterControllerOutput>,
player_coords: Res<PlayerCoords>,
time: Res<Time>,
) {
let (mut vel, p_transform, mut player, mut controller) = query.single_mut();
let (mut cam_transform) = camera_query.single_mut();
let (output) = phys.get_single();
if player.move_cooldown.tick(time.delta()).finished() {
let mut moved = false;
let mut move_x = 0;
let mut move_y = 0;
let mut jump = false;
if kb_input.pressed(KeyCode::KeyA) {
moved = true;
move_x -= 1;
}
if kb_input.pressed(KeyCode::KeyD) {
moved = true;
move_x += 1;
}
if kb_input.pressed(KeyCode::Space) && output.is_ok_and(|x| x.grounded) {
moved = true;
move_y += 1;
}
let orig = cam_transform.translation;
cam_transform.translation -= ((orig - p_transform.translation.xy().extend(0.0)) / 30.0);
controller.translation = Some(Vec2::new(move_x as f32 * 6., 0. - 0.01));
vel.linvel += Vec2::new(0., move_y as f32 * 3. * METER);
}
}
fn add_player(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut texture_atlas_layouts: ResMut<Assets<TextureAtlasLayout>>,
asset_server: Res<AssetServer>,
player_coords: Res<PlayerCoords>,
) {
let tex_idle = asset_server.load("idle.png");
let layout_idle = TextureAtlasLayout::from_grid(UVec2::splat(512), 2, 1, None, None);
let layout_idle_handle = texture_atlas_layouts.add(layout_idle);
let tex_walk = asset_server.load("walk.png");
let layout_walk = TextureAtlasLayout::from_grid(UVec2::splat(512), 4, 1, None, None);
let layout_walk_handle = texture_atlas_layouts.add(layout_walk);
let anims = animation::AnimationManager::default()
.insert(
PlayerAnimations::Idle,
Animation::new(layout_idle_handle.clone(), 2, 4, tex_idle.clone()),
)
.insert(
PlayerAnimations::Walk,
Animation::new(layout_walk_handle.clone(), 4, 10, tex_walk.clone()),
);
commands
.spawn((
Player::default(),
AnimBundle {
tag: PlayerAnimations::Idle,
mgr: anims,
},
SpriteBundle {
sprite: Sprite {
custom_size: Some(Vec2::splat(1.)),
..Default::default()
},
transform: (*player_coords).into(),
texture: tex_idle,
..Default::default()
},
TextureAtlas {
layout: layout_idle_handle,
index: 0,
},
))
.insert((
RigidBody::Dynamic,
player_coords.get_collider(),
LockedAxes::ROTATION_LOCKED,
Velocity::default(),
))
.insert(KinematicCharacterController {
//translation: todo!(),
//custom_shape: todo!(),
//custom_mass: todo!(),
//up: todo!(),
offset: CharacterLength::Absolute(0.01),
slide: true,
//autostep: Some(CharacterAutostep {
// max_height: CharacterLength::Relative(0.1),
// min_width: CharacterLength::Absolute(1.0),
// include_dynamic_bodies: false,
//}),
//max_slope_climb_angle: todo!(),
//min_slope_slide_angle: todo!(),
//apply_impulse_to_dynamic_bodies: todo!(),
snap_to_ground: Some(CharacterLength::Absolute(0.5)),
//filter_flags: todo!(),
//filter_groups: todo!(),
// normal_nudge_factor: 1.,
..Default::default()
});
}