俄罗斯方块高频刷新应局部擦除旧方块区域而非全屏清屏;方块用结构体+查表坐标偏移表示和旋转;移动旋转前预测目标位置并检查越界与碰撞;消行分统计、删除、下沉三步,配合消行动画状态机实现。

EasyX 绘图循环里怎么清屏又不闪
直接用 cleardevice() 会闪,因为它是全屏擦除+重绘,而俄罗斯方块需要高频刷新(每秒10–60帧)。正确做法是只擦除「上一帧动过的位置」:用 setfillcolor(RGB(255,255,255)) 配合 solidrectangle() 擦掉旧方块区域,再画新位置。注意必须用和背景一致的颜色擦,否则留残影;如果背景是渐变或图片,就得先缓存背景图,用 putimage() 贴回去。
怎么表示和旋转一个方块(tetromino)
别用二维数组硬存7种形状——内存浪费且旋转难。推荐用结构体 + 坐标偏移:
struct Tetromino {
int x, y; // 当前方块左上角在游戏区的格子坐标(0-based)
int type; // 0~6,对应I/O/T/S/Z/J/L
int rot; // 0~3,当前旋转态
static const int data[7][4][4]; // 静态查表:type→rot→4个相对坐标(x,y)
};
旋转靠查表实现,不是数学计算:每个 type 对应4组 (dx, dy),rot 变化时直接切换索引。这样避免浮点误差、边界越界,也方便碰撞检测。
下落、左右移动、旋转时怎么判断是否合法
核心是「预测+检查」:先算出目标位置的4个格子坐标,再逐个查是否越界或被已落定的方块占据。关键点:
立即学习“C++免费学习笔记(深入)”;
- 游戏区逻辑坐标建议设为
10×20(宽10格,高20格),对应数组grid[20][10],索引从0开始 - 检查越界:目标
x = 10 || y >= 20(y - 检查碰撞:对每个预测格子
(tx, ty),若ty >= 0 && grid[ty][tx]为真,就冲突 - 旋转前先用目标
rot查表得新坐标,再统一检查;不要原地改rot后再验
怎么处理消行和分数计算
消行不是边画边删,而是分三步:统计 → 删除 → 下沉。具体:
- 从第0行开始扫
grid,用std::vector<int> fullRows</int>记录满行索引 - 按从下到上顺序遍历
fullRows,用memcpy把上面所有行往下拷一行(grid[i] = grid[i-1]),最顶行填0 - 分数按「一次消1/2/3/4行」给不同倍率,别漏掉连击加成:维护一个
combo计数器,每次消行后递增,没消就清零
容易忽略的是:消行动画要视觉反馈,但不能卡主线程。建议用状态机控制——进入「消行中」状态后,暂停下落,每帧高亮一行,持续300ms后再执行删除逻辑。


















