From df84ef60dab6dba0582a647f42663a3248d88cbb Mon Sep 17 00:00:00 2001 From: jacopograndi Date: Fri, 5 Aug 2022 16:26:39 +0200 Subject: trainwreck --- src/main.rs | 295 ++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 187 insertions(+), 108 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index 1074319..7131c68 100644 --- a/src/main.rs +++ b/src/main.rs @@ -8,12 +8,16 @@ use bevy::{prelude::*, render::camera::ScalingMode, window::WindowResized}; use bevy_rapier2d::{pipeline::CollisionEvent::*, prelude::*}; -use bevy_ggrs::{GGRSPlugin, SessionType}; -use ggrs::{Config, PlayerHandle, PlayerType, SessionBuilder, UdpNonBlockingSocket}; +use bevy_ggrs::{GGRSPlugin, Rollback, RollbackIdProvider, SessionType}; +use ggrs::{ + Config, InputStatus, P2PSession, PlayerHandle, PlayerType, SessionBuilder, SpectatorSession, + SyncTestSession, UdpNonBlockingSocket, +}; use bytemuck::{Pod, Zeroable}; use std::net::SocketAddr; +use bincode::{deserialize, serialize}; use structopt::StructOpt; #[derive(Debug)] @@ -24,39 +28,9 @@ impl Config for GGRSConfig { type Address = SocketAddr; } -#[repr(C)] -#[derive(Copy, Clone, PartialEq, Pod, Zeroable)] -pub struct BoxInput { - pub inp: u8, -} - -const FPS: usize = 60; +const FPS: usize = 10; const ROLLBACK_DEFAULT: &str = "rollback_default"; -const INPUT_UP: u8 = 1 << 0; -const INPUT_DOWN: u8 = 1 << 1; -const INPUT_LEFT: u8 = 1 << 2; -const INPUT_RIGHT: u8 = 1 << 3; - -pub fn input(_handle: In, keyboard_input: Res>) -> BoxInput { - let mut input: u8 = 0; - - if keyboard_input.pressed(KeyCode::W) { - input |= INPUT_UP; - } - if keyboard_input.pressed(KeyCode::A) { - input |= INPUT_LEFT; - } - if keyboard_input.pressed(KeyCode::S) { - input |= INPUT_DOWN; - } - if keyboard_input.pressed(KeyCode::D) { - input |= INPUT_RIGHT; - } - - BoxInput { inp: input } -} - // structopt will read command line parameters for u #[derive(StructOpt)] struct Opt { @@ -105,12 +79,17 @@ fn main() -> Result<(), Box> { GGRSPlugin::::new() .with_update_frequency(FPS) .with_input_system(input) - .register_rollback_type::() - .register_rollback_type::() + .register_rollback_type::() + .register_rollback_type::() + .register_rollback_type::() .with_rollback_schedule( Schedule::default().with_stage( ROLLBACK_DEFAULT, - SystemStage::parallel() + SystemStage::single_threaded() + .with_system(physics_deser) + .with_system(movement) + .with_system(shoot) + .with_system(hits) .with_system_set(RapierPhysicsPlugin::<()>::get_systems( PhysicsStages::SyncBackend, )) @@ -122,7 +101,8 @@ fn main() -> Result<(), Box> { )) .with_system_set(RapierPhysicsPlugin::<()>::get_systems( PhysicsStages::DetectDespawn, - )), + )) + .with_system(physics_ser), ), ) .build(&mut app); @@ -136,24 +116,50 @@ fn main() -> Result<(), Box> { .insert_resource(sess) .insert_resource(SessionType::P2PSession) .add_plugins(DefaultPlugins) - .add_startup_system(spawn_camera) + .add_startup_system(physics_init) .add_startup_system(setup) - .add_plugin(LogDiagnosticsPlugin::default()) - .add_plugin(FrameTimeDiagnosticsPlugin::default()) + .add_startup_system(spawn_camera) + //.add_plugin(LogDiagnosticsPlugin::default()) + //.add_plugin(FrameTimeDiagnosticsPlugin::default()) .add_plugin( RapierPhysicsPlugin::::pixels_per_meter(100.0).with_default_system_setup(false), ) - .add_plugin(RapierDebugRenderPlugin::default()) - .add_system_to_stage(CoreStage::Update, movement) - .add_system_to_stage(CoreStage::Update, shoot) + //.add_plugin(RapierDebugRenderPlugin::default()) .add_system_to_stage(CoreStage::PostUpdate, camera_follow) - .add_system_to_stage(CoreStage::PostUpdate, hits) .add_system(window_resized_event) .run(); Ok(()) } +#[derive(Default, Reflect, Component)] +struct SerPhysics { + pub ser: Vec, +} + +fn physics_init( + mut commands: Commands, + context: Res, + mut rip: ResMut, +) { + commands + .spawn() + .insert(SerPhysics { + ser: bincode::serialize(context.into_inner()).unwrap(), + }) + .insert(Rollback::new(rip.next_id())); +} + +fn physics_ser(mut ser_query: Query<&mut SerPhysics>, context: Res) { + ser_query.single_mut().ser = bincode::serialize(context.into_inner()).unwrap(); +} + +fn physics_deser(ser_query: Query<&SerPhysics>, mut commands: Commands) { + commands.remove_resource::(); + commands + .insert_resource(bincode::deserialize::(&ser_query.single().ser).unwrap()); +} + fn window_resized_event( mut events: EventReader, mut window: ResMut, @@ -167,11 +173,18 @@ fn window_resized_event( fn camera_follow( player_query: Query<(&Player, &Transform)>, mut camera_query: Query<&mut Transform, (Without, With)>, + p2p_session: Option>>, ) { - let (_, transform) = player_query.single(); - let mut camera_transform = camera_query.single_mut(); - camera_transform.translation.x = transform.translation.x; - camera_transform.translation.y = transform.translation.y; + let handles = p2p_session.unwrap().local_player_handles(); + if handles.len() > 0 { + let (_, transform) = player_query + .iter() + .find(|(p, _)| p.handle == handles[0]) + .unwrap(); + let mut camera_transform = camera_query.single_mut(); + camera_transform.translation.x = transform.translation.x; + camera_transform.translation.y = transform.translation.y; + } } fn spawn_camera(mut commands: Commands) { @@ -205,30 +218,86 @@ fn hits( } } -#[derive(Component)] +#[derive(Component, Default, Reflect)] pub struct Bullet; -#[derive(Component)] +#[derive(Component, Default, Reflect)] pub struct Player { - speed: f32, - radius: f32, + pub handle: usize, + pub speed: f32, + pub radius: f32, +} + +#[repr(C)] +#[derive(Copy, Clone, PartialEq, Pod, Zeroable)] +pub struct BoxInput { + pub inp: u8, + pub sx: u8, + pub sy: u8, +} + +const INPUT_UP: u8 = 1 << 0; +const INPUT_DOWN: u8 = 1 << 1; +const INPUT_LEFT: u8 = 1 << 2; +const INPUT_RIGHT: u8 = 1 << 3; + +pub fn input(_handle: In, keyboard_input: Res>) -> BoxInput { + let mut input: u8 = 0; + + if keyboard_input.pressed(KeyCode::W) { + input |= INPUT_UP; + } + if keyboard_input.pressed(KeyCode::A) { + input |= INPUT_LEFT; + } + if keyboard_input.pressed(KeyCode::S) { + input |= INPUT_DOWN; + } + if keyboard_input.pressed(KeyCode::D) { + input |= INPUT_RIGHT; + } + + let mut x: u8 = 127; + let mut y: u8 = 127; + if keyboard_input.pressed(KeyCode::Up) { + y = 255; + } + if keyboard_input.pressed(KeyCode::Down) { + y = 0; + } + if keyboard_input.pressed(KeyCode::Left) { + x = 0; + } + if keyboard_input.pressed(KeyCode::Right) { + x = 255; + } + + BoxInput { + inp: input, + sx: x, + sy: y, + } } -fn movement(mut player_query: Query<(&mut Player, &mut Velocity)>, keyboard: Res>) { +fn movement( + mut player_query: Query<(&mut Player, &mut Velocity)>, + inputs: Res>, +) { for (player, mut rb_vels) in player_query.iter_mut() { + let input = inputs[player.handle as usize].0.inp; let mut acc = Vec2::new(0.0, 0.0); - if keyboard.pressed(KeyCode::W) { - acc.y += 1.0; - } - if keyboard.pressed(KeyCode::S) { + if input & INPUT_UP != 0 && input & INPUT_DOWN == 0 { acc.y -= 1.0; } - if keyboard.pressed(KeyCode::A) { + if input & INPUT_UP == 0 && input & INPUT_DOWN != 0 { acc.x -= 1.0; } - if keyboard.pressed(KeyCode::D) { + if input & INPUT_LEFT != 0 && input & INPUT_RIGHT == 0 { acc.x += 1.0; } + if input & INPUT_LEFT == 0 && input & INPUT_RIGHT != 0 { + acc.x -= 1.0; + } if acc.length_squared() > 0.0 { acc /= acc.length(); } @@ -238,23 +307,15 @@ fn movement(mut player_query: Query<(&mut Player, &mut Velocity)>, keyboard: Res fn shoot( player_query: Query<(&Player, &Transform, &Velocity)>, - keyboard: Res>, + inputs: Res>, mut commands: Commands, + mut rip: ResMut, ) { for (player, player_transform, _rb_vels) in player_query.iter() { - let mut acc = Vec2::new(0.0, 0.0); - if keyboard.pressed(KeyCode::Up) { - acc.y += 1.0; - } - if keyboard.pressed(KeyCode::Down) { - acc.y -= 1.0; - } - if keyboard.pressed(KeyCode::Left) { - acc.x -= 1.0; - } - if keyboard.pressed(KeyCode::Right) { - acc.x += 1.0; - } + let input = inputs[player.handle as usize].0; + let sx: f32 = (input.sx as f32) - 127.0 / 256.0; + let sy: f32 = (input.sy as f32) - 127.0 / 256.0; + let mut acc = Vec2::new(sx, sy); if acc.length_squared() > 0.0 { acc /= acc.length(); let head = Vec3::new(acc.x, acc.y, 0.0) * (2.0 + player.radius + 3.0); @@ -285,7 +346,8 @@ fn shoot( .insert(Ccd::enabled()) .insert(Velocity::linear(acc * 1000.0)) .insert(CollisionGroups::new(0b010, 0b101)) - .insert(ActiveEvents::COLLISION_EVENTS); + .insert(ActiveEvents::COLLISION_EVENTS) + .insert(Rollback::new(rip.next_id())); } } } @@ -368,7 +430,14 @@ fn setup_map(mut commands: Commands) { } } -fn setup(mut commands: Commands, mut rapier_config: ResMut) { +fn setup( + mut commands: Commands, + mut rapier_config: ResMut, + mut rip: ResMut, + p2p_session: Option>>, + synctest_session: Option>>, + spectator_session: Option>>, +) { rapier_config.gravity = Vec2::ZERO; let color = commands @@ -383,40 +452,50 @@ fn setup(mut commands: Commands, mut rapier_config: ResMut) }) .id(); - commands - .spawn() - .insert_bundle(SpriteBundle { - transform: Transform { - translation: Vec3::new(0.0, 0.0, 0.0), - scale: Vec3::splat(10.0), - ..default() - }, - sprite: Sprite { - color: Color::WHITE, + let num_players = p2p_session + .map(|s| s.num_players()) + .or_else(|| synctest_session.map(|s| s.num_players())) + .or_else(|| spectator_session.map(|s| s.num_players())) + .expect("No GGRS session found"); + + for handle in 0..num_players { + commands + .spawn() + .insert_bundle(SpriteBundle { + transform: Transform { + translation: Vec3::new(handle as f32, 0.0, 0.0), + scale: Vec3::splat(10.0), + ..default() + }, + sprite: Sprite { + color: Color::WHITE, + ..default() + }, ..default() - }, - ..default() - }) - .push_children(&[color]) - .insert(Player { - speed: 150.0, - radius: 10.0, - }) - .insert(RigidBody::Dynamic) - .insert(Restitution::coefficient(0.0)) - .insert(Collider::ball(1.0)) - .insert(LockedAxes::ROTATION_LOCKED) - .insert(Damping { - linear_damping: 30.0, - angular_damping: 1.0, - }) - .insert(Friction { - coefficient: 0.0, - combine_rule: CoefficientCombineRule::Min, - }) - .insert(Ccd::enabled()) - .insert(Velocity::zero()) - .insert(CollisionGroups::new(0b001, 0b111)); + }) + .push_children(&[color]) + .insert(Player { + handle, + speed: 150.0, + radius: 10.0, + }) + .insert(RigidBody::Dynamic) + .insert(Restitution::coefficient(0.0)) + .insert(Collider::ball(1.0)) + .insert(LockedAxes::ROTATION_LOCKED) + .insert(Damping { + linear_damping: 30.0, + angular_damping: 1.0, + }) + .insert(Friction { + coefficient: 0.0, + combine_rule: CoefficientCombineRule::Min, + }) + .insert(Ccd::enabled()) + .insert(Velocity::zero()) + .insert(CollisionGroups::new(0b001, 0b111)) + .insert(Rollback::new(rip.next_id())); + } setup_map(commands); } -- cgit v1.2.3-54-g00ecf