WQS2WD437EWG2CKPOY5TDWPEBE3US7LGHVAH2HVYQ7RW2L6FHJ5AC T7TFTN36VJXR3CQDC66LXB2LKYSYUBVCI5KN3YAKNT2VESP7TPGQC EG65GETJ6WWNENAGPJYVO3O2TGAHFIMFY52GGLKE5GTLPD47IRCQC MKB2A5XCWBZO2E6QFE6PD36LF3IGMJCGJB5TGMRAPSKCKHS75ISAC 7FTW5AQKOO4W5AIHYZSAKLQR6LGVTXH7SKMSTA4ER4C4HP54VE4QC C5GZASC2IIWFVVD2UTI2IKF7YDQYT3NHSUUUW66GSN4NCXTSPVIQC 7SXAXY6J4QHPDUUHCKZDEZOZ2IUMSBWODICOMIZH2KA2BGV3F54QC EV477LPQ57FEHMFO6E3LL5MFWZC6NTGER42SKP5CJN73SWXGB5AQC DBHCCY3W2DG4WYMXBZ2UCNYVGZ5PS5UUUNWCXVYJ4TMXQDIZT6GAC CAN3DHITMPDA2DJC63QMMPMIC63FMWCUAI4ZLKPLEHIYG2EWIAHAC 5Y32O2B2GTH2UHFA3NO4ZY673XNHT3W4DQADFMK4LMKLSXMZKHGQC ZH7HF4FYTYVE5NQFULKSDXIE3LHMFVQGI3FKF366QRY7NJLPADRQC DHAY4KB3FVA3WZVBDVVGGBGLEACA7C4PFKSKGHNFOSXVNGYOXJ7AC 66PNECCRWS2BPZS555P2355EY2PAHZWHJJEXTDU2WUBOHANRNXFQC ZUZLL6PWZE57MLTQJ56MT3HGIQU6NEHQRB63VQYJRY5HNVC7NVMAC OQCI44VL3IROGBJ52MUI3AICPKEPAJVFL45PGQNNQRK4TKIK7HAAC YT2GB32PAGZCSNZGKTQH7MCJ675TK2G5OHS7SY4R2FDCNBKQHXYAC HYJ4HJQVLLDTE6JYKEYQK2LBWREOQUATESGB3QP7WDJB3IMVS6OAC 5EIYEUF3S5ETMMVECT7GGEEW6O45AJHAA7HS2EWK5II2IYYD7JGAC NT6M5NVCET62C54HC6RHQRH2RJUGD4LYCYNSIKJFKCHBN7F33UQQC D4QISWMTFAC4M2VFEQJBQ4FTJRRKTJCJCECDQPICUELOD75XSMUAC RX53J3WT6RGLQVUDTYKRCMO2BMD765ZF4JC6ADPUVWSVLDZ7RI5AC 7BH3JTSGT655ESF4H7UY2BPSXV35JGKAKYUWZVLCKPCEAQDSL57QC 3PEU6H5YDCRN2O7IIORFPJRKDE6FOJVMBOXSAGU7CJWOHULYNEAQC use super::{movement_pointer, PlayerAssets};use bevy::prelude::*;use bevy_ecs_ldtk::LdtkEntity;use bevy_prototype_lyon::{entity::ShapeBundle, geometry::GeometryBuilder, shapes};use leafwing_input_manager::prelude::*;use moonshine_spawn::{spawn_children, SpawnChildren};#[derive(Component)]pub(crate) struct DashState(pub bool);pub(crate) fn handle_dashing(mut query: Query<(&mut DashState, &ActionState<PlayerAction>)>) {for (mut dash_state, action_state) in query.iter_mut() {// handle hold dashif action_state.just_pressed(&PlayerAction::HoldDash) {dash_state.0 = true;} else if action_state.just_released(&PlayerAction::HoldDash) {dash_state.0 = false;}// Handle toggle dashif action_state.just_pressed(&PlayerAction::ToggleDash) {dash_state.0 = !dash_state.0;}}}pub(crate) fn move_player(mut query: Query<(&ActionState<PlayerAction>,&mut Transform,Option<&mut Sprite>,&DashState,&mut movement_pointer::MovementDirection,),With<Player>,>,time: Res<Time>,) {for (action_state, mut transform, maybe_sprite, dash, mut md) in query.iter_mut() {// Right now, treat our joystick as a velocity.if let Some(dad) = action_state.clamped_axis_pair(&PlayerAction::Move) {const SPEED: f32 = 350.0;const DASH_SPEED: f32 = 700.0;let movement = dad.xy();if let Some(movement_norm) = movement.try_normalize() {let speed = if dash.0 { DASH_SPEED } else { SPEED };transform.translation += movement_norm.extend(0.0) * speed * time.delta_seconds();md.0 = movement_norm;md.1 = speed;if let Some(mut sprite) = maybe_sprite {// If we have a sprite, flip x if we moved in a negative x dir// Might not be necessarylet x_movement = movement_norm.x;match x_movement.signum() {x if x == 1.0 && x_movement > f32::EPSILON => {sprite.flip_x = false;}// cuz negx if x == -1.0 && x_movement < f32::EPSILON => {sprite.flip_x = true;}_ => {}}}} else {md.0 = Vec2::ZERO;md.1 = 0.0;}}}}#[derive(Actionlike, PartialEq, Eq, Hash, Clone, Copy, Debug, Reflect)]pub(crate) enum PlayerAction {Move,LightAttack,HeavyAttack,// Dash variants, both should just enable dash, but one// needs to be held, while the other toggles dash on and offHoldDash,ToggleDash,// X axis - switching between cards// +Y axis - above deadzone, use card// -Y axis - above deadzone, held, exhaust handHand,}#[derive(Component, Default)]pub(crate) struct Player;#[derive(Bundle, Default, LdtkEntity)]pub(crate) struct PlayerBlueprint {pub(crate) player: Player,}#[derive(Bundle)]pub(crate) struct PlayerBundle {pub(crate) input_manager_bundle: InputManagerBundle<PlayerAction>,// For now, use a mesh// mesh: MaterialMesh2dBundle<ColorMaterial>,pub(crate) sprite_sheet: SpriteSheetBundle,// used to render a pointed arrowpub(crate) movement_dir: movement_pointer::MovementDirection,pub(crate) dash: DashState,// moonshine childrenpub(crate) children: SpawnChildren,}pub(crate) fn process_player_start(mut commands: Commands,new_entity_instances: Query<(Entity, &Transform), Added<Player>>,// mut meshes: ResMut<Assets<Mesh>>,mut materials: ResMut<Assets<ColorMaterial>>,player_assets: Res<PlayerAssets>,) {for (entity, transform) in new_entity_instances.iter() {commands.entity(entity).insert(PlayerBundle {input_manager_bundle: InputManagerBundle::with_map(default_input_map()),movement_dir: movement_pointer::MovementDirection(Vec2::X, 0.0),dash: DashState(false),sprite_sheet: SpriteSheetBundle {texture: player_assets.texture.clone(),atlas: TextureAtlas {layout: player_assets.layout.clone(),index: 0,},transform: (*transform) * Transform::default().with_translation(Vec3::Y * 8.0),..default()},// mesh: MaterialMesh2dBundle {// mesh: meshes// .add(Rectangle {// half_size: (16.0, 24.0).into(),// })// .into(),// // Be careful not to overwrite the LDtk transform// // Change our origin// transform: (*transform) * Transform::default().with_translation(Vec3::Y * 8.0),// material: materials.add(Color::PURPLE),// ..default()// },children: spawn_children(|cb| {cb.spawn(movement_pointer::MovementPointerBundle {pointer: movement_pointer::MovementPointer,shape: ShapeBundle {spatial: SpatialBundle {transform: Transform::default().with_scale(Vec3::new(0.5, 1.0, 1.0)),..default()},path: GeometryBuilder::build_as(&shapes::RegularPolygon {sides: 3,feature: shapes::RegularPolygonFeature::Apothem(5.0),..default()}),material: materials.add(Color::ORANGE_RED),..default()},});}),});}}pub(crate) fn default_input_map() -> InputMap<PlayerAction> {let mut map = InputMap::default();map.insert(PlayerAction::Move, DualAxis::left_stick());map.insert(PlayerAction::Move, VirtualDPad::wasd());map.insert(PlayerAction::LightAttack, KeyCode::KeyZ);map.insert(PlayerAction::HeavyAttack, KeyCode::KeyX);map.insert(PlayerAction::HoldDash, GamepadButtonType::RightTrigger);map.insert(PlayerAction::HoldDash, KeyCode::ShiftLeft);map.insert(PlayerAction::ToggleDash, KeyCode::KeyC);map.insert(PlayerAction::Hand, VirtualDPad::gamepad_face_buttons());map.insert(PlayerAction::Hand, VirtualDPad::arrow_keys());map}
}}#[derive(Component)]struct DashState(bool);fn handle_dashing(mut query: Query<(&mut DashState, &ActionState<PlayerAction>)>) {for (mut dash_state, action_state) in query.iter_mut() {// handle hold dashif action_state.just_pressed(&PlayerAction::HoldDash) {dash_state.0 = true;} else if action_state.just_released(&PlayerAction::HoldDash) {dash_state.0 = false;}// Handle toggle dashif action_state.just_pressed(&PlayerAction::ToggleDash) {dash_state.0 = !dash_state.0;}}}fn move_player(mut query: Query<(&ActionState<PlayerAction>,&mut Transform,Option<&mut Sprite>,&DashState,&mut movement_pointer::MovementDirection,),With<Player>,>,time: Res<Time>,) {for (action_state, mut transform, maybe_sprite, dash, mut md) in query.iter_mut() {// Right now, treat our joystick as a velocity.if let Some(dad) = action_state.clamped_axis_pair(&PlayerAction::Move) {const SPEED: f32 = 350.0;const DASH_SPEED: f32 = 700.0;let movement = dad.xy();if let Some(movement_norm) = movement.try_normalize() {let speed = if dash.0 { DASH_SPEED } else { SPEED };transform.translation += movement_norm.extend(0.0) * speed * time.delta_seconds();md.0 = movement_norm;md.1 = speed;if let Some(mut sprite) = maybe_sprite {// If we have a sprite, flip x if we moved in a negative x dir// Might not be necessarylet x_movement = movement_norm.x;match x_movement.signum() {x if x == 1.0 && x_movement > f32::EPSILON => {sprite.flip_x = false;}// cuz negx if x == -1.0 && x_movement < f32::EPSILON => {sprite.flip_x = true;}_ => {}}}} else {md.0 = Vec2::ZERO;md.1 = 0.0;}}}}#[derive(Actionlike, PartialEq, Eq, Hash, Clone, Copy, Debug, Reflect)]enum PlayerAction {Move,LightAttack,HeavyAttack,// Dash variants, both should just enable dash, but one// needs to be held, while the other toggles dash on and offHoldDash,ToggleDash,// X axis - switching between cards// +Y axis - above deadzone, use card// -Y axis - above deadzone, held, exhaust handHand,}#[derive(Component, Default)]struct Player;#[derive(Bundle, Default, LdtkEntity)]struct PlayerBlueprint {player: Player,}#[derive(Bundle)]struct PlayerBundle {input_manager_bundle: InputManagerBundle<PlayerAction>,// For now, use a mesh// mesh: MaterialMesh2dBundle<ColorMaterial>,sprite_sheet: SpriteSheetBundle,// used to render a pointed arrowmovement_dir: movement_pointer::MovementDirection,dash: DashState,// moonshine childrenchildren: SpawnChildren,}fn process_player_start(mut commands: Commands,new_entity_instances: Query<(Entity, &Transform), Added<Player>>,// mut meshes: ResMut<Assets<Mesh>>,mut materials: ResMut<Assets<ColorMaterial>>,player_assets: Res<PlayerAssets>,) {for (entity, transform) in new_entity_instances.iter() {commands.entity(entity).insert(PlayerBundle {input_manager_bundle: InputManagerBundle::with_map(default_input_map()),movement_dir: movement_pointer::MovementDirection(Vec2::X, 0.0),dash: DashState(false),sprite_sheet: SpriteSheetBundle {texture: player_assets.texture.clone(),atlas: TextureAtlas {layout: player_assets.layout.clone(),index: 0,},transform: (*transform) * Transform::default().with_translation(Vec3::Y * 8.0),..default()},// mesh: MaterialMesh2dBundle {// mesh: meshes// .add(Rectangle {// half_size: (16.0, 24.0).into(),// })// .into(),// // Be careful not to overwrite the LDtk transform// // Change our origin// transform: (*transform) * Transform::default().with_translation(Vec3::Y * 8.0),// material: materials.add(Color::PURPLE),// ..default()// },children: spawn_children(|cb| {cb.spawn(movement_pointer::MovementPointerBundle {pointer: movement_pointer::MovementPointer,shape: ShapeBundle {spatial: SpatialBundle {transform: Transform::default().with_scale(Vec3::new(0.5, 1.0, 1.0)),..default()},path: GeometryBuilder::build_as(&shapes::RegularPolygon {sides: 3,feature: RegularPolygonFeature::Apothem(5.0),..default()}),material: materials.add(Color::ORANGE_RED),..default()},});}),});
}fn default_input_map() -> InputMap<PlayerAction> {let mut map = InputMap::default();map.insert(PlayerAction::Move, DualAxis::left_stick());map.insert(PlayerAction::Move, VirtualDPad::wasd());map.insert(PlayerAction::LightAttack, KeyCode::KeyZ);map.insert(PlayerAction::HeavyAttack, KeyCode::KeyX);map.insert(PlayerAction::HoldDash, GamepadButtonType::RightTrigger);map.insert(PlayerAction::HoldDash, KeyCode::ShiftLeft);map.insert(PlayerAction::ToggleDash, KeyCode::KeyC);map.insert(PlayerAction::Hand, VirtualDPad::gamepad_face_buttons());map.insert(PlayerAction::Hand, VirtualDPad::arrow_keys());map}#[derive(Component)]struct Camera;#[derive(Bundle)]struct CameraBundle {camera: Camera,camera_2d: Camera2dBundle,pixel_camera: PixelCamera,chroma_aberration: post_process::ChromaticAberattionSettings,}fn setup_camera(mut commands: Commands) {commands.spawn(CameraBundle {camera: Camera,camera_2d: Camera2dBundle::default(),pixel_camera: PixelCamera::from_size(ViewportSize::AutoMax {max_width: LOGICAL_WIDTH,max_height: LOGICAL_HEIGHT,}),chroma_aberration: post_process::ChromaticAberattionSettings {// intensity: 0.02,..default()},});
fn update_camera(mut camera: Query<(&mut PixelCamera, &GlobalTransform), With<Camera>>,player: Query<&GlobalTransform, With<Player>>,) {match (player.get_single(), camera.get_single_mut()) {(Ok(transform), Ok((mut camera, cam_transform))) => {// Lerp the camera to player's global translation pointlet source = cam_transform.translation();let goal = transform.translation();let diff = goal - source;let lerped = source + diff * 0.1; //* time.delta_seconds();camera.subpixel_pos = lerped.xy();}_ => {// Either the camera or the player doesnt exist}}}
use super::{player::Player, post_process, LOGICAL_HEIGHT, LOGICAL_WIDTH};use bevy::prelude::*;use bevy_smooth_pixel_camera::components::PixelCamera;use bevy_smooth_pixel_camera::viewport::ViewportSize;#[derive(Component)]pub(crate) struct Camera;#[derive(Bundle)]pub(crate) struct CameraBundle {pub(crate) camera: Camera,pub(crate) camera_2d: Camera2dBundle,pub(crate) pixel_camera: PixelCamera,pub(crate) chroma_aberration: post_process::ChromaticAberattionSettings,}pub(crate) fn setup_camera(mut commands: Commands) {commands.spawn(CameraBundle {camera: Camera,camera_2d: Camera2dBundle::default(),pixel_camera: PixelCamera::from_size(ViewportSize::AutoMax {max_width: LOGICAL_WIDTH,max_height: LOGICAL_HEIGHT,}),chroma_aberration: post_process::ChromaticAberattionSettings {// intensity: 0.02,..default()},});}pub(crate) fn update_camera(mut camera: Query<(&mut PixelCamera, &GlobalTransform), With<Camera>>,player: Query<&GlobalTransform, With<Player>>,) {match (player.get_single(), camera.get_single_mut()) {(Ok(transform), Ok((mut camera, cam_transform))) => {// Lerp the camera to player's global translation pointlet source = cam_transform.translation();let goal = transform.translation();let diff = goal - source;let lerped = source + diff * 0.1; //* time.delta_seconds();camera.subpixel_pos = lerped.xy();}_ => {// Either the camera or the player doesnt exist}}}