package snake import k2 "../.." import "core:math" import "core:fmt" import "core:time" import "core:math/rand" import "base:intrinsics" import "core:log" import "core:mem" _ :: mem WINDOW_SIZE :: 1000 GRID_WIDTH :: 20 CELL_SIZE :: 16 CANVAS_SIZE :: GRID_WIDTH*CELL_SIZE TICK_RATE :: 0.13 Vec2i :: [2]int MAX_SNAKE_LENGTH :: GRID_WIDTH*GRID_WIDTH snake: [MAX_SNAKE_LENGTH]Vec2i snake_length: int tick_timer: f32 = TICK_RATE move_direction: Vec2i game_over: bool food_pos: Vec2i food_sprite: k2.Texture head_sprite: k2.Texture body_sprite: k2.Texture tail_sprite: k2.Texture food_eaten_at: time.Time started_at: time.Time prev_time: time.Time place_food :: proc() { occupied: [GRID_WIDTH][GRID_WIDTH]bool for i in 0.. 0 { random_cell_index := rand.int31_max(i32(len(free_cells))) food_pos = free_cells[random_cell_index] } } restart :: proc() { start_head_pos := Vec2i { GRID_WIDTH / 2, GRID_WIDTH / 2 } snake[0] = start_head_pos snake[1] = start_head_pos - {0, 1} snake[2] = start_head_pos - {0, 2} snake_length = 3 move_direction = {0, 1} game_over = false place_food() } main :: proc() { context.logger = log.create_console_logger() init() run := true for run { run = step() } shutdown() } font: k2.Font_Handle init :: proc() { k2.init(WINDOW_SIZE, WINDOW_SIZE, "Snake") prev_time = time.now() restart() food_sprite = k2.load_texture_from_bytes(#load("food.png")) head_sprite = k2.load_texture_from_bytes(#load("head.png")) body_sprite = k2.load_texture_from_bytes(#load("body.png")) tail_sprite = k2.load_texture_from_bytes(#load("tail.png")) food_eaten_at = time.now() started_at = time.now() } step :: proc() -> bool { k2.new_frame() k2.process_events() if k2.key_is_held(.Up) || k2.gamepad_button_is_held(0, .Left_Face_Up) { move_direction = {0, -1} } if k2.key_is_held(.Down) || k2.gamepad_button_is_held(0, .Left_Face_Down) { move_direction = {0, 1} } if k2.key_is_held(.Left) || k2.gamepad_button_is_held(0, .Left_Face_Left) { move_direction = {-1, 0} } if k2.key_is_held(.Right) || k2.gamepad_button_is_held(0, .Left_Face_Right) { move_direction = {1, 0} } dt := k2.get_frame_time() if game_over { if k2.key_went_down(.Enter) { restart() } } else { tick_timer -= dt } if tick_timer <= 0 { next_part_pos := snake[0] snake[0] += move_direction head_pos := snake[0] if head_pos.x < 0 || head_pos.y < 0 || head_pos.x >= GRID_WIDTH || head_pos.y >= GRID_WIDTH { game_over = true } for i in 1..