升级改为四选一并重做赌徒与方块改造机制
This commit is contained in:
@@ -7,7 +7,7 @@
|
|||||||
- [x] 保留当前原版俄罗斯方块玩法,作为“经典模式”
|
- [x] 保留当前原版俄罗斯方块玩法,作为“经典模式”
|
||||||
- [x] 新增开始菜单,进入游戏前先选择模式
|
- [x] 新增开始菜单,进入游戏前先选择模式
|
||||||
- [x] 模式至少包含:`经典模式`、`Rogue 模式`
|
- [x] 模式至少包含:`经典模式`、`Rogue 模式`
|
||||||
- [x] 强化选择界面固定为“三选一”三个选项框,视觉参考《吸血鬼幸存者》
|
- [x] 强化选择界面固定为“四选一”四个选项框,视觉参考《吸血鬼幸存者》
|
||||||
- [ ] 美术、图标、特效、音频先全部使用占位符资源
|
- [ ] 美术、图标、特效、音频先全部使用占位符资源
|
||||||
|
|
||||||
## 阶段 0:重构准备与技术基线
|
## 阶段 0:重构准备与技术基线
|
||||||
@@ -100,7 +100,7 @@
|
|||||||
- [x] 消行后可以稳定增加分数和经验
|
- [x] 消行后可以稳定增加分数和经验
|
||||||
- [x] 达到阈值后必定进入升级选择状态
|
- [x] 达到阈值后必定进入升级选择状态
|
||||||
|
|
||||||
## 阶段 5:强化池与三选一系统
|
## 阶段 5:强化池与四选一系统
|
||||||
|
|
||||||
目标:先完成最关键的 Rogue 核心体验。
|
目标:先完成最关键的 Rogue 核心体验。
|
||||||
|
|
||||||
@@ -112,33 +112,33 @@
|
|||||||
- [x] `preview_plus_one`
|
- [x] `preview_plus_one`
|
||||||
- [x] `exp_multiplier`
|
- [x] `exp_multiplier`
|
||||||
- [x] `last_chance`
|
- [x] `last_chance`
|
||||||
- [x] 随机抽取 3 个不重复选项,避免当前局内明显无效选项
|
- [x] 随机抽取 4 个不重复选项,避免当前局内明显无效选项
|
||||||
- [x] 支持重复强化的层数叠加
|
- [x] 支持重复强化的层数叠加
|
||||||
- [x] 选中后立即应用效果并返回游戏
|
- [x] 选中后立即应用效果并返回游戏
|
||||||
- [x] 为后续强化扩展预留 `applyUpgradeById()` 分发函数
|
- [x] 为后续强化扩展预留 `applyUpgradeById()` 分发函数
|
||||||
|
|
||||||
完成标准:
|
完成标准:
|
||||||
|
|
||||||
- [x] 每次升级都稳定弹出三个选项框
|
- [x] 每次升级都稳定弹出四个选项框
|
||||||
- [x] 选择任一选项后效果立即生效
|
- [x] 选择任一选项后效果立即生效
|
||||||
|
|
||||||
## 阶段 6:升级界面 UI
|
## 阶段 6:升级界面 UI
|
||||||
|
|
||||||
目标:实现参考《吸血鬼幸存者》的三选一视觉结构,先用占位表现。
|
目标:实现参考《吸血鬼幸存者》的四选一视觉结构,先用占位表现。
|
||||||
|
|
||||||
- [x] 增加全屏或半透明遮罩,压暗游戏场景
|
- [x] 增加全屏或半透明遮罩,压暗游戏场景
|
||||||
- [x] 中央显示三个横向或纵向排列的选项框
|
- [x] 中央显示四个横向或纵向排列的选项框
|
||||||
- [x] 每个选项框至少包含:占位图标、强化名、强化说明、强化分类、当前层数
|
- [x] 每个选项框至少包含:占位图标、强化名、强化说明、强化分类、当前层数
|
||||||
- [x] 支持键盘选择:`A/D` 或方向键切换,`Enter/Space` 确认
|
- [x] 支持键盘选择:`A/D` 或方向键切换,`Enter/Space` 确认
|
||||||
- [ ] 高亮态、选中态、禁用态视觉区分明确
|
- [ ] 高亮态、选中态、禁用态视觉区分明确
|
||||||
- [x] 保证三个框尺寸一致、布局稳定,不因文本长度错位
|
- [x] 保证四个框尺寸一致、布局稳定,不因文本长度错位
|
||||||
- [x] 右侧现有信息面板在升级状态下保留或弱化显示,但不能抢焦点
|
- [x] 右侧现有信息面板在升级状态下保留或弱化显示,但不能抢焦点
|
||||||
- [ ] 占位资源统一放入 `assets`,命名先按 `placeholder_*`
|
- [ ] 占位资源统一放入 `assets`,命名先按 `placeholder_*`
|
||||||
|
|
||||||
完成标准:
|
完成标准:
|
||||||
|
|
||||||
- [x] 升级界面可以独立显示
|
- [x] 升级界面可以独立显示
|
||||||
- [x] 三个选项框可操作、可确认、可关闭
|
- [x] 四个选项框可操作、可确认、可关闭
|
||||||
- [x] 视觉结构已经接近目标形式,后续只需替换资源
|
- [x] 视觉结构已经接近目标形式,后续只需替换资源
|
||||||
|
|
||||||
## 阶段 7:玩法强化第一轮
|
## 阶段 7:玩法强化第一轮
|
||||||
@@ -204,7 +204,7 @@
|
|||||||
|
|
||||||
- [ ] 开局正常生成方块
|
- [ ] 开局正常生成方块
|
||||||
- [ ] 消行得分与经验正确
|
- [ ] 消行得分与经验正确
|
||||||
- [x] 升级必出 3 个选项框
|
- [x] 升级必出 4 个选项框
|
||||||
- [x] 选择后恢复游戏且不丢状态
|
- [x] 选择后恢复游戏且不丢状态
|
||||||
- [ ] 复活、暂停、失败、重开互不冲突
|
- [ ] 复活、暂停、失败、重开互不冲突
|
||||||
|
|
||||||
|
|||||||
@@ -56,14 +56,15 @@ struct PlayerStats
|
|||||||
int explosiveLevel;
|
int explosiveLevel;
|
||||||
int stableStructureLevel;
|
int stableStructureLevel;
|
||||||
int doubleGrowthLevel;
|
int doubleGrowthLevel;
|
||||||
int luckyRollLevel;
|
|
||||||
int gamblerLevel;
|
int gamblerLevel;
|
||||||
|
int pieceTuningLevels[7];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct UpgradeOption
|
struct UpgradeOption
|
||||||
{
|
{
|
||||||
int id;
|
int id;
|
||||||
int currentLevel;
|
int currentLevel;
|
||||||
|
int targetPieceType;
|
||||||
const TCHAR* name;
|
const TCHAR* name;
|
||||||
const TCHAR* category;
|
const TCHAR* category;
|
||||||
const TCHAR* description;
|
const TCHAR* description;
|
||||||
@@ -85,7 +86,7 @@ struct UpgradeUiState
|
|||||||
int optionCount;
|
int optionCount;
|
||||||
int pendingCount;
|
int pendingCount;
|
||||||
int totalChosenCount;
|
int totalChosenCount;
|
||||||
UpgradeOption options[3];
|
UpgradeOption options[4];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FeedbackState
|
struct FeedbackState
|
||||||
|
|||||||
+40
-6
@@ -264,19 +264,53 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|||||||
{
|
{
|
||||||
case VK_LEFT:
|
case VK_LEFT:
|
||||||
case 'A':
|
case 'A':
|
||||||
upgradeUiState.selectedIndex--;
|
if (upgradeUiState.optionCount > 1)
|
||||||
if (upgradeUiState.selectedIndex < 0)
|
|
||||||
{
|
{
|
||||||
upgradeUiState.selectedIndex = upgradeUiState.optionCount - 1;
|
if ((upgradeUiState.selectedIndex % 2) == 1)
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex = (upgradeUiState.selectedIndex + 1 < upgradeUiState.optionCount)
|
||||||
|
? upgradeUiState.selectedIndex + 1
|
||||||
|
: upgradeUiState.selectedIndex;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
InvalidateRect(hWnd, nullptr, FALSE);
|
InvalidateRect(hWnd, nullptr, FALSE);
|
||||||
break;
|
break;
|
||||||
case VK_RIGHT:
|
case VK_RIGHT:
|
||||||
case 'D':
|
case 'D':
|
||||||
upgradeUiState.selectedIndex++;
|
if (upgradeUiState.optionCount > 1)
|
||||||
if (upgradeUiState.selectedIndex >= upgradeUiState.optionCount)
|
|
||||||
{
|
{
|
||||||
upgradeUiState.selectedIndex = 0;
|
if ((upgradeUiState.selectedIndex % 2) == 0 && upgradeUiState.selectedIndex + 1 < upgradeUiState.optionCount)
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex--;
|
||||||
|
if (upgradeUiState.selectedIndex < 0)
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
InvalidateRect(hWnd, nullptr, FALSE);
|
||||||
|
break;
|
||||||
|
case VK_UP:
|
||||||
|
case 'W':
|
||||||
|
if (upgradeUiState.optionCount > 2 && upgradeUiState.selectedIndex >= 2)
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex -= 2;
|
||||||
|
}
|
||||||
|
InvalidateRect(hWnd, nullptr, FALSE);
|
||||||
|
break;
|
||||||
|
case VK_DOWN:
|
||||||
|
case 'S':
|
||||||
|
if (upgradeUiState.optionCount > 2 && upgradeUiState.selectedIndex + 2 < upgradeUiState.optionCount)
|
||||||
|
{
|
||||||
|
upgradeUiState.selectedIndex += 2;
|
||||||
}
|
}
|
||||||
InvalidateRect(hWnd, nullptr, FALSE);
|
InvalidateRect(hWnd, nullptr, FALSE);
|
||||||
break;
|
break;
|
||||||
|
|||||||
+160
-70
@@ -38,7 +38,7 @@ enum UpgradeId
|
|||||||
UPGRADE_EXPLOSIVE_PIECE = 9,
|
UPGRADE_EXPLOSIVE_PIECE = 9,
|
||||||
UPGRADE_STABLE_STRUCTURE = 10,
|
UPGRADE_STABLE_STRUCTURE = 10,
|
||||||
UPGRADE_DOUBLE_GROWTH = 11,
|
UPGRADE_DOUBLE_GROWTH = 11,
|
||||||
UPGRADE_LUCKY_ROLL = 12,
|
UPGRADE_PIECE_TUNING = 12,
|
||||||
UPGRADE_GAMBLER = 13
|
UPGRADE_GAMBLER = 13
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -56,8 +56,8 @@ static const UpgradeEntry kUpgradePool[] =
|
|||||||
{ UPGRADE_EXPLOSIVE_PIECE, -1, true, _T("\u7206\u7834\u65b9\u5757"), _T("\u7279\u6b8a"), _T("\u63d0\u9ad8\u7206\u7834\u65b9\u5757\u51fa\u73b0\u6982\u7387\uff0c\u843d\u5730\u65f6\u89e6\u53d1 3x3 \u6e05\u9664\u3002") },
|
{ UPGRADE_EXPLOSIVE_PIECE, -1, true, _T("\u7206\u7834\u65b9\u5757"), _T("\u7279\u6b8a"), _T("\u63d0\u9ad8\u7206\u7834\u65b9\u5757\u51fa\u73b0\u6982\u7387\uff0c\u843d\u5730\u65f6\u89e6\u53d1 3x3 \u6e05\u9664\u3002") },
|
||||||
{ UPGRADE_STABLE_STRUCTURE, -1, true, _T("\u7a33\u5b9a\u7ed3\u6784"), _T("\u7279\u6b8a"), _T("\u843d\u5730\u540e\u5c0f\u6982\u7387\u81ea\u52a8\u586b\u8865\u90bb\u8fd1\u7a7a\u6d1e\uff0c\u63d0\u9ad8\u76d8\u9762\u7ed3\u6784\u7a33\u5b9a\u6027\u3002") },
|
{ UPGRADE_STABLE_STRUCTURE, -1, true, _T("\u7a33\u5b9a\u7ed3\u6784"), _T("\u7279\u6b8a"), _T("\u843d\u5730\u540e\u5c0f\u6982\u7387\u81ea\u52a8\u586b\u8865\u90bb\u8fd1\u7a7a\u6d1e\uff0c\u63d0\u9ad8\u76d8\u9762\u7ed3\u6784\u7a33\u5b9a\u6027\u3002") },
|
||||||
{ UPGRADE_DOUBLE_GROWTH, -1, true, _T("\u53cc\u500d\u6210\u957f"), _T("\u7279\u6b8a"), _T("\u989d\u5916\u63d0\u9ad8\u6d88\u884c\u5f97\u5206\u4e0e EXP \u6536\u76ca\uff0c\u6bcf\u5c42\u518d\u8ffd\u52a0 15%\u3002") },
|
{ UPGRADE_DOUBLE_GROWTH, -1, true, _T("\u53cc\u500d\u6210\u957f"), _T("\u7279\u6b8a"), _T("\u989d\u5916\u63d0\u9ad8\u6d88\u884c\u5f97\u5206\u4e0e EXP \u6536\u76ca\uff0c\u6bcf\u5c42\u518d\u8ffd\u52a0 15%\u3002") },
|
||||||
{ UPGRADE_LUCKY_ROLL, -1, true, _T("\u65b9\u5757\u6539\u8fd0"), _T("\u7279\u6b8a"), _T("\u4f18\u5316 Next \u961f\u5217\uff0c\u964d\u4f4e\u8fde\u7eed\u91cd\u590d\u65b9\u5757\u51fa\u73b0\u7684\u6982\u7387\u3002") },
|
{ UPGRADE_PIECE_TUNING, -1, true, _T("\u65b9\u5757\u6539\u9020"), _T("\u7279\u6b8a"), _T("\u9009\u62e9\u4e00\u79cd\u65b9\u5757\uff0c\u964d\u4f4e\u5176\u540e\u7eed\u51fa\u73b0\u6982\u7387\u3002") },
|
||||||
{ UPGRADE_GAMBLER, -1, true, _T("\u8d4c\u5f92"), _T("\u7279\u6b8a"), _T("\u6d88\u884c\u6536\u76ca\u4f1a\u989d\u5916\u968f\u673a\u6ce2\u52a8\uff0c\u5c42\u6570\u8d8a\u9ad8\u6ce2\u52a8\u8d8a\u5927\u3002") }
|
{ UPGRADE_GAMBLER, -1, true, _T("\u8d4c\u5f92"), _T("\u7279\u6b8a"), _T("\u9009\u62e9\u5f3a\u5316\u65f6\uff0c\u6709\u6982\u7387\u53cc\u500d\u751f\u6548\uff0c\u4e5f\u6709\u6982\u7387\u5b8c\u5168\u843d\u7a7a\u3002") }
|
||||||
};
|
};
|
||||||
|
|
||||||
static constexpr int kUpgradePoolSize = sizeof(kUpgradePool) / sizeof(kUpgradePool[0]);
|
static constexpr int kUpgradePoolSize = sizeof(kUpgradePool) / sizeof(kUpgradePool[0]);
|
||||||
@@ -215,8 +215,11 @@ static void ResetPlayerStats(PlayerStats& stats, bool useRogueRules)
|
|||||||
stats.explosiveLevel = 0;
|
stats.explosiveLevel = 0;
|
||||||
stats.stableStructureLevel = 0;
|
stats.stableStructureLevel = 0;
|
||||||
stats.doubleGrowthLevel = 0;
|
stats.doubleGrowthLevel = 0;
|
||||||
stats.luckyRollLevel = 0;
|
|
||||||
stats.gamblerLevel = 0;
|
stats.gamblerLevel = 0;
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
stats.pieceTuningLevels[i] = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int GetNextPreviewLimit()
|
static int GetNextPreviewLimit()
|
||||||
@@ -267,8 +270,6 @@ static int GetUpgradeCurrentLevel(int upgradeId)
|
|||||||
return rogueStats.stableStructureLevel;
|
return rogueStats.stableStructureLevel;
|
||||||
case UPGRADE_DOUBLE_GROWTH:
|
case UPGRADE_DOUBLE_GROWTH:
|
||||||
return rogueStats.doubleGrowthLevel;
|
return rogueStats.doubleGrowthLevel;
|
||||||
case UPGRADE_LUCKY_ROLL:
|
|
||||||
return rogueStats.luckyRollLevel;
|
|
||||||
case UPGRADE_GAMBLER:
|
case UPGRADE_GAMBLER:
|
||||||
return rogueStats.gamblerLevel;
|
return rogueStats.gamblerLevel;
|
||||||
default:
|
default:
|
||||||
@@ -276,6 +277,27 @@ static int GetUpgradeCurrentLevel(int upgradeId)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const TCHAR* GetPieceShortName(int pieceType)
|
||||||
|
{
|
||||||
|
static const TCHAR* kPieceNames[7] =
|
||||||
|
{
|
||||||
|
_T("I"),
|
||||||
|
_T("T"),
|
||||||
|
_T("L"),
|
||||||
|
_T("J"),
|
||||||
|
_T("O"),
|
||||||
|
_T("S"),
|
||||||
|
_T("Z")
|
||||||
|
};
|
||||||
|
|
||||||
|
if (pieceType < 0 || pieceType >= 7)
|
||||||
|
{
|
||||||
|
return _T("?");
|
||||||
|
}
|
||||||
|
|
||||||
|
return kPieceNames[pieceType];
|
||||||
|
}
|
||||||
|
|
||||||
static bool IsUpgradeSelectable(const UpgradeEntry& entry)
|
static bool IsUpgradeSelectable(const UpgradeEntry& entry)
|
||||||
{
|
{
|
||||||
if (entry.repeatable)
|
if (entry.repeatable)
|
||||||
@@ -390,42 +412,37 @@ static int ClearExplosiveAreaAt(int centerY, int centerX)
|
|||||||
|
|
||||||
static int RollNextPieceType()
|
static int RollNextPieceType()
|
||||||
{
|
{
|
||||||
int candidate = rand() % 7;
|
int weights[7] = { 100, 100, 100, 100, 100, 100, 100 };
|
||||||
|
|
||||||
if (currentMode != MODE_ROGUE || rogueStats.luckyRollLevel <= 0)
|
if (currentMode == MODE_ROGUE)
|
||||||
{
|
{
|
||||||
return candidate;
|
for (int i = 0; i < 7; i++)
|
||||||
}
|
|
||||||
|
|
||||||
int rerollCount = rogueStats.luckyRollLevel;
|
|
||||||
if (rerollCount > 3)
|
|
||||||
{
|
|
||||||
rerollCount = 3;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int attempt = 0; attempt < rerollCount; attempt++)
|
|
||||||
{
|
|
||||||
bool matchesCurrent = (candidate == type);
|
|
||||||
bool matchesQueue = false;
|
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
|
||||||
{
|
{
|
||||||
if (nextTypes[i] == candidate)
|
weights[i] -= rogueStats.pieceTuningLevels[i] * 20;
|
||||||
|
if (weights[i] < 20)
|
||||||
{
|
{
|
||||||
matchesQueue = true;
|
weights[i] = 20;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!matchesCurrent && !matchesQueue)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
candidate = rand() % 7;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return candidate;
|
int totalWeight = 0;
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
totalWeight += weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
int roll = rand() % totalWeight;
|
||||||
|
for (int i = 0; i < 7; i++)
|
||||||
|
{
|
||||||
|
if (roll < weights[i])
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
roll -= weights[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return rand() % 7;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int TryStabilizeBoard()
|
static int TryStabilizeBoard()
|
||||||
@@ -544,7 +561,7 @@ static void FillUpgradeOptions()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int optionCount = selectableCount < 3 ? selectableCount : 3;
|
int optionCount = selectableCount < 4 ? selectableCount : 4;
|
||||||
upgradeUiState.optionCount = optionCount;
|
upgradeUiState.optionCount = optionCount;
|
||||||
upgradeUiState.selectedIndex = 0;
|
upgradeUiState.selectedIndex = 0;
|
||||||
|
|
||||||
@@ -556,10 +573,45 @@ static void FillUpgradeOptions()
|
|||||||
|
|
||||||
upgradeUiState.options[i].id = pickedEntry.id;
|
upgradeUiState.options[i].id = pickedEntry.id;
|
||||||
upgradeUiState.options[i].currentLevel = GetUpgradeCurrentLevel(pickedEntry.id);
|
upgradeUiState.options[i].currentLevel = GetUpgradeCurrentLevel(pickedEntry.id);
|
||||||
|
upgradeUiState.options[i].targetPieceType = -1;
|
||||||
upgradeUiState.options[i].name = pickedEntry.name;
|
upgradeUiState.options[i].name = pickedEntry.name;
|
||||||
upgradeUiState.options[i].category = pickedEntry.category;
|
upgradeUiState.options[i].category = pickedEntry.category;
|
||||||
upgradeUiState.options[i].description = pickedEntry.description;
|
upgradeUiState.options[i].description = pickedEntry.description;
|
||||||
|
|
||||||
|
if (pickedEntry.id == UPGRADE_PIECE_TUNING)
|
||||||
|
{
|
||||||
|
int targetPieceType = rand() % 7;
|
||||||
|
bool duplicatedPiece = true;
|
||||||
|
int guard = 0;
|
||||||
|
|
||||||
|
while (duplicatedPiece && guard < 16)
|
||||||
|
{
|
||||||
|
duplicatedPiece = false;
|
||||||
|
for (int optionIndex = 0; optionIndex < i; optionIndex++)
|
||||||
|
{
|
||||||
|
if (upgradeUiState.options[optionIndex].id == UPGRADE_PIECE_TUNING &&
|
||||||
|
upgradeUiState.options[optionIndex].targetPieceType == targetPieceType)
|
||||||
|
{
|
||||||
|
duplicatedPiece = true;
|
||||||
|
targetPieceType = (targetPieceType + 1) % 7;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
guard++;
|
||||||
|
}
|
||||||
|
|
||||||
|
upgradeUiState.options[i].targetPieceType = targetPieceType;
|
||||||
|
upgradeUiState.options[i].currentLevel = rogueStats.pieceTuningLevels[targetPieceType];
|
||||||
|
upgradeUiState.options[i].name = _T("\u65b9\u5757\u6539\u9020");
|
||||||
|
|
||||||
|
static TCHAR tuningDescriptions[4][64];
|
||||||
|
_stprintf_s(
|
||||||
|
tuningDescriptions[i],
|
||||||
|
_T("\u964d\u4f4e %s \u65b9\u5757\u7684\u51fa\u73b0\u6982\u7387\u3002"),
|
||||||
|
GetPieceShortName(targetPieceType));
|
||||||
|
upgradeUiState.options[i].description = tuningDescriptions[i];
|
||||||
|
}
|
||||||
|
|
||||||
selectableIndexes[pickSlot] = selectableIndexes[selectableCount - 1];
|
selectableIndexes[pickSlot] = selectableIndexes[selectableCount - 1];
|
||||||
selectableCount--;
|
selectableCount--;
|
||||||
}
|
}
|
||||||
@@ -570,77 +622,80 @@ static int GetRogueFallInterval()
|
|||||||
return 500 + rogueStats.slowFallStacks * 80;
|
return 500 + rogueStats.slowFallStacks * 80;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void ApplyUpgradeById(int upgradeId)
|
static void ApplyUpgradeById(int upgradeId, int targetPieceType, int applyCount)
|
||||||
{
|
{
|
||||||
|
if (applyCount <= 0)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
switch (upgradeId)
|
switch (upgradeId)
|
||||||
{
|
{
|
||||||
case UPGRADE_SCORE_MULTIPLIER:
|
case UPGRADE_SCORE_MULTIPLIER:
|
||||||
rogueStats.scoreMultiplierPercent += 20;
|
rogueStats.scoreMultiplierPercent += 20 * applyCount;
|
||||||
rogueStats.scoreUpgradeLevel++;
|
rogueStats.scoreUpgradeLevel += applyCount;
|
||||||
break;
|
break;
|
||||||
case UPGRADE_COMBO_BONUS:
|
case UPGRADE_COMBO_BONUS:
|
||||||
rogueStats.comboBonusStacks++;
|
rogueStats.comboBonusStacks += applyCount;
|
||||||
break;
|
break;
|
||||||
case UPGRADE_EXP_MULTIPLIER:
|
case UPGRADE_EXP_MULTIPLIER:
|
||||||
rogueStats.expMultiplierPercent += 25;
|
rogueStats.expMultiplierPercent += 25 * applyCount;
|
||||||
rogueStats.expUpgradeLevel++;
|
rogueStats.expUpgradeLevel += applyCount;
|
||||||
break;
|
break;
|
||||||
case UPGRADE_SLOW_FALL:
|
case UPGRADE_SLOW_FALL:
|
||||||
rogueStats.slowFallStacks++;
|
rogueStats.slowFallStacks += applyCount;
|
||||||
currentFallInterval = GetRogueFallInterval();
|
currentFallInterval = GetRogueFallInterval();
|
||||||
break;
|
break;
|
||||||
case UPGRADE_PREVIEW_PLUS_ONE:
|
case UPGRADE_PREVIEW_PLUS_ONE:
|
||||||
if (rogueStats.previewCount < 3)
|
for (int i = 0; i < applyCount; i++)
|
||||||
{
|
{
|
||||||
rogueStats.previewCount++;
|
if (rogueStats.previewCount < 3)
|
||||||
|
{
|
||||||
|
rogueStats.previewCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
rogueStats.previewUpgradeLevel = rogueStats.previewCount - 1;
|
rogueStats.previewUpgradeLevel = rogueStats.previewCount - 1;
|
||||||
break;
|
break;
|
||||||
case UPGRADE_LAST_CHANCE:
|
case UPGRADE_LAST_CHANCE:
|
||||||
rogueStats.lastChanceCount = 1;
|
rogueStats.lastChanceCount += applyCount;
|
||||||
rogueStats.lastChanceUpgradeLevel = 1;
|
rogueStats.lastChanceUpgradeLevel += applyCount;
|
||||||
break;
|
break;
|
||||||
case UPGRADE_HOLD_UNLOCK:
|
case UPGRADE_HOLD_UNLOCK:
|
||||||
rogueStats.holdUnlocked = 1;
|
rogueStats.holdUnlocked = 1;
|
||||||
break;
|
break;
|
||||||
case UPGRADE_PRESSURE_RELIEF:
|
case UPGRADE_PRESSURE_RELIEF:
|
||||||
{
|
{
|
||||||
rogueStats.pressureReliefLevel++;
|
rogueStats.pressureReliefLevel += applyCount;
|
||||||
int topOccupiedRow = GetTopOccupiedRow();
|
for (int i = 0; i < applyCount; i++)
|
||||||
if (topOccupiedRow >= 0)
|
|
||||||
{
|
{
|
||||||
DeleteOneLine(topOccupiedRow);
|
int topOccupiedRow = GetTopOccupiedRow();
|
||||||
SetFeedbackMessage(_T("\u51cf\u538b\u751f\u6548"), _T("\u5df2\u7acb\u5373\u6e05\u9664\u5f53\u524d\u6700\u9ad8\u5360\u7528\u884c\u3002"), 12);
|
if (topOccupiedRow >= 0)
|
||||||
}
|
{
|
||||||
else
|
DeleteOneLine(topOccupiedRow);
|
||||||
{
|
}
|
||||||
SetFeedbackMessage(_T("\u51cf\u538b\u751f\u6548"), _T("\u5f53\u524d\u76d8\u9762\u8fd8\u5f88\u7a7a\uff0c\u672c\u6b21\u6ca1\u6709\u989d\u5916\u6e05\u9664\u884c\u3002"), 12);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case UPGRADE_SWEEPER:
|
case UPGRADE_SWEEPER:
|
||||||
rogueStats.sweeperLevel++;
|
rogueStats.sweeperLevel += applyCount;
|
||||||
SetFeedbackMessage(_T("\u6e05\u626b\u8005\u5df2\u52a0\u5165"), _T("\u7d2f\u8ba1\u6d88\u884c\u540e\u5c06\u81ea\u52a8\u6e05\u7406\u5e95\u90e8\u79ef\u538b\u3002"), 12);
|
|
||||||
break;
|
break;
|
||||||
case UPGRADE_EXPLOSIVE_PIECE:
|
case UPGRADE_EXPLOSIVE_PIECE:
|
||||||
rogueStats.explosiveLevel++;
|
rogueStats.explosiveLevel += applyCount;
|
||||||
SetFeedbackMessage(_T("\u7206\u7834\u65b9\u5757\u5df2\u5f3a\u5316"), _T("\u540e\u7eed\u5c06\u6709\u66f4\u9ad8\u6982\u7387\u51fa\u73b0\u7206\u7834\u65b9\u5757\u3002"), 12);
|
|
||||||
break;
|
break;
|
||||||
case UPGRADE_STABLE_STRUCTURE:
|
case UPGRADE_STABLE_STRUCTURE:
|
||||||
rogueStats.stableStructureLevel++;
|
rogueStats.stableStructureLevel += applyCount;
|
||||||
SetFeedbackMessage(_T("\u7a33\u5b9a\u7ed3\u6784\u5df2\u5f3a\u5316"), _T("\u540e\u7eed\u843d\u5730\u7ed3\u7b97\u65f6\u5c06\u6709\u6982\u7387\u81ea\u52a8\u8865\u6d1e\u3002"), 12);
|
|
||||||
break;
|
break;
|
||||||
case UPGRADE_DOUBLE_GROWTH:
|
case UPGRADE_DOUBLE_GROWTH:
|
||||||
rogueStats.doubleGrowthLevel++;
|
rogueStats.doubleGrowthLevel += applyCount;
|
||||||
SetFeedbackMessage(_T("\u53cc\u500d\u6210\u957f\u5df2\u53e0\u52a0"), _T("\u540e\u7eed\u6d88\u884c\u7684\u5f97\u5206\u548c EXP \u6536\u76ca\u4f1a\u66f4\u9ad8\u3002"), 12);
|
|
||||||
break;
|
break;
|
||||||
case UPGRADE_LUCKY_ROLL:
|
case UPGRADE_PIECE_TUNING:
|
||||||
rogueStats.luckyRollLevel++;
|
if (targetPieceType >= 0 && targetPieceType < 7)
|
||||||
SetFeedbackMessage(_T("\u65b9\u5757\u6539\u8fd0\u5df2\u5f3a\u5316"), _T("Next \u961f\u5217\u4f1a\u66f4\u5c11\u51fa\u73b0\u8fde\u7eed\u91cd\u590d\u5757\u578b\u3002"), 12);
|
{
|
||||||
|
rogueStats.pieceTuningLevels[targetPieceType] += applyCount;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case UPGRADE_GAMBLER:
|
case UPGRADE_GAMBLER:
|
||||||
rogueStats.gamblerLevel++;
|
rogueStats.gamblerLevel += applyCount;
|
||||||
SetFeedbackMessage(_T("\u8d4c\u5f92\u5df2\u53e0\u52a0"), _T("\u540e\u7eed\u6d88\u884c\u7684\u5206\u6570\u548c EXP \u4f1a\u989d\u5916\u968f\u673a\u6ce2\u52a8\u3002"), 12);
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -1272,12 +1327,47 @@ void ConfirmUpgradeSelection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
UpgradeOption selectedOption = upgradeUiState.options[upgradeUiState.selectedIndex];
|
UpgradeOption selectedOption = upgradeUiState.options[upgradeUiState.selectedIndex];
|
||||||
ApplyUpgradeById(selectedOption.id);
|
int applyCount = 1;
|
||||||
|
TCHAR gamblerSuffix[64] = _T("");
|
||||||
|
|
||||||
|
if (currentMode == MODE_ROGUE && rogueStats.gamblerLevel > 0)
|
||||||
|
{
|
||||||
|
int gamblerChance = 20 + (rogueStats.gamblerLevel - 1) * 5;
|
||||||
|
if (gamblerChance > 40)
|
||||||
|
{
|
||||||
|
gamblerChance = 40;
|
||||||
|
}
|
||||||
|
|
||||||
|
int roll = rand() % 100;
|
||||||
|
if (roll < gamblerChance)
|
||||||
|
{
|
||||||
|
applyCount = 2;
|
||||||
|
_stprintf_s(gamblerSuffix, _T(" \u8d4c\u5f92\uff1a\u53cc\u500d"));
|
||||||
|
}
|
||||||
|
else if (roll >= 100 - gamblerChance)
|
||||||
|
{
|
||||||
|
applyCount = 0;
|
||||||
|
_stprintf_s(gamblerSuffix, _T(" \u8d4c\u5f92\uff1a\u843d\u7a7a"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ApplyUpgradeById(selectedOption.id, selectedOption.targetPieceType, applyCount);
|
||||||
upgradeUiState.totalChosenCount++;
|
upgradeUiState.totalChosenCount++;
|
||||||
TCHAR feedbackTitle[64];
|
TCHAR feedbackTitle[64];
|
||||||
TCHAR feedbackDetail[128];
|
TCHAR feedbackDetail[128];
|
||||||
_stprintf_s(feedbackTitle, _T("\u5df2\u83b7\u5f97\uff1a%s"), selectedOption.name);
|
_stprintf_s(feedbackTitle, _T("\u5df2\u83b7\u5f97\uff1a%s"), selectedOption.name);
|
||||||
_stprintf_s(feedbackDetail, _T("%s"), selectedOption.description);
|
if (selectedOption.id == UPGRADE_PIECE_TUNING && selectedOption.targetPieceType >= 0)
|
||||||
|
{
|
||||||
|
_stprintf_s(
|
||||||
|
feedbackDetail,
|
||||||
|
_T("\u964d\u4f4e %s \u65b9\u5757\u51fa\u73b0\u6982\u7387%s"),
|
||||||
|
GetPieceShortName(selectedOption.targetPieceType),
|
||||||
|
gamblerSuffix);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_stprintf_s(feedbackDetail, _T("%s%s"), selectedOption.description, gamblerSuffix);
|
||||||
|
}
|
||||||
SetFeedbackMessage(feedbackTitle, feedbackDetail, 12);
|
SetFeedbackMessage(feedbackTitle, feedbackDetail, 12);
|
||||||
|
|
||||||
if (upgradeUiState.pendingCount > 0)
|
if (upgradeUiState.pendingCount > 0)
|
||||||
|
|||||||
+42
-15
@@ -362,7 +362,7 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
hdc,
|
hdc,
|
||||||
_T("\u7ecf\u5178\u6a21\u5f0f\uff1a\u4fdd\u6301\u539f\u7248\u4fc4\u7f57\u65af\u65b9\u5757\u73a9\u6cd5\uff0c\u4ee5\u6d88\u884c\u548c\u751f\u5b58\u4e3a\u4e3b\u3002\r\n\r\n")
|
_T("\u7ecf\u5178\u6a21\u5f0f\uff1a\u4fdd\u6301\u539f\u7248\u4fc4\u7f57\u65af\u65b9\u5757\u73a9\u6cd5\uff0c\u4ee5\u6d88\u884c\u548c\u751f\u5b58\u4e3a\u4e3b\u3002\r\n\r\n")
|
||||||
_T("Rogue \u6a21\u5f0f\uff1a\u6d88\u884c\u540e\u9664\u4e86\u83b7\u5f97\u5206\u6570\uff0c\u8fd8\u4f1a\u83b7\u5f97 EXP\u3002EXP \u8fbe\u5230\u9608\u503c\u540e\u89e6\u53d1\u5347\u7ea7\uff0c\u4ece\u4e09\u4e2a\u5f3a\u5316\u4e2d\u9009\u4e00\u4e2a\u3002\r\n\r\n")
|
_T("Rogue \u6a21\u5f0f\uff1a\u6d88\u884c\u540e\u9664\u4e86\u83b7\u5f97\u5206\u6570\uff0c\u8fd8\u4f1a\u83b7\u5f97 EXP\u3002EXP \u8fbe\u5230\u9608\u503c\u540e\u89e6\u53d1\u5347\u7ea7\uff0c\u4ece\u4e09\u4e2a\u5f3a\u5316\u4e2d\u9009\u4e00\u4e2a\u3002\r\n\r\n")
|
||||||
_T("\u5f53\u524d\u5df2\u63a5\u5165\uff1a\u5206\u6570\u500d\u7387\u3001EXP \u500d\u7387\u3001\u6162\u901f\u4e0b\u843d\u3001Hold \u89e3\u9501\u3001\u51cf\u538b\u3001\u6e05\u626b\u8005\u3001\u7206\u7834\u65b9\u5757\u3001\u7a33\u5b9a\u7ed3\u6784\u3001\u53cc\u500d\u6210\u957f\u3001\u65b9\u5757\u6539\u8fd0\u3001\u8d4c\u5f92\u3002\r\n\r\n")
|
_T("\u5f53\u524d\u5df2\u63a5\u5165\uff1a\u5206\u6570\u500d\u7387\u3001EXP \u500d\u7387\u3001\u6162\u901f\u4e0b\u843d\u3001Hold \u89e3\u9501\u3001\u51cf\u538b\u3001\u6e05\u626b\u8005\u3001\u7206\u7834\u65b9\u5757\u3001\u7a33\u5b9a\u7ed3\u6784\u3001\u53cc\u500d\u6210\u957f\u3001\u65b9\u5757\u6539\u9020\u3001\u8d4c\u5f92\u3002\r\n\r\n")
|
||||||
_T("\u63d0\u793a\uff1a\u6682\u505c\u3001\u5931\u8d25\u548c\u5347\u7ea7\u4f1a\u8fdb\u5165\u4e0d\u540c\u754c\u9762\uff0c\u8bf7\u6839\u636e\u5c4f\u5e55\u63d0\u793a\u64cd\u4f5c\u3002"),
|
_T("\u63d0\u793a\uff1a\u6682\u505c\u3001\u5931\u8d25\u548c\u5347\u7ea7\u4f1a\u8fdb\u5165\u4e0d\u540c\u754c\u9762\uff0c\u8bf7\u6839\u636e\u5c4f\u5e55\u63d0\u793a\u64cd\u4f5c\u3002"),
|
||||||
-1,
|
-1,
|
||||||
&rulesBody,
|
&rulesBody,
|
||||||
@@ -699,10 +699,18 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(178), growthText, lstrlen(growthText));
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(178), growthText, lstrlen(growthText));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rogueStats.luckyRollLevel > 0)
|
int tunedPieces = 0;
|
||||||
|
for (int pieceType = 0; pieceType < 7; pieceType++)
|
||||||
|
{
|
||||||
|
if (rogueStats.pieceTuningLevels[pieceType] > 0)
|
||||||
|
{
|
||||||
|
tunedPieces++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (tunedPieces > 0)
|
||||||
{
|
{
|
||||||
TCHAR luckyText[96];
|
TCHAR luckyText[96];
|
||||||
_stprintf_s(luckyText, _T("\u6539\u8fd0\u91cd\u63b7 %d \u6b21"), rogueStats.luckyRollLevel > 3 ? 3 : rogueStats.luckyRollLevel);
|
_stprintf_s(luckyText, _T("\u65b9\u5757\u6539\u9020 %d \u79cd\u5df2\u8c03\u6574"), tunedPieces);
|
||||||
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(210), luckyText, lstrlen(luckyText));
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(210), luckyText, lstrlen(luckyText));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -710,11 +718,11 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
{
|
{
|
||||||
TCHAR gamblerText[96];
|
TCHAR gamblerText[96];
|
||||||
int variance = 20 + (rogueStats.gamblerLevel - 1) * 10;
|
int variance = 20 + (rogueStats.gamblerLevel - 1) * 10;
|
||||||
if (variance > 50)
|
if (variance > 40)
|
||||||
{
|
{
|
||||||
variance = 50;
|
variance = 40;
|
||||||
}
|
}
|
||||||
_stprintf_s(gamblerText, _T("\u8d4c\u5f92\u6ce2\u52a8 \u00b1%d%%"), variance);
|
_stprintf_s(gamblerText, _T("\u8d4c\u5f92\u6982\u7387 \u53cc\u500d/%u\u6548 %d%%"), variance, variance);
|
||||||
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(242), gamblerText, lstrlen(gamblerText));
|
TextOut(hdc, combatRect.left + SS(18), combatRect.top + SS(242), gamblerText, lstrlen(gamblerText));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,9 +796,24 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
{
|
{
|
||||||
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u53cc\u500d\u6210\u957f Lv.%d\r\n"), rogueStats.doubleGrowthLevel);
|
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u53cc\u500d\u6210\u957f Lv.%d\r\n"), rogueStats.doubleGrowthLevel);
|
||||||
}
|
}
|
||||||
if (rogueStats.luckyRollLevel > 0)
|
int tunedPieceCount = 0;
|
||||||
|
for (int pieceType = 0; pieceType < 7; pieceType++)
|
||||||
{
|
{
|
||||||
_stprintf_s(upgradeSummary + lstrlen(upgradeSummary), 512 - lstrlen(upgradeSummary), _T("\u65b9\u5757\u6539\u8fd0 Lv.%d\r\n"), rogueStats.luckyRollLevel);
|
if (rogueStats.pieceTuningLevels[pieceType] > 0)
|
||||||
|
{
|
||||||
|
tunedPieceCount++;
|
||||||
|
_stprintf_s(
|
||||||
|
upgradeSummary + lstrlen(upgradeSummary),
|
||||||
|
512 - lstrlen(upgradeSummary),
|
||||||
|
_T("%s \u65b9\u5757\u6539\u9020 Lv.%d\r\n"),
|
||||||
|
(pieceType == 0 ? _T("I") :
|
||||||
|
pieceType == 1 ? _T("T") :
|
||||||
|
pieceType == 2 ? _T("L") :
|
||||||
|
pieceType == 3 ? _T("J") :
|
||||||
|
pieceType == 4 ? _T("O") :
|
||||||
|
pieceType == 5 ? _T("S") : _T("Z")),
|
||||||
|
rogueStats.pieceTuningLevels[pieceType]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (rogueStats.gamblerLevel > 0)
|
if (rogueStats.gamblerLevel > 0)
|
||||||
{
|
{
|
||||||
@@ -1108,22 +1131,26 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
DrawText(hdc, _T("\u8bf7\u4ece\u4e09\u4e2a\u9009\u9879\u4e2d\u9009\u62e9\u4e00\u4e2a\u5f3a\u5316"), -1, &overlaySubtitleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
DrawText(hdc, _T("\u8bf7\u4ece\u4e09\u4e2a\u9009\u9879\u4e2d\u9009\u62e9\u4e00\u4e2a\u5f3a\u5316"), -1, &overlaySubtitleRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||||
|
|
||||||
int gap = SS(18);
|
int gap = SS(18);
|
||||||
int cardWidth = (overlayRect.right - overlayRect.left - SS(72) - gap * 2) / 3;
|
int horizontalPadding = SS(36);
|
||||||
int cardTop = overlayRect.top + SS(138);
|
int verticalTop = overlayRect.top + SS(138);
|
||||||
int cardBottom = overlayRect.bottom - SS(72);
|
int cardWidth = (overlayRect.right - overlayRect.left - horizontalPadding * 2 - gap) / 2;
|
||||||
|
int cardHeight = (overlayRect.bottom - verticalTop - SS(72) - gap) / 2;
|
||||||
|
|
||||||
for (int i = 0; i < upgradeUiState.optionCount; i++)
|
for (int i = 0; i < upgradeUiState.optionCount; i++)
|
||||||
{
|
{
|
||||||
bool isSelected = (i == upgradeUiState.selectedIndex);
|
bool isSelected = (i == upgradeUiState.selectedIndex);
|
||||||
int left = overlayRect.left + SS(36) + i * (cardWidth + gap);
|
int column = i % 2;
|
||||||
|
int row = i / 2;
|
||||||
|
int left = overlayRect.left + horizontalPadding + column * (cardWidth + gap);
|
||||||
|
int top = verticalTop + row * (cardHeight + gap);
|
||||||
int right = left + cardWidth;
|
int right = left + cardWidth;
|
||||||
|
|
||||||
RECT cardRect =
|
RECT cardRect =
|
||||||
{
|
{
|
||||||
left,
|
left,
|
||||||
cardTop,
|
top,
|
||||||
right,
|
right,
|
||||||
cardBottom
|
top + cardHeight
|
||||||
};
|
};
|
||||||
|
|
||||||
HBRUSH cardBrush = CreateSolidBrush(isSelected ? RGB(255, 235, 242) : RGB(255, 247, 250));
|
HBRUSH cardBrush = CreateSolidBrush(isSelected ? RGB(255, 235, 242) : RGB(255, 247, 250));
|
||||||
@@ -1219,7 +1246,7 @@ void TDrawScreen(HDC hdc, HWND hWnd)
|
|||||||
overlayRect.right - SS(30),
|
overlayRect.right - SS(30),
|
||||||
overlayRect.bottom - SS(18)
|
overlayRect.bottom - SS(18)
|
||||||
};
|
};
|
||||||
DrawText(hdc, _T("A / D \u6216\u65b9\u5411\u952e\u5207\u6362\uff0cEnter \u6216 Space \u786e\u8ba4"), -1, &hintRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
DrawText(hdc, _T("W/A/S/D \u6216\u65b9\u5411\u952e\u5207\u6362\uff0cEnter \u6216 Space \u786e\u8ba4"), -1, &hintRect, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
|
||||||
}
|
}
|
||||||
|
|
||||||
SelectObject(hdc, oldFont);
|
SelectObject(hdc, oldFont);
|
||||||
|
|||||||
Reference in New Issue
Block a user