use std::cell::*;
use kioto::keyboard::*;
use kioto::runtime::*;
use kioto::video::*;
#[derive(Debug, Clone, PartialEq)]
pub struct Position {
pub x: i32,
pub y: i32,
}
impl Position {
#[allow(dead_code)]
pub fn move_towards(&mut self, direction: Direction) {
match direction {
Direction::Up => self.y -= 1,
Direction::Down => self.y += 1,
Direction::Left => self.x -= 1,
Direction::Right => self.x += 1,
}
}
}
#[derive(Debug, Copy, Clone, PartialEq)]
pub enum Direction {
Up,
Right,
Down,
Left,
}
impl Direction {
pub fn opposite(&self) -> Direction {
match *self {
Direction::Up => Direction::Down,
Direction::Right => Direction::Left,
Direction::Down => Direction::Up,
Direction::Left => Direction::Right,
}
}
}
struct Segment {
color: Color,
position: Position,
}
struct Entity {
directions: Vec<Direction>,
segments: Vec<Segment>,
}
impl Entity {
fn new(x: i32, y: i32, len: i32) -> Self {
let directions: Vec<Direction> = Vec::new();
let mut segments: Vec<Segment> = Vec::new();
segments.push(Segment {
color: Color::GREEN,
position: Position {
x: 0,
y: 0,
},
});
for i in 1..len {
segments.push(Segment {
color: Color::WHITE,
position: Position { x, y: y + i},
});
}
Self {
directions,
segments,
}
}
pub fn move_forward(&mut self) {
if self.directions.len() == 0 {
return;
}
if self.segments.len() == 0 {
return;
}
let mut head = &mut self.segments[0];
let direction = &self.directions[0];
match direction {
Direction::Up => head.position.y -= 1,
Direction::Right => head.position.x += 1,
Direction::Down => head.position.y += 1,
Direction::Left => head.position.x -= 1,
}
if self.directions.len() > 1 {
self.directions.remove(0);
}
}
}
fn draw_entity(entity: &Entity) {
for segment in &entity.segments {
draw_rectangle(segment.position.x * 32, segment.position.y * 32, 32, 32, segment.color);
}
}
struct State {
player: Entity,
}
impl State {
pub fn new() -> Self {
let player = Entity::new(0, 0, 3);
Self {
player,
}
}
pub fn tick(&mut self) {
for key_code in key_iter() {
match key_code {
KeyCode::A | KeyCode::Left => self.player.directions.push(Direction::Left),
KeyCode::W | KeyCode::Up => self.player.directions.push(Direction::Up),
KeyCode::D | KeyCode::Right => self.player.directions.push(Direction::Right),
KeyCode::S | KeyCode::Down => self.player.directions.push(Direction::Down),
_ => {}
}
}
self.player.move_forward();
clear_background(Color::BLACK);
draw_entity(&self.player);
}
}
fn main() {
let state_cell = RefCell::new(State::new());
let mut runtime = Builder::new()
.title("Snake")
.enable_video()
.build()
.unwrap();
runtime.run_with(|_runtime| {
let mut state = state_cell.borrow_mut();
state.tick();
Ok(())
}).unwrap();
}