Created
June 19, 2025 23:51
-
-
Save naranyala/9acb1477aa2bbc0d3bcea2d146033366 to your computer and use it in GitHub Desktop.
snake game in odin code using raylib
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import rl "vendor:raylib" | |
import "core:math/rand" | |
main :: proc() { | |
rl.InitWindow(800, 600, "Simple Snake Game") | |
defer rl.CloseWindow() | |
rl.SetTargetFPS(60) | |
// Snake body | |
snake_body: [dynamic]rl.Vector2 | |
defer delete(snake_body) | |
snake_size: i32 = 20 | |
// Initialize snake with head | |
append(&snake_body, rl.Vector2{400, 300}) | |
// Snake direction | |
dir_x: i32 = snake_size | |
dir_y: i32 = 0 | |
// Food | |
food_x: i32 = 200 | |
food_y: i32 = 200 | |
// Game timer | |
timer: f32 = 0.0 | |
move_speed: f32 = 0.2 | |
// Score | |
score: i32 = 0 | |
for !rl.WindowShouldClose() { | |
dt := rl.GetFrameTime() | |
timer += dt | |
// Input handling | |
if rl.IsKeyPressed(rl.KeyboardKey.UP) && dir_y == 0 { | |
dir_x = 0 | |
dir_y = -snake_size | |
} | |
if rl.IsKeyPressed(rl.KeyboardKey.DOWN) && dir_y == 0 { | |
dir_x = 0 | |
dir_y = snake_size | |
} | |
if rl.IsKeyPressed(rl.KeyboardKey.LEFT) && dir_x == 0 { | |
dir_x = -snake_size | |
dir_y = 0 | |
} | |
if rl.IsKeyPressed(rl.KeyboardKey.RIGHT) && dir_x == 0 { | |
dir_x = snake_size | |
dir_y = 0 | |
} | |
// Move snake | |
if timer >= move_speed { | |
timer = 0.0 | |
// Get current head position | |
head := snake_body[0] | |
new_head := rl.Vector2{head.x + f32(dir_x), head.y + f32(dir_y)} | |
// Add new head | |
inject_at(&snake_body, 0, new_head) | |
// Check food collision | |
if i32(new_head.x) == food_x && i32(new_head.y) == food_y { | |
score += 10 | |
// Move food to new random position | |
food_x = i32(rand.int31() % 39) * snake_size | |
food_y = i32(rand.int31() % 29) * snake_size | |
} else { | |
// Remove tail if no food eaten | |
pop(&snake_body) | |
} | |
} | |
// Check wall collision and self collision | |
if len(snake_body) > 0 { | |
head := snake_body[0] | |
// Wall collision | |
if head.x < 0 || head.x >= 800 || head.y < 0 || head.y >= 600 { | |
// Reset game | |
clear(&snake_body) | |
append(&snake_body, rl.Vector2{400, 300}) | |
dir_x = snake_size | |
dir_y = 0 | |
score = 0 | |
} | |
// Self collision | |
for i in 1..<len(snake_body) { | |
segment := snake_body[i] | |
if head.x == segment.x && head.y == segment.y { | |
// Reset game | |
clear(&snake_body) | |
append(&snake_body, rl.Vector2{400, 300}) | |
dir_x = snake_size | |
dir_y = 0 | |
score = 0 | |
break | |
} | |
} | |
} | |
// Drawing | |
rl.BeginDrawing() | |
rl.ClearBackground(rl.BLACK) | |
// Draw snake body | |
for segment, i in snake_body { | |
color := rl.GREEN | |
if i == 0 { // Head | |
color = rl.LIME | |
} | |
rl.DrawRectangle(i32(segment.x), i32(segment.y), snake_size, snake_size, color) | |
} | |
// Draw food | |
rl.DrawRectangle(food_x, food_y, snake_size, snake_size, rl.RED) | |
// Draw score with actual value | |
score_text := rl.TextFormat("Score: %d", score) | |
rl.DrawText(score_text, 10, 10, 20, rl.WHITE) | |
// Draw controls | |
rl.DrawText("Use Arrow Keys", 10, 550, 16, rl.GRAY) | |
rl.EndDrawing() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment