移除主窗口无用菜单栏并修正窗口尺寸计算 为 rogue treis 做准备
This commit is contained in:
@@ -0,0 +1,624 @@
|
||||
# 《Rogue Tetris》功能设计文档
|
||||
|
||||
## 1. 项目概述
|
||||
|
||||
本项目基于经典俄罗斯方块玩法,加入类肉鸽成长系统。玩家通过消除方块获得积分与经验,达到一定条件后触发升级,从随机出现的强化选项中选择一项,形成不同流派与策略组合。
|
||||
|
||||
游戏核心循环为:
|
||||
|
||||
```text
|
||||
下落方块 → 摆放 → 消行 → 获得积分/经验 → 升级 → 选择强化 → 提升能力 → 继续挑战
|
||||
```
|
||||
|
||||
项目目标是在保留俄罗斯方块基础规则的同时,增强随机性、成长性和可重复游玩价值。
|
||||
|
||||
---
|
||||
|
||||
## 2. 基础玩法设计
|
||||
|
||||
### 2.1 棋盘设计
|
||||
|
||||
游戏区域采用标准俄罗斯方块棋盘:
|
||||
|
||||
```cpp
|
||||
const int BOARD_WIDTH = 10;
|
||||
const int BOARD_HEIGHT = 20;
|
||||
```
|
||||
|
||||
棋盘使用二维数组或 `vector<vector<int>>` 存储。
|
||||
|
||||
```cpp
|
||||
int board[BOARD_HEIGHT][BOARD_WIDTH];
|
||||
```
|
||||
|
||||
其中:
|
||||
|
||||
| 数值 | 含义 |
|
||||
|---|---|
|
||||
| 0 | 空格 |
|
||||
| 1-7 | 不同类型的普通方块 |
|
||||
| 8 | 特殊方块,例如爆破方块 |
|
||||
|
||||
### 2.2 方块类型
|
||||
|
||||
游戏包含七种经典方块:
|
||||
|
||||
| 类型 | 说明 |
|
||||
|---|---|
|
||||
| I | 长条方块 |
|
||||
| O | 方形方块 |
|
||||
| T | T 型方块 |
|
||||
| S | S 型方块 |
|
||||
| Z | Z 型方块 |
|
||||
| J | J 型方块 |
|
||||
| L | L 型方块 |
|
||||
|
||||
### 2.3 玩家操作
|
||||
|
||||
| 按键 | 功能 |
|
||||
|---|---|
|
||||
| A / ← | 左移 |
|
||||
| D / → | 右移 |
|
||||
| W / ↑ | 旋转 |
|
||||
| S / ↓ | 软降 |
|
||||
| 空格 | 硬降 |
|
||||
| C | 暂存方块 |
|
||||
| P | 暂停 |
|
||||
|
||||
---
|
||||
|
||||
## 3. 肉鸽成长系统设计
|
||||
|
||||
### 3.1 经验获取
|
||||
|
||||
玩家通过消行获得经验。
|
||||
|
||||
| 消除行数 | 获得经验 |
|
||||
|---|---|
|
||||
| 1 行 | 10 EXP |
|
||||
| 2 行 | 25 EXP |
|
||||
| 3 行 | 45 EXP |
|
||||
| 4 行 | 80 EXP |
|
||||
|
||||
### 3.2 升级规则
|
||||
|
||||
玩家经验达到当前等级需求后升级。
|
||||
|
||||
```cpp
|
||||
requiredExp = 100 + level * 50;
|
||||
```
|
||||
|
||||
升级时:
|
||||
|
||||
1. 游戏暂停;
|
||||
2. 随机生成若干强化选项;
|
||||
3. 玩家选择其中一个;
|
||||
4. 应用强化效果;
|
||||
5. 游戏继续。
|
||||
|
||||
### 3.3 升级流程示例
|
||||
|
||||
```cpp
|
||||
void levelUp() {
|
||||
player.level++;
|
||||
player.exp -= player.requiredExp;
|
||||
player.requiredExp = 100 + player.level * 50;
|
||||
|
||||
vector<Upgrade> choices = upgradeSystem.getRandomUpgrades(player.upgradeChoiceCount);
|
||||
int selected = showUpgradeChoices(choices);
|
||||
upgradeSystem.applyUpgrade(choices[selected], player, board);
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 4. 强化系统设计
|
||||
|
||||
### 4.1 强化分类
|
||||
|
||||
| 类型 | 说明 |
|
||||
|---|---|
|
||||
| 得分强化 | 提高积分收益 |
|
||||
| 操作强化 | 改善玩家操作体验 |
|
||||
| 消行强化 | 增强消行效果 |
|
||||
| 生存强化 | 降低游戏失败风险 |
|
||||
| 特殊强化 | 改变游戏规则 |
|
||||
|
||||
---
|
||||
|
||||
## 5. 强化内容设计
|
||||
|
||||
### 5.1 得分类强化
|
||||
|
||||
#### 1. 积分倍率
|
||||
|
||||
效果:所有得分提高 20%。
|
||||
|
||||
```cpp
|
||||
player.scoreMultiplier += 0.2f;
|
||||
```
|
||||
|
||||
可重复获得。
|
||||
|
||||
#### 2. 连击奖励
|
||||
|
||||
效果:连续消行时获得额外积分。
|
||||
|
||||
```cpp
|
||||
player.comboBonus += 50;
|
||||
```
|
||||
|
||||
当玩家连续多个方块都产生消行时,触发连击奖励。
|
||||
|
||||
#### 3. 四消强化
|
||||
|
||||
效果:一次消除 4 行时额外获得 300 分。
|
||||
|
||||
```cpp
|
||||
if (linesCleared == 4) {
|
||||
score += 300;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5.2 操作类强化
|
||||
|
||||
#### 4. 慢速下落
|
||||
|
||||
效果:方块自然下落速度降低 10%。
|
||||
|
||||
```cpp
|
||||
player.fallSpeed *= 0.9f;
|
||||
```
|
||||
|
||||
#### 5. 额外预览
|
||||
|
||||
效果:增加下一个方块预览数量。
|
||||
|
||||
```cpp
|
||||
player.previewCount += 1;
|
||||
```
|
||||
|
||||
#### 6. 暂存槽
|
||||
|
||||
效果:解锁 Hold 功能,允许玩家暂存当前方块。
|
||||
|
||||
```cpp
|
||||
player.canHold = true;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5.3 消行类强化
|
||||
|
||||
#### 7. 清扫者
|
||||
|
||||
效果:每累计消除 10 行,自动清除最底部一行。
|
||||
|
||||
```cpp
|
||||
if (player.totalLinesCleared % 10 == 0) {
|
||||
board.clearBottomLine();
|
||||
}
|
||||
```
|
||||
|
||||
#### 8. 爆破方块
|
||||
|
||||
效果:每隔一定数量的方块,生成一个特殊爆破方块。爆破方块落地后清除周围 3x3 区域。
|
||||
|
||||
```cpp
|
||||
void explode(int x, int y) {
|
||||
for (int dy = -1; dy <= 1; dy++) {
|
||||
for (int dx = -1; dx <= 1; dx++) {
|
||||
board[y + dy][x + dx] = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### 9. 经验强化
|
||||
|
||||
效果:消行获得经验提高 25%。
|
||||
|
||||
```cpp
|
||||
player.expMultiplier += 0.25f;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5.4 生存类强化
|
||||
|
||||
#### 10. 最后一搏
|
||||
|
||||
效果:当玩家即将失败时,自动清除底部 3 行。每局只能触发一次。
|
||||
|
||||
```cpp
|
||||
player.hasRevive = true;
|
||||
```
|
||||
|
||||
#### 11. 减压
|
||||
|
||||
效果:每次升级后,自动清除当前最高的一行障碍。
|
||||
|
||||
```cpp
|
||||
board.clearHighestOccupiedLine();
|
||||
```
|
||||
|
||||
#### 12. 稳定结构
|
||||
|
||||
效果:方块锁定后,有小概率自动填补附近空洞。
|
||||
|
||||
```cpp
|
||||
if (rand() % 100 < 10) {
|
||||
board.fillNearbyHole();
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5.5 特殊类强化
|
||||
|
||||
#### 13. 双倍成长
|
||||
|
||||
效果:之后每次升级出现 4 个选项,而不是 3 个。
|
||||
|
||||
```cpp
|
||||
player.upgradeChoiceCount = 4;
|
||||
```
|
||||
|
||||
#### 14. 赌徒
|
||||
|
||||
效果:选择强化时有概率获得双倍效果,也有概率无效果。
|
||||
|
||||
```cpp
|
||||
int chance = rand() % 100;
|
||||
if (chance < 30) {
|
||||
applyUpgradeTwice();
|
||||
} else if (chance < 50) {
|
||||
noEffect();
|
||||
}
|
||||
```
|
||||
|
||||
#### 15. 方块改造
|
||||
|
||||
效果:降低某一种方块的出现概率,例如减少 Z 方块出现概率。
|
||||
|
||||
```cpp
|
||||
blockWeight[BlockType::Z] -= 1;
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6. 数据结构设计
|
||||
|
||||
### 6.1 方块结构
|
||||
|
||||
```cpp
|
||||
struct Tetromino {
|
||||
int type;
|
||||
int rotation;
|
||||
int x;
|
||||
int y;
|
||||
vector<vector<int>> shape;
|
||||
};
|
||||
```
|
||||
|
||||
### 6.2 玩家状态
|
||||
|
||||
```cpp
|
||||
struct PlayerStats {
|
||||
int score = 0;
|
||||
int level = 1;
|
||||
int exp = 0;
|
||||
int requiredExp = 100;
|
||||
|
||||
int totalLinesCleared = 0;
|
||||
int combo = 0;
|
||||
int comboBonus = 0;
|
||||
|
||||
float scoreMultiplier = 1.0f;
|
||||
float expMultiplier = 1.0f;
|
||||
float fallSpeed = 1.0f;
|
||||
|
||||
bool canHold = false;
|
||||
bool hasRevive = false;
|
||||
|
||||
int previewCount = 1;
|
||||
int upgradeChoiceCount = 3;
|
||||
};
|
||||
```
|
||||
|
||||
### 6.3 强化结构
|
||||
|
||||
```cpp
|
||||
enum class UpgradeType {
|
||||
Score,
|
||||
Control,
|
||||
Clear,
|
||||
Survival,
|
||||
Special
|
||||
};
|
||||
|
||||
struct Upgrade {
|
||||
string name;
|
||||
string description;
|
||||
UpgradeType type;
|
||||
int level;
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 7. 计分系统设计
|
||||
|
||||
### 7.1 基础得分
|
||||
|
||||
| 消除行数 | 基础分 |
|
||||
|---|---|
|
||||
| 1 行 | 100 |
|
||||
| 2 行 | 300 |
|
||||
| 3 行 | 500 |
|
||||
| 4 行 | 800 |
|
||||
|
||||
### 7.2 得分计算
|
||||
|
||||
```cpp
|
||||
int calculateScore(int linesCleared) {
|
||||
int baseScore = 0;
|
||||
|
||||
switch (linesCleared) {
|
||||
case 1: baseScore = 100; break;
|
||||
case 2: baseScore = 300; break;
|
||||
case 3: baseScore = 500; break;
|
||||
case 4: baseScore = 800; break;
|
||||
default: return 0;
|
||||
}
|
||||
|
||||
int finalScore = static_cast<int>(baseScore * player.scoreMultiplier);
|
||||
|
||||
if (player.combo > 1) {
|
||||
finalScore += player.combo * player.comboBonus;
|
||||
}
|
||||
|
||||
return finalScore;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 8. 强化随机池设计
|
||||
|
||||
### 8.1 强化池初始化
|
||||
|
||||
```cpp
|
||||
vector<Upgrade> upgradePool;
|
||||
|
||||
void initUpgradePool() {
|
||||
upgradePool.push_back({
|
||||
"积分倍率",
|
||||
"所有得分提高20%",
|
||||
UpgradeType::Score,
|
||||
1
|
||||
});
|
||||
|
||||
upgradePool.push_back({
|
||||
"慢速下落",
|
||||
"方块下落速度降低10%",
|
||||
UpgradeType::Control,
|
||||
1
|
||||
});
|
||||
|
||||
upgradePool.push_back({
|
||||
"最后一搏",
|
||||
"失败时自动清除底部3行,每局一次",
|
||||
UpgradeType::Survival,
|
||||
1
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 8.2 随机抽取强化
|
||||
|
||||
```cpp
|
||||
vector<Upgrade> getRandomUpgrades(int count) {
|
||||
vector<Upgrade> result;
|
||||
vector<Upgrade> pool = upgradePool;
|
||||
|
||||
random_shuffle(pool.begin(), pool.end());
|
||||
|
||||
for (int i = 0; i < count && i < pool.size(); i++) {
|
||||
result.push_back(pool[i]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 9. 主要类设计
|
||||
|
||||
### 9.1 Game 类
|
||||
|
||||
```cpp
|
||||
class Game {
|
||||
private:
|
||||
Board board;
|
||||
Tetromino currentBlock;
|
||||
PlayerStats player;
|
||||
UpgradeSystem upgradeSystem;
|
||||
|
||||
public:
|
||||
void init();
|
||||
void update();
|
||||
void render();
|
||||
void handleInput();
|
||||
void checkGameOver();
|
||||
};
|
||||
```
|
||||
|
||||
### 9.2 Board 类
|
||||
|
||||
```cpp
|
||||
class Board {
|
||||
private:
|
||||
int grid[20][10];
|
||||
|
||||
public:
|
||||
bool checkCollision(Tetromino block);
|
||||
void lockBlock(Tetromino block);
|
||||
int clearLines();
|
||||
void clearBottomLine();
|
||||
void clearHighestOccupiedLine();
|
||||
bool isGameOver();
|
||||
};
|
||||
```
|
||||
|
||||
### 9.3 UpgradeSystem 类
|
||||
|
||||
```cpp
|
||||
class UpgradeSystem {
|
||||
private:
|
||||
vector<Upgrade> upgradePool;
|
||||
|
||||
public:
|
||||
void init();
|
||||
vector<Upgrade> getRandomUpgrades(int count);
|
||||
void applyUpgrade(Upgrade upgrade, PlayerStats& player, Board& board);
|
||||
};
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 10. 游戏主流程
|
||||
|
||||
```text
|
||||
初始化游戏数据
|
||||
↓
|
||||
生成当前方块和预览方块
|
||||
↓
|
||||
进入游戏主循环
|
||||
↓
|
||||
读取玩家输入
|
||||
↓
|
||||
更新方块位置
|
||||
↓
|
||||
检测碰撞
|
||||
↓
|
||||
无法下落时锁定方块
|
||||
↓
|
||||
检测并消除完整行
|
||||
↓
|
||||
计算得分和经验
|
||||
↓
|
||||
判断是否升级
|
||||
↓
|
||||
若升级,进入强化选择界面
|
||||
↓
|
||||
应用强化效果
|
||||
↓
|
||||
继续游戏
|
||||
↓
|
||||
判断是否失败
|
||||
↓
|
||||
游戏结束,显示最终得分
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 11. 界面设计
|
||||
|
||||
### 11.1 主界面示意
|
||||
|
||||
```text
|
||||
+--------------------+----------------+
|
||||
| | Score: 1200 |
|
||||
| | Level: 3 |
|
||||
| | EXP: 40/250 |
|
||||
| | |
|
||||
| 游戏棋盘 | Next: |
|
||||
| | [T] [L] [I] |
|
||||
| | |
|
||||
| | Upgrades: |
|
||||
| | 积分倍率 Lv2 |
|
||||
+--------------------+----------------+
|
||||
```
|
||||
|
||||
### 11.2 升级界面示意
|
||||
|
||||
```text
|
||||
请选择一个强化:
|
||||
|
||||
[1] 积分倍率
|
||||
所有得分提高20%
|
||||
|
||||
[2] 慢速下落
|
||||
方块下落速度降低10%
|
||||
|
||||
[3] 最后一搏
|
||||
失败时自动清除底部3行,每局一次
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 12. 模块划分
|
||||
|
||||
| 模块 | 功能 |
|
||||
|---|---|
|
||||
| Game | 控制游戏主循环 |
|
||||
| Board | 管理棋盘数据 |
|
||||
| Tetromino | 管理方块形状、旋转、移动 |
|
||||
| Renderer | 负责界面绘制 |
|
||||
| InputManager | 处理键盘输入 |
|
||||
| ScoreSystem | 计算分数与经验 |
|
||||
| UpgradeSystem | 管理强化池、升级、强化应用 |
|
||||
| PlayerStats | 保存玩家成长数据 |
|
||||
|
||||
---
|
||||
|
||||
## 13. 开发优先级
|
||||
|
||||
| 优先级 | 内容 |
|
||||
|---|---|
|
||||
| P0 | 实现基础俄罗斯方块逻辑 |
|
||||
| P0 | 实现消行和计分 |
|
||||
| P1 | 实现经验和升级系统 |
|
||||
| P1 | 实现随机强化三选一 |
|
||||
| P1 | 实现 5 到 8 个基础强化 |
|
||||
| P2 | 实现特殊方块,例如爆破方块 |
|
||||
| P2 | 实现 Hold、预览数量等操作强化 |
|
||||
| P3 | 增加稀有度、成就、存档等扩展内容 |
|
||||
|
||||
---
|
||||
|
||||
## 14. 技术实现建议
|
||||
|
||||
| 技术 | 用途 |
|
||||
|---|---|
|
||||
| C++ | 主体开发语言 |
|
||||
| STL vector | 存储棋盘、方块、强化池 |
|
||||
| enum class | 表示方块类型和强化类型 |
|
||||
| class | 进行模块化封装 |
|
||||
| random | 实现随机强化和随机方块 |
|
||||
| SFML / SDL / Qt | 可选,用于图形界面 |
|
||||
|
||||
如果课程要求较基础,可以先完成控制台版本,再根据时间增加图形界面。
|
||||
|
||||
---
|
||||
|
||||
## 15. 创新点总结
|
||||
|
||||
本项目的主要创新点包括:
|
||||
|
||||
1. 在传统俄罗斯方块中加入经验和等级系统;
|
||||
2. 将消行行为与角色成长绑定;
|
||||
3. 每次升级随机提供强化选项;
|
||||
4. 强化之间可以叠加,形成不同构筑路线;
|
||||
5. 加入生存类和特殊类强化,提高策略空间;
|
||||
6. 每局强化组合不同,提升重复游玩价值。
|
||||
|
||||
---
|
||||
|
||||
## 16. 结论
|
||||
|
||||
《Rogue Tetris》在经典俄罗斯方块的基础上引入类肉鸽升级机制,使游戏从单纯的消行挑战扩展为具有成长路线、随机选择和策略构筑的玩法。玩家每局都能通过不同强化组合形成不同体验,既保留了俄罗斯方块的核心规则,也体现了创新性,适合作为 C++ 课程大作业项目。
|
||||
@@ -0,0 +1,185 @@
|
||||
# Rogue Tetris TODO List
|
||||
|
||||
说明:本清单基于 [Rogue_Tetris_功能设计文档](./Rogue_Tetris_功能设计文档.md) 整理,后续实现严格遵守以下约束:
|
||||
|
||||
- [ ] 不使用 `class`、继承、多态等面向对象特性
|
||||
- [ ] 以 `struct + 全局状态 + 纯函数/过程函数 + 模块化源文件` 组织代码
|
||||
- [ ] 强化选择界面固定为“三选一”三个选项框,视觉参考《吸血鬼幸存者》
|
||||
- [ ] 美术、图标、特效、音频先全部使用占位符资源
|
||||
|
||||
## 阶段 0:重构准备与技术基线
|
||||
|
||||
目标:在不破坏现有可运行版本的前提下,为肉鸽系统预留结构。
|
||||
|
||||
- [ ] 盘点当前全局变量、输入流程、计时器流程、渲染流程
|
||||
- [ ] 明确哪些旧逻辑保留,哪些逻辑需要拆分成独立过程函数
|
||||
- [ ] 设计新的状态拆分方案:游戏主状态、棋盘状态、当前方块状态、玩家成长状态、强化状态、UI 状态
|
||||
- [ ] 统一命名风格,避免后续继续扩散 `type/state/nType` 这类语义偏弱命名
|
||||
- [ ] 明确“升级中暂停”和“普通暂停”是两个不同状态
|
||||
- [ ] 确定占位符资源策略:纯色块、边框、占位图标、占位按钮
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 写出核心数据结构草案
|
||||
- [ ] 写出模块拆分草案
|
||||
- [ ] 当前版本仍可正常编译运行
|
||||
|
||||
## 阶段 1:核心数据结构改造
|
||||
|
||||
目标:把当前普通俄罗斯方块状态扩展成可承载 Rogue 系统的数据。
|
||||
|
||||
- [ ] 新增 `GameState` 相关结构,记录运行态、暂停态、升级选择态、结算态
|
||||
- [ ] 新增 `PieceState` 结构,管理当前方块、下一方块、目标落点、是否可 Hold
|
||||
- [ ] 新增 `PlayerStats` 结构,包含分数、等级、经验、所需经验、连击、总消行数
|
||||
- [ ] 新增 `UpgradeEntry` 结构,包含 `id`、名称、描述、分类、当前层数、是否可重复
|
||||
- [ ] 新增 `UpgradeRuntime` 结构,保存已获得强化和运行时效果值
|
||||
- [ ] 新增 `UiState` 结构,保存当前三个升级选项、当前高亮项、弹窗可见性
|
||||
- [ ] 将现有散落的全局变量逐步收敛到几个结构体中
|
||||
- [ ] 保留纯过程式调用,不引入成员函数
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 代码中已能通过结构体访问大部分核心状态
|
||||
- [ ] 不再继续新增零散全局变量
|
||||
|
||||
## 阶段 2:分数、经验、等级主循环
|
||||
|
||||
目标:把“消行 -> 得分 -> 获得经验 -> 触发升级”接入当前主循环。
|
||||
|
||||
- [ ] 重写消行结算函数,返回本次消除行数
|
||||
- [ ] 按文档接入基础得分:1/2/3/4 行分别对应不同分值
|
||||
- [ ] 按文档接入经验收益:1/2/3/4 行分别给予不同 EXP
|
||||
- [ ] 接入倍率计算:分数倍率、经验倍率、四消奖励、连击奖励
|
||||
- [ ] 新增升级判定函数,支持一次结算后连续升多级
|
||||
- [ ] 升级触发时停止下落计时与普通输入
|
||||
- [ ] 在右侧信息面板显示等级、EXP、所需 EXP、当前已获得强化摘要
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 消行后可以稳定增加分数和经验
|
||||
- [ ] 达到阈值后必定进入升级选择状态
|
||||
|
||||
## 阶段 3:强化池与三选一系统
|
||||
|
||||
目标:先完成最关键的 Rogue 核心体验。
|
||||
|
||||
- [ ] 建立强化池初始化函数,不使用类,采用静态数组或 `std::vector<UpgradeEntry>`
|
||||
- [ ] 先实现一批 P1 基础强化,优先选 6 个左右最稳定的:
|
||||
- [ ] `score_multiplier`
|
||||
- [ ] `combo_bonus`
|
||||
- [ ] `slow_fall`
|
||||
- [ ] `preview_plus_one`
|
||||
- [ ] `exp_multiplier`
|
||||
- [ ] `last_chance`
|
||||
- [ ] 随机抽取 3 个不重复选项,避免当前局内明显无效选项
|
||||
- [ ] 支持重复强化的层数叠加
|
||||
- [ ] 选中后立即应用效果并返回游戏
|
||||
- [ ] 为后续强化扩展预留 `applyUpgradeById()` 分发函数
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 每次升级都稳定弹出三个选项框
|
||||
- [ ] 选择任一选项后效果立即生效
|
||||
|
||||
## 阶段 4:升级界面 UI
|
||||
|
||||
目标:实现参考《吸血鬼幸存者》的三选一视觉结构,先用占位表现。
|
||||
|
||||
- [ ] 增加全屏或半透明遮罩,压暗游戏场景
|
||||
- [ ] 中央显示三个横向或纵向排列的选项框
|
||||
- [ ] 每个选项框至少包含:占位图标、强化名、强化说明、强化分类、当前层数
|
||||
- [ ] 支持键盘选择:`A/D` 或方向键切换,`Enter/Space` 确认
|
||||
- [ ] 高亮态、选中态、禁用态视觉区分明确
|
||||
- [ ] 保证三个框尺寸一致、布局稳定,不因文本长度错位
|
||||
- [ ] 右侧现有信息面板在升级状态下保留或弱化显示,但不能抢焦点
|
||||
- [ ] 占位资源统一放入 `assets`,命名先按 `placeholder_*`
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 升级界面可以独立显示
|
||||
- [ ] 三个选项框可操作、可确认、可关闭
|
||||
- [ ] 视觉结构已经接近目标形式,后续只需替换资源
|
||||
|
||||
## 阶段 5:玩法强化第一轮
|
||||
|
||||
目标:把最影响体验的几个强化真正接入玩法。
|
||||
|
||||
- [ ] 分数倍率:影响所有结算得分
|
||||
- [ ] 连击奖励:连续多次成功消行追加奖励
|
||||
- [ ] 慢速下落:降低自然下落速度
|
||||
- [ ] 额外预览:从 1 个 Next 扩展到 2~3 个
|
||||
- [ ] EXP 强化:提升经验获取倍率
|
||||
- [ ] 最后一搏:失败前自动清除底部 3 行,仅触发一次
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 每个强化都能在实际对局中观察到效果
|
||||
- [ ] 强化效果叠加后不会引发明显逻辑冲突
|
||||
|
||||
## 阶段 6:特殊机制第二轮
|
||||
|
||||
目标:在主体验稳定后再上特殊规则,避免一开始把复杂度拉满。
|
||||
|
||||
- [ ] Hold 功能改造成可解锁能力,而不是默认启用
|
||||
- [ ] 扩展更多预览块显示
|
||||
- [ ] 清扫者:累计消行触发底部清除
|
||||
- [ ] 爆破方块:生成特殊方块并实现 3x3 清除
|
||||
- [ ] 减压:升级后清除最高占用行
|
||||
- [ ] 稳定结构:小概率自动填补邻近空洞
|
||||
- [ ] 双倍成长 / 赌徒 / 方块改运等特殊强化
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 至少 2 个特殊机制能稳定跑通
|
||||
- [ ] 不会明显破坏基础俄罗斯方块节奏
|
||||
|
||||
## 阶段 7:界面补全与反馈
|
||||
|
||||
目标:让系统信息足够清楚,不靠猜测理解机制。
|
||||
|
||||
- [ ] 右侧面板补充等级、EXP 条、强化列表、当前倍率
|
||||
- [ ] 增加本次结算浮动提示:`+Score`、`+EXP`、`Level Up`
|
||||
- [ ] 为特殊强化增加简短提示文案
|
||||
- [ ] 增加暂停、升级、失败三种不同遮罩样式
|
||||
- [ ] 增加占位图标、占位按钮、占位边框资源
|
||||
- [ ] 检查中文排版、字号、留白、长文本换行
|
||||
|
||||
完成标准:
|
||||
|
||||
- [ ] 玩家能看懂自己为什么升级、为什么得分变化
|
||||
|
||||
## 阶段 8:平衡与稳定性
|
||||
|
||||
目标:把版本从“能跑”拉到“能玩”。
|
||||
|
||||
- [ ] 调整等级需求曲线
|
||||
- [ ] 调整强化出现权重,避免过强或无效强化频繁出现
|
||||
- [ ] 调整下落速度、经验速度、升级频率
|
||||
- [ ] 修复升级状态下的非法输入问题
|
||||
- [ ] 修复连续升级、失败复活、爆破消行等边界问题
|
||||
- [ ] 增加最基础回归测试清单
|
||||
|
||||
回归检查:
|
||||
|
||||
- [ ] 开局正常生成方块
|
||||
- [ ] 消行得分与经验正确
|
||||
- [ ] 升级必出 3 个选项框
|
||||
- [ ] 选择后恢复游戏且不丢状态
|
||||
- [ ] 复活、暂停、失败、重开互不冲突
|
||||
|
||||
## 建议实现顺序
|
||||
|
||||
1. 先做阶段 1 和阶段 2,把“经验升级”主循环打通。
|
||||
2. 再做阶段 3 和阶段 4,优先完成“三选一选项框”体验。
|
||||
3. 然后做阶段 5,把 6 个基础强化真正接上。
|
||||
4. 最后做阶段 6 到阶段 8,补特殊机制、表现和调平衡。
|
||||
|
||||
## 当前最近一轮执行清单
|
||||
|
||||
- [ ] 建立新的状态结构体与头文件声明
|
||||
- [ ] 重写消行结算返回值
|
||||
- [ ] 加入 `PlayerStats`
|
||||
- [ ] 加入经验与升级判定
|
||||
- [ ] 加入升级状态切换
|
||||
- [ ] 做出三个升级选项框的占位 UI
|
||||
- [ ] 接入第一批 6 个基础强化
|
||||
@@ -91,7 +91,7 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
|
||||
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TETRIS));
|
||||
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
|
||||
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
|
||||
wcex.lpszMenuName = MAKEINTRESOURCE(IDC_TETRIS);
|
||||
wcex.lpszMenuName = nullptr;
|
||||
wcex.lpszClassName = szWindowClass;
|
||||
wcex.hIconSm = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_SMALL));
|
||||
|
||||
@@ -111,7 +111,7 @@ ATOM MyRegisterClass(HINSTANCE hInstance)
|
||||
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
|
||||
{
|
||||
RECT rect = { 0, 0, WINDOW_CLIENT_WIDTH, WINDOW_CLIENT_HEIGHT };
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, TRUE);
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW, FALSE);
|
||||
|
||||
hInst = hInstance;
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
||||
int layoutWidth = MulDiv(WINDOW_CLIENT_WIDTH, scale, 1000);
|
||||
int layoutHeight = MulDiv(WINDOW_CLIENT_HEIGHT, scale, 1000);
|
||||
int offsetX = (clientWidth - layoutWidth) / 2;
|
||||
int offsetY = (clientHeight - layoutHeight) / 2;
|
||||
int offsetY = 0;
|
||||
|
||||
auto SX = [offsetX, scale](int value) -> int
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user