First working version
Next we will be looking at implementing multi-controller multiplayer
This commit is contained in:
parent
0b15908469
commit
15b0b8efc3
5
.gitignore
vendored
5
.gitignore
vendored
@ -10,3 +10,8 @@ Cargo.lock
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
|
||||
|
||||
#Added by cargo
|
||||
|
||||
/target
|
||||
|
19
Cargo.toml
Normal file
19
Cargo.toml
Normal file
@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "LJ-rust-filters"
|
||||
version = "0.1.0"
|
||||
authors = ["Leo Le Bouter <lle-bout@zaclys.net>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
serde_json = "1.0.58"
|
||||
gilrs = "0.7.4"
|
||||
clap = "2.33.3"
|
||||
anyhow = "1.0.33"
|
||||
chrono = "0.4.19"
|
||||
rand = "0.7.3"
|
||||
ncollide2d = "0.25.0"
|
||||
nphysics2d = "0.17.0"
|
||||
nalgebra = "0.22.0"
|
||||
nphysics_testbed2d = "0.10.0"
|
135
src/main copy.rs_
Normal file
135
src/main copy.rs_
Normal file
@ -0,0 +1,135 @@
|
||||
use anyhow::Result;
|
||||
use gilrs::{Axis, Button, EventType};
|
||||
use io::Write;
|
||||
|
||||
use std::{io, thread, time::Duration};
|
||||
|
||||
fn main() -> Result<()> {
|
||||
use gilrs::{Button, Event, Gilrs};
|
||||
|
||||
let mut gilrs = Gilrs::new().unwrap();
|
||||
|
||||
// Iterate over all connected gamepads
|
||||
for (_id, gamepad) in gilrs.gamepads() {
|
||||
eprintln!("{} is {:?}", gamepad.name(), gamepad.power_info());
|
||||
}
|
||||
|
||||
let mut alter_x: f32 = 0.;
|
||||
let mut alter_y: f32 = 0.;
|
||||
let mut old_alter_y: f32 = 0.;
|
||||
let mut last_v: f32 = 0.;
|
||||
let mut was_x = false;
|
||||
let mut is_one = false;
|
||||
let mut is_jump = false;
|
||||
let mut velocity = 1.0;
|
||||
|
||||
let mut active_gamepad = None;
|
||||
|
||||
loop {
|
||||
let mut line = String::new();
|
||||
io::stdin().read_line(&mut line)?;
|
||||
|
||||
let frame: Vec<(f32, f32, u32)> = serde_json::from_str(&line)?;
|
||||
|
||||
// Examine new events
|
||||
if let Some(Event { id, event, time }) = gilrs.next_event() {
|
||||
// eprintln!("{:?} New event from {}: {:?}", time, id, event);
|
||||
|
||||
active_gamepad = Some(id);
|
||||
|
||||
// match event {
|
||||
// EventType::AxisChanged(axis, v, _code) => {
|
||||
// if axis == Axis::LeftStickX {
|
||||
// alter_x -= 1.;
|
||||
// // was_x = true;
|
||||
// } else if axis == Axis::LeftStickY {
|
||||
// alter_y -= 1.;
|
||||
// // was_x = false;
|
||||
// }
|
||||
// }
|
||||
// _ => {}
|
||||
// }
|
||||
}
|
||||
|
||||
// if is_one {
|
||||
// if was_x {
|
||||
// alter_x -= 1.0;
|
||||
// } else {
|
||||
// alter_y -= 1.0;
|
||||
// }
|
||||
// }
|
||||
if let Some(active_gamepad) = active_gamepad {
|
||||
let gp = gilrs.gamepad(active_gamepad);
|
||||
|
||||
{
|
||||
let velocity = 0.5;
|
||||
|
||||
let (sx, sy) = (gp.value(Axis::LeftStickX), gp.value(Axis::LeftStickY));
|
||||
|
||||
if sx.abs() > 0.5 || sy.abs() > 0.5 {
|
||||
if sx.abs() > 0.5 {
|
||||
alter_x -= velocity * sx.signum();
|
||||
}
|
||||
if !is_jump {
|
||||
if sy.abs() > 0.5 {
|
||||
alter_y -= velocity * sy.signum();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if gp.is_pressed(Button::South) && !is_jump {
|
||||
is_jump = true;
|
||||
old_alter_y = alter_y;
|
||||
velocity = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
if is_jump {
|
||||
if velocity >= -1. {
|
||||
alter_y -= velocity;
|
||||
velocity -= 0.05;
|
||||
} else {
|
||||
is_jump = false;
|
||||
alter_y = old_alter_y;
|
||||
}
|
||||
|
||||
eprintln!("Jump: alter_y: {:?}", alter_y);
|
||||
}
|
||||
|
||||
let altered_frame: Vec<(f32, f32, u32)> = frame
|
||||
.iter()
|
||||
.map(|(x, y, color)| {
|
||||
let mut new_x = if *x + alter_x * 10. >= 800. {
|
||||
800.
|
||||
} else {
|
||||
*x + alter_x * 10.
|
||||
};
|
||||
|
||||
let mut new_y = if *y + alter_y * 10. >= 800. {
|
||||
800.
|
||||
} else {
|
||||
*y + alter_y * 10.
|
||||
};
|
||||
|
||||
if new_x < 0. {
|
||||
new_x = 0.;
|
||||
}
|
||||
|
||||
if new_y < 0. {
|
||||
new_y = 0.;
|
||||
}
|
||||
|
||||
(new_x, new_y, *color)
|
||||
})
|
||||
.collect();
|
||||
|
||||
serde_json::to_writer(io::stdout(), &altered_frame)?;
|
||||
io::stdout().write(b"\n")?;
|
||||
io::stdout().flush()?;
|
||||
|
||||
// serde_json::to_writer(io::stderr(), &altered_frame)?;
|
||||
// io::stderr().write(b"\n")?;
|
||||
// io::stderr().flush()?;
|
||||
}
|
||||
}
|
269
src/main.rs
Normal file
269
src/main.rs
Normal file
@ -0,0 +1,269 @@
|
||||
use anyhow::Result;
|
||||
use chrono::offset::Utc;
|
||||
use gilrs::{Axis, Button, Event, EventType, Gilrs};
|
||||
use rand::prelude::*;
|
||||
|
||||
use std::{
|
||||
io::{self, Write},
|
||||
thread, time,
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
type Segment = [[f32; 2]; 2];
|
||||
|
||||
#[derive(Default)]
|
||||
struct Game {
|
||||
platforms: Vec<Vec<Segment>>,
|
||||
player: Vec<Segment>,
|
||||
joystick_player_delta: [f32; 2],
|
||||
jump_player_delta: f32,
|
||||
}
|
||||
|
||||
const COLORS: [u32; 12] = [
|
||||
0xFF0000, 0xFF8000, 0xFFFF00, 0x80FF00, 0x00FF00, 0x00FF80, 0x00FFFF, 0x0080FF, 0x0000FF,
|
||||
0x7F00FF, 0xFF00FF, 0xFF007F,
|
||||
];
|
||||
|
||||
fn main() -> Result<()> {
|
||||
let mut gilrs = Gilrs::new().unwrap();
|
||||
let mut rng = rand::thread_rng();
|
||||
let mut frame_count: u64 = 0;
|
||||
let mut last_press_frame_count = 0;
|
||||
let mut is_jump = false;
|
||||
let mut double_jump = false;
|
||||
let mut velocity = 1.0;
|
||||
let mut last_is_colide = false;
|
||||
let mut x_pressed = 0;
|
||||
let mut velocity_under_0 = 0;
|
||||
let mut color = 0xFFFFFF;
|
||||
let mut colors_iter = COLORS.iter().cycle();
|
||||
let mut destroyed_platforms_without_ground = 0;
|
||||
|
||||
let mut game = Game {
|
||||
player: vec![
|
||||
[[600.0, 600.0], [650.0, 600.0]],
|
||||
[[650.0, 600.0], [650.0, 650.0]],
|
||||
[[650.0, 650.0], [600.0, 650.0]], // bottom line
|
||||
[[600.0, 650.0], [600.0, 600.0]],
|
||||
],
|
||||
..Game::default()
|
||||
};
|
||||
|
||||
let mut active_gamepad = None;
|
||||
|
||||
loop {
|
||||
let mut is_collide = false;
|
||||
|
||||
if let Some(Event { id, event, time }) = gilrs.next_event() {
|
||||
active_gamepad = Some(id);
|
||||
}
|
||||
|
||||
if let Some(active_gamepad) = active_gamepad {
|
||||
let gp = gilrs.gamepad(active_gamepad);
|
||||
|
||||
{
|
||||
let velocity = 0.5;
|
||||
|
||||
let (sx, sy) = (gp.value(Axis::LeftStickX), gp.value(Axis::LeftStickY));
|
||||
|
||||
if sx.abs() > 0.5 || sy.abs() > 0.5 {
|
||||
if sx.abs() > 0.5 {
|
||||
let x = velocity * sx.signum();
|
||||
if game.joystick_player_delta[0] + x >= -50.
|
||||
&& game.joystick_player_delta[0] + x <= 20.
|
||||
{
|
||||
game.joystick_player_delta[0] += x;
|
||||
}
|
||||
}
|
||||
// if sy.abs() > 0.5 {
|
||||
// game.joystick_player_delta[1] -= velocity * sy.signum();
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
for l in game.platforms.iter_mut() {
|
||||
if (game.player[2][0][1]
|
||||
+ game.joystick_player_delta[1] * 10.
|
||||
+ game.jump_player_delta
|
||||
>= l[0][0][1] - 18.
|
||||
&& game.player[2][0][1]
|
||||
+ game.joystick_player_delta[1] * 10.
|
||||
+ game.jump_player_delta
|
||||
<= l[0][0][1] + 18.)
|
||||
&& (game.player[2][0][0] + game.joystick_player_delta[0] * 7. >= l[0][0][0]
|
||||
&& game.player[2][1][0] + game.joystick_player_delta[0] * 7. <= l[0][1][0])
|
||||
{
|
||||
is_collide = true;
|
||||
}
|
||||
|
||||
if !is_collide && last_is_colide && !double_jump {
|
||||
velocity = 0.;
|
||||
}
|
||||
|
||||
if is_collide && !last_is_colide {
|
||||
double_jump = false;
|
||||
if destroyed_platforms_without_ground % 5 == 0
|
||||
&& destroyed_platforms_without_ground != 0
|
||||
{
|
||||
color = *colors_iter.next().unwrap();
|
||||
destroyed_platforms_without_ground += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if last_press_frame_count + rng.gen_range(100, 4000) <= frame_count {
|
||||
let height = rng.gen_range(300., 550.);
|
||||
game.platforms
|
||||
.push(vec![[[800., height], [rng.gen_range(810., 900.), height]]]);
|
||||
last_press_frame_count = frame_count;
|
||||
}
|
||||
/*if gp.is_pressed(Button::West) &&
|
||||
} else*/
|
||||
if gp.is_pressed(Button::South) {
|
||||
if game.jump_player_delta == 0. {
|
||||
x_pressed += 1;
|
||||
is_jump = true;
|
||||
velocity = 1.0;
|
||||
}
|
||||
|
||||
if is_collide || (velocity > 0. && !double_jump) {
|
||||
x_pressed += 1;
|
||||
velocity = 1.0;
|
||||
double_jump = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if is_collide
|
||||
&& game.joystick_player_delta[0] >= -49.
|
||||
&& game.joystick_player_delta[0] <= 20.
|
||||
{
|
||||
game.joystick_player_delta[0] -= 1. / 7.;
|
||||
}
|
||||
|
||||
// if is_jump && !is_collide && !double_jump {
|
||||
|
||||
// } else {
|
||||
// is_jump = false;
|
||||
// double_jump = false;
|
||||
// game.jump_player_delta = 0.;
|
||||
// }
|
||||
|
||||
// //eprintln!("Jump: alter_y: {:?}", game.jump_player_delta);
|
||||
// }
|
||||
|
||||
if is_jump {
|
||||
game.jump_player_delta -= velocity * 30.;
|
||||
is_jump = false;
|
||||
}
|
||||
|
||||
if (game.player[2][0][1] + game.joystick_player_delta[1] * 10. + game.jump_player_delta)
|
||||
< 650.
|
||||
{
|
||||
if !is_collide || velocity >= 0. {
|
||||
if velocity >= 0. {
|
||||
velocity_under_0 += 1;
|
||||
}
|
||||
game.jump_player_delta -= velocity * 30.;
|
||||
velocity -= 0.05;
|
||||
}
|
||||
} else {
|
||||
color = 0xFFFFFF;
|
||||
destroyed_platforms_without_ground = 0;
|
||||
colors_iter = COLORS.iter().cycle();
|
||||
game.jump_player_delta = 0.;
|
||||
}
|
||||
|
||||
let mut frame: Vec<(f32, f32, u32)> = vec![];
|
||||
|
||||
let mut to_remove = vec![];
|
||||
for (k, l) in game.platforms.iter_mut().enumerate() {
|
||||
let mut must_remove = false;
|
||||
|
||||
for (i, p) in l.iter_mut().enumerate() {
|
||||
frame.push((p[0][0], p[0][1], 0));
|
||||
|
||||
frame.push((p[0][0], p[0][1], color));
|
||||
frame.push((p[1][0], p[1][1], color));
|
||||
|
||||
frame.push((p[1][0], p[1][1], 0));
|
||||
|
||||
if p[0][0] >= 50. {
|
||||
p[0][0] -= 1.;
|
||||
p[1][0] -= 1.;
|
||||
} else {
|
||||
must_remove = true;
|
||||
}
|
||||
}
|
||||
|
||||
if must_remove {
|
||||
to_remove.push(k);
|
||||
}
|
||||
}
|
||||
for i in to_remove {
|
||||
game.platforms.remove(i);
|
||||
destroyed_platforms_without_ground += 1;
|
||||
}
|
||||
|
||||
for p in game.player.iter() {
|
||||
let p = [
|
||||
(
|
||||
p[0][0] + game.joystick_player_delta[0] * 7.,
|
||||
p[0][1] + game.joystick_player_delta[1] * 10. + game.jump_player_delta,
|
||||
),
|
||||
(
|
||||
p[1][0] + game.joystick_player_delta[0] * 7.,
|
||||
p[1][1] + game.joystick_player_delta[1] * 10. + game.jump_player_delta,
|
||||
),
|
||||
];
|
||||
|
||||
frame.push((p[0].0, p[0].1, 0));
|
||||
|
||||
frame.push((p[0].0, p[0].1, color));
|
||||
frame.push((p[1].0, p[1].1, color));
|
||||
|
||||
frame.push((p[1].0, p[1].1, 0));
|
||||
}
|
||||
|
||||
let out = serde_json::to_string(&frame)?;
|
||||
if !frame.is_empty() {
|
||||
io::stdout().write_all(out.as_bytes())?;
|
||||
io::stdout().write(b"\n")?;
|
||||
io::stdout().flush()?;
|
||||
}
|
||||
|
||||
eprintln!("score: {:?}", destroyed_platforms_without_ground);
|
||||
// eprintln!(
|
||||
// "{}:
|
||||
// game.player: {:?}
|
||||
// game.platforms: {:?}
|
||||
// game.joystick_player_delta: {:?}
|
||||
// game.jump_player_delta: {:?}
|
||||
// is_collide: {:?}
|
||||
// is_jump: {:?}
|
||||
// double_jump: {:?}
|
||||
// velocity: {:?}
|
||||
// x_pressed: {:?}
|
||||
// velocity_under_0: {:?}
|
||||
// {:?}",
|
||||
// Utc::now().time(),
|
||||
// game.player,
|
||||
// game.platforms,
|
||||
// game.joystick_player_delta,
|
||||
// (game.player[2][0][1] + game.joystick_player_delta[1] * 10. + game.jump_player_delta),
|
||||
// is_collide,
|
||||
// is_jump,
|
||||
// double_jump,
|
||||
// velocity,
|
||||
// x_pressed,
|
||||
// velocity_under_0,
|
||||
// game.player[2][0][1] + game.joystick_player_delta[1] * 10. + game.jump_player_delta
|
||||
// );
|
||||
|
||||
thread::sleep(Duration::from_millis(1000 / 60));
|
||||
frame_count += 1;
|
||||
last_is_colide = is_collide;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
144
src/main.rs_
Normal file
144
src/main.rs_
Normal file
@ -0,0 +1,144 @@
|
||||
extern crate nalgebra as na;
|
||||
|
||||
use na::{Point2, Point3, RealField, Vector2};
|
||||
use ncollide2d::pipeline::CollisionGroups;
|
||||
use ncollide2d::shape::{Cuboid, ShapeHandle};
|
||||
use nphysics2d::force_generator::DefaultForceGeneratorSet;
|
||||
use nphysics2d::joint::DefaultJointConstraintSet;
|
||||
use nphysics2d::object::{
|
||||
BodyPartHandle, ColliderDesc, DefaultBodySet, DefaultColliderSet, Ground, RigidBodyDesc,
|
||||
};
|
||||
use nphysics2d::world::{DefaultGeometricalWorld, DefaultMechanicalWorld};
|
||||
use nphysics_testbed2d::Testbed;
|
||||
|
||||
|
||||
macro_rules! r(
|
||||
($e: expr) => {
|
||||
nalgebra::convert::<f64, N>($e)
|
||||
}
|
||||
);
|
||||
|
||||
/*
|
||||
* NOTE: The `r` macro is only here to convert from f64 to the `N` scalar type.
|
||||
* This simplifies experimentation with various scalar types (f32, fixed-point numbers, etc.)
|
||||
*/
|
||||
pub fn init_world<N: RealField>(testbed: &mut Testbed<N>) {
|
||||
/*
|
||||
* World
|
||||
*/
|
||||
let mechanical_world = DefaultMechanicalWorld::new(Vector2::new(r!(0.0), r!(-9.81)));
|
||||
let geometrical_world = DefaultGeometricalWorld::new();
|
||||
let mut bodies = DefaultBodySet::new();
|
||||
let mut colliders = DefaultColliderSet::new();
|
||||
let joint_constraints = DefaultJointConstraintSet::new();
|
||||
let force_generators = DefaultForceGeneratorSet::new();
|
||||
|
||||
/*
|
||||
* Setup a static body used as the ground.
|
||||
*/
|
||||
let ground_handle = bodies.insert(Ground::new());
|
||||
|
||||
/*
|
||||
* Setup groups.
|
||||
*/
|
||||
const GREEN_GROUP_ID: usize = 0;
|
||||
let mut green_group = CollisionGroups::new();
|
||||
green_group.set_membership(&[GREEN_GROUP_ID]);
|
||||
green_group.set_whitelist(&[GREEN_GROUP_ID]);
|
||||
|
||||
const BLUE_GROUP_ID: usize = 1;
|
||||
let mut blue_group = CollisionGroups::new();
|
||||
blue_group.set_membership(&[BLUE_GROUP_ID]);
|
||||
blue_group.set_whitelist(&[BLUE_GROUP_ID]);
|
||||
|
||||
/*
|
||||
* A floor that will collide with everything (default behaviour).
|
||||
*/
|
||||
let ground_thickness = r!(0.2);
|
||||
let ground_shape = ShapeHandle::new(Cuboid::new(Vector2::new(r!(3.0), ground_thickness)));
|
||||
|
||||
let main_floor = ColliderDesc::new(ground_shape)
|
||||
.translation(Vector2::y() * -ground_thickness)
|
||||
.build(BodyPartHandle(ground_handle, 0));
|
||||
colliders.insert(main_floor);
|
||||
|
||||
/*
|
||||
* A green floor that will collide with the GREEN group only.
|
||||
*/
|
||||
let ground_shape = ShapeHandle::new(Cuboid::new(Vector2::new(r!(1.0), r!(0.1))));
|
||||
let green_floor = ColliderDesc::new(ground_shape.clone())
|
||||
.translation(Vector2::y())
|
||||
.collision_groups(green_group)
|
||||
.build(BodyPartHandle(ground_handle, 0));
|
||||
let green_collider_handle = colliders.insert(green_floor);
|
||||
|
||||
testbed.set_collider_color(green_collider_handle, Point3::new(0.0, 1.0, 0.0));
|
||||
|
||||
/*
|
||||
* A blue floor that will collide with the BLUE group only.
|
||||
*/
|
||||
let blue_floor = ColliderDesc::new(ground_shape)
|
||||
.translation(Vector2::y() * r!(2.0))
|
||||
.collision_groups(blue_group)
|
||||
.build(BodyPartHandle(ground_handle, 0));
|
||||
let blue_collider_handle = colliders.insert(blue_floor);
|
||||
|
||||
testbed.set_collider_color(blue_collider_handle, Point3::new(0.0, 0.0, 1.0));
|
||||
|
||||
/*
|
||||
* Create the boxes
|
||||
*/
|
||||
let num = 8;
|
||||
let rad = r!(0.1);
|
||||
|
||||
let cuboid = ShapeHandle::new(Cuboid::new(Vector2::repeat(rad)));
|
||||
let shift = (rad + ColliderDesc::<N>::default_margin()) * r!(2.0);
|
||||
let centerx = shift * r!(num as f64) / r!(2.0);
|
||||
let centery = r!(2.5);
|
||||
|
||||
for k in 0usize..4 {
|
||||
for i in 0usize..num {
|
||||
let x = r!(i as f64) * shift - centerx;
|
||||
let y = r!(k as f64) * shift + centery;
|
||||
|
||||
// Alternate between the GREEN and BLUE groups.
|
||||
let (group, color) = if k % 2 == 0 {
|
||||
(green_group, Point3::new(0.0, 1.0, 0.0))
|
||||
} else {
|
||||
(blue_group, Point3::new(0.0, 0.0, 1.0))
|
||||
};
|
||||
|
||||
// Build the rigid body.
|
||||
let rb = RigidBodyDesc::new().translation(Vector2::new(x, y)).build();
|
||||
let rb_handle = bodies.insert(rb);
|
||||
|
||||
// Build the collider.
|
||||
let co = ColliderDesc::new(cuboid.clone())
|
||||
.density(r!(1.0))
|
||||
.collision_groups(group)
|
||||
.build(BodyPartHandle(rb_handle, 0));
|
||||
colliders.insert(co);
|
||||
|
||||
testbed.set_body_color(rb_handle, color);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set up the testbed.
|
||||
*/
|
||||
testbed.set_ground_handle(Some(ground_handle));
|
||||
testbed.set_world(
|
||||
mechanical_world,
|
||||
geometrical_world,
|
||||
bodies,
|
||||
colliders,
|
||||
joint_constraints,
|
||||
force_generators,
|
||||
);
|
||||
testbed.look_at(Point2::new(0.0, 1.0), 100.0);
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let testbed = Testbed::<f32>::from_builders(0, vec![("Collision groups", init_world)]);
|
||||
testbed.run()
|
||||
}
|
Loading…
Reference in New Issue
Block a user