,,,,,

#include <windows.h>
#include <stdbool.h>
#include <stdlib.h>
#include <time.h>

#define GRID_WIDTH 10
#define GRID_HEIGHT 20
#define CELL_SIZE 30

typedef struct {
    int x, y;
} Point;

typedef struct {
    Point blocks[4];
    Point position;
    COLORREF color;
} Tetromino;

Tetromino tetrominoes[7] = {
    {{ {0, 0}, {0, 1}, {0, 2}, {0, 3} }, {GRID_WIDTH / 2 - 2, 0}, RGB(0, 255, 255)}, // I
    {{ {0, 0}, {0, 1}, {1, 0}, {1, 1} }, {GRID_WIDTH / 2 - 1, 0}, RGB(255, 255, 0)}, // O
    {{ {0, 0}, {1, 0}, {2, 0}, {1, 1} }, {GRID_WIDTH / 2 - 1, 0}, RGB(128, 0, 128)}, // T
    {{ {0, 1}, {1, 1}, {1, 0}, {2, 0} }, {GRID_WIDTH / 2 - 1, 0}, RGB(0, 255, 0)},   // S
    {{ {0, 0}, {1, 0}, {1, 1}, {2, 1} }, {GRID_WIDTH / 2 - 1, 0}, RGB(255, 0, 0)},   // Z
    {{ {0, 1}, {1, 1}, {2, 1}, {2, 0} }, {GRID_WIDTH / 2 - 1, 0}, RGB(0, 0, 255)},   // J
    {{ {0, 0}, {0, 1}, {1, 1}, {2, 1} }, {GRID_WIDTH / 2 - 1, 0}, RGB(255, 165, 0)}  // L
};

int grid[GRID_HEIGHT][GRID_WIDTH] = {0};

bool check_collision(Tetromino *tetromino, int offsetX, int offsetY) {
    for (int i = 0; i < 4; i++) {
        int newX = tetromino->blocks[i].x + tetromino->position.x + offsetX;
        int newY = tetromino->blocks[i].y + tetromino->position.y + offsetY;
        if (newX < 0 || newX >= GRID_WIDTH || newY < 0 || newY >= GRID_HEIGHT || grid[newY][newX]) {
            return true;
        }
    }
    return false;
}

void lock_tetromino(Tetromino *tetromino) {
    for (int i = 0; i < 4; i++) {
        int x = tetromino->blocks[i].x + tetromino->position.x;
        int y = tetromino->blocks[i].y + tetromino->position.y;
        grid[y][x] = 1;
    }
}

void render_grid(HDC hdc) {
    for (int y = 0; y < GRID_HEIGHT; y++) {
        for (int x = 0; x < GRID_WIDTH; x++) {
            if (grid[y][x]) {
                RECT cell = { x * CELL_SIZE, y * CELL_SIZE, (x + 1) * CELL_SIZE, (y + 1) * CELL_SIZE };
                FillRect(hdc, &cell, (HBRUSH)(COLOR_WINDOW+1));
            }
        }
    }
}

void render_tetromino(HDC hdc, Tetromino *tetromino) {
    HBRUSH brush = CreateSolidBrush(tetromino->color);
    HBRUSH oldBrush = SelectObject(hdc, brush);
    for (int i = 0; i < 4; i++) {
        RECT block = { (tetromino->blocks[i].x + tetromino->position.x) * CELL_SIZE, 
                       (tetromino->blocks[i].y + tetromino->position.y) * CELL_SIZE, 
                       (tetromino->blocks[i].x + tetromino->position.x + 1) * CELL_SIZE, 
                       (tetromino->blocks[i].y + tetromino->position.y + 1) * CELL_SIZE };
        FillRect(hdc, &block, brush);
    }
    SelectObject(hdc, oldBrush);
    DeleteObject(brush);
}

LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) {
    static Tetromino current_tetromino;
    static UINT_PTR timer;

    switch (uMsg) {
        case WM_CREATE:
            srand((unsigned int)time(NULL));
            current_tetromino = tetrominoes[rand() % 7];
            timer = SetTimer(hwnd, 1, 500, NULL);
            break;

        case WM_KEYDOWN:
            switch (wParam) {
                case VK_LEFT:
                    if (!check_collision(&current_tetromino, -1, 0)) {
                        current_tetromino.position.x -= 1;
                    }
                    break;
                case VK_RIGHT:
                    if (!check_collision(&current_tetromino, 1, 0)) {
                        current_tetromino.position.x += 1;
                    }
                    break;
                case VK_DOWN:
                    if (!check_collision(&current_tetromino, 0, 1)) {
                        current_tetromino.position.y += 1;
                    }
                    break;
            }
            InvalidateRect(hwnd, NULL, TRUE);
            break;

        case WM_TIMER:
            if (!check_collision(&current_tetromino, 0, 1)) {
                current_tetromino.position.y += 1;
            } else {
                lock_tetromino(&current_tetromino);
                current_tetromino = tetrominoes[rand() % 7];
                if (check_collision(&current_tetromino, 0, 0)) {
                    KillTimer(hwnd, timer);
                    MessageBox(hwnd, L"Game Over", L"Tetris", MB_OK);
                    DestroyWindow(hwnd);
                }
            }
            InvalidateRect(hwnd, NULL, TRUE);
            break;

        case WM_PAINT: {
            PAINTSTRUCT ps;
            HDC hdc = BeginPaint(hwnd, &ps);
            render_grid(hdc);
            render_tetromino(hdc, &current_tetromino);
            EndPaint(hwnd, &ps);
            break;
        }

        case WM_DESTROY:
            KillTimer(hwnd, timer);
            PostQuitMessage(0);
            break;

        default:
            return DefWindowProc(hwnd, uMsg, wParam, lParam);
    }

    return 0;
}

int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
    const wchar_t CLASS_NAME[] = L"TetrisWindowClass";
    WNDCLASS wc = { };

    wc.lpfnWndProc = WindowProc;
    wc.hInstance = hInstance;
    wc.lpszClassName = CLASS_NAME;
    wc.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);

    RegisterClass(&wc);

    HWND hwnd = CreateWindowEx(
        0,
        CLASS_NAME,
        L"Tetris",
        WS_OVERLAPPEDWINDOW,
        CW_USEDEFAULT, CW_USEDEFAULT, GRID_WIDTH * CELL_SIZE, GRID_HEIGHT * CELL_SIZE,
        NULL,
        NULL,
        hInstance,
        NULL
    );

    if (hwnd == NULL) {
        return 0;
    }

    ShowWindow(hwnd, nCmdShow);

    MSG msg = { };
    while (GetMessage(&msg, NULL, 0, 0)) {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }

    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值