C++2D地铁跑酷代码

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;
}
相关推荐
紫荆鱼4 小时前
设计模式-状态模式(State)
c++·后端·设计模式·状态模式
深思慎考4 小时前
微服务即时通讯系统(服务端)——Speech 语音模块开发(2)
linux·c++·微服务·云原生·架构·语音识别·聊天室项目
「QT(C++)开发工程师」4 小时前
【LUA教程】LUA脚本语言中文教程.PDF
开发语言·pdf·lua
程序定小飞4 小时前
基于springboot的民宿在线预定平台开发与设计
java·开发语言·spring boot·后端·spring
沐怡旸5 小时前
【穿越Effective C++】条款7:为多态基类声明virtual析构函数——C++多态资源管理的基石
c++·面试
天天进步20155 小时前
Python全栈项目--基于计算机视觉的车牌识别系统
开发语言·python·计算机视觉
Algo-hx5 小时前
C++编程基础(五):字符数组和字符串
开发语言·c++
无敌最俊朗@5 小时前
C++ STL中 std::list 的高频面试题与答案
开发语言·c++·list
星光一影5 小时前
Java医院管理系统HIS源码带小程序和安装教程
java·开发语言·小程序