#include <iostream>
#include <conio.h>
#include <windows.h>
#include <vector>
#include <cstdlib>
#include <ctime>
#include <algorithm>
using namespace std;
// 控制台图形设置
const int CONSOLE_WIDTH = 80;
const int CONSOLE_HEIGHT = 25;
const int GROUND_LEVEL = 20;
// 游戏状态
bool gameOver = false;
int score = 0;
int gameSpeed = 50;
// 控制台光标位置设置
void gotoXY(int x, int y) {
COORD coord;
coord.X = x;
coord.Y = y;
SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}
// 隐藏光标
void hideCursor() {
CONSOLE_CURSOR_INFO cursorInfo;
GetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
cursorInfo.bVisible = FALSE;
SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursorInfo);
}
// 清屏函数
void clearScreen() {
system("cls");
}
// 火柴人类
class StickMan {
private:
int x, y;
int velocityY;
bool isJumping;
bool isCrouching;
int jumpForce;
public:
StickMan() {
x = 10;
y = GROUND_LEVEL - 5;
velocityY = 0;
isJumping = false;
isCrouching = false;
jumpForce = 4;
}
int getX() { return x; }
int getY() { return y; }
bool getIsJumping() { return isJumping; }
void jump() {
if (!isJumping) {
isJumping = true;
velocityY = -jumpForce;
}
}
void crouch() {
isCrouching = true;
}
void stand() {
isCrouching = false;
}
void update() {
if (isJumping) {
y += velocityY;
velocityY += 1;
int groundPos = GROUND_LEVEL - (isCrouching ? 3 : 5);
if (y >= groundPos) {
y = groundPos;
isJumping = false;
velocityY = 0;
}
if (y < 5) {
y = 5;
velocityY = 0;
}
}
}
void draw() {
int drawY = y;
gotoXY(x, drawY);
cout << " O ";
gotoXY(x, drawY + 1);
cout << "/|\\";
gotoXY(x, drawY + 2);
if (isCrouching) {
cout << "< >";
} else {
cout << "/ \\";
}
}
void clear() {
for (int i = 0; i < 3; i++) {
gotoXY(x, y + i);
cout << " ";
}
}
int getCollisionHeight() {
return isCrouching ? 3 : 5;
}
int getCollisionY() {
return y;
}
void reset() {
x = 10;
y = GROUND_LEVEL - 5;
velocityY = 0;
isJumping = false;
isCrouching = false;
}
};
// 障碍物类
class Obstacle {
private:
int x, y;
int type;
int width;
public:
Obstacle(int startX, int obstacleType) {
x = startX;
type = obstacleType;
width = 3;
if (type == 0) {
y = GROUND_LEVEL - 2;
} else {
y = GROUND_LEVEL - 5;
}
}
int getX() { return x; }
int getY() { return y; }
int getType() { return type; }
int getWidth() { return width; }
void update() {
x--;
}
void draw() {
if (type == 0) {
gotoXY(x, y);
cout << "█";
gotoXY(x + 1, y);
cout << "█";
gotoXY(x + 2, y);
cout << "█";
gotoXY(x, y + 1);
cout << "█";
gotoXY(x + 1, y + 1);
cout << "█";
gotoXY(x + 2, y + 1);
cout << "█";
} else {
for (int i = 0; i < 5; i++) {
gotoXY(x, y + i);
cout << "█";
}
gotoXY(x + 1, y);
cout << "█";
gotoXY(x + 2, y);
cout << "█";
gotoXY(x + 1, y + 1);
cout << "█";
gotoXY(x + 2, y + 1);
cout << "█";
gotoXY(x + 1, y + 2);
cout << "█";
gotoXY(x + 2, y + 2);
cout << "█";
}
}
void clear() {
if (type == 0) {
for (int i = 0; i < 2; i++) {
gotoXY(x, y + i);
cout << " ";
}
} else {
for (int i = 0; i < 5; i++) {
gotoXY(x, y + i);
cout << " ";
}
for (int i = 0; i < 3; i++) {
gotoXY(x + 1, y + i);
cout << " ";
gotoXY(x + 2, y + i);
cout << " ";
}
}
}
bool checkCollision(StickMan& player) {
int playerLeft = player.getX();
int playerRight = player.getX() + 2;
int playerTop = player.getCollisionY();
int playerBottom = playerTop + player.getCollisionHeight();
int obstacleLeft = x;
int obstacleRight = x + width - 1;
int obstacleTop = y;
int obstacleBottom = y + (type == 0 ? 1 : 4);
if (playerRight >= obstacleLeft && playerLeft <= obstacleRight &&
playerBottom >= obstacleTop && playerTop <= obstacleBottom) {
return true;
}
return false;
}
};
// 游戏类
class Game {
private:
StickMan player;
vector<Obstacle> obstacles;
int obstacleTimer;
int obstacleSpawnDelay;
public:
Game() {
obstacleTimer = 0;
obstacleSpawnDelay = 20;
srand((unsigned int)time(0));
}
void initialize() {
obstacles.clear();
obstacleTimer = 0;
score = 0;
gameOver = false;
gameSpeed = 50;
player.reset();
}
void drawGame() {
clearScreen();
// 绘制边框
for (int i = 0; i < CONSOLE_WIDTH; i++) {
gotoXY(i, 0);
cout << "=";
gotoXY(i, CONSOLE_HEIGHT - 1);
cout << "=";
}
for (int i = 0; i < CONSOLE_HEIGHT; i++) {
gotoXY(0, i);
cout << "|";
gotoXY(CONSOLE_WIDTH - 1, i);
cout << "|";
}
// 绘制地面
for (int i = 1; i < CONSOLE_WIDTH - 1; i++) {
gotoXY(i, GROUND_LEVEL);
cout << "=";
}
// 绘制分数
gotoXY(CONSOLE_WIDTH - 15, 2);
cout << "分数: " << score;
// 绘制标题
gotoXY(5, 2);
cout << "火柴人跑酷";
// 绘制操作说明
gotoXY(5, 4);
cout << "操作: 空格键跳跃, 下箭头蹲下, ESC退出";
}
void processInput() {
if (_kbhit()) {
int key = _getch();
if (key == 32) {
player.jump();
} else if (key == 224) {
key = _getch();
if (key == 80) {
player.crouch();
}
} else if (key == 27) {
gameOver = true;
} else if ((key == 'r' || key == 'R') && gameOver) {
initialize();
}
} else {
player.stand();
}
}
void update() {
player.update();
// 使用传统循环更新障碍物(兼容旧标准)
for (size_t i = 0; i < obstacles.size(); i++) {
obstacles[i].update();
}
// 使用传统循环删除屏幕外的障碍物
for (vector<Obstacle>::iterator it = obstacles.begin(); it != obstacles.end();) {
if (it->getX() < 0) {
it = obstacles.erase(it);
} else {
++it;
}
}
// 生成新障碍物
obstacleTimer++;
if (obstacleTimer >= obstacleSpawnDelay) {
int obstacleType = rand() % 2;
obstacles.push_back(Obstacle(CONSOLE_WIDTH - 5, obstacleType));
obstacleTimer = 0;
obstacleSpawnDelay = max(10, 20 - score / 20);
}
// **碰撞
for (size_t i = 0; i < obstacles.size(); i++) {
if (obstacles[i].checkCollision(player)) {
gameOver = true;
break;
}
}
// 更新分数
if (!gameOver) {
score++;
}
}
void draw() {
player.draw();
for (size_t i = 0; i < obstacles.size(); i++) {
obstacles[i].draw();
}
}
void showGameOver() {
clearScreen();
gotoXY(CONSOLE_WIDTH / 2 - 5, CONSOLE_HEIGHT / 2 - 2);
cout << "游戏结束!";
gotoXY(CONSOLE_WIDTH / 2 - 8, CONSOLE_HEIGHT / 2);
cout << "最终分数: " << score;
gotoXY(CONSOLE_WIDTH / 2 - 10, CONSOLE_HEIGHT / 2 + 2);
cout << "按 R 重新开始,ESC 退出";
gotoXY(CONSOLE_WIDTH / 2 - 15, CONSOLE_HEIGHT / 2 + 4);
cout << "=================================";
}
};
// 主函数
int main() {
system("mode con cols=80 lines=25");
hideCursor();
Game game;
game.initialize();
while (true) {
if (!gameOver) {
game.drawGame();
game.processInput();
game.update();
game.draw();
Sleep(gameSpeed);
} else {
game.showGameOver();
while (gameOver) {
if (_kbhit()) {
char key = _getch();
if (key == 'r' || key == 'R') {
game.initialize();
break;
} else if (key == 27) {
return 0;
}
}
Sleep(100);
}
}
}
return 0;
}
