#include <iostream>
#include <vector>
#include <conio.h> // 用于 _getch()
#include <algorithm> // 用于 std::find_if
#include <cstdlib> // 用于 system(), rand()
#include <ctime> // 用于 time()
#include <cmath> // 用于 abs(), sin(), cos(), M_PI, fmod()
#include <string>
// --------------------
// 前置声明
// --------------------
struct Entity;
struct Pickup;
struct Weapon;
struct DestructibleObstacle;
void playCampaign(int campaign); // 战役 1-4(地图模式)
void playCampaign5(); // 战役 5(Panther 坦克模式)
// --------------------
// 数据结构(公共部分)
// --------------------
struct Entity {
int x, y;
int health;
char symbol;
};
struct Pickup {
int x, y;
char symbol;
int value; // 例如:生命回复
};
struct Weapon {
std::string name;
int range; // 有效射程(以网格为单位)
int ammo; // 当前弹夹中的子弹数量
int clipSize; // 弹夹容量
};
struct DestructibleObstacle {
int x, y;
int health;
char symbol;
};
int score = 0;
// --------------------
// 工具函数
// --------------------
float degToRad(float deg) {
return deg * M_PI / 180.0f;
}
// 计算两个角度之间的最小差值(单位:度)
float angleDiff(float a, float b) {
float diff = fabs(a - b);
return diff > 180 ? 360 - diff : diff;
}
// 打印生命条
void displayHealthBar(const std::string &name, int health, int maxHealth) {
int barWidth = 20;
int pos = (health * barWidth) / maxHealth;
std::cout << name << " 生命: [";
for (int i = 0; i < barWidth; i++) {
std::cout << (i < pos ? "#" : "-");
}
std::cout << "] " << health << "/" << maxHealth << std::endl;
}
// --------------------
// 战斗遭遇系统(用于战役 1-3)
// --------------------
bool battleEncounter(const std::string &battleName, int &playerHealth, int maxPlayerHealth, int enemyHealth) {
std::cout << "\n=== 战斗: " << battleName << " ===\n";
while (playerHealth > 0 && enemyHealth > 0) {
displayHealthBar("玩家", playerHealth, maxPlayerHealth);
std::cout << "敌人生命值: " << enemyHealth << std::endl;
std::cout << "按 's' 射击: ";
char action = _getch();
if (action == 's' || action == 'S') {
// 步枪伤害:10 到 60
int damage = 10 + rand() % 51;
std::cout << "\n你射击敌人,造成 " << damage << " 点伤害!\n";
enemyHealth -= damage;
if (enemyHealth <= 0) {
std::cout << "敌人被击败!\n";
break;
}
} else {
std::cout << "\n输入错误,失去射击机会!\n";
}
int enemyDamage = 10 + rand() % 6; // 10-15伤害
std::cout << "敌人反击,造成 " << enemyDamage << " 点伤害!\n";
playerHealth -= enemyDamage;
if (playerHealth <= 0) {
std::cout << "在战斗 " << battleName << " 中你被击败了!\n";
return false;
}
}
return true;
}
bool battleBunker(Entity &bunker, int &playerHealth) {
int bunkerMaxHealth = bunker.health;
std::cout << "\n开始进攻掩体(坐标: " << bunker.x << "," << bunker.y << "),掩体生命值: " << bunker.health << "\n";
while (bunker.health > 0 && playerHealth > 0) {
displayHealthBar("玩家", playerHealth, 150);
displayHealthBar("掩体", bunker.health, bunkerMaxHealth);
std::cout << "按 's' 射击掩体: ";
char action = _getch();
if (action == 's' || action == 'S') {
int damage = 10 + rand() % 51; // 10-60伤害
std::cout << "\n你射击掩体,造成 " << damage << " 点伤害!\n";
bunker.health -= damage;
if (bunker.health <= 0) {
std::cout << "掩体被摧毁并占领!\n";
return true;
}
} else {
std::cout << "\n输入错误,失去射击机会!\n";
}
int turretDamage = 5 + rand() % 6; // 5-10伤害
std::cout << "掩体炮塔开火,造成 " << turretDamage << " 点伤害!\n";
playerHealth -= turretDamage;
if (playerHealth <= 0) {
std::cout << "你被掩体防御击杀了!\n";
return false;
}
}
return true;
}
// --------------------
// 地图模式(战役 1-4)
// --------------------
void render(const std::vector<std::vector<char>> &baseMap,
const Entity &player,
const std::vector<Entity> &enemies,
const std::vector<Pickup> &pickups,
const std::vector<Entity> &bunkers,
const Weapon &weapon) {
system("cls");
std::vector<std::vector<char>> displayMap = baseMap;
for (const auto &p : pickups)
displayMap[p.y][p.x] = p.symbol;
for (const auto &b : bunkers)
displayMap[b.y][b.x] = b.symbol;
for (const auto &e : enemies)
displayMap[e.y][e.x] = e.symbol;
displayMap[player.y][player.x] = player.symbol;
for (const auto &row : displayMap) {
for (char c : row)
std::cout << c << ' ';
std::cout << std::endl;
}
std::cout << "玩家生命值: " << player.health;
if (player.health < 30)
std::cout << " [警告: 生命值过低]";
std::cout << "\n得分: " << score;
std::cout << "\n武器: " << weapon.name << " | 子弹: " << weapon.ammo << "/" << weapon.clipSize << std::endl;
std::cout << "\n操作提示:\n 移动: w/a/s/d 以及对角 (q, e, z, c)\n 射击: i/j/k/l (分别代表 上/左/下/右)\n 手雷: g 装弹: r" << std::endl;
}
void addObstacles(std::vector<std::vector<char>> &baseMap, int count) {
int height = baseMap.size(), width = baseMap[0].size();
int placed = 0;
while (placed < count) {
int x = rand() % width, y = rand() % height;
if (baseMap[y][x] == '.') {
baseMap[y][x] = '#';
placed++;
}
}
}
// --------------------
// 辅助函数:根据坦克角度返回显示符号
// --------------------
char getTankSymbol(float angle) {
angle = fmod(angle, 360.0f);
if (angle < 0) angle += 360.0f;
if (angle < 45 || angle >= 315) return '>';
else if (angle < 135) return '^';
else if (angle < 225) return '<';
else return 'v';
}
// --------------------
// 战役5:德国亚丁攻势(Panther 坦克突击)
// --------------------
struct Tank {
float x, y;
float angle; // 0 表示向右,逆时针增加
float speed;
int health;
};
void addObstaclesDestructible(std::vector<std::vector<char>> &grid, std::vector<DestructibleObstacle> &obs, int count) {
int height = grid.size(), width = grid[0].size();
int placed = 0;
while (placed < count) {
int x = rand() % width, y = rand() % height;
if (grid[y][x] == '.') {
grid[y][x] = '#';
obs.push_back({x, y, 100, '#'}); // 每个障碍物 100 点生命
placed++;
}
}
}
// --------------------
// 战役 1-4 的主函数(地图模式)
// --------------------
void playCampaign(int campaign) {
const int MAP_WIDTH = 10, MAP_HEIGHT = 10;
std::vector<std::vector<char>> baseMap(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
addObstacles(baseMap, 10);
// 为降低难度,玩家初始生命值增加到150
Entity player = {5, 9, 150, 'P'};
std::vector<Entity> enemies;
std::vector<Pickup> pickups;
// 步枪伤害公式:10 + rand() % 51(10~60)
Weapon weapon = {"步枪", 6, 6, 6};
std::vector<Entity> bunkers;
if (campaign == 1) {
std::cout << "任务简报: 诺曼底登陆 - 占领海岸的敌人掩体。\n";
bunkers.push_back({3, 0, 50, 'B'});
bunkers.push_back({7, 0, 50, 'B'});
baseMap[0][3] = 'B';
baseMap[0][7] = 'B';
enemies = { {3,3,50,'E'}, {7,3,50,'E'}, {5,5,50,'E'} };
pickups.push_back({2,6,'M',20});
}
else if (campaign == 2) {
std::cout << "任务简报: 亚丁攻势 - 顽抗敌军!\n";
enemies = { {2,2,50,'E'}, {4,3,50,'E'}, {6,2,50,'E'}, {3,4,50,'E'}, {7,4,50,'E'} };
pickups.push_back({1,8,'M',20});
}
else if (campaign == 3) {
std::cout << "任务简报: 柏林进攻 - 深入敌后,占领旗帜!\n";
baseMap[0][5] = 'F';
enemies = { {4,2,50,'E'}, {6,2,50,'E'}, {5,4,50,'E'}, {3,3,50,'E'} };
pickups.push_back({8,7,'M',20});
}
else if (campaign == 4) {
std::cout << "德国诺曼底任务:在战壕中使用机枪防御10波盟军进攻,与你的NPC战友协同作战。\n";
player.health = 150;
// 提高战友生命值
std::vector<Entity> teammates = { {4,9,120,'T'}, {6,9,120,'T'} };
int totalWaves = 10;
int baseEnemyCount = 3; // 基础敌人数量
int waveNumber = 1;
while (waveNumber <= totalWaves) {
std::cout << "\n--- 第 " << waveNumber << " 波 ---\n";
// 每 3 波增加 2 个敌人
int enemyCount = baseEnemyCount + ((waveNumber - 1) / 3) * 2;
std::vector<Entity> waveEnemies;
for (int i = 0; i < enemyCount; i++) {
// 敌人生命值随波数稍微提升
waveEnemies.push_back({rand() % MAP_WIDTH, 0, 40 + waveNumber * 5, 'A'});
}
while (!waveEnemies.empty() && player.health > 0) {
system("cls");
std::cout << "德国诺曼底 - 第 " << waveNumber << " 波 / 共 " << totalWaves << " 波\n";
displayHealthBar("玩家", player.health, 150);
for (size_t i = 0; i < teammates.size(); i++)
std::cout << "战友" << i+1 << " 生命值: " << teammates[i].health << "\n";
std::cout << "剩余攻击者: " << waveEnemies.size() << "\n";
std::cout << "请按方向键 (i/j/k/l) 选择机枪射击方向:";
char action = _getch();
int mdx = 0, mdy = 0;
if (action == 'i') { mdy = -1; }
else if (action == 'k') { mdy = 1; }
else if (action == 'j') { mdx = -1; }
else if (action == 'l') { mdx = 1; }
else { std::cout << "\n输入错误,本回合跳过。\n"; }
int shotX = player.x + mdx;
int shotY = player.y + mdy;
bool hit = false;
// 机枪伤害:25 到 50
for (int r = 0; r < 6 && !hit; r++) {
if (shotX < 0 || shotX >= MAP_WIDTH || shotY < 0 || shotY >= MAP_HEIGHT)
break;
auto it = std::find_if(waveEnemies.begin(), waveEnemies.end(), [shotX, shotY](const Entity &e){
return e.x == shotX && e.y == shotY;
});
if (it != waveEnemies.end()) {
int damage = 25 + rand() % 26;
it->health -= damage;
std::cout << "\n你使用机枪射击攻击者(" << shotX << "," << shotY << "),造成 " << damage << " 点伤害。\n";
if (it->health <= 0) {
waveEnemies.erase(it);
score += 100;
std::cout << "攻击者被消灭!(+100分)\n";
}
hit = true;
break;
}
shotX += mdx;
shotY += mdy;
}
// 战友自动射击
for (auto &tm : teammates) {
if (!waveEnemies.empty()) {
int targetIndex = rand() % waveEnemies.size();
int damage = 25 + rand() % 26;
waveEnemies[targetIndex].health -= damage;
std::cout << "战友射击,造成 " << damage << " 点伤害。\n";
if (waveEnemies[targetIndex].health <= 0) {
waveEnemies.erase(waveEnemies.begin() + targetIndex);
score += 100;
std::cout << "攻击者被战友击毙!(+100分)\n";
}
}
}
// 攻击者反击
for (auto &ae : waveEnemies) {
int dmg = 10 + rand() % 6; // 10-15伤害
if (!teammates.empty() && (rand() % 2 == 0)) {
int tIndex = rand() % teammates.size();
teammates[tIndex].health -= dmg;
std::cout << "攻击者射击战友" << tIndex+1 << ",造成 " << dmg << " 点伤害。\n";
if (teammates[tIndex].health <= 0) {
std::cout << "战友" << tIndex+1 << "阵亡!\n";
teammates.erase(teammates.begin() + tIndex);
}
} else {
player.health -= dmg;
std::cout << "攻击者射击你,造成 " << dmg << " 点伤害。\n";
}
}
std::cout << "\n按任意键进入本波下一回合...";
_getch();
if (player.health <= 0) break;
}
if (player.health <= 0) break;
// 每 3 波,为玩家补充 15 生命(上限150)
if (waveNumber % 3 == 0) {
int repair = 15;
player.health += repair;
if (player.health > 150) player.health = 150;
std::cout << " 你获得了坦克维修(+15 生命)!\n";
}
std::cout << "\n第 " << waveNumber << " 波清除!按任意键进入下一波...";
_getch();
waveNumber++;
}
if (player.health > 0)
std::cout << "\n所有波次已击退!德国诺曼底任务完成。\n";
else
std::cout << "\n你在战壕中被击溃。任务失败。\n";
return;
}
// 战役 1-3 常规地图模式循环
while (true) {
render(baseMap, player, enemies, pickups, bunkers, weapon);
char input = _getch();
int dx = 0, dy = 0;
bool isMove = false, isShoot = false, isGrenade = false, isReload = false;
if (input=='w') { dy = -1; isMove = true; }
else if (input=='s') { dy = 1; isMove = true; }
else if (input=='a') { dx = -1; isMove = true; }
else if (input=='d') { dx = 1; isMove = true; }
else if (input=='q') { dx = -1; dy = -1; isMove = true; }
else if (input=='e') { dx = 1; dy = -1; isMove = true; }
else if (input=='z') { dx = -1; dy = 1; isMove = true; }
else if (input=='c') { dx = 1; dy = 1; isMove = true; }
else if (input=='i') { dy = -1; isShoot = true; }
else if (input=='k') { dy = 1; isShoot = true; }
else if (input=='j') { dx = -1; isShoot = true; }
else if (input=='l') { dx = 1; isShoot = true; }
else if (input=='g') { isGrenade = true; }
else if (input=='r') { isReload = true; }
if (isMove) {
int newX = player.x + dx;
int newY = player.y + dy;
if (newX >= 0 && newX < MAP_WIDTH && newY >= 0 && newY < MAP_HEIGHT &&
(baseMap[newY][newX]=='.' || baseMap[newY][newX]=='B' || baseMap[newY][newX]=='F')) {
player.x = newX;
player.y = newY;
// 若是战役1,且走到Bunker,触发掩体战
if (campaign==1 && baseMap[newY][newX]=='B') {
auto it = std::find_if(bunkers.begin(), bunkers.end(), [newX,newY](const Entity &b){
return b.x==newX && b.y==newY;
});
if (it != bunkers.end()) {
bool survived = battleBunker(*it, player.health);
if (survived) {
score += 100;
baseMap[newY][newX] = '.';
bunkers.erase(it);
} else {
render(baseMap, player, enemies, pickups, bunkers, weapon);
std::cout << "游戏结束!被掩体防御击杀。\n";
return;
}
}
}
// 若是战役3,且走到旗帜,算占领成功
if (campaign==3 && baseMap[newY][newX]=='F') {
baseMap[newY][newX] = '.';
score += 100;
std::cout << "旗帜占领成功!(+100分)\n";
}
}
// 检查拾取物
for (auto it = pickups.begin(); it != pickups.end(); ) {
if (it->x==player.x && it->y==player.y) {
player.health += it->value;
if (player.health>150) player.health=150;
std::cout << "捡到急救包(回复 " << it->value << " 生命)\n";
score += 50;
it = pickups.erase(it);
} else {
++it;
}
}
}
else if (isShoot) {
if (weapon.ammo <= 0) {
std::cout << "弹药不足!按 'r' 装弹!\n";
} else {
weapon.ammo--;
std::cout << "BANG!\n";
int shotX = player.x + dx;
int shotY = player.y + dy;
for (int r = 0; r < weapon.range; r++) {
if (shotX < 0 || shotX >= MAP_WIDTH || shotY < 0 || shotY >= MAP_HEIGHT) break;
if (baseMap[shotY][shotX]=='#') break;
auto it = std::find_if(enemies.begin(), enemies.end(), [shotX,shotY](const Entity &e){
return e.x==shotX && e.y==shotY;
});
if (it != enemies.end()) {
int damage = 10 + rand() % 51; // 步枪伤害 10-60
it->health -= damage;
std::cout << "击中敌人(" << shotX << "," << shotY << "),造成 " << damage << " 点伤害。\n";
if (it->health <= 0) {
enemies.erase(it);
score += 100;
std::cout << "敌人被消灭!(+100分)\n";
}
break;
}
shotX += dx;
shotY += dy;
}
}
}
else if (isGrenade) {
std::cout << "BOOM! 手雷爆炸。\n请输入手雷投掷方向 (i/j/k/l): ";
char gDir = _getch();
int centerX = player.x;
int centerY = player.y;
if (gDir=='i') centerY = player.y - 1;
else if (gDir=='k') centerY = player.y + 1;
else if (gDir=='j') centerX = player.x - 1;
else if (gDir=='l') centerX = player.x + 1;
for (auto it = enemies.begin(); it != enemies.end(); ) {
if (abs(it->x - centerX) <= 1 && abs(it->y - centerY) <= 1) {
it->health -= 20;
std::cout << "手雷击中敌人(" << it->x << "," << it->y << "),造成 20 点伤害。\n";
if (it->health <= 0) {
it = enemies.erase(it);
score += 100;
std::cout << "敌人被手雷消灭!(+100分)\n";
continue;
}
}
++it;
}
}
else if (isReload) {
weapon.ammo = weapon.clipSize;
std::cout << "装弹中...\n";
}
// 敌人行为
for (auto &enemy : enemies) {
// 若与玩家同列或同行,则可射击
if (enemy.x == player.x || enemy.y == player.y) {
int shotDx = (enemy.x == player.x) ? 0 : (enemy.x < player.x ? 1 : -1);
int shotDy = (enemy.y == player.y) ? 0 : (enemy.y < player.y ? 1 : -1);
int shotX = enemy.x + shotDx;
int shotY = enemy.y + shotDy;
while (shotX >= 0 && shotX < MAP_WIDTH && shotY >= 0 && shotY < MAP_HEIGHT) {
if (baseMap[shotY][shotX]=='#') break;
if (shotX==player.x && shotY==player.y) {
int dmg = 10 + rand() % 6;
player.health -= dmg;
std::cout << "敌人射击你,造成 " << dmg << " 点伤害!\n";
break;
}
shotX += shotDx;
shotY += shotDy;
}
} else {
// 向玩家移动
int moveDx = (enemy.x < player.x) ? 1 : (enemy.x > player.x ? -1 : 0);
int moveDy = (enemy.y < player.y) ? 1 : (enemy.y > player.y ? -1 : 0);
int newX = enemy.x + moveDx;
int newY = enemy.y + moveDy;
if (newX >= 0 && newX < MAP_WIDTH && newY >= 0 && newY < MAP_HEIGHT &&
baseMap[newY][newX]=='.') {
enemy.x = newX;
enemy.y = newY;
}
}
}
if (player.health <= 0) {
render(baseMap, player, enemies, pickups, bunkers, weapon);
std::cout << "游戏结束!你在任务中阵亡。\n";
return;
}
// 战役 1 完成条件:掩体全部占领
if (campaign == 1 && bunkers.empty()) {
render(baseMap, player, enemies, pickups, bunkers, weapon);
std::cout << "\n所有掩体已占领。进入最终战斗...\n";
bool result = battleEncounter("最终进攻", player.health, 150, 80);
std::cout << (result ? "胜利!任务完成。\n" : "失败!最终战斗中失败。\n");
return;
}
// 战役 2 完成条件:敌人全部消灭
else if (campaign == 2 && enemies.empty()) {
render(baseMap, player, enemies, pickups, bunkers, weapon);
std::cout << "\n所有敌人已消灭。进入最终战斗...\n";
bool result = battleEncounter("最终防御", player.health, 150, 90);
std::cout << (result ? "胜利!任务完成。\n" : "失败!最终战斗中失败。\n");
return;
}
// 战役 3 完成条件:旗帜占领(地图上的 'F' 被清除)
else if (campaign == 3 && baseMap[0][5] != 'F') {
render(baseMap, player, enemies, pickups, bunkers, weapon);
std::cout << "\n旗帜已占领。进入最终战斗...\n";
bool result = battleEncounter("旗帜防御", player.health, 150, 80);
std::cout << (result ? "胜利!任务完成。\n" : "失败!最终战斗中失败。\n");
return;
}
}
}
// --------------------
// 战役5 主函数(Panther 坦克模式)
// --------------------
void playCampaign5() {
const int MAP_WIDTH = 20, MAP_HEIGHT = 10;
std::vector<std::vector<char>> grid(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
std::vector<DestructibleObstacle> obstacles;
addObstaclesDestructible(grid, obstacles, 5); // 放置 5 个可破坏障碍物
// 降低难度:坦克生命值 200,速度固定 1.0
Tank playerTank = { MAP_WIDTH/2.0f, MAP_HEIGHT - 2.0f, 90.0f, 1.0f, 200 };
int cannonAmmo = 4;
int machineGunAmmo = 20;
// 机组成员始终跟随坦克
std::vector<Entity> crew = {
{ (int)round(playerTank.x)-1, (int)round(playerTank.y), 100, 'C' },
{ (int)round(playerTank.x)+1, (int)round(playerTank.y), 100, 'C' }
};
int totalWaves = 8;
int baseInfantry = 3;
for (int wave = 1; wave <= totalWaves; wave++) {
std::cout << "\n--- 第 " << wave << " 波 ---\n";
// 每 3 波 +2 步兵, +1 敌坦
int numInfantry = baseInfantry + ((wave - 1) / 3) * 2;
int numEnemyTanks = 1 + ((wave - 1) / 3);
std::vector<Entity> enemies;
// 生成步兵
for (int i = 0; i < numInfantry; i++) {
enemies.push_back({ rand() % MAP_WIDTH, 0, 40 + wave * 5, 'I' });
}
// 生成敌坦
for (int i = 0; i < numEnemyTanks; i++) {
enemies.push_back({ rand() % MAP_WIDTH, 0, 80 + wave * 5, 'T' });
}
// 波次循环
while (!enemies.empty()) {
std::vector<std::vector<char>> currentGrid(MAP_HEIGHT, std::vector<char>(MAP_WIDTH, '.'));
for (const auto &o : obstacles)
currentGrid[o.y][o.x] = o.symbol;
for (const auto &e : enemies)
currentGrid[e.y][e.x] = e.symbol;
for (const auto &c : crew)
currentGrid[c.y][c.x] = c.symbol;
int tx = (int)round(playerTank.x);
int ty = (int)round(playerTank.y);
currentGrid[ty][tx] = getTankSymbol(playerTank.angle);
system("cls");
for (auto &row : currentGrid) {
for (char c : row)
std::cout << c << ' ';
std::cout << "\n";
}
std::cout << "德国亚丁攻势(Panther 坦克突击) - 第 " << wave << " 波 / 共 " << totalWaves << " 波\n";
std::cout << "坦克生命值: " << playerTank.health << "\n";
std::cout << "机组成员: ";
for (size_t i = 0; i < crew.size(); i++)
std::cout << "机组" << i+1 << "(" << crew[i].health << ") ";
std::cout << "\n主炮弹药: " << cannonAmmo << " 机枪弹药: " << machineGunAmmo << "\n";
std::cout << "剩余敌人: " << enemies.size() << "\n";
std::cout << "控制: w(加速), s(刹车), a/d(转向), [空格]主炮, m机枪, r装弹\n";
std::cout << "请输入指令: ";
char cmd = _getch();
// 简化驾驶控制
if (cmd == 'w') {
playerTank.speed = 1.0f;
} else if (cmd == 's') {
playerTank.speed = 0.0f;
} else if (cmd == 'a') {
playerTank.angle += 15.0f;
if (playerTank.angle >= 360.0f) playerTank.angle -= 360.0f;
} else if (cmd == 'd') {
playerTank.angle -= 15.0f;
if (playerTank.angle < 0) playerTank.angle += 360.0f;
}
// 主炮
else if (cmd == ' ') {
if (cannonAmmo <= 0) {
std::cout << "\n主炮弹药不足!按 r 装弹。\n";
} else {
cannonAmmo--;
std::cout << "\n发射主炮!\n";
float rad = degToRad(playerTank.angle);
int shotRange = 8;
int hitIndex = -1;
int bx = (int)round(playerTank.x), by = (int)round(playerTank.y);
for (int r = 0; r < shotRange; r++) {
bx += (int)round(cos(rad));
by -= (int)round(sin(rad));
bool obstacleHit = false;
for (size_t i = 0; i < obstacles.size(); i++) {
if (obstacles[i].x == bx && obstacles[i].y == by) {
int damage = 200; // 主炮基础伤害
float dx = obstacles[i].x - playerTank.x;
float dy = playerTank.y - obstacles[i].y;
float targetAngle = atan2(dy, dx) * 180.0f / M_PI;
if (targetAngle < 0) targetAngle += 360.0f;
float diff = angleDiff(playerTank.angle, targetAngle);
float multiplier = (diff < 45 ? 0.5f : (diff > 135 ? 1.5f : 1.0f));
int finalDamage = (int)(damage * multiplier);
obstacles[i].health -= finalDamage;
std::cout << "主炮击中障碍物(" << obstacles[i].x << "," << obstacles[i].y << "),造成 " << finalDamage << " 点伤害。\n";
if (obstacles[i].health <= 0) {
std::cout << "障碍物被摧毁!\n";
obstacles.erase(obstacles.begin() + i);
}
obstacleHit = true;
break;
}
}
if (obstacleHit) break;
for (size_t i = 0; i < enemies.size(); i++) {
if (enemies[i].x == bx && enemies[i].y == by) {
hitIndex = i;
break;
}
}
if (hitIndex != -1) break;
}
if (hitIndex != -1) {
int baseDamage = 200;
float dx = enemies[hitIndex].x - playerTank.x;
float dy = playerTank.y - enemies[hitIndex].y;
float targetAngle = atan2(dy, dx) * 180.0f / M_PI;
if (targetAngle < 0) targetAngle += 360.0f;
float diff = angleDiff(playerTank.angle, targetAngle);
float multiplier = (diff < 45 ? 0.5f : (diff > 135 ? 1.5f : 1.0f));
int damage = (int)(baseDamage * multiplier);
enemies[hitIndex].health -= damage;
std::cout << "主炮击中敌人(" << enemies[hitIndex].x << "," << enemies[hitIndex].y << "),造成 " << damage << " 点伤害。\n";
if (enemies[hitIndex].health <= 0) {
std::cout << "敌人被摧毁!\n";
enemies.erase(enemies.begin() + hitIndex);
score += 150;
}
} else {
std::cout << "主炮未命中。\n";
}
}
}
// 机枪
else if (cmd == 'm') {
if (machineGunAmmo <= 0) {
std::cout << "\n机枪弹药不足!按 r 装弹。\n";
} else {
machineGunAmmo--;
std::cout << "\n发射机枪!\n";
float rad = degToRad(playerTank.angle);
int shotRange = 6;
int hitIndex = -1;
int bx = (int)round(playerTank.x), by = (int)round(playerTank.y);
for (int r = 0; r < shotRange; r++) {
bx += (int)round(cos(rad));
by -= (int)round(sin(rad));
bool obstacleHit = false;
for (size_t i = 0; i < obstacles.size(); i++) {
if (obstacles[i].x == bx && obstacles[i].y == by) {
int damage = 30 + rand() % 11; // 30-40伤害
obstacles[i].health -= damage;
std::cout << "机枪击中障碍物(" << obstacles[i].x << "," << obstacles[i].y << "),造成 " << damage << " 点伤害。\n";
if (obstacles[i].health <= 0) {
std::cout << "障碍物被摧毁!\n";
obstacles.erase(obstacles.begin() + i);
}
obstacleHit = true;
break;
}
}
if (obstacleHit) break;
for (size_t i = 0; i < enemies.size(); i++) {
if (enemies[i].x == bx && enemies[i].y == by) {
hitIndex = i;
break;
}
}
if (hitIndex != -1) break;
}
if (hitIndex != -1) {
int damage = 30 + rand() % 11; // 30-40伤害
enemies[hitIndex].health -= damage;
std::cout << "机枪击中敌人(" << enemies[hitIndex].x << "," << enemies[hitIndex].y << "),造成 " << damage << " 点伤害。\n";
if (enemies[hitIndex].health <= 0) {
std::cout << "敌人被摧毁!\n";
enemies.erase(enemies.begin() + hitIndex);
score += 100;
}
} else {
std::cout << "机枪未命中。\n";
}
}
}
// 装弹
else if (cmd == 'r') {
cannonAmmo = 4;
machineGunAmmo = 20;
std::cout << "\n正在装弹...\n";
}
// 更新坦克位置
float rad = degToRad(playerTank.angle);
playerTank.x += playerTank.speed * cos(rad);
playerTank.y -= playerTank.speed * sin(rad);
if (playerTank.x < 0) playerTank.x = 0;
if (playerTank.x >= MAP_WIDTH) playerTank.x = MAP_WIDTH - 1;
if (playerTank.y < 0) playerTank.y = 0;
if (playerTank.y >= MAP_HEIGHT) playerTank.y = MAP_HEIGHT - 1;
// 更新机组成员位置
int tnx = (int)round(playerTank.x);
int tny = (int)round(playerTank.y);
crew[0].x = tnx - 1;
crew[0].y = tny;
crew[1].x = tnx + 1;
crew[1].y = tny;
// 敌人行动
for (auto &enemy : enemies) {
if (enemy.x < (int)round(playerTank.x)) enemy.x++;
else if (enemy.x > (int)round(playerTank.x)) enemy.x--;
if (enemy.y < (int)round(playerTank.y)) enemy.y++;
else if (enemy.y > (int)round(playerTank.y)) enemy.y--;
// 有 30% 几率射击
if (rand() % 100 < 30) {
int baseDmg = 15 + rand() % 6; // 15-20伤害
float dx = enemy.x - playerTank.x;
float dy = playerTank.y - enemy.y;
float enemyAngle = atan2(dy, dx) * 180.0f / M_PI;
if (enemyAngle < 0) enemyAngle += 360.0f;
float diff = angleDiff(playerTank.angle, enemyAngle);
float multiplier = (diff < 45 ? 0.5f : (diff > 135 ? 1.5f : 1.0f));
int dmg = (int)(baseDmg * multiplier);
playerTank.health -= dmg;
std::cout << "敌人射击你,造成 " << dmg << " 点伤害。\n";
}
}
std::cout << "\n按任意键进入本波下一回合...";
_getch();
if (playerTank.health <= 0) break;
}
if (playerTank.health <= 0) {
std::cout << "\n你的 Panther 坦克和机组被摧毁。任务失败。\n";
return;
}
std::cout << "\n本波清除!按任意键进入下一波...";
_getch();
// 每 3 波,坦克修复 15 点生命(上限 200)
if (wave % 3 == 0) {
playerTank.health += 15;
if (playerTank.health > 200) playerTank.health = 200;
std::cout << " 坦克获得维修(+15 生命)!\n";
}
}
std::cout << "\n所有敌防被摧毁!德国亚丁攻势任务完成。\n";
}
// --------------------
// Main 函数
// --------------------
int main() {
srand(static_cast<unsigned int>(time(0)));
std::cout << "战场 1 - 增强版\n";
std::cout << "【操作说明】\n";
std::cout << "(战役1-4)移动: w/a/s/d 及对角 (q, e, z, c) 射击: i/j/k/l(上/左/下/右) 手雷: g 装弹: r\n";
std::cout << "\n请选择战役:\n";
std::cout << "1. 诺曼底登陆\n2. 亚丁攻势\n3. 柏林进攻\n4. 德国诺曼底(机枪防御)\n5. 德国亚丁攻势(Panther 坦克突击)\n请输入战役编号 (1-5): ";
int choice;
std::cin >> choice;
if (choice >= 1 && choice <= 5) {
if (choice == 5) {
playCampaign5();
} else {
playCampaign(choice);
}
} else {
std::cout << "输入无效!\n";
}
std::cout << "\n按任意键退出...";
_getch();
return 0;
}