sudo apt-get install libsdl2-dev

#include <SDL2/SDL.h>

#include <stdbool.h>

#include <time.h>

#include <stdlib.h>

 

#define WINDOW_WIDTH 800

#define WINDOW_HEIGHT 600

#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;

    SDL_Color color;

} Tetromino;

 

// Tetris pieces (I, O, T, S, Z, J, L)

Tetromino tetrominoes[7] = {

    {{ {0, 0}, {0, 1}, {0, 2}, {0, 3} }, {GRID_WIDTH / 2 - 2, 0}, {0, 255, 255, 255}}, // I

    {{ {0, 0}, {0, 1}, {1, 0}, {1, 1} }, {GRID_WIDTH / 2 - 1, 0}, {255, 255, 0, 255}}, // O

    {{ {0, 0}, {1, 0}, {2, 0}, {1, 1} }, {GRID_WIDTH / 2 - 1, 0}, {128, 0, 128, 255}}, // T

    {{ {0, 1}, {1, 1}, {1, 0}, {2, 0} }, {GRID_WIDTH / 2 - 1, 0}, {0, 255, 0, 255}}, // S

    {{ {0, 0}, {1, 0}, {1, 1}, {2, 1} }, {GRID_WIDTH / 2 - 1, 0}, {255, 0, 0, 255}}, // Z

    {{ {0, 1}, {1, 1}, {2, 1}, {2, 0} }, {GRID_WIDTH / 2 - 1, 0}, {0, 0, 255, 255}}, // J

    {{ {0, 0}, {0, 1}, {1, 1}, {2, 1} }, {GRID_WIDTH / 2 - 1, 0}, {255, 165, 0, 255}} // 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(SDL_Renderer *renderer) {

    SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);

    SDL_RenderClear(renderer);

    for (int y = 0; y < GRID_HEIGHT; y++) {

        for (int x = 0; x < GRID_WIDTH; x++) {

            if (grid[y][x]) {

                SDL_Rect cell = { x * CELL_SIZE, y * CELL_SIZE, CELL_SIZE, CELL_SIZE };

                SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);

                SDL_RenderFillRect(renderer, &cell);

            }

        }

    }

}

 

void render_tetromino(SDL_Renderer *renderer, Tetromino *tetromino) {

    SDL_SetRenderDrawColor(renderer, tetromino->color.r, tetromino->color.g, tetromino->color.b, tetromino->color.a);

    for (int i = 0; i < 4; i++) {

        SDL_Rect block = { (tetromino->blocks[i].x + tetromino->position.x) * CELL_SIZE, 

                           (tetromino->blocks[i].y + tetromino->position.y) * CELL_SIZE, 

                           CELL_SIZE, CELL_SIZE };

        SDL_RenderFillRect(renderer, &block);

    }

}

 

int main(int argc, char *argv[]) {

    if (SDL_Init(SDL_INIT_VIDEO) != 0) {

        printf("SDL_Init Error: %s\n", SDL_GetError());

        return 1;

    }

 

    SDL_Window *window = SDL_CreateWindow("Tetris", 100, 100, WINDOW_WIDTH, WINDOW_HEIGHT, SDL_WINDOW_SHOWN);

    if (window == NULL) {

        printf("SDL_CreateWindow Error: %s\n", SDL_GetError());

        SDL_Quit();

        return 1;

    }

 

    SDL_Renderer *renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);

    if (renderer == NULL) {

        SDL_DestroyWindow(window);

        printf("SDL_CreateRenderer Error: %s\n", SDL_GetError());

        SDL_Quit();

        return 1;

    }

 

    srand(time(NULL));

    Tetromino current_tetromino = tetrominoes[rand() % 7];

    bool running = true;

    SDL_Event event;

    Uint32 lastTick = SDL_GetTicks(), currentTick;

 

    while (running) {

        while (SDL_PollEvent(&event)) {

            if (event.type == SDL_QUIT) {

                running = false;

            } else if (event.type == SDL_KEYDOWN) {

                switch (event.key.keysym.sym) {

                    case SDLK_LEFT:

                        if (!check_collision(&current_tetromino, -1, 0)) {

                            current_tetromino.position.x -= 1;

                        }

                        break;

                    case SDLK_RIGHT:

                        if (!check_collision(&current_tetromino, 1, 0)) {

                            current_tetromino.position.x += 1;

                        }

                        break;

                    case SDLK_DOWN:

                        if (!check_collision(&current_tetromino, 0, 1)) {

                            current_tetromino.position.y += 1;

                        }

                        break;

                }

            }

        }

 

        currentTick = SDL_GetTicks();

        if (currentTick - lastTick > 500) {

            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)) {

                    running = false; // Game over

                }

            }

            lastTick = currentTick;

        }

 

        render_grid(renderer);

        render_tetromino(renderer, &current_tetromino);

        SDL_RenderPresent(renderer);

    }

 

    SDL_DestroyRenderer(renderer);

    SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值