15.总结
15.1 知识点

主要学习内容

总结目的


强调

15.2 核心要点速览
基于本系列 14 篇正文完整阅读提取,按逻辑分类。
项目概述
| 项目 |
说明 |
| 目标 |
控制台俄罗斯方块:场景切换沿用贪吃蛇框架,核心为方块生成、移动、变形、落底、消行、结束判定 |
| 核心类 |
游戏对象类(小方块)、地图类(固定墙+动态墙)、砖块信息类(形态偏移)、搬砖工人类(方块与地图交互) |
| 坐标 |
一个方块 = 4 个 DrawObject;blocks[0] 为原点,其余位置 = 原点 + BlockInfo 中的相对偏移;横向步长 2,纵向 1 |
场景与入口
| 类型 |
说明 |
| Game |
w=50,h=35;nowScene 当前场景;Start() 死循环调 nowScene.Update();ChangeScene 先 Clear 再 new 对应场景 |
| ISceneUpdate |
接口,仅 void Update() |
| Begin/End |
继承 BeginOrEndBaseScene;W/S 选选项、J 确认;Begin 选 0 进游戏/1 退出,End 选 0 回开始/1 退出 |
绘制与基础类型
| 类型 |
说明 |
| IDraw |
void Draw() |
| Position |
结构体 x,y;重载 ==、!=、+ |
| DrawObject |
pos+E_DrawType;Draw 按类型设颜色写「■」;ClearDraw 写两空格;ChangeType 落底时改为墙 |
| E_DrawType |
Wall/Cube/Line/Tank/Left_Ladder/Right_Ladder/Left_Long_Ladder/Right_Long_Ladder(共 8 种,随机时用 1-7 排除墙) |
地图
| 能力 |
说明 |
| 固定墙 |
构造里:底边 i+=2 到 Game.w,两侧 0 与 Game.w-2,高度 Game.h-6;存于 walls |
| 动态墙 |
dynamicWalls;AddWalls(list):遍历改类型为 Wall 并加入,消行逻辑里顺带 ClearDraw、CheckClear、再 Draw |
| 消行 |
recordInfo[行] 记录每行方块数;满行则该行方块进 delList 再 Remove、上行 y+1、recordInfo 下移、递归 CheckClear;行索引 h-1-pos.y |
| 结束 |
Map(GameScene);AddWalls 时若某块 pos.y<=0 则 StopThread、ChangeScene(End)、return |
方块形态与搬砖工人
| 能力 |
说明 |
| BlockInfo |
按 E_DrawType 存 List<Position[]>,每元素为一种形态的 3 个相对偏移;索引器越界时回退到首/尾;Count 为形态数 |
| BlockWorker |
blocks 当前 4 块,blockInfoDic 七种类型对应 BlockInfo,nowBlockInfo+nowInfoIndex 当前形态 |
| 随机出新块 |
(E_DrawType)r.Next(1,8);4 个 DrawObject(type);原点 blocks[0].pos=(24,5) 或 (24,-5);取形态偏移算 blocks[1..3].pos |
| 变形 |
E_Change_Type Left/Right;Change 前 ClearDraw,改 nowInfoIndex(循环),用 nowBlockInfo[nowInfoIndex] 重算三块 pos 再 Draw |
| 可变形判断 |
CanChange:用临时索引取形态,算 4 点;若任一点 x<2、x>=Game.w-2、y>=map.h 或与 dynamicWalls 某点同则 false |
移动与落底
| 能力 |
说明 |
| 左右 |
MoveRL:ClearDraw,偏移 (±2,0),遍历 pos+= 再 Draw;CanMoveRL:模拟偏移后查边界与 dynamicWalls |
| 下落 |
AutoMove:ClearDraw,各块 pos.y+=1 再 Draw;CanMove:模拟 (0,1),触底或碰动态墙则 AddWalls(blocks)、RandomCreateBlock()、return false |
| 主循环 |
Update 内:lock(blockWorker){ map.Draw(); blockWorker.Draw(); if(CanMove) AutoMove(); } 然后 Thread.Sleep(200) |
输入与线程
| 能力 |
说明 |
| 问题 |
Update 里 Sleep 导致输入延迟;双线程同时写控制台需同步 |
| 做法 |
单独输入线程 while(true) 里 KeyAvailable 时 lock(blockWorker) 读键并执行变形/左右/下落;锁内不含 Sleep |
| 优化 |
InputThread 单例,内部线程死循环调 inputEvent?.Invoke();GameScene 构造时 inputEvent += CheckInputThread,StopThread 时 -= CheckInputThread;场景 new 时不再 new 线程,避免线程堆积 |
实现顺序建议
- 场景框架(Program、Game、ISceneUpdate、Begin/End/GameScene 空壳)。
- 绘制基础(IDraw、Position、E_DrawType、DrawObject、ClearDraw、ChangeType)。
- 地图(Map 固定墙+动态墙、Draw、AddWalls)。
- 形态数据(BlockInfo 各类型多形态偏移、索引器、Count)。
- 搬砖工人(blockInfoDic、RandomCreateBlock、Draw)。
- 变形(E_Change_Type、nowInfoIndex、Change、ClearDraw、CanChange)。
- 左右移动(MoveRL、CanMoveRL)。
- 下落与落底(AutoMove、CanMove、AddWalls+RandomCreateBlock)。
- 输入线程(Thread、lock(blockWorker)、键位映射)。
- 消行(recordInfo、AddWalls 里计数、CheckClear 递归)。
- 结束(y<=0 判定、StopThread、Map 持 GameScene)。
- 可选:InputThread 单例+事件、新块初始 y 上移、屏幕外不绘制。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com