Initial commit

This commit is contained in:
Mateusz Słodkowicz 2024-03-07 22:57:21 +00:00
commit 77d6ab3785
Signed by: materus
GPG Key ID: 28D140BCA60B4FD1
4 changed files with 341 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/target

126
Cargo.lock generated Normal file
View File

@ -0,0 +1,126 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "cc"
version = "1.0.90"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd6604a82acf3039f1144f54b8eb34e91ffba622051189e71b781822d5ee1f5"
[[package]]
name = "cfg-if"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
name = "cmake"
version = "0.1.50"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31c789563b815f77f4250caee12365734369f942439b7defd71e18a48197130"
dependencies = [
"cc",
]
[[package]]
name = "fs_extra"
version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
[[package]]
name = "getrandom"
version = "0.2.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "190092ea657667030ac6a35e305e62fc4dd69fd98ac98631e5d3a2b1575a12b5"
dependencies = [
"cfg-if",
"libc",
"wasi",
]
[[package]]
name = "lazy_static"
version = "1.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.153"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c198f91728a82281a64e1f4f9eeb25d82cb32a5de251c6bd1b5154d63a8e7bd"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "rand"
version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
[[package]]
name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "raylib"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fb567269b7ea9ae3c4a5aab4dc95e0b4d8df2a49a25e1670a3bb17bc17504606"
dependencies = [
"cfg-if",
"lazy_static",
"libc",
"raylib-sys",
]
[[package]]
name = "raylib-sys"
version = "3.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20c97b5e251b73c52183914d4756104cab401050f244c19abe83fa05a4e86840"
dependencies = [
"cc",
"cmake",
"fs_extra",
]
[[package]]
name = "snake"
version = "0.1.0"
dependencies = [
"rand",
"raylib",
]
[[package]]
name = "wasi"
version = "0.11.0+wasi-snapshot-preview1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"

10
Cargo.toml Normal file
View File

@ -0,0 +1,10 @@
[package]
name = "snake"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
rand = "0.8.5"
raylib = "3.7.0"

204
src/main.rs Normal file
View File

