#include <iostream>
#include <windows.h>
#include <vector>
#include <conio.h>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
const int WIDTH = 60;
const int HEIGHT = 30;
int playerX;
int playerY;
bool gameOver;
int lives;
struct Bullet {
int x, y;
};
vector<Bullet> playerBullets;
vector<Bullet> enemyBullets;
struct Enemy {
int x, y;
bool alive;
};
vector<Enemy> enemies;
struct Boss {
int x, y;
int hp;
int dir;
bool alive;
} boss;
int enemyDir;
int enemyMoveSpeed;
int enemyFireRate;
int enemyMoveTimer;
int score;
char screen[HEIGHT][WIDTH + 1];
void setPos(int x, int y) {
COORD pos = {(SHORT)x, (SHORT)y};
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), pos);
}
void hideCursor() {
CONSOLE_CURSOR_INFO info;
info.dwSize = 1;
info.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &info);
}
void clearScreen() {
for (int y = 0; y < HEIGHT; y++) {
for (int x = 0; x < WIDTH; x++) {
screen[y][x] = ' ';
}
screen[y][WIDTH] = '\0';
}
}
void drawBorder() {
for (int x = 0; x < WIDTH; x++) screen[0][x] = '-';
for (int y = 1; y < HEIGHT - 1; y++) {
screen[y][0] = '|';
screen[y][WIDTH - 1] = '|';
}
for (int x = 0; x < WIDTH; x++) screen[HEIGHT - 1][x] = '-';
}
void renderScreen() {
setPos(0,0);
for (int y = 0; y < HEIGHT; y++) cout << screen[y] << endl;
}
void initGame() {
playerX = WIDTH / 2;
playerY = HEIGHT - 3;
gameOver = false;
lives = 3;
enemyDir = 1;
enemyMoveSpeed = 8;
enemyFireRate = 25;
enemyMoveTimer = 0;
score = 0;
boss.alive = false;
}
void initEnemies() {
for (int i = 0; i < 10; i++) {
Enemy e;
e.x = 5 + i * 4;
e.y = 2;
e.alive = true;
enemies.push_back(e);
}
}
void spawnBoss() {
if (score >= 300 && !boss.alive) {
boss.alive = true;
boss.x = WIDTH / 2;
boss.y = 4;
boss.hp = 40;
boss.dir = 1;
}
}
void input() {
if (_kbhit()) {
char key = _getch();
if (key == 75 && playerX > 2) playerX--;
if (key == 77 && playerX < WIDTH - 3) playerX++;
if (key == 32) {
Bullet b;
b.x = playerX;
b.y = playerY - 1;
playerBullets.push_back(b);
}
if (key == 27) gameOver = true;
}
}
void logic() {
// 玩家子弹移动
for (int i = 0; i < playerBullets.size(); i++) {
playerBullets[i].y--;
if (playerBullets[i].y < 1) {
playerBullets.erase(playerBullets.begin() + i);
i--;
}
}
// 敌人子弹移动
for (int i = 0; i < enemyBullets.size(); i++) {
enemyBullets[i].y++;
if (enemyBullets[i].y > HEIGHT - 2) {
enemyBullets.erase(enemyBullets.begin() + i);
i--;
}
}
// 敌人移动
enemyMoveTimer++;
if (enemyMoveTimer >= enemyMoveSpeed) {
enemyMoveTimer = 0;
bool drop = false;
for (int i = 0; i < enemies.size(); i++) {
if (!enemies[i].alive) continue;
enemies[i].x += enemyDir;
if (enemies[i].x <= 1 || enemies[i].x >= WIDTH - 2) drop = true;
}
if (drop) {
enemyDir *= -1;
for (int i = 0; i < enemies.size(); i++) {
if (enemies[i].alive) enemies[i].y++;
}
}
}
// 敌人射击
if (rand() % enemyFireRate == 0) {
int r = rand() % enemies.size();
if (enemies[r].alive) {
Bullet b;
b.x = enemies[r].x;
b.y = enemies[r].y + 1;
enemyBullets.push_back(b);
}
}
// BOSS 逻辑
if (boss.alive) {
boss.x += boss.dir;
if (boss.x < 5 || boss.x > WIDTH - 5) boss.dir *= -1;
if (rand() % 8 == 0) {
Bullet b1, b2, b3;
b1.x = boss.x; b1.y = boss.y + 1;
b2.x = boss.x - 1; b2.y = boss.y + 1;
b3.x = boss.x + 1; b3.y = boss.y + 1;
enemyBullets.push_back(b1);
enemyBullets.push_back(b2);
enemyBullets.push_back(b3);
}
}
// 子弹击中敌人
for (int i = 0; i < enemies.size(); i++) {
if (!enemies[i].alive) continue;
for (int j = 0; j < playerBullets.size(); j++) {
if (playerBullets[j].x == enemies[i].x && playerBullets[j].y == enemies[i].y) {
enemies[i].alive = false;
score += 10;
playerBullets.erase(playerBullets.begin() + j);
break;
}
}
}
// 子弹击中BOSS
if (boss.alive) {
for (int j = 0; j < playerBullets.size(); j++) {
if (playerBullets[j].y == boss.y &&
playerBullets[j].x >= boss.x - 1 &&
playerBullets[j].x <= boss.x + 1) {
boss.hp--;
score += 10;
playerBullets.erase(playerBullets.begin() + j);
if (boss.hp <= 0) {
boss.alive = false;
}
break;
}
}
}
// 玩家碰撞
bool hit = false;
for (int i = 0; i < enemyBullets.size(); i++) {
if (enemyBullets[i].x == playerX && enemyBullets[i].y == playerY) {
hit = true;
}
}
for (int i = 0; i < enemies.size(); i++) {
if (enemies[i].alive && enemies[i].x == playerX && enemies[i].y == playerY) {
hit = true;
}
}
if (boss.alive && playerY == boss.y && playerX >= boss.x - 1 && playerX <= boss.x + 1) {
hit = true;
}
if (hit) {
lives--;
playerX = WIDTH / 2;
enemyBullets.clear();
if (lives <= 0) gameOver = true;
}
}
void drawGame() {
clearScreen();
drawBorder();
// 玩家
screen[playerY][playerX] = '^';
// 敌人
for (int i = 0; i < enemies.size(); i++) {
if (enemies[i].alive) {
screen[enemies[i].y][enemies[i].x] = '*';
}
}
// BOSS
if (boss.alive) {
screen[boss.y][boss.x - 1] = '#';
screen[boss.y][boss.x] = '#';
screen[boss.y][boss.x + 1] = '#';
}
// 子弹
for (int i = 0; i < playerBullets.size(); i++) {
screen[playerBullets[i].y][playerBullets[i].x] = '|';
}
for (int i = 0; i < enemyBullets.size(); i++) {
screen[enemyBullets[i].y][enemyBullets[i].x] = '.';
}
// 信息
char info[60];
sprintf(info, "Score:%-4d HP:%d", score, lives);
for (int i = 0; info[i]; i++) {
screen[HEIGHT-1][2+i] = info[i];
}
if (boss.alive) {
sprintf(info, "BOSS HP:%d", boss.hp);
for (int i = 0; info[i]; i++) {
screen[HEIGHT-1][25+i] = info[i];
}
}
renderScreen();
Sleep(30);
}
int main() {
srand((unsigned)time(NULL));
system("mode con cols=60 lines=31");
hideCursor();
initGame();
initEnemies();
while (!gameOver) {
input();
spawnBoss();
logic();
drawGame();
}
setPos(0, HEIGHT-1);
cout << " GAME OVER! Score: " << score << endl;
return 0;
}