Snake
RepositoryI created this project in order to learn the modern programming language Rust. For this, I recreated the iconic game Snake. I was able to make myself familiar with the principles of Rust and its syntax. I use a minimal graphics library to get a graphics interface, instead of just a console application.
Game Struct
Here I created a Game struct with a new() function. This struct is the primary object that contains all the game logic. The new() function can be used to start a new game window, but it is only used during the initial setup.
1struct Game {
2 window: Window,
3 width: usize,
4 height: usize,
5 buffer: Vec<u32>,
6 cell_size: usize,
7 snake: Snake,
8 has_started: bool,
9 cookie_pos: [usize; 2],
10}
11
12impl Game {
13 fn new() -> Self {
14 let width = 600;
15 let height = 400;
16 let window = Window::new("Snake", width, height, WindowOptions::default())
17 .expect("Failed to create window");
18 let buffer = vec![0x000000; width * height];
19 Game {
20 window,
21 width,
22 height,
23 buffer,
24 cell_size: 20,
25 snake: Snake::new(),
26 has_started: false,
27 cookie_pos: [8, 9],
28 }
29 }
30}Game::run() Function
This is the run() function. This function handles the entire game loop. First, it checks whether the player is pressing the spacebar while the game hasn't started yet. If this happens, the game is initialized and proceeds to the next if statement. In this next block, the player's input is processed, then the next position is calculated, then it checks whether a cookie has been collected (to grow the snake), and finally, the buffer is updated to render the next position. If the player loses by running into a wall or into themselves, a new snake is created using Snake::new(). You can exit the game at any time using the Escape key.
1fn run(&mut self) {
2 while self.window.is_open() {
3 if self.window. is_key_down(Key::Space) && self.has_started == false {
4 self.reset_buffer();
5 self.has_started = true;
6 let head = *self.snake.body.front().unwrap();
7 self.set_cell_color(head[0], head[1], self.snake.color);
8 self.set_cell_color(self.cookie_pos[0], self.cookie_pos[1], 0xF59B42);
9 self.update();
10 }
11 if self.has_started == true {
12 self.capture_input(150);
13 self.calculate_next_position();
14 self.cookie_check();
15 let head = *self.snake.body.front().unwrap();
16 self.set_cell_color(head[0], head[1], self.snake.color);
17 }
18 if !self.has_started {
19 self.snake = Snake::new();
20 }
21 self.update();
22 if self.window.is_key_down(Key::Escape) {
23 break;
24 }
25 }
26}Snake Struct
Here I created a complex data type, a struct, that stores the data related to the snake. I also created a new() function that can be called to create a new snake, similar to a constructor in a Java program.
1struct Snake {
2 color: u32,
3 body: VecDeque<[usize; 2]>,
4 direction: u8,
5 length: usize,
6}
7
8impl Snake {
9 fn new() -> Self {
10 let color = 0xFF73F1;
11 let direction = 0;
12 let snake_length = 5;
13 let starting_position: [usize; 2] = [10, 12];
14 let mut snake_body = VecDeque::new();
15 snake_body.push_front(starting_position);
16 Snake {
17 color: color,
18 body: snake_body,
19 direction: direction,
20 length: snake_length,
21 }
22 }
23}Try it out yourself!
DownloadIf you want to try this app out for yourself, click on the download button and install rust-snake.rar from GitHub, extract the .rar file and run the rust-snake executable.
Video Demonstration
This video requires optional cookies (YouTube).