LJ-rust-filters/src/main.rs

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(())
}