init()
while running:
 process_input()
 update_game_state()
 render()
 sleep(frame_duration)
  • VecDeque<Point> push_front push_front + pop_back
  • Point
  • enum Direction { Up, Down, Left, Right }

piston macroquad macroquad clear() + draw_rectangle()

8-15fps async_std::task::sleep std::thread::sleep


[dependencies]
macroquad = "0.4"
use macroquad::prelude::*;
use std::collections::VecDeque;
 
#[derive(PartialEq)]
enum Dir { Up, Down, Left, Right }
 
struct Game {
 snake: VecDeque<(i32, i32)>,
 food: (i32, i32),
 dir: Dir,
 score: u32,
}
 
impl Game {
 fn new() -> Self {
 Self {
 snake: VecDeque::from([(5, 5)]),
 food: (10, 10),
 dir: Dir::Right,
 score: 0,
 }
 }
 
 fn update(&mut self) -> bool {
 let head = *self.snake.front().unwrap();
 let new_head = match self.dir {
 Dir::Up => (head.0, head.1 - 1),
 Dir::Down => (head.0, head.1 + 1),
 Dir::Left => (head.0 - 1, head.1),
 Dir::Right => (head.0 + 1, head.1),
 };
 if self.snake.contains(&new_head) { return false; }
 self.snake.push_front(new_head);
 if new_head == self.food {
 self.score += 1;
 self.food = (rand::gen_range(0, 20), rand::gen_range(0, 20));
 } else {
 self.snake.pop_back();
 }
 true
 }
}
 
#[macroquad::main("Snake")]
async fn main() {
 let mut game = Game::new();
 loop {
 if is_key_pressed(KeyCode::Up) { game.dir = Dir::Up; }
 if is_key_pressed(KeyCode::Down) { game.dir = Dir::Down; }
 // ...
 
 if !game.update() { break; }
 
 clear_background(BLACK);
 for (x, y) in &game.snake {
 draw_rectangle(*x as f32 * 20.0, *y as f32 * 20.0, 18.0, 18.0, GREEN);
 }
 next_frame().await;
 }
}

: —