First working version
Next we will be looking at implementing multi-controller multiplayer
This commit is contained in:
parent
0b15908469
commit
15b0b8efc3
|
@ -10,3 +10,8 @@ Cargo.lock
|
||||||
# These are backup files generated by rustfmt
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#Added by cargo
|
||||||
|
|
||||||
|
/target
|
||||||
|
|
|
@ -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"
|
|
@ -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()?;
|
||||||
|
}
|
||||||
|
}
|
|
@ -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(())
|
||||||
|
}
|
|
@ -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