#include <iostream>
#include <vector>
#include <string>
#include <cstdlib>
#include <ctime>
#include <conio.h>
#include <windows.h>
#include <algorithm>

using namespace std;

// 游戏配置
const int WIDTH = 80;
const int HEIGHT = 20;
const int PLAYER_SPEED = 2;
const int BULLET_SPEED = 3;
const int ENEMY_SPEED = 1;
const int ENEMY_ROWS = 4;
const int ENEMY_COLS = 10;
const int ENEMY_SHOOT_PROB = 200; // 越小越容易射击
const int INITIAL_LIVES = 3;

// 方向枚举
enum Direction { LEFT, RIGHT, UP, DOWN };

// 位置结构体
struct Position {
    int x, y;
};

// 游戏对象基类
class GameObject {
protected:
    Position pos;
    char symbol;
    bool active;

public:
    GameObject(int x, int y, char sym) : pos{x, y}, symbol{sym}, active{true} {}
    
    Position getPosition() const { return pos; }
    char getSymbol() const { return symbol; }
    bool isActive() const { return active; }
    void deactivate() { active = false; }
    
    virtual void move(Direction dir) = 0;
};

// 玩家类
class Player : public GameObject {
private:
    int lives;
    int score;

public:
    Player() : GameObject(WIDTH / 2, HEIGHT - 2, '^'), lives{INITIAL_LIVES}, score{0} {}
    
    int getLives() const { return lives; }
    void loseLife() { lives--; }
    int getScore() const { return score; }
    void addScore(int points) { score += points; }
    
    void move(Direction dir) override {
        switch (dir) {
            case LEFT:
                if (pos.x > 1) pos.x -= PLAYER_SPEED;
                break;
            case RIGHT:
                if (pos.x < WIDTH - 2) pos.x += PLAYER_SPEED;
                break;
            default:
                break;
        }
    }
    
    void resetPosition() {
        pos.x = WIDTH / 2;
    }
};

// 子弹类
class Bullet : public GameObject {
private:
    Direction dir;

public:
    Bullet(int x, int y, Direction d, char sym = '*') 
        : GameObject(x, y, sym), dir{d} {}
    
    void move(Direction) override {
        if (dir == UP) {
            pos.y -= BULLET_SPEED;
            if (pos.y < 0) deactivate();
        } else {
            pos.y += BULLET_SPEED;
            if (pos.y >= HEIGHT) deactivate();
        }
    }
};

// 敌人类
class Enemy : public GameObject {
private:
    static char symbols[4];
    int type;

public:
    Enemy(int x, int y, int t) 
        : GameObject(x, y, symbols[t % 4]), type{t} {}
    
    void move(Direction dir) override {
        switch (dir) {
            case LEFT:
                pos.x -= ENEMY_SPEED;
                break;
            case RIGHT:
                pos.x += ENEMY_SPEED;
                break;
            case DOWN:
                pos.y += 1;
                break;
            default:
                break;
        }
    }
    
    int getType() const { return type; }
    
    bool shouldShoot() const {
        return rand() % ENEMY_SHOOT_PROB == 0;
    }
};

char Enemy::symbols[4] = {'V', 'W', 'M', 'X'};

// 游戏类
class Game {
private:
    Player player;
    vector<Bullet> bullets;
    vector<Enemy> enemies;
    vector<Bullet> enemyBullets;
    bool gameOver;
    bool quit;
    int level;
    Direction enemyDirection;
    int enemyMoveCounter;
    int enemyMoveThreshold;

public:
    Game() : gameOver{false}, quit{false}, level{1}, 
             enemyDirection{RIGHT}, enemyMoveCounter{0},
             enemyMoveThreshold{100} {
        srand(time(nullptr));
        initializeEnemies();
    }
    
    void initializeEnemies() {
        enemies.clear();
        for (int row = 0; row < ENEMY_ROWS; ++row) {
            for (int col = 0; col < ENEMY_COLS; ++col) {
                int x = 5 + col * 7;
                int y = 2 + row * 3;
                enemies.emplace_back(x, y, row);
            }
        }
    }
    
    void processInput() {
        if (_kbhit()) {
            char key = _getch();
            switch (key) {
                case 'a':
                case 'A':
                case 75: // 左箭头
                    player.move(LEFT);
                    break;
                case 'd':
                case 'D':
                case 77: // 右箭头
                    player.move(RIGHT);
                    break;
                case ' ':
                    bullets.emplace_back(player.getPosition().x, 
                                        player.getPosition().y - 1, UP);
                    break;
                case 'q':
                case 'Q':
                    quit = true;
                    break;
            }
        }
    }
    
    void update() {
        // 更新玩家子弹
        for (auto& bullet : bullets) {
            if (bullet.isActive()) {
                bullet.move(UP);
            }
        }
        
        // 更新敌人子弹
        for (auto& bullet : enemyBullets) {
            if (bullet.isActive()) {
                bullet.move(DOWN);
            }
        }
        
        // 敌人移动逻辑
        enemyMoveCounter++;
        if (enemyMoveCounter >= enemyMoveThreshold) {
            bool changeDirection = false;
            for (auto& enemy : enemies) {
                if (enemy.isActive()) {
                    if (enemyDirection == RIGHT && 
                        enemy.getPosition().x >= WIDTH - 5) {
                        changeDirection = true;
                        break;
                    } else if (enemyDirection == LEFT && 
                               enemy.getPosition().x <= 5) {
                        changeDirection = true;
                        break;
                    }
                }
            }
            
            if (changeDirection) {
                enemyDirection = (enemyDirection == RIGHT) ? LEFT : RIGHT;
                for (auto& enemy : enemies) {
                    if (enemy.isActive()) {
                        enemy.move(DOWN);
                        if (enemy.getPosition().y >= HEIGHT - 3) {
                            gameOver = true;
                        }
                    }
                }
            } else {
                for (auto& enemy : enemies) {
                    if (enemy.isActive()) {
                        enemy.move(enemyDirection);
                    }
                }
            }
            
            enemyMoveCounter = 0;
        }
        
        // 敌人射击逻辑
        for (const auto& enemy : enemies) {
            if (enemy.isActive() && enemy.shouldShoot()) {
                enemyBullets.emplace_back(enemy.getPosition().x, 
                                         enemy.getPosition().y + 1, DOWN, 'v');
            }
        }
        
        // 检测碰撞
        checkCollisions();
        
        // 移除不活跃的对象
        removeInactiveObjects();
        
        // 检查游戏状态
        if (enemies.empty()) {
            levelUp();
        }
        
        if (player.getLives() <= 0) {
            gameOver = true;
        }
    }
    
    void checkCollisions() {
        // 玩家子弹与敌人碰撞
        for (auto& bullet : bullets) {
            if (!bullet.isActive()) continue;
            
            for (auto& enemy : enemies) {
                if (enemy.isActive() &&
                    bullet.getPosition().x == enemy.getPosition().x &&
                    bullet.getPosition().y == enemy.getPosition().y) {
                    bullet.deactivate();
                    enemy.deactivate();
                    player.addScore(10 * (enemy.getType() + 1));
                    break;
                }
            }
        }
        
        // 敌人子弹与玩家碰撞
        for (auto& bullet : enemyBullets) {
            if (!bullet.isActive()) continue;
            
            Position playerPos = player.getPosition();
            if (bullet.getPosition().x >= playerPos.x - 1 &&
                bullet.getPosition().x <= playerPos.x + 1 &&
                bullet.getPosition().y == playerPos.y) {
                bullet.deactivate();
                player.loseLife();
                player.resetPosition();
                break;
            }
        }
    }
    
    void removeInactiveObjects() {
        // 移除不活跃的子弹
        bullets.erase(remove_if(bullets.begin(), bullets.end(),
                               [](const Bullet& b) { return !b.isActive(); }),
                     bullets.end());
        
        enemyBullets.erase(remove_if(enemyBullets.begin(), enemyBullets.end(),
                                    [](const Bullet& b) { return !b.isActive(); }),
                          enemyBullets.end());
        
        // 移除不活跃的敌人
        enemies.erase(remove_if(enemies.begin(), enemies.end(),
                               [](const Enemy& e) { return !e.isActive(); }),
                     enemies.end());
    }
    
    void levelUp() {
        level++;
        enemyMoveThreshold = max(30, enemyMoveThreshold - 10);
        initializeEnemies();
    }
    
    void render() {
        system("cls"); // 清屏
        
        // 创建游戏屏幕
        vector<string> screen(HEIGHT, string(WIDTH, ' '));
        
        // 绘制边界
        for (int i = 0; i < WIDTH; ++i) {
            screen[0][i] = '-';
            screen[HEIGHT - 1][i] = '-';
        }
        for (int i = 0; i < HEIGHT; ++i) {
            screen[i][0] = '|';
            screen[i][WIDTH - 1] = '|';
        }
        
        // 绘制玩家
        Position playerPos = player.getPosition();
        screen[playerPos.y][playerPos.x] = player.getSymbol();
        screen[playerPos.y + 1][playerPos.x - 1] = '/';
        screen[playerPos.y + 1][playerPos.x + 1] = '\\';
        
        // 绘制子弹
        for (const auto& bullet : bullets) {
            if (bullet.isActive()) {
                Position pos = bullet.getPosition();
                screen[pos.y][pos.x] = bullet.getSymbol();
            }
        }
        
        // 绘制敌人
        for (const auto& enemy : enemies) {
            if (enemy.isActive()) {
                Position pos = enemy.getPosition();
                screen[pos.y][pos.x] = enemy.getSymbol();
            }
        }
        
        // 绘制敌人子弹
        for (const auto& bullet : enemyBullets) {
            if (bullet.isActive()) {
                Position pos = bullet.getPosition();
                screen[pos.y][pos.x] = bullet.getSymbol();
            }
        }
        
        // 显示游戏信息
        string info = "Score: " + to_string(player.getScore()) + 
                     " | Lives: " + to_string(player.getLives()) + 
                     " | Level: " + to_string(level);
        screen[HEIGHT - 1] = info + string(WIDTH - info.length() - 1, ' ');
        
        // 显示控制说明
        string controls = "A/D or ←/→: Move | Space: Shoot | Q: Quit";
        screen[HEIGHT - 2] = controls + string(WIDTH - controls.length() - 1, ' ');
        
        // 输出屏幕
        for (const auto& row : screen) {
            cout << row << endl;
        }
        
        // 游戏结束信息
        if (gameOver) {
            cout << endl << "Game Over! Final Score: " << player.getScore() << endl;
            cout << "Press Q to exit." << endl;
        }
    }
    
    void gameLoop() {
        while (!quit && !gameOver) {
            processInput();
            update();
            render();
            Sleep(20); // 控制游戏速度
        }
        
        // 游戏结束后等待退出
        while (!quit) {
            if (_kbhit() && (_getch() == 'q' || _getch() == 'Q')) {
                quit = true;
            }
        }
    }
};

int main() {
    cout << "Welcome to Space Invaders!" << endl;
    cout << "Press any key to start..." << endl;
    _getch();
    
    Game game;
    game.gameLoop();
    
    return 0;
}    

3 条评论

  • 1

信息

ID
116
时间
1000ms
内存
256MiB
难度
8
标签
递交数
56
已通过
9
上传者