🧱 Breakout game

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

local gizmos = eh_singleton(eh_runtime_gizmos)

local paddle_width = 100
local paddle_height = 15
local ball_size = 10
local brick_width = 60
local brick_height = 20
local brick_rows = 5
local brick_columns = 8
local screen_width = 800
local screen_height = 600
local ball_speed = 5
local line_width = 2

local paddle = {
    x = screen_width / 2 - paddle_width / 2,
    y = screen_height - 50
}

local ball = {
    x = screen_width / 2,
    y = screen_height - 70,
    dx = 0,
    dy = -ball_speed
}

local bricks = {}
local game_over = false
local game_won = false
local score = 0

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 init_bricks()
    bricks = {}
    for row = 0, brick_rows - 1 do
        for col = 0, brick_columns - 1 do
            table.insert(bricks, {
                x = col * (brick_width + 5) + 50,
                y = row * (brick_height + 5) + 50,
                active = true
            })
        end
    end
end

local function check_collision(x1, y1, w1, h1, x2, y2, w2, h2)
    return x1 < x2 + w2 and
           x1 + w1 > x2 and
           y1 < y2 + h2 and
           y1 + h1 > y2
end

local function handle_input()
    if Input.GetKeyDown(KeyCode.R) then
        if game_over or game_won then
            ball.x = screen_width / 2
            ball.y = screen_height - 70
            ball.dx = 0
            ball.dy = -ball_speed
            paddle.x = screen_width / 2 - paddle_width / 2
            init_bricks()
            game_over = false
            game_won = false
            score = 0
            return true
        end
    end

    if Input.GetKey(KeyCode.A) or Input.GetKey(KeyCode.LeftArrow) then
        paddle.x = math.max(0, paddle.x - 10)
    end
    if Input.GetKey(KeyCode.D) or Input.GetKey(KeyCode.RightArrow) then
        paddle.x = math.min(screen_width - paddle_width, paddle.x + 10)
    end
    return false
end

events.add("Update", function()
    local reset = handle_input()
    if reset then return end
    
    if game_over or game_won then return end
    
    ball.x = ball.x + ball.dx
    ball.y = ball.y + ball.dy
    
    if ball.x <= 0 or ball.x >= screen_width - ball_size then
        ball.dx = -ball.dx
    end
    if ball.y <= 0 then
        ball.dy = -ball.dy
    end
    
    if check_collision(ball.x, ball.y, ball_size, ball_size, 
                      paddle.x, paddle.y, paddle_width, paddle_height) then
        ball.dy = -ball.dy
        local hit_pos = (ball.x - paddle.x) / paddle_width
        ball.dx = ball_speed * (hit_pos * 2 - 1)
    end
    
    for i, brick in ipairs(bricks) do
        if brick.active and check_collision(ball.x, ball.y, ball_size, ball_size,
                                         brick.x, brick.y, brick_width, brick_height) then
            brick.active = false
            ball.dy = -ball.dy
            score = score + 10
            
            local all_destroyed = true
            for _, b in ipairs(bricks) do
                if b.active then
                    all_destroyed = false
                    break
                end
            end
            if all_destroyed then
                game_won = true
            end
        end
    end
    
    if ball.y >= screen_height then
        game_over = true
    end
end)

events.add("OnGUI", function()
    if Event.current.type == EventType.Repaint then
        gizmos.push_image(-1, Rect(paddle.x, paddle.y, paddle_width, paddle_height),
            Texture2D.whiteTexture, Color.white, 0, 1)
        
        gizmos.push_image(-1, Rect(ball.x, ball.y, ball_size, ball_size),
            Texture2D.whiteTexture, Color.white, 0, 1)
        
        for _, brick in ipairs(bricks) do
            if brick.active then
                gizmos.push_image(-1, Rect(brick.x, brick.y, brick_width, brick_height),
                    Texture2D.whiteTexture, Color32(255, 100, 100, 255), 0, 1)
            end
        end
        
        gizmos.push_text(-1, Rect(10, 10, 200, 30),
            "score: " .. score, Color.white, Color.black, 1, text_outline.shadow, text_style)
        
        if game_over then
            gizmos.push_text(-1, Rect(screen_width/2 - 100, screen_height/2 - 30, 200, 60),
                "game over!\npress R to restart", Color.white, Color.black, 1, text_outline.shadow, text_style)
        elseif game_won then
            gizmos.push_text(-1, Rect(screen_width/2 - 100, screen_height/2 - 30, 200, 60),
                "win!\npress R to restart", Color.white, Color.black, 1, text_outline.shadow, text_style)
        end
    end
end)

init_bricks()

Last updated