use crate::assets::{AssetHandles, FetchPhysicsConfig}; use crate::system::{AppState, ChaseCam, PolyInputManager}; use bevy::prelude::*; use crate::entities::physics::HasGravity; use crate::entities::{ Acceleration, PhysicsLimits, PhysicsSet, SimpleAnimation, SimpleAnimationBundle, Velocity, GRAVITY_ACC, }; use bevy_rapier2d::prelude::*; #[derive(Component, Clone, Copy, Debug)] pub struct Player; pub fn spawn_player(mut commands: Commands, assets: Res<AssetHandles>) { commands.spawn(( Player, SpriteSheetBundle { sprite: TextureAtlasSprite::new(9), texture_atlas: assets.atlas("characters"), transform: Transform::from_xyz(0.0, 0.0, 100.0), ..Default::default() }, RigidBody::KinematicPositionBased, Collider::cuboid(8.0, 12.0), KinematicCharacterController { snap_to_ground: Some(CharacterLength::Absolute(0.5)), offset: CharacterLength::Absolute(0.03), ..Default::default() }, Acceleration::default(), Velocity::default(), HasGravity, PhysicsLimits { velocity: ( Some(Vec2::new(f32::NEG_INFINITY, GRAVITY_ACC)), Some(Vec2::new(f32::INFINITY, (-GRAVITY_ACC) * 2.0)), ), acceleration: Default::default(), }, ChaseCam, SimpleAnimationBundle::new( SimpleAnimation { frames: vec![9], frame_time: 10.0, }, SimpleAnimation { frames: vec![10, 9], frame_time: 0.2, }, ), )); } pub fn handle_input( input: PolyInputManager, mut query: Query<(&mut Velocity, &KinematicCharacterControllerOutput), With<Player>>, phys_config: FetchPhysicsConfig, ) { let speed = phys_config .get() .map(|phys_config| phys_config.speed) .unwrap_or_default(); for (mut velocity, controller) in &mut query { let delta_y = if controller.grounded && input.is_jump_just_pressed() { Some(40.0) } else { None }; let delta_x = if input.is_right_pressed_or_active() { speed } else if input.is_left_pressed_or_active() { -speed } else { 0.0 }; if let Some(dy) = delta_y { velocity.y = dy; } velocity.x = delta_x; } } pub struct PlayerSetupPlugin; impl Plugin for PlayerSetupPlugin { fn build(&self, app: &mut App) { app.add_systems(OnEnter(AppState::InGame), spawn_player) .add_systems(Update, handle_input.before(PhysicsSet)); } }