270 lines
8.5 KiB
Rust
270 lines
8.5 KiB
Rust
|
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(())
|
||
|
}
|