一、TDM-GCC(MinGW 类编译器)下载安装步骤
下载 TDM-GCC(MinGW 类编译器)的步骤很简单,按以下流程操作即可:
步骤 1:访问官方下载页
打开浏览器,进入 TDM-GCC 的官方下载地址: https://jmeubank.github.io/tdm-gcc/articles/2021-05/10.3.0-release
本文介绍了在 Windows 环境下安装 TDM-GCC 编译器、配置 VS Code 智能提示以及使用 CMake 构建 C++ 游戏的完整流程。内容包括环境变量设置、头文件路径配置、CMakeLists.txt 编写及编译运行验证,附带一个基于控制台的角色扮演游戏示例代码。

下载 TDM-GCC(MinGW 类编译器)的步骤很简单,按以下流程操作即可:
打开浏览器,进入 TDM-GCC 的官方下载地址: https://jmeubank.github.io/tdm-gcc/articles/2021-05/10.3.0-release
64 位 Windows 系统(主流):选择 tdm64-gcc-xxx.exe(比如 tdm64-gcc-10.3.0-2.exe,版本号可能更新);32 位系统:选择 tdm-gcc-xxx.exe。 可选'在线安装包'(体积小,需联网)或'离线安装包'(体积大,无需联网),直接点击对应安装包开始下载。
选择安装路径(建议默认 C:\TDM-GCC-64,或自定义路径,注意路径不要有中文);关键:勾选'Add to PATH'选项(自动将编译器添加到系统环境变量,后续可直接在命令行调用);点击'Install'完成安装。
双击下载好的.exe 文件,启动安装向导。
打开命令提示符(CMD),输入以下命令:
gcc --version
如果显示类似 gcc (TDM-GCC) 10.3.0 的信息,说明安装成功。
若安装时未勾选'Add to PATH'选项,需手动配置环境变量,具体操作如下:
找到你安装 TDM-GCC 的目录,若为默认文件夹名称,典型路径为 D:\\TDM-GCC-64(64 位系统)或 D:\\TDM-GCC(32 位系统);若你自定义了安装文件夹名称,需记准实际完整路径。关键是找到该目录下的 bin 子文件夹(完整路径示例:D:\\TDM-GCC-64\\bin 或 D:\\Programs\\TDM-GCC-64\\bin),后续需将此 bin 路径添加到环境变量中。
方法一(常规操作):右键点击'此电脑' → 选择'属性' → 点击'高级系统设置' → 在弹出的窗口中切换到'高级'选项卡 → 点击右下角的'环境变量'。
方法二(快捷方式):按 Win + R 键打开'运行'窗口,输入 sysdm.cpl 并回车,直接进入'系统属性'窗口,再按上述步骤点击'环境变量'即可。
在'环境变量'窗口中,分为'用户变量'和'系统变量'两部分,建议编辑'系统变量'(对所有用户生效,需管理员权限);在'系统变量'列表中,找到名为 Path 的变量,选中后点击'编辑'按钮;在弹出的'编辑环境变量'窗口中,点击'新建' → 输入第二步确认的 TDM-GCC 的 bin 文件夹完整路径(示例:D:\\TDM-GCC-64\\bin 或 D:\\Programs\\TDM-GCC-64\\bin);点击'确定'保存当前编辑,再逐级点击所有打开窗口的'确定'按钮,完成环境变量配置。
重启命令提示符(CMD)(若已打开需关闭重新打开),再次输入以下命令验证:
gcc --version
若能正常显示 GCC 版本信息,说明环境变量配置成功;若仍提示'gcc 不是内部或外部命令',需检查添加的路径是否正确,或重新确认安装目录下的 bin 文件夹是否存在。
注意事项:环境变量修改后,需重启已打开的终端或相关程序才能生效;添加路径时需注意区分中英文符号,路径中不能有空格或中文,否则会导致配置失效;若仅需对当前用户生效,可编辑'用户变量'中的 Path 变量,操作步骤与编辑系统变量一致,无需管理员权限。
若在 VS Code 中编写 C++ 代码时,出现红色波浪线(非导入语句问题),大概率是 C++ 智能提示(IntelliSense)未找到系统头文件路径导致的。需配置 C++ 扩展的 includePath(头文件搜索路径),具体步骤如下:
若尚未完成编译器安装和环境变量配置,需先完成以下操作:下载 TDM-GCC 编译器,按前文步骤安装在 D 盘(记准安装路径,如 D:\\TDM-GCC-64);将编译器的 bin 目录(如 D:\\TDM-GCC-64\\bin)添加到系统环境变量 Path 中,完成后重启 VS Code。
进入配置页面后,按以下要求设置参数:
D:\\TDM-GCC-64\\include, D:\\TDM-GCC-64\\include\\c++\\12.2.0, D:\\TDM-GCC-64\\include\\c++\\12.2.0\\x86_64-w64-mingw32。说明:版本号(如 12.2.0)、架构名(如 x86_64-w64-mingw32)需对应你安装的 TDM-GCC 实际情况,可进入 D 盘 TDM-GCC 安装目录下的 include 文件夹查看具体路径。g++.exe 路径(示例:D:\\TDM-GCC-64\\bin\\g++.exe)。在 VS Code 中按下快捷键 Ctrl+Shift+P,在弹出的命令面板中输入并选择 'C/C++: 编辑配置 (UI)'。
上述配置会自动保存到当前项目的 .vscode/c_cpp_properties.json 文件中。配置完成后,重启 VS Code,红色波浪线即可消失,此时 IntelliSense 能正常找到系统头文件。
CMake 可自动生成适配 TDM-GCC 的构建文件(Makefile),实现代码的编译打包。以下是完整步骤,适配你 D 盘安装的 TDM-GCC 编译器及当前游戏代码特性(含 Windows 控制台 API、跨平台清屏等):
整理代码文件:将你提供的游戏代码保存为 game.cpp,并放在单独的项目目录中(示例:D:\\C++Projects\\CastleGame,路径无中文、无空格)。重点注意确认 TDM-GCC 路径:记准你 D 盘 TDM-GCC 的安装目录(示例:D:\\TDM-GCC-64),后续需在 CMake 中指定该编译器。
确认已安装 CMake:访问 CMake 官网 下载 Windows 版本(建议选择'Windows x64 Installer'),安装时勾选'Add CMake to the system PATH'(自动添加环境变量),完成后重启命令行。
在项目目录(D:\\C++Projects\\CastleGame)中,新建一个名为 CMakeLists.txt 的文件(无后缀),复制以下内容并根据实际路径修改:
cmake_minimum_required(VERSION 3.10)
project(CastleGame)
set(CMAKE_CXX_COMPILER "D:/TDM-GCC-64/bin/gcc.exe")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++17")
add_executable(CastleGame game.cpp user32.lib)
说明:
D:/TDM-GCC-64/bin/gcc.exe 需替换为你实际的路径(注意路径分隔符用'/'或双反斜杠'\\');user32.lib 是 Windows 系统库,用于控制台颜色控制等功能,必须添加否则会编译失败;add_executable 的第一个参数 CastleGame 是最终生成的 exe 文件名,可自定义(如 城堡密宝.exe)。通过命令行执行以下步骤,或使用 CMake GUI 操作(适合不熟悉命令行的用户),两种方式任选其一:
方式一:命令行操作(推荐,简洁高效)
打开命令提示符(CMD),进入项目目录:cd /d D:\\C++Projects\\CastleGame
创建构建目录(建议单独创建 build 目录,避免生成文件混乱):mkdir build && cd build
执行 CMake 生成 Makefile(基于 TDM-GCC):cmake -G "MinGW Makefiles" ..
说明:-G "MinGW Makefiles" 指定生成适配 MinGW(TDM-GCC)的 Makefile,'..'表示 CMakeLists.txt 在上级目录。若执行成功,会在 build 目录下生成 Makefile 等文件。
编译生成 exe 文件:mingw32-make
说明:mingw32-make 是 TDM-GCC 的编译命令,执行后会自动编译 game.cpp 并链接库,最终在 build 目录下生成 CastleGame.exe(或你自定义的名称)。
编译成功后,进入 build 目录,找到生成的 CastleGame.exe(或自定义名称);双击运行 exe,若能正常显示游戏开场界面、响应键盘操作(W/A/S/D 移动等),说明打包成功;若运行时提示'缺少 libgcc_s_seh-1.dll'等错误:
D:\\TDM-GCC-64\\bin)添加到系统环境变量 Path(前文已补充该步骤),重启 exe 即可;libgcc_s_seh-1.dll、libstdc++-6.dll、libwinpthread-1.dll 三个文件复制到 exe 所在目录。注意事项:CMakeLists.txt 的文件名必须严格为 CMakeLists.txt(首字母大写,无后缀),否则 CMake 无法识别;若代码中新增了文件(如 utils.cpp),需在 add_executable 中补充文件名,示例:add_executable(CastleGame game.cpp utils.cpp);若需要生成 Release 版本(优化编译,体积更小),在执行 CMake 时添加参数:cmake -G "MinGW Makefiles" -DCMAKE_BUILD_TYPE=Release ..,再执行 mingw32-make;若编译失败,优先检查:① TDM-GCC 路径是否正确;② CMakeLists.txt 是否添加了 user32.lib;③ 代码中是否有语法错误。
#include <iostream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <algorithm>
#include <conio.h> // Windows Input
#include <cstdlib> // system("cls")
#include <ctime> // for rand()
#include <sstream> // for stringstream
#include <iomanip> // for setw
using namespace std;
// --- 跨平台清屏 ---
void clearScreen() {
system("cls"); // Windows 系统
// system("clear"); // Mac/Linux 系统
}
// --- 彩色输出宏 (Windows) ---
#ifdef _WIN32
#include <windows.h>
void setColor(int color) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), color);
}
#else
void setColor(int color) {
// Linux/Mac 使用 ANSI 颜色代码
const char* colors[] = { "\033[0m", // 0: 重置
"\033[31m", // 1: 红色
"\033[32m", // 2: 绿色
"\033[33m", // 3: 黄色
"\033[34m", // 4: 蓝色
"\033[35m", // 5: 紫色
"\033[36m", // 6: 青色
"\033[37m" // 7: 白色
};
if (color >= 0 && color <= 7) cout << colors[color];
}
#endif
// --- 艺术图案(移除 Unicode 表情符号)---
void drawArt(const string& type) {
setColor(6); // 青色
if (type == "hall") {
cout << R"(
===============================
| |
| [ 破 败 大 厅 ] |
| |
| \\ // |
| \\ // |
| \\_________// |
| |
| |
| |
|_________| |
===============================
)" << endl;
}
// ... (此处省略部分 drawArt 分支以保持篇幅,实际使用时保留完整代码)
setColor(7); // 重置为白色
}
// --- 数据结构 ---
struct Monster {
string name;
int hp;
int max_hp;
int attack;
int defense; // 新增防御力
int exp; // 击败后获得的经验值
int level; // 怪物等级 - 新增
string introMsg; // 遇敌台词
string deathMsg; // 死亡台词
vector<string> loot;
};
struct Player {
string location;
vector<string> inventory;
int hp = 30;
int max_hp = 30;
int attack = 5;
int defense = 2;
int level = 1;
int exp = 0;
int exp_to_next = 50;
int gold = 0;
string equippedWeapon = "无";
string equippedArmor = "无";
// 统计信息
int monsters_killed = 0;
int items_collected = 0;
int rooms_visited = 0;
};
struct Room {
string name;
string desc;
string artKey;
unordered_map<string, string> exits; // direction -> room id
unordered_set<string> items;
bool locked = false;
string keyName;
bool visited = false; // 是否已访问过
// 怪物系统
bool hasMonster = false;
Monster monster;
// 商店功能(可选)
bool isShop = false;
unordered_map<string, int> shopItems; // 物品名 -> 价格
};
struct Game {
unordered_map<string, Room> rooms;
Player player;
bool running = true;
bool won = false;
string currentQuest;
string message;
vector<string> log; // 游戏日志
// 添加日志
void addLog(const string& msg) {
log.push_back(msg);
if (log.size() > 10) log.erase(log.begin());
}
// 显示日志
void showLog() {
clearScreen();
cout << "=== 游戏日志 ===\n";
for (const auto& entry : log) {
cout << "- " << entry << endl;
}
cout << "\n按任意键返回...";
_getch();
}
// 初始化游戏
void init() {
srand(static_cast<unsigned int>(time(0))); // 修正 time_t 转换警告
// --- 剧情开场 ---
clearScreen();
setColor(3); // 青色
cout << "\n\n";
cout << " ==============================================\n";
cout << " == 城堡密宝:被诅咒的骑士 ==\n";
cout << " ==============================================\n\n";
setColor(7);
cout << " 传说,老男爵为了复活爱妻,与黑暗做了交易。\n";
cout << " 整个城堡在一夜之间陷入死寂,只剩徘徊的亡灵。\n";
cout << " 你作为一名猎魔人,推开了城堡沉重的大门……\n\n";
cout << " 你的目标:找到诅咒之源并终结它!\n";
cout << "\n 控制说明:\n";
cout << " - W/A/S/D: 移动\n";
cout << " - J: 拾取/互动\n";
cout << " - K: 背包\n";
cout << " - L: 查看状态\n";
cout << " - M: 地图\n";
cout << " - H: 帮助\n";
cout << " - Q: 退出游戏\n\n";
cout << " 按任意键开始命运的轮盘...";
_getch();
// --- 房间配置 ---
// (此处省略详细房间配置代码,实际使用时请保留完整 init 函数)
player.location = "hall";
player.inventory = { "potion" }; // 起始物品
player.rooms_visited = 1;
currentQuest = "探索大厅,寻找有用的物品。";
message = "小心,这里的黑暗不仅仅是缺少光亮。";
addLog("你进入了城堡大厅。");
render();
inputLoop();
}
// --- 经验与升级系统 ---
void gainExp(int amount) {
player.exp += amount;
addLog("获得 " + to_string(amount) + " 点经验值。");
// 检查升级
while (player.exp >= player.exp_to_next) {
levelUp();
}
}
void levelUp() {
player.level++;
player.exp -= player.exp_to_next;
player.exp_to_next = player.level * 50 + 25;
// 属性提升
player.max_hp += 10;
player.hp = player.max_hp; // 升级时回满血
player.attack += 2;
player.defense += 1;
clearScreen();
setColor(2); // 绿色
cout << "\n* 恭喜升级!*\n";
cout << "你现在是等级 " << player.level << "!\n";
cout << "生命值 +10,攻击力 +2,防御力 +1\n";
cout << "生命值已恢复!\n";
setColor(7);
cout << "\n按任意键继续...";
_getch();
addLog("升级到等级 " + to_string(player.level) + "!");
}
// --- 战斗系统 ---
void combatLoop(Monster& m) {
bool inCombat = true;
bool playerTurn = true; // 玩家先手
string combatLog = "战斗开始!\n" + m.introMsg;
while (inCombat && running) {
clearScreen();
cout << "========================================\n";
cout << " 战 斗\n";
cout << "========================================\n\n";
// 怪物状态
setColor(4); // 红色
cout << "敌人:" << m.name << " (Lv " << m.level << ")\n";
cout << "HP: [";
int bars = (m.hp * 20) / m.max_hp;
for (int i = 0; i < 20; ++i) {
if (i < bars) {
if (i < bars / 2) setColor(2); // 绿色
else setColor(3); // 黄色
cout << "#";
setColor(4);
} else {
cout << ".";
}
}
cout << "] " << m.hp << "/" << m.max_hp << "\n";
cout << "攻击力:" << m.attack << " 防御力:" << m.defense << "\n\n";
setColor(7); // 玩家状态
setColor(3); // 青色
cout << "猎魔人 (等级 " << player.level << ")\n";
cout << "HP: [";
bars = (player.hp * 20) / player.max_hp;
for (int i = 0; i < 20; ++i) {
if (i < bars) {
if (i < bars / 2) setColor(2); // 绿色
else setColor(3); // 黄色
cout << "#";
setColor(3);
} else {
cout << ".";
}
}
cout << "] " << player.hp << "/" << player.max_hp << "\n";
cout << "攻击力:" << player.attack << " 防御力:" << player.defense << "\n";
cout << "经验值:" << player.exp << "/" << player.exp_to_next << "\n\n";
setColor(7);
// 战斗日志
cout << "----------------------------------------\n";
cout << "战斗日志:\n";
cout << combatLog << "\n";
cout << "----------------------------------------\n";
if (playerTurn) {
cout << "[J] 攻击 [K] 防御\n";
cout << "[L] 物品 [F] 逃跑\n";
char c = _getch();
c = tolower(c);
if (c == 'j') {
// 攻击
int baseDmg = player.attack + (rand() % 4);
int actualDmg = max(1, baseDmg - m.defense);
m.hp -= actualDmg;
if (m.hp > 0) {
combatLog = "你对 " + m.name + " 造成 " + to_string(actualDmg) + " 点伤害!";
playerTurn = false;
} else {
combatLog = "致命一击!你对 " + m.name + " 造成 " + to_string(actualDmg) + " 点伤害!";
}
} else if (c == 'k') {
// 防御(下一回合减少 50% 伤害)
combatLog = "你采取防御姿态,下一回合受到的伤害减半!";
playerTurn = false;
} else if (c == 'l') {
// 使用物品
if (useItemInCombat()) {
playerTurn = false;
}
continue; // 重新显示战斗界面
} else if (c == 'f') {
// 逃跑(成功率 70%)
if (rand() % 100 < 70) {
combatLog = "你成功逃离了战斗!";
cout << "\n" << combatLog;
_getch();
return;
} else {
combatLog = "逃跑失败!怪物拦住了你的去路!";
playerTurn = false;
}
}
}
// 怪物回合
if (!playerTurn && m.hp > 0) {
int baseDmg = m.attack + (rand() % 3);
int actualDmg = max(1, baseDmg - player.defense);
player.hp -= actualDmg;
combatLog += "\n" + m.name + " 对你造成 " + to_string(actualDmg) + " 点伤害!";
playerTurn = true;
}
// 检查战斗结果
if (player.hp <= 0) {
inCombat = false;
running = false;
won = false;
addLog("你被 " + m.name + " 击败了...");
clearScreen();
drawArt("gameover");
cout << "\nX 你被 " << m.name << " 击杀了……\n";
cout << "你的冒险在此终结。\n\n";
cout << "统计信息:\n";
cout << " 等级:" << player.level << "\n";
cout << " 击杀怪物:" << player.monsters_killed << "\n";
cout << " 收集物品:" << player.items_collected << "\n";
cout << " 探索房间:" << player.rooms_visited << "\n";
cout << " 获得金币:" << player.gold << "\n\n";
cout << "按任意键退出...";
_getch();
return;
} else if (m.hp <= 0) {
inCombat = false;
// 获得奖励
gainExp(m.exp);
player.monsters_killed++;
player.gold += m.exp / 2; // 一半经验值转化为金币
// 掉落物品
for (const auto& item : m.loot) {
rooms[player.location].items.insert(item);
}
// 清除怪物标记
rooms[player.location].hasMonster = false;
clearScreen();
cout << "\n* " << m.deathMsg << "\n";
cout << "获得 " << m.exp << " 经验值!\n";
cout << "获得 " << (m.exp / 2) << " 金币!\n";
if (!m.loot.empty()) {
cout << "怪物掉落了物品!\n";
}
cout << "\n按任意键继续...";
_getch();
addLog("击败了 " + m.name + "!");
updateQuest();
return;
}
}
}
// 战斗中使用的物品
bool useItemInCombat() {
clearScreen();
cout << "战斗中可使用的物品:\n";
cout << "----------------------------------------\n";
vector<string> usableItems;
for (const auto& item : player.inventory) {
if (item == "potion") {
cout << "[1] 治疗药水 - 恢复 20 点生命值\n";
usableItems.push_back(item);
}
}
if (usableItems.empty()) {
cout << "没有可用的物品!\n";
cout << "\n按任意键返回战斗...";
_getch();
return false;
}
cout << "\n输入物品编号 (0 返回): ";
char c = _getch();
if (c == '0') return false;
int idx = c - '1';
if (idx >= 0 && idx < usableItems.size()) {
string item = usableItems[idx];
if (item == "potion") {
player.hp = min(player.max_hp, player.hp + 20);
player.inventory.erase(find(player.inventory.begin(), player.inventory.end(), "potion"));
message = "使用治疗药水,恢复 20 点生命值!";
addLog("在战斗中使用治疗药水。");
return true;
}
}
return false;
}
// --- 任务系统 ---
void updateQuest() {
bool hasDiary = false;
bool hasKey = false;
bool hasSword = false;
bool hasNotes = false;
bool hasArmor = false;
for (auto& i : player.inventory) {
if (i == "old_diary") hasDiary = true;
if (i == "armory_key") hasKey = true;
if (i == "iron_sword") hasSword = true;
if (i == "research_notes") hasNotes = true;
if (i == "leather_armor") hasArmor = true;
}
Room& vault = rooms["vault"];
Room& storage = rooms["storage"];
// 根据游戏进度更新任务
if (player.location == "hall" && !hasSword) {
currentQuest = "探索大厅,寻找有用的物品。";
} else if (storage.hasMonster && player.location == "storage") {
currentQuest = "击败储藏室的食尸鬼!";
} else if (!hasSword) {
currentQuest = "去军械库寻找武器。";
} else if (!hasDiary) {
currentQuest = "去图书馆寻找男爵的日记。";
} else if (!hasKey) {
currentQuest = "根据日记线索,去军械库找密室钥匙。";
} else if (hasKey && vault.hasMonster) {
currentQuest = "前往封印之间,终结男爵的诅咒!";
} else if (!vault.hasMonster && vault.items.count("cursed_artifact")) {
currentQuest = "打开宝箱,拿走诅咒之源!";
} else if (player.inventory.end() != find(player.inventory.begin(), player.inventory.end(), "cursed_artifact")) {
currentQuest = "带着诅咒之源逃离城堡!";
}
}
// --- 渲染游戏界面 ---
void render() {
clearScreen();
// 顶部状态栏
setColor(6); // 黄色
cout << "==================================================\n";
cout << "城堡密宝:被诅咒的骑士";
cout << " 等级:" << player.level;
cout << " 金币:" << player.gold << "\n";
cout << "==================================================\n";
setColor(7);
// 任务显示
setColor(3); // 青色
cout << "任务:" << currentQuest << "\n";
cout << "--------------------------------------------------\n";
setColor(7);
// 玩家状态
cout << "HP: " << player.hp << "/" << player.max_hp << "\t";
cout << "攻击:" << player.attack << "\t";
cout << "防御:" << player.defense << "\n";
cout << "经验:" << player.exp << "/" << player.exp_to_next << "\t";
cout << "位置:" << rooms[player.location].name << "\n";
cout << "--------------------------------------------------\n";
// 房间描述和艺术图
Room& r = rooms[player.location];
if (!r.artKey.empty()) {
drawArt(r.artKey);
}
// 如果是第一次访问,显示特殊提示
if (!r.visited) {
setColor(2); // 绿色
cout << "【新区域】";
setColor(7);
r.visited = true;
if (player.location != "hall") {
player.rooms_visited++;
}
}
cout << r.desc << "\n\n";
// 显示物品
if (!r.items.empty()) {
setColor(2); // 绿色
cout << "发现物品:";
for (auto& it : r.items) {
cout << "[" << it << "] ";
}
cout << "\n";
setColor(7);
}
// 显示出口
cout << "\n出口:";
for (auto& exit : r.exits) {
string dir;
if (exit.first == "n") dir = "北";
else if (exit.first == "s") dir = "南";
else if (exit.first == "e") dir = "东";
else if (exit.first == "w") dir = "西";
else if (exit.first == "d") dir = "楼下";
else if (exit.first == "a") dir = "楼上";
else dir = exit.first;
// 检查门是否上锁
Room& targetRoom = rooms[exit.second];
if (targetRoom.locked) {
cout << "[" << dir << " - 锁定] ";
} else {
cout << "[" << dir << " - " << targetRoom.name << "] ";
}
}
cout << "\n";
// 显示怪物
if (r.hasMonster) {
setColor(4); // 红色
cout << "\n警告:" << r.monster.name << "在此房间!\n";
setColor(7);
}
// 消息区域
cout << "\n--------------------------------------------------\n";
if (!message.empty()) {
setColor(6); // 黄色
cout << message << "\n";
setColor(7);
}
cout << "--------------------------------------------------\n";
// 控制提示
cout << "[W/A/S/D] 移动 [J] 拾取/互动 [K] 背包 [L] 状态\n";
cout << "[M] 地图 [H] 帮助 [Q] 退出 [G] 日志\n";
}
// --- 显示地图 ---
void showMap() {
clearScreen();
cout << "\n";
setColor(6);
cout << " 城 堡 地 图\n";
cout << " ================\n\n";
setColor(7);
// 简单的地图布局
cout << " [书房] \n";
cout << " | \n";
cout << " [图书馆]---[封印之间] (BOSS)\n";
cout << " | \n";
cout << "[储藏室]---[走廊]---[大厅]---[军械库]\n";
cout << " |\n";
cout << " [楼上]\n\n";
// 当前位置标记
cout << "你当前在:";
setColor(2);
cout << rooms[player.location].name;
setColor(7);
cout << "\n\n";
// 图例
cout << "图例:可探索 怪物 上锁 宝藏\n\n";
cout << "按任意键返回...";
_getch();
}
// --- 拾取物品 ---
void takeAction() {
Room& r = rooms[player.location];
if (r.items.empty()) {
message = "这里没什么可拿的。";
return;
}
// 复制物品列表以便迭代
vector<string> itemsToTake(r.items.begin(), r.items.end());
for (const string& item : itemsToTake) {
player.inventory.push_back(item);
player.items_collected++;
// 特殊物品效果
if (item == "iron_sword") {
player.attack += 5;
player.equippedWeapon = "铁剑";
message = "你装备了【铁剑】!攻击力 +5!";
drawArt("sword");
addLog("获得了铁剑,攻击力提升。");
} else if (item == "leather_armor") {
player.defense += 3;
player.equippedArmor = "皮甲";
message = "你装备了【皮甲】!防御力 +3!";
addLog("获得了皮甲,防御力提升。");
} else if (item == "potion") {
message = "获得【治疗药水】x1";
drawArt("potion");
} else if (item == "old_diary") {
message = "获得【男爵的日记】,记录了诅咒的秘密...";
addLog("找到了男爵的日记。");
} else if (item == "gold_coin") {
player.gold += 10;
message = "获得 10 金币!";
} else {
message = "拾取了:" + item;
}
// 从房间移除
r.items.erase(item);
}
updateQuest();
}
// --- 使用物品 ---
void useAction() {
if (player.inventory.empty()) {
message = "背包是空的。";
return;
}
clearScreen();
cout << "背 包 物 品 (" << player.inventory.size() << "/20)\n";
cout << "========================================\n";
// 统计同类物品
unordered_map<string, int> itemCounts;
for (const auto& item : player.inventory) {
itemCounts[item]++;
}
// 显示物品列表
int index = 1;
unordered_map<int, string> indexToItem;
for (const auto& pair : itemCounts) {
cout << " [" << index << "] " << pair.first;
if (pair.second > 1) {
cout << " x" << pair.second;
}
cout << "\n";
indexToItem[index] = pair.first;
index++;
}
cout << "\n [0] 返回\n";
cout << "========================================\n";
cout << "输入物品编号使用:";
char c = _getch();
if (c == '0') return;
int idx = c - '0';
if (idx > 0 && idx < index) {
string item = indexToItem[idx];
applyItem(item);
}
}
void applyItem(const string& item) {
if (item == "potion") {
int healAmount = 20;
player.hp = min(player.max_hp, player.hp + healAmount);
// 从背包移除
auto it = find(player.inventory.begin(), player.inventory.end(), "potion");
if (it != player.inventory.end()) {
player.inventory.erase(it);
}
message = "使用治疗药水,恢复" + to_string(healAmount) + "点生命值!";
drawArt("potion");
addLog("使用了治疗药水。");
} else if (item == "torch") {
message = "火把照亮了周围,但这里似乎没什么特别的。";
addLog("使用了火把。");
} else if (item == "old_diary") {
clearScreen();
cout << "男爵的日记(节选)\n";
cout << "========================================\n";
cout << "...我无法忍受失去她的痛苦。\n";
cout << "那个黑暗的存在承诺可以让她回来...\n";
cout << "但我现在明白了,那是个可怕的错误。\n";
cout << "诅咒已经扩散,我无法控制它了...\n";
cout << "钥匙在军械库,真相在书房...\n";
cout << "如果有人找到这本日记,请阻止我...\n";
cout << "========================================\n\n";
cout << "按任意键继续...";
_getch();
message = "日记揭示了城堡的秘密...";
addLog("阅读了男爵的日记。");
} else {
message = "这个物品无法直接使用。";
}
}
// --- 显示状态 ---
void showStatus() {
clearScreen();
setColor(6);
cout << "\n 玩 家 状 态\n";
cout << " ================\n\n";
setColor(7);
cout << " 等级:" << player.level << "\n";
cout << " 经验:" << player.exp << "/" << player.exp_to_next << "\n";
cout << " 生命:" << player.hp << "/" << player.max_hp << "\n";
cout << " 攻击:" << player.attack << "\n";
cout << " 防御:" << player.defense << "\n";
cout << " 金币:" << player.gold << "\n\n";
cout << " 装备武器:" << player.equippedWeapon << "\n";
cout << " 装备防具:" << player.equippedArmor << "\n\n";
cout << " 统计信息:\n";
cout << " - 击杀怪物:" << player.monsters_killed << "\n";
cout << " - 收集物品:" << player.items_collected << "\n";
cout << " - 探索房间:" << player.rooms_visited << "\n";
cout << "\n按任意键返回...";
_getch();
}
// --- 移动系统 ---
void movePlayer(const string& direction) {
Room& current = rooms[player.location];
if (current.exits.count(direction)) {
string targetRoom = current.exits[direction];
Room& target = rooms[targetRoom];
// 检查门是否上锁
if (target.locked) {
// 检查是否有钥匙
bool hasKey = false;
for (const auto& item : player.inventory) {
if (item == target.keyName) {
hasKey = true;
break;
}
}
if (hasKey) {
target.locked = false;
message = "使用 " + target.keyName + " 打开了门!";
addLog("打开了 " + target.name + " 的门。");
} else {
message = "门被锁住了。需要:" + target.keyName;
return;
}
}
// 检查是否有怪物(BOSS 房间特殊提示)
if (target.hasMonster && target.artKey == "vault") {
clearScreen();
drawArt("vault");
cout << "\n警告:前方传来强大的邪恶气息!\n";
cout << "这是最终之战,准备好了吗?\n";
cout << "\n[1] 进入挑战 [2] 再准备一下\n";
char c = _getch();
if (c != '1') {
message = "你决定再准备一下...";
return;
}
}
// 执行移动
player.location = targetRoom;
addLog("进入了 " + target.name);
// 如果房间有怪物,进入战斗
if (target.hasMonster) {
combatLoop(target.monster);
if (!running) return; // 如果玩家死亡,结束游戏
}
updateQuest();
} else {
message = "这个方向没有路。";
}
}
// --- 输入循环 ---
void inputLoop() {
while (running) {
render();
char input = _getch();
input = tolower(input);
switch (input) {
case 'w': movePlayer("n"); break;
case 's': movePlayer("s"); break;
case 'a': movePlayer("w"); break;
case 'd': movePlayer("e"); break;
case 'j': {
Room& r = rooms[player.location];
if (r.hasMonster) {
combatLoop(r.monster);
} else {
takeAction();
}
} break;
case 'k': useAction(); break;
case 'l': showStatus(); break;
case 'm': showMap(); break;
case 'h': {
clearScreen();
cout << "\n=== 游戏帮助 ===\n\n";
cout << "目标:探索城堡,击败怪物,最终解除诅咒。\n\n";
cout << "基本控制:\n";
cout << " W/A/S/D - 移动 (北/西/南/东)\n";
cout << " J - 拾取物品/与怪物战斗\n";
cout << " K - 打开背包使用物品\n";
cout << " L - 查看玩家状态\n";
cout << " M - 查看地图\n";
cout << " G - 查看游戏日志\n";
cout << " H - 显示帮助\n";
cout << " Q - 退出游戏\n\n";
cout << "战斗系统:\n";
cout << " - 攻击 (J): 对敌人造成伤害\n";
cout << " - 防御 (K): 减少受到的伤害\n";
cout << " - 物品 (L): 使用背包中的物品\n";
cout << " - 逃跑 (F): 尝试逃离战斗\n\n";
cout << "按任意键返回...";
_getch();
} break;
case 'g': showLog(); break;
case 'q': {
clearScreen();
cout << "\n确定要退出游戏吗?(Y/N): ";
char confirm = _getch();
if (tolower(confirm) == 'y') {
running = false;
cout << "\n游戏已保存。再见!\n";
_getch();
}
} break;
}
// 检查胜利条件
checkWinCondition();
}
}
// --- 检查胜利条件 ---
void checkWinCondition() {
// 如果获得了诅咒之源并回到大厅
if (find(player.inventory.begin(), player.inventory.end(), "cursed_artifact") != player.inventory.end() && player.location == "hall") {
won = true;
running = false;
clearScreen();
drawArt("victory");
setColor(2);
cout << "\n恭喜!你成功解除了城堡的诅咒!\n\n";
setColor(7);
cout << "你带着诅咒之源逃离了城堡,\n";
cout << "这片土地终于恢复了平静。\n\n";
cout << "=== 最终统计 ===\n";
cout << " 最终等级:" << player.level << "\n";
cout << " 击杀怪物:" << player.monsters_killed << "\n";
cout << " 收集物品:" << player.items_collected << "\n";
cout << " 探索房间:" << player.rooms_visited << "\n";
cout << " 获得金币:" << player.gold << "\n";
cout << " 游戏时间:约" << (player.rooms_visited * 2) << "分钟\n\n";
cout << "感谢游玩!按任意键退出...";
_getch();
}
}
};
// --- 主函数 ---
int main() {
// 设置控制台编码为 UTF-8 (Windows)
#ifdef _WIN32
SetConsoleOutputCP(65001);
#endif
Game game;
game.init();
return 0;
}

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online
通过删除不必要的空白来缩小和压缩JSON。 在线工具,JSON 压缩在线工具,online
将JSON字符串修饰为友好的可读格式。 在线工具,JSON美化和格式化在线工具,online