- 小书童——凯撒密码
Q
- 2025-5-4 12:44:16 @
#include <SFML/Graphics.hpp> #include #include #include
// 窗口大小 const int WINDOW_WIDTH = 800; const int WINDOW_HEIGHT = 600;
// 飞机大小 const int PLANE_WIDTH = 50; const int PLANE_HEIGHT = 50;
// 子弹大小 const int BULLET_WIDTH = 5; const int BULLET_HEIGHT = 10;
// 敌机大小 const int ENEMY_WIDTH = 50; const int ENEMY_HEIGHT = 50;
// 障碍物大小 const int OBSTACLE_WIDTH = 30; const int OBSTACLE_HEIGHT = 30;
// 飞机类 class Plane { public: sf::RectangleShape shape; float speed;
Plane() {
shape.setSize(sf::Vector2f(PLANE_WIDTH, PLANE_HEIGHT));
shape.setFillColor(sf::Color::Green);
shape.setPosition(WINDOW_WIDTH / 2 - PLANE_WIDTH / 2, WINDOW_HEIGHT - PLANE_HEIGHT - 10);
speed = 5.0f;
}
void moveLeft() {
if (shape.getPosition().x > 0) {
shape.move(-speed, 0);
}
}
void moveRight() {
if (shape.getPosition().x < WINDOW_WIDTH - PLANE_WIDTH) {
shape.move(speed, 0);
}
}
void shoot(std::vector<sf::RectangleShape>& bullets) {
sf::RectangleShape bullet;
bullet.setSize(sf::Vector2f(BULLET_WIDTH, BULLET_HEIGHT));
bullet.setFillColor(sf::Color::Yellow);
bullet.setPosition(shape.getPosition().x + PLANE_WIDTH / 2 - BULLET_WIDTH / 2, shape.getPosition().y);
bullets.push_back(bullet);
}
};
// 障碍物类 class Obstacle { public: sf::RectangleShape shape;
Obstacle() {
shape.setSize(sf::Vector2f(OBSTACLE_WIDTH, OBSTACLE_HEIGHT));
shape.setFillColor(sf::Color::Black);
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> xDis(0, WINDOW_WIDTH - OBSTACLE_WIDTH);
std::uniform_int_distribution<> yDis(0, WINDOW_HEIGHT / 2);
shape.setPosition(xDis(gen), yDis(gen));
}
};
// 基础敌机类 class BaseEnemy { public: sf::RectangleShape shape; float speed; std::random_device rd; std::mt19937 gen; std::uniform_int_distribution<> moveDirDis; std::uniform_int_distribution<> moveProbDis; std::uniform_real_distribution<> speedChangeDis;
BaseEnemy() : gen(rd()), moveDirDis(0, 3), moveProbDis(0, 1), speedChangeDis(0.8, 1.2) {
shape.setSize(sf::Vector2f(ENEMY_WIDTH, ENEMY_HEIGHT));
shape.setFillColor(sf::Color::Red);
shape.setPosition(rand() % (WINDOW_WIDTH - ENEMY_WIDTH), -rand() % 200);
speed = 2.0f;
}
virtual void move(const std::vector<Obstacle>& obstacles) {
if (moveProbDis(gen) == 1) {
speed *= speedChangeDis(gen);
int dir = moveDirDis(gen);
sf::Vector2f newPos = shape.getPosition();
switch (dir) {
case 0: // 向下
newPos.y += speed;
break;
case 1: // 向左下
if (shape.getPosition().x > 0) {
newPos.x -= speed;
newPos.y += speed;
}
break;
case 2: // 向右下
if (shape.getPosition().x < WINDOW_WIDTH - ENEMY_WIDTH) {
newPos.x += speed;
newPos.y += speed;
}
break;
case 3: // 暂停
return;
}
sf::RectangleShape tempShape = shape;
tempShape.setPosition(newPos);
bool willCollide = false;
for (const auto& obstacle : obstacles) {
if (checkCollision(tempShape, obstacle.shape)) {
willCollide = true;
break;
}
}
if (!willCollide) {
shape.setPosition(newPos);
}
}
}
};
// 快速敌机类,继承自基础敌机类 class FastEnemy : public BaseEnemy { public: FastEnemy() { shape.setFillColor(sf::Color::Magenta); speed = 4.0f; }
void move(const std::vector<Obstacle>& obstacles) override {
BaseEnemy::move(obstacles);
}
};
// 斜向敌机类,继承自基础敌机类 class DiagonalEnemy : public BaseEnemy { public: DiagonalEnemy() { shape.setFillColor(sf::Color::Cyan); speed = 2.5f; }
void move(const std::vector<Obstacle>& obstacles) override {
BaseEnemy::move(obstacles);
}
};
// 检查碰撞 bool checkCollision(const sf::RectangleShape& a, const sf::RectangleShape& b) { return a.getGlobalBounds().intersects(b.getGlobalBounds()); }
int main() { sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Aircraft War");
Plane player;
std::vector<sf::RectangleShape> bullets;
std::vector<std::unique_ptr<BaseEnemy>> enemies;
std::vector<Obstacle> obstacles;
sf::Clock clock;
sf::Time enemySpawnTimer = sf::Time::Zero;
sf::Time obstacleSpawnTimer = sf::Time::Zero;
std::random_device rd;
std::mt19937 gen(rd());
std::uniform_int_distribution<> enemyTypeDis(0, 2);
std::uniform_int_distribution<> enemySpawnIntervalDis(500, 2000);
std::uniform_int_distribution<> obstacleSpawnIntervalDis(3000, 5000); // 障碍物生成时间间隔范围
sf::Time enemySpawnInterval = sf::milliseconds(enemySpawnIntervalDis(gen));
sf::Time obstacleSpawnInterval = sf::milliseconds(obstacleSpawnIntervalDis(gen));
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) {
window.close();
}
if (event.type == sf::Event::KeyPressed) {
if (event.key.code == sf::Keyboard::Left) {
player.moveLeft();
}
if (event.key.code == sf::Keyboard::Right) {
player.moveRight();
}
if (event.key.code == sf::Keyboard::Space) {
player.shoot(bullets);
}
}
}
// 生成敌机
enemySpawnTimer += clock.restart();
if (enemySpawnTimer >= enemySpawnInterval) {
int enemyType = enemyTypeDis(gen);
switch (enemyType) {
case 0:
enemies.emplace_back(std::make_unique<BaseEnemy>());
break;
case 1:
enemies.emplace_back(std::make_unique<FastEnemy>());
break;
case 2:
enemies.emplace_back(std::make_unique<DiagonalEnemy>());
break;
}
enemySpawnTimer = sf::Time::Zero;
enemySpawnInterval = sf::milliseconds(enemySpawnIntervalDis(gen));
}
// 生成障碍物
obstacleSpawnTimer += clock.getElapsedTime();
if (obstacleSpawnTimer >= obstacleSpawnInterval) {
obstacles.emplace_back();
obstacleSpawnTimer = sf::Time::Zero;
obstacleSpawnInterval = sf::milliseconds(obstacleSpawnIntervalDis(gen));
}
// 移动子弹
for (auto it = bullets.begin(); it != bullets.end();) {
it->move(0, -5);
if (it->getPosition().y < 0) {
it = bullets.erase(it);
} else {
++it;
}
}
// 移动敌机
for (auto enemyIt = enemies.begin(); enemyIt != enemies.end();) {
(*enemyIt)->move(obstacles);
if ((*enemyIt)->shape.getPosition().y > WINDOW_HEIGHT) {
enemyIt = enemies.erase(enemyIt);
} else {
// 检查子弹与敌机的碰撞
for (auto bulletIt = bullets.begin(); bulletIt != bullets.end();) {
if (checkCollision((*enemyIt)->shape, *bulletIt)) {
enemyIt = enemies.erase(enemyIt);
bulletIt = bullets.erase(bulletIt);
break;
} else {
++bulletIt;
}
}
// 检查敌机与玩家的碰撞
if (checkCollision((*enemyIt)->shape, player.shape)) {
std::cout << "Game Over!" << std::endl;
window.close();
}
if (enemyIt != enemies.end()) {
++enemyIt;
}
}
}
window.clear();
// 绘制玩家飞机
window.draw(player.shape);
// 绘制子弹
for (const auto& bullet : bullets) {
window.draw(bullet);
}
// 绘制敌机
for (const auto& enemy : enemies) {
window.draw(enemy->shape);
}
// 绘制障碍物
for (const auto& obstacle : obstacles) {
window.draw(obstacle.shape);
}
window.display();
}
return 0;
}
0 条评论
信息
- ID
- 1976
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 5
- 标签
- 递交数
- 64
- 已通过
- 25
- 上传者