🐍 Snake Rattle ’n’ Roll

Простенькая луа на игру-змейку (Комментариев больше не будет, я заебался их писать, извините)

local gizmos = eh_singleton(eh_runtime_gizmos)

local cell_size = 20
local grid_width = 20
local grid_height = 15
local snake_speed = 0.2
local last_move_time = 0

local snake = {
    {x = math.random(0, grid_width - 1), y = math.random(0, grid_height - 1)},
}
local direction = {x = 1, y = 0} 
local food = {x = 10, y = 10}
local game_over = false
local game_started = false

local text_style = GUIStyle()
local style_state = GUIStyleState()
style_state.textColor = Color.white
text_style.normal = style_state
text_style.alignment = TextAnchor.MiddleCenter
text_style.fontSize = 20

local function spawn_food()
    food.x = math.random(0, grid_width - 1)
    food.y = math.random(0, grid_height - 1)
    
    for _, segment in ipairs(snake) do
        if segment.x == food.x and segment.y == food.y then
            spawn_food()
            return
        end
    end
end

local function is_on_snake(pos)
    for _, segment in ipairs(snake) do
        if segment.x == pos.x and segment.y == pos.y then
            return true
        end
    end
    return false
end

function handle_input()
    if game_over then
        if Input.GetKeyDown(KeyCode.R) then
            snake = {{x = math.random(0, grid_width - 1), y = math.random(0, grid_height - 1)}}
            direction = {x = 1, y = 0}
            game_over = false
            game_started = false
            spawn_food()
        end
        return
    end

    if Input.GetKeyDown(KeyCode.W) and direction.y <= 0 then
        direction = {x = 0, y = -1}
        game_started = true
    elseif Input.GetKeyDown(KeyCode.S) and direction.y >= 0 then
        direction = {x = 0, y = 1}
        game_started = true
    elseif Input.GetKeyDown(KeyCode.A) and direction.x <= 0 then
        direction = {x = -1, y = 0}
        game_started = true
    elseif Input.GetKeyDown(KeyCode.D) and direction.x >= 0 then
        direction = {x = 1, y = 0}
        game_started = true
    end
end

events.add("FixedUpdate", function()
    handle_input()
end)

events.add("Update", function()
    if not game_over and game_started and Time.time - last_move_time >= snake_speed then
        local new_head = {
            x = snake[1].x + direction.x,
            y = snake[1].y + direction.y
        }

        if new_head.x < 0 or new_head.x >= grid_width or
           new_head.y < 0 or new_head.y >= grid_height or
           is_on_snake(new_head) then
            game_over = true
        else
            table.insert(snake, 1, new_head)
            
            if new_head.x == food.x and new_head.y == food.y then
                spawn_food()
            else
                table.remove(snake)
            end
        end
        
        last_move_time = Time.time
    end
end)

events.add("OnGUI", function()
    if(Event.current.type == EventType.Repaint) then
        local start_x = (Screen.width - grid_width * cell_size) / 2
        local start_y = (Screen.height - grid_height * cell_size) / 2 

        local border_rect = Rect(start_x - 2, start_y - 2, grid_width * cell_size + 4, grid_height * cell_size + 4)
        gizmos.push_image(-1, border_rect, Texture2D.whiteTexture, Color32(255, 255, 255, 255), 0, 1)

        for _, segment in ipairs(snake) do
            local snake_rect = Rect(
                start_x + segment.x * cell_size,
                start_y + segment.y * cell_size,
                cell_size - 1,
                cell_size - 1
            )
            gizmos.push_image(-1, snake_rect, Texture2D.whiteTexture, Color(0, 1, 0, 0.8), 0, 1)
        end

        local food_rect = Rect(
            start_x + food.x * cell_size,
            start_y + food.y * cell_size,
            cell_size - 1,
            cell_size - 1
        )
        gizmos.push_image(-1, food_rect, Texture2D.whiteTexture, Color(1, 0, 0, 0.8), 0, 1)

        if game_over then
            local text = "game over! press R to restart"
            local text_rect = Rect(Screen.width / 2 - 150, Screen.height / 2 - 50, 300, 40)
            gizmos.push_text(-2, text_rect, text, Color.red, Color.black, 1, text_outline.shadow, text_style)
        end

        local score_text = "score: " .. (#snake - 1)
        local score_rect = Rect(start_x, start_y - 40, 200, 30)
        gizmos.push_text(-2, score_rect, score_text, Color.white, Color.black, 1, text_outline.shadow, text_style)
    end
end)

Last updated