@ -0,0 +1,204 @@
use raylib::prelude::*;
use rand::prelude::*;
const WIDTH: i32 = 800;
const HEIGHT: i32 = 800;
const RECT_SIZE: i32 = 20;
const BOARD_HEIGHT: i32 = HEIGHT / RECT_SIZE;
const BOARD_WIDTH: i32 = WIDTH / RECT_SIZE;
#[derive(Copy, Clone)]
enum RectType {
HEAD,
BODY,
EMPTY,
APPLE,
}
#[derive(Copy, Clone)]
enum Direction {
TOP,
DOWN,
LEFT,
RIGHT,
}
#[derive(Copy, Clone, PartialEq)]
struct Position {
x: i32,
y: i32,
}
fn gen_apple(game_data: &GameData) -> Position {
let mut pos: Position = Position {x:0, y:0};
let mut done = false;
while !done {
done = true;
pos = Position {x: thread_rng().gen_range(0..BOARD_WIDTH), y: thread_rng().gen_range(0..BOARD_HEIGHT)};
if game_data.head == pos {done = false}
else {
for tail_seg in &game_data.tail
{
if (tail_seg.x == pos.x) && (tail_seg.y == pos.y) {
done = false;
break;
}
}
}
}
pos
}
struct GameData {
board: [RectType; (BOARD_HEIGHT * BOARD_HEIGHT) as usize],
head: Position,
tail: Vec<Position>,
direction: Direction,
last_direction: Direction,
game_over: bool,
score: u32,
apple: Position
}
fn update_game(game_data: &mut GameData) {
game_data.last_direction = game_data.direction;
let old_head_pos = game_data.head;
match game_data.direction {
Direction::DOWN => game_data.head.y += 1,
Direction::TOP => game_data.head.y -= 1,
Direction::LEFT => game_data.head.x -= 1,
Direction::RIGHT => game_data.head.x += 1,
}
if game_data.head.x >= BOARD_WIDTH {
game_data.head.x = 0
} else if game_data.head.x < 0 {
game_data.head.x = BOARD_WIDTH - 1
} else if game_data.head.y < 0 {
game_data.head.y = BOARD_HEIGHT - 1
} else if game_data.head.y >= BOARD_HEIGHT {
game_data.head.y = 0
}
if game_data.head == game_data.apple
{
game_data.apple = gen_apple(game_data);
game_data.score += 1;
game_data.tail.push(game_data.tail.last().copied().unwrap());
}
let last_tail = game_data.tail.last().copied().unwrap();
for tail_id in (1..game_data.tail.len()).rev() {
game_data.tail[tail_id] = game_data.tail[tail_id - 1];
if game_data.head == game_data.tail[tail_id] {
game_data.game_over = true;
}
game_data.board
[(game_data.tail[tail_id].x + game_data.tail[tail_id].y * BOARD_HEIGHT) as usize] =
RectType::BODY;
}
game_data.board[(last_tail.x + last_tail.y * BOARD_HEIGHT) as usize] = RectType::EMPTY;
game_data.tail[0] = old_head_pos;
game_data.board[(old_head_pos.x + old_head_pos.y * BOARD_HEIGHT) as usize] = RectType::BODY;
game_data.board[(game_data.head.x + game_data.head.y * BOARD_HEIGHT) as usize] = RectType::HEAD;
game_data.board[(game_data.apple.x + game_data.apple.y * BOARD_HEIGHT) as usize] = RectType::APPLE;
}
fn create_game_data() -> GameData {
let mut game_data = GameData {
board: [RectType::EMPTY; (BOARD_HEIGHT * BOARD_WIDTH) as usize],
head: Position {
x: BOARD_WIDTH / 2,
y: BOARD_HEIGHT / 2,
},
tail: vec![
Position {
x: BOARD_WIDTH / 2,
y: BOARD_HEIGHT / 2,
};
3
],
direction: Direction::RIGHT,
last_direction: Direction::LEFT,
game_over: false,
score: 0,
apple: Position {x: 0, y: 0}
};
game_data.apple = gen_apple(&game_data);
game_data
}
fn main() {
let (mut rl, thread) = raylib::init()
.size(WIDTH, HEIGHT)
.title("Snake")
.vsync()
.build();
let show_fps: bool = false;
let mut time: f64 = 0.0;
let mut game_data = create_game_data();
while !rl.window_should_close() {
let fps = rl.get_fps();
let frame_time = rl.get_frame_time();
time += f64::from(frame_time);
if (rl.is_key_down(KeyboardKey::KEY_UP) || rl.is_key_down(KeyboardKey::KEY_W))
&& !matches!(game_data.last_direction, Direction::DOWN)
{
game_data.direction = Direction::TOP
}
if (rl.is_key_down(KeyboardKey::KEY_DOWN) || rl.is_key_down(KeyboardKey::KEY_S))
&& !matches!(game_data.last_direction, Direction::TOP)
{
game_data.direction = Direction::DOWN
}
if (rl.is_key_down(KeyboardKey::KEY_LEFT) || rl.is_key_down(KeyboardKey::KEY_A))
&& !matches!(game_data.last_direction, Direction::RIGHT)
{
game_data.direction = Direction::LEFT
}
if (rl.is_key_down(KeyboardKey::KEY_RIGHT) || rl.is_key_down(KeyboardKey::KEY_D))
&& !matches!(game_data.last_direction, Direction::LEFT)
{
game_data.direction = Direction::RIGHT
}
if time >= 0.1 {
time = 0.0;
if !game_data.game_over {
update_game(&mut game_data);
};
}
if rl.is_key_down(KeyboardKey::KEY_ENTER) && game_data.game_over {
game_data = create_game_data();
time = 0.0;
}
let mut d = rl.begin_drawing(&thread);
d.clear_background(Color::WHITE);
for y in 0..BOARD_HEIGHT {
for x in 0..BOARD_WIDTH {
let color: Color;
match game_data.board[(x + y * BOARD_WIDTH) as usize] {
RectType::HEAD => color = Color::GREEN,
RectType::BODY => color = Color::DARKGREEN,
RectType::APPLE => color = Color::RED,
RectType::EMPTY => color = Color::WHITE,
};
d.draw_rectangle(x * RECT_SIZE, y * RECT_SIZE, RECT_SIZE, RECT_SIZE, color);
}
}
if game_data.game_over {
d.draw_text("Game Over", WIDTH / 2 - 100, HEIGHT / 2, 40, Color::BLACK);
d.draw_text(
format!("Score: {}", game_data.score).as_str(),
WIDTH / 2 - 50,
HEIGHT / 2 + 50,
20,
Color::BLACK,
);
d.draw_text("Press Enter", WIDTH / 2 - 40, HEIGHT / 2 + 75, 10, Color::BLACK);
}
if show_fps {
d.draw_text(fps.to_string().as_str(), 20, 10, 20, Color::BLUE)
}
}
}