Skip to content

A snake game

package snake
import "core:fmt"
import rl "vendor:raylib"
WIN_HEIGHT :: 450
WIN_WIDTH :: 800
SNAKE_MAXLENGTH :: 100
SNAKE_STEP :: 20
GAME_TITLE :: "Snake game"
Vec2i :: struct {
x, y: i32,
}
// Define a struct to handle the snake's state
Snake :: struct {
head: Vec2i,
body: [SNAKE_MAXLENGTH]Vec2i,
length: int,
}
// Initialize the snake with a starting position and length
snake_init :: proc() -> Snake {
return Snake{head = Vec2i{0, 0}, length = 1}
}
// Update snake position and handle wrapping around the screen
snake_update_position :: proc(snake: ^Snake) {
prev_head := snake.head
if rl.IsKeyDown(.RIGHT) {
snake.head.x += SNAKE_STEP
if snake.head.x >= WIN_WIDTH {
snake.head.x = 0
}
} else if rl.IsKeyDown(.LEFT) {
snake.head.x -= SNAKE_STEP
if snake.head.x < 0 {
snake.head.x = WIN_WIDTH - SNAKE_STEP
}
} else if rl.IsKeyDown(.UP) {
snake.head.y -= SNAKE_STEP
if snake.head.y < 0 {
snake.head.y = WIN_HEIGHT - SNAKE_STEP
}
} else if rl.IsKeyDown(.DOWN) {
snake.head.y += SNAKE_STEP
if snake.head.y >= WIN_HEIGHT {
snake.head.y = 0
}
}
// Move body segments, keeping length within SNAKE_MAXLENGTH
for i := snake.length - 1; i > 0; i -= 1 {
snake.body[i] = snake.body[i - 1]
}
snake.body[0] = prev_head
if snake.length < SNAKE_MAXLENGTH {
snake.length += 1
}
}
// Render the snake on the screen
snake_draw :: proc(snake: ^Snake) {
for i in 0 ..< snake.length {
pos := snake.body[i]
color: rl.Color
if i == 0 {
color = rl.GREEN // Head color
} else {
color = rl.BLUE // Body color
}
rl.DrawRectangle(pos.x, pos.y, SNAKE_STEP, SNAKE_STEP, color)
}
rl.DrawRectangle(snake.head.x, snake.head.y, SNAKE_STEP, SNAKE_STEP, rl.GREEN)
}
main :: proc() {
rl.InitWindow(WIN_WIDTH, WIN_HEIGHT, GAME_TITLE)
defer rl.CloseWindow()
rl.SetTargetFPS(60)
snake := snake_init()
for !rl.WindowShouldClose() {
snake_update_position(&snake)
rl.BeginDrawing()
defer rl.EndDrawing()
rl.ClearBackground(rl.BLACK)
snake_draw(&snake)
}
}

Programming odin