cpp
复制代码
#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <chrono>
#include <algorithm>
#include <conio.h>
#include <windows.h>
using namespace std;
// 控制台颜色定义
enum Color {
BLACK = 0,
BLUE = 1,
GREEN = 2,
CYAN = 3,
RED = 4,
MAGENTA = 5,
YELLOW = 6,
WHITE = 7,
GRAY = 8,
BRIGHT_BLUE = 9,
BRIGHT_GREEN = 10,
BRIGHT_CYAN = 11,
BRIGHT_RED = 12,
BRIGHT_MAGENTA = 13,
BRIGHT_YELLOW = 14,
BRIGHT_WHITE = 15
};
// 设置控制台颜色
void setColor(int foreground, int background = BLACK) {
SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), foreground + (background << 4));
}
// 设置光标位置
void setCursor(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
// 隐藏光标
void hideCursor() {
CONSOLE_CURSOR_INFO cursorInfo;
cursorInfo.dwSize = 100;
cursorInfo.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
class Player {
public:
int x, y;
bool jumping;
bool ducking;
int jumpHeight;
int jumpCounter;
int normalHeight;
int duckHeight;
bool hasJetpack;
int jetpackTime;
bool doubleScore;
int doubleScoreTime;
Player() : x(3), y(8), jumping(false), ducking(false), jumpHeight(5), jumpCounter(0),
normalHeight(8), duckHeight(9), hasJetpack(false), jetpackTime(0),
doubleScore(false), doubleScoreTime(0) {}
void jump() {
if (!jumping && !ducking) {
jumping = true;
jumpCounter = 0;
}
}
void startDuck() {
if (!jumping) {
ducking = true;
y = duckHeight;
} else {
// 如果在跳跃中下蹲,加速下降
jumpCounter = jumpHeight; // 立即进入下降阶段
}
}
void endDuck() {
ducking = false;
y = normalHeight;
}
void activateJetpack() {
hasJetpack = true;
jetpackTime = 200; // 持续4秒
}
void activateDoubleScore() {
doubleScore = true;
doubleScoreTime = 200; // 持续4秒
}
void update() {
// 更新道具时间
if (hasJetpack) {
jetpackTime--;
if (jetpackTime <= 0) {
hasJetpack = false;
}
}
if (doubleScore) {
doubleScoreTime--;
if (doubleScoreTime <= 0) {
doubleScore = false;
}
}
if (jumping) {
if (hasJetpack) {
// 喷气背包:缓慢下降
if (jumpCounter < jumpHeight * 2) {
y--;
} else if (jumpCounter < jumpHeight * 3) {
// 保持高度
} else if (jumpCounter < jumpHeight * 4) {
y++;
} else {
jumping = false;
y = normalHeight;
}
} else if (ducking) {
// 下蹲时加速下降
y += 2;
if (y >= duckHeight) {
y = duckHeight;
jumping = false;
}
} else {
// 正常跳跃
if (jumpCounter < jumpHeight) {
y--;
} else if (jumpCounter < jumpHeight * 2) {
y++;
} else {
jumping = false;
y = normalHeight;
}
}
jumpCounter++;
}
}
void draw() {
if (ducking) {
setCursor(x, y);
setColor(BRIGHT_CYAN);
cout << "█";
} else {
setCursor(x, y);
setColor(BRIGHT_CYAN);
cout << "█";
setCursor(x, y+1);
setColor(BRIGHT_BLUE);
cout << "?";
}
// 绘制喷气背包效果
if (hasJetpack) {
setCursor(x-1, y+2);
setColor(BRIGHT_YELLOW);
cout << "▲";
setCursor(x+1, y+2);
cout << "▲";
}
}
};
class Obstacle {
public:
int x, y;
int type; // 0: 低障碍, 1: 高障碍, 2: 双障碍
Obstacle(int startX, int obsType) : x(startX), y(9), type(obsType) {}
void update() {
x--;
}
void draw() {
setColor(BRIGHT_RED);
if (type == 0) { // 低障碍
setCursor(x, y);
cout << "▓";
} else if (type == 1) { // 高障碍
setCursor(x, y-1);
cout << "▓";
setCursor(x, y);
cout << "▓";
} else { // 双障碍
setCursor(x, y-2);
cout << "▓";
setCursor(x, y);
cout << "▓";
}
}
bool checkCollision(const Player& player) {
if (player.x == x) {
if (player.ducking) {
// 下蹲时可以躲避低障碍
if (type == 0) return false;
if (type == 1 && player.y >= y - 1) return true;
if (type == 2 && player.y >= y - 1) return true;
} else {
if (type == 0 && player.y >= y - 1) return true;
if (type == 1 && player.y >= y - 2) return true;
if (type == 2 && (player.y >= y - 1 || player.y <= y - 3)) return true;
}
}
return false;
}
};
class Coin {
public:
int x, y;
bool collected;
Coin(int startX, int startY) : x(startX), y(startY), collected(false) {}
void update() {
x--;
}
void draw() {
if (!collected) {
setCursor(x, y);
setColor(BRIGHT_YELLOW);
cout << "●";
}
}
bool checkCollection(const Player& player) {
if (!collected && player.x == x && player.y == y) {
collected = true;
return true;
}
return false;
}
};
class PowerUp {
public:
int x, y;
int type; // 0: 双倍得分, 1: 喷气背包
bool collected;
PowerUp(int startX, int startY, int powerType) : x(startX), y(startY), type(powerType), collected(false) {}
void update() {
x--;
}
void draw() {
if (!collected) {
setCursor(x, y);
if (type == 0) {
setColor(BRIGHT_MAGENTA);
cout << "★";
} else {
setColor(BRIGHT_GREEN);
cout << "▲";
}
}
}
bool checkCollection(const Player& player) {
if (!collected && player.x == x && player.y == y) {
collected = true;
return true;
}
return false;
}
};
class Metro {
public:
int x, y;
bool moving;
int speed;
int length;
Metro(int startX, int startY, bool isMoving, int metroLength = 6) :
x(startX), y(startY), moving(isMoving), speed(1), length(metroLength) {}
void update() {
if (moving) {
x -= speed;
if (x < -length) {
x = 40; // 重新从右侧出现
}
}
}
void draw() {
setColor(BRIGHT_WHITE);
// 绘制地铁车身
for (int i = 0; i < length; i++) {
setCursor(x + i, y);
cout << "█";
}
// 绘制车窗
setColor(BRIGHT_CYAN);
for (int i = 1; i < length-1; i++) {
setCursor(x + i, y - 1);
cout << "?";
}
// 绘制车头灯
setColor(BRIGHT_YELLOW);
setCursor(x, y - 1);
cout << "○";
setCursor(x + length - 1, y - 1);
cout << "○";
}
bool checkCollision(const Player& player) {
// 检查玩家是否与地铁碰撞
if (player.y == y || player.y == y-1) {
for (int i = 0; i < length; i++) {
if (player.x == x + i) {
return true;
}
}
}
return false;
}
};
class Game {
private:
Player player;
vector<Obstacle> obstacles;
vector<Coin> coins;
vector<PowerUp> powerUps;
vector<Metro> metros;
int score;
int speed;
bool gameOver;
int gameWidth;
int gameHeight;
mt19937 rng;
int tunnelPosition;
bool inTunnel;
int tunnelCounter;
public:
Game() : score(0), speed(1), gameOver(false), gameWidth(30), gameHeight(12),
tunnelPosition(-1), inTunnel(false), tunnelCounter(0) {
rng.seed(static_cast<unsigned int>(chrono::steady_clock::now().time_since_epoch().count()));
hideCursor();
// 初始化地铁
metros.push_back(Metro(15, 7, true, 4));
metros.push_back(Metro(25, 7, false, 4));
}
void drawBackground() {
// 绘制天空 - 简化设计
setColor(BRIGHT_BLUE);
for (int y = 0; y < 3; y++) {
setCursor(0, y);
for (int x = 0; x < gameWidth; x++) {
cout << " ";
}
}
// 绘制远山 - 简化设计
setColor(GREEN);
for (int y = 3; y < 5; y++) {
setCursor(0, y);
for (int x = 0; x < gameWidth; x++) {
if ((x + y) % 8 < 2) cout << "▲";
else cout << " ";
}
}
// 绘制建筑 - 简化设计
setColor(GRAY);
for (int x = 0; x < gameWidth; x += 6) {
setCursor(x, 4);
cout << "█";
setCursor(x, 5);
cout << "█";
}
// 绘制轨道 - 简化设计
setColor(YELLOW);
for (int y = 9; y < 11; y++) {
setCursor(0, y);
for (int x = 0; x < gameWidth; x++) {
if (y == 9) {
cout << (x % 2 == 0 ? "═" : " ");
} else {
cout << (x % 4 < 2 ? "█" : " ");
}
}
}
// 绘制地铁墙壁 - 简化设计
setColor(BRIGHT_WHITE);
for (int y = 0; y < gameHeight; y++) {
setCursor(0, y);
cout << "│";
setCursor(gameWidth-1, y);
cout << "│";
}
// 绘制隧道 - 简化设计
if (inTunnel) {
setColor(BLACK, GRAY);
for (int y = 4; y < 8; y++) {
setCursor(tunnelPosition, y);
for (int x = 0; x < 8; x++) {
cout << " ";
}
}
// 隧道入口
setColor(GRAY, BLACK);
setCursor(tunnelPosition, 3);
cout << "┌──────┐";
setCursor(tunnelPosition, 8);
cout << "└──────┘";
}
}
void generateObstacles() {
uniform_int_distribution<int> dist(0, 100);
if (dist(rng) < 6 && (obstacles.empty() || obstacles.back().x < gameWidth - 8)) {
uniform_int_distribution<int> typeDist(0, 2);
obstacles.push_back(Obstacle(gameWidth-2, typeDist(rng)));
}
}
void generateCoins() {
uniform_int_distribution<int> dist(0, 100);
if (dist(rng) < 10 && (coins.empty() || coins.back().x < gameWidth - 6)) {
uniform_int_distribution<int> heightDist(5, 7);
coins.push_back(Coin(gameWidth-2, heightDist(rng)));
}
}
void generatePowerUps() {
uniform_int_distribution<int> dist(0, 100);
if (dist(rng) < 4 && (powerUps.empty() || powerUps.back().x < gameWidth - 10)) {
uniform_int_distribution<int> typeDist(0, 1);
uniform_int_distribution<int> heightDist(5, 7);
powerUps.push_back(PowerUp(gameWidth-2, heightDist(rng), typeDist(rng)));
}
}
void updateTunnel() {
if (tunnelPosition == -1) {
uniform_int_distribution<int> dist(0, 200);
if (dist(rng) < 3) {
tunnelPosition = gameWidth;
inTunnel = false;
tunnelCounter = 0;
}
} else {
tunnelPosition--;
tunnelCounter++;
if (tunnelPosition < -10) {
tunnelPosition = -1;
inTunnel = false;
} else if (tunnelPosition < gameWidth && tunnelPosition > gameWidth - 12) {
inTunnel = true;
}
}
}
void update() {
player.update();
// 更新地铁
for (auto& metro : metros) {
metro.update();
// 检测地铁碰撞
if (metro.checkCollision(player)) {
gameOver = true;
return;
}
}
// 更新隧道
updateTunnel();
// 更新障碍物
for (auto& obstacle : obstacles) {
obstacle.update();
if (obstacle.checkCollision(player)) {
gameOver = true;
return;
}
}
// 移除屏幕外的障碍物
obstacles.erase(remove_if(obstacles.begin(), obstacles.end(),
[](const Obstacle& o) { return o.x < 0; }), obstacles.end());
// 更新金币
int coinValue = player.doubleScore ? 20 : 10;
for (auto& coin : coins) {
coin.update();
if (coin.checkCollection(player)) {
score += coinValue;
}
}
// 移除屏幕外的金币或已收集的金币
coins.erase(remove_if(coins.begin(), coins.end(),
[](const Coin& c) { return c.x < 0 || c.collected; }), coins.end());
// 更新道具
for (auto& powerUp : powerUps) {
powerUp.update();
if (powerUp.checkCollection(player)) {
if (powerUp.type == 0) {
player.activateDoubleScore();
} else {
player.activateJetpack();
}
}
}
// 移除屏幕外的道具或已收集的道具
powerUps.erase(remove_if(powerUps.begin(), powerUps.end(),
[](const PowerUp& p) { return p.x < 0 || p.collected; }), powerUps.end());
// 生成新障碍物、金币和道具
generateObstacles();
generateCoins();
generatePowerUps();
// 增加分数
score += player.doubleScore ? 2 : 1;
// 每200分增加速度
if (score % 200 == 0) {
speed++;
}
}
void draw() {
system("cls");
// 绘制背景
drawBackground();
// 绘制地铁
for (auto& metro : metros) {
metro.draw();
}
// 绘制玩家
player.draw();
// 绘制障碍物
for (auto& obstacle : obstacles) {
obstacle.draw();
}
// 绘制金币
for (auto& coin : coins) {
coin.draw();
}
// 绘制道具
for (auto& powerUp : powerUps) {
powerUp.draw();
}
// 绘制UI - 重新设计布局
setCursor(2, 1);
setColor(BRIGHT_YELLOW);
cout << "SCORE:" << score;
setCursor(2, 2);
setColor(BRIGHT_GREEN);
cout << "SPEED:" << speed;
// 显示道具状态 - 重新设计布局
setCursor(gameWidth - 12, 1);
if (player.doubleScore) {
setColor(BRIGHT_MAGENTA);
cout << "2X:" << player.doubleScoreTime / 10;
} else {
cout << " ";
}
setCursor(gameWidth - 12, 2);
if (player.hasJetpack) {
setColor(BRIGHT_GREEN);
cout << "JET:" << player.jetpackTime / 10;
} else {
cout << " ";
}
if (gameOver) {
setCursor(gameWidth/2 - 4, gameHeight/2 - 1);
setColor(BRIGHT_RED, RED);
cout << "GAME OVER";
setCursor(gameWidth/2 - 5, gameHeight/2 + 1);
setColor(BRIGHT_WHITE);
cout << "SCORE: " << score;
setCursor(gameWidth/2 - 7, gameHeight/2 + 3);
cout << "R-RESTART Q-QUIT";
}
}
void handleInput() {
if (_kbhit()) {
char key = _getch();
if (!gameOver) {
if (key == 'w' || key == 'W') {
player.jump();
} else if (key == 's' || key == 'S') {
player.startDuck();
}
} else {
if (key == 'r' || key == 'R') {
reset();
} else if (key == 'q' || key == 'Q') {
exit(0);
}
}
} else if (!gameOver) {
// 检测按键释放
player.endDuck();
}
}
void reset() {
player = Player();
obstacles.clear();
coins.clear();
powerUps.clear();
metros.clear();
metros.push_back(Metro(15, 7, true, 4));
metros.push_back(Metro(25, 7, false, 4));
score = 0;
speed = 1;
gameOver = false;
tunnelPosition = -1;
inTunnel = false;
}
void run() {
// 开始界面
drawStartScreen();
// 等待空格键开始
while (true) {
if (_kbhit()) {
char key = _getch();
if (key == ' ') {
break;
}
}
_sleep(150);
}
// 游戏主循环
while (true) {
auto startTime = chrono::steady_clock::now();
handleInput();
if (!gameOver) {
update();
}
draw();
auto endTime = chrono::steady_clock::now();
auto elapsedTime = chrono::duration_cast<chrono::milliseconds>(endTime - startTime);
auto sleepTime = 150 - elapsedTime.count();
if (sleepTime > 0) {
_sleep(static_cast<unsigned long>(sleepTime));
}
}
}
void drawStartScreen() {
system("cls");
// 绘制标题 - 重新设计
setCursor(gameWidth/2 - 4, 2);
setColor(BRIGHT_CYAN);
cout << "SUBWAY RUN";
// 绘制玩家示例
setCursor(gameWidth/2 - 1, 4);
setColor(BRIGHT_CYAN);
cout << "█";
setCursor(gameWidth/2 - 1, 5);
setColor(BRIGHT_BLUE);
cout << "?";
// 绘制障碍物示例
setCursor(gameWidth/2 + 2, 7);
setColor(BRIGHT_RED);
cout << "▓";
// 绘制地铁示例
setCursor(gameWidth/2 + 5, 7);
setColor(BRIGHT_WHITE);
cout << "██";
// 绘制金币示例
setCursor(gameWidth/2 + 8, 5);
setColor(BRIGHT_YELLOW);
cout << "●";
// 绘制道具示例
setCursor(gameWidth/2 - 6, 5);
setColor(BRIGHT_MAGENTA);
cout << "★";
setCursor(gameWidth/2 - 6, 6);
setColor(BRIGHT_GREEN);
cout << "▲";
// 绘制控制说明 - 重新设计
setCursor(gameWidth/2 - 5, 7);
setColor(BRIGHT_GREEN);
cout << "W-JUMP";
setCursor(gameWidth/2 - 5, 8);
cout << "S-DUCK";
setCursor(gameWidth/2 - 8, 9);
setColor(BRIGHT_YELLOW);
cout << "AVOID TRAINS & OBSTACLES";
setCursor(gameWidth/2 - 5, 10);
setColor(BRIGHT_WHITE);
cout << "SPACE-START";
}
};
int main() {
// 设置控制台窗口大小 - 进一步缩小范围
system("mode con cols=30 lines=12");
Game game;
game.run();
return 0;
}