You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SDL2窗口按右方向键生成彩色方块、左方向键删除的实现问题

SDL2方块动态增删实现方案

核心修改思路

  • 新增Square结构体存储每个方块的位置、颜色属性
  • 用std::vector容器维护所有方块实例,原生支持后增后删的操作逻辑,刚好匹配需求里「新方块加在最后、删的时候先删最新」的规则
  • 预定义颜色池,新增方块时按顺序轮询取色,保证每个方块颜色不同
  • 修正原代码逻辑错误:渲染代码不能嵌套在事件轮询SDL_PollEvent的循环内,否则只有触发输入事件时才会刷新画面;同时删除原代码混用SDL_RenderPresent和SDL_UpdateWindowSurface的冲突逻辑,统一用Renderer渲染即可

完整可运行代码

#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <stdio.h>
#include <vector>
#include <string>
#include <cmath>

const int SCREEN_WIDTH = 800;
const int SCREEN_HEIGHT = 640;
const int MAX_SQUARES = 20;
const int SQUARE_SIZE = 100;

// 方块结构体
struct Square {
    SDL_Rect rect;
    SDL_Color color;
};

// 预定义颜色池
const SDL_Color COLORS[] = {
    {255, 165, 0, 255},   // 橙色
    {39, 139, 34, 255},   // 绿色
    {0, 255, 255, 255},   // 青色
    {127, 0, 255, 255},   // 紫色
    {255, 0, 0, 255}      // 红色
};
const int COLOR_COUNT = sizeof(COLORS) / sizeof(COLORS[0]);

SDL_Window* gWindow = NULL;
SDL_Renderer* gRenderer = NULL;

int main( int argc, char* args[] ) {
    SDL_Init(SDL_INIT_VIDEO);
    SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1");
    gWindow = SDL_CreateWindow("Muhammad Hilmi Bin Sazali Q1771290", SDL_WINDOWPOS_UNDEFINED, 
                                               SDL_WINDOWPOS_UNDEFINED, 
                                               SCREEN_WIDTH, SCREEN_HEIGHT, 
                                               SDL_WINDOW_SHOWN);
    gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);
    SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF);

    // 初始化第一个方块
    std::vector<Square> squares;
    Square firstSquare = {
        {SCREEN_WIDTH / 4, SCREEN_HEIGHT / 4, SQUARE_SIZE, SQUARE_SIZE},
        COLORS[0]
    };
    squares.push_back(firstSquare);

    bool quit = false;
    SDL_Event e;

    while( !quit ) {
        // 处理事件
        while( SDL_PollEvent( &e ) != 0 ) {
            if( e.type == SDL_QUIT )
                quit = true;
            else if (e.type == SDL_KEYDOWN) {
                switch (e.key.keysym.sym) {
                case SDLK_LEFT:
                    // 最少保留1个方块
                    if (squares.size() > 1) {
                        squares.pop_back();
                    }
                    break;
                case SDLK_RIGHT:
                    // 最多20个方块
                    if (squares.size() < MAX_SQUARES) {
                        Square newSquare;
                        // 新方块位置做偏移,避免完全重叠,可按需调整
                        int offset = squares.size() * 20;
                        newSquare.rect.x = (SCREEN_WIDTH / 4 + offset) % (SCREEN_WIDTH - SQUARE_SIZE);
                        newSquare.rect.y = (SCREEN_HEIGHT / 4 + offset) % (SCREEN_HEIGHT - SQUARE_SIZE);
                        newSquare.rect.w = SQUARE_SIZE;
                        newSquare.rect.h = SQUARE_SIZE;
                        // 轮询取颜色
                        newSquare.color = COLORS[squares.size() % COLOR_COUNT];
                        squares.push_back(newSquare);
                    }
                    break;
                }
            }
        }

        // 渲染逻辑
        SDL_SetRenderDrawColor( gRenderer, 0xFF, 0xFF, 0xFF, 0xFF );
        SDL_RenderClear( gRenderer );

        // 遍历渲染所有方块
        for (const auto& sq : squares) {
            SDL_SetRenderDrawColor(gRenderer, sq.color.r, sq.color.g, sq.color.b, sq.color.a);
            SDL_RenderFillRect(gRenderer, &sq.rect);
        }

        SDL_RenderPresent( gRenderer );
    }

    // 资源释放
    SDL_DestroyRenderer(gRenderer);
    SDL_DestroyWindow(gWindow);
    gWindow = NULL;
    gRenderer = NULL;
    IMG_Quit();
    SDL_Quit();

    return 0;
}

功能说明

  • 启动后默认显示第一个橙色方块
  • 按下右方向键:最多新增到20个方块,每个方块颜色按预设池轮询,位置自动偏移不会完全重叠
  • 按下左方向键:从最新生成的方块开始删除,直到只剩1个初始方块为止

内容的提问来源于stack exchange,提问作者Hilmi Blaze

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 14:15:08