躺平发育.cpp

#include <SFML/Graphics.hpp>

//全文仅供参考

#include <iostream>

#include <vector>

#include <cmath>

#include <ctime>

#include <thread>

#include <chrono>

#include <algorithm>

using namespace sf;

using namespace std;

// 资源管理器

class ResourceManager {

public:

static ResourceManager& getInstance() {

static ResourceManager instance;

return instance;

}

Font font;

Texture playerTexture;

Texture ghostTexture;

Texture bedTexture;

Texture doorTexture;

Texture turretTexture;

Texture backgroundTexture;

private:

ResourceManager() {

// 加载资源

if (!font.loadFromFile("arial.ttf")) {

cerr << "Failed to load font!" << endl;

}

if (!playerTexture.loadFromFile("player.png")) {

cerr << "Failed to load player texture!" << endl;

}

if (!ghostTexture.loadFromFile("ghost.png")) {

cerr << "Failed to load ghost texture!" << endl;

}

if (!bedTexture.loadFromFile("bed.png")) {

cerr << "Failed to load bed texture!" << endl;

}

if (!doorTexture.loadFromFile("door.png")) {

cerr << "Failed to load door texture!" << endl;

}

if (!turretTexture.loadFromFile("turret.png")) {

cerr << "Failed to load turret texture!" << endl;

}

if (!backgroundTexture.loadFromFile("background.png")) {

cerr << "Failed to load background texture!" << endl;

}

}

};

// 建筑基类

class Building {

public:

Sprite sprite;

Vector2f position;

int level = 1;

int maxLevel = 5;

int upgradeCost = 50;

Building(Vector2f pos, Texture& tex) : position(pos) {

sprite.setTexture(tex);

sprite.setPosition(pos);

sprite.setOrigin(tex.getSize().x / 2.0f, tex.getSize().y / 2.0f);

}

virtual void upgrade() {

if (level < maxLevel) {

level++;

upgradeCost *= 2;

sprite.setScale(1.0f + level * 0.1f, 1.0f + level * 0.1f);

}

}

virtual void draw(RenderWindow& window) {

window.draw(sprite);

}

};

// 门类

class Door : public Building {

public:

int health = 100;

int maxHealth = 100;

Door(Vector2f pos) : Building(pos, ResourceManager::getInstance().doorTexture) {

sprite.setScale(0.8f, 0.8f);

}

void upgrade() override {

Building::upgrade();

maxHealth = 100 + (level - 1) * 50;

health = maxHealth;

}

void takeDamage(int damage) {

health -= damage;

if (health < 0) health = 0;

// 根据血量改变颜色

float healthRatio = static_cast<float>(health) / maxHealth;

sprite.setColor(Color(255, 255 * healthRatio, 255 * healthRatio));

}

};

// 床类

class Bed : public Building {

public:

int coinGeneration = 1;

bool occupied = false;

Bed(Vector2f pos) : Building(pos, ResourceManager::getInstance().bedTexture) {

sprite.setScale(0.7f, 0.7f);

}

void upgrade() override {

Building::upgrade();

coinGeneration = level;

}

void generateCoins(int& coins) {

if (occupied) {

coins += coinGeneration;

}

}

};

// 炮台类

class Turret : public Building {

public:

int damage = 5;

float range = 150.0f;

float fireRate = 1.0f; // 每秒攻击次数

float fireTimer = 0.0f;

Turret(Vector2f pos) : Building(pos, ResourceManager::getInstance().turretTexture) {

sprite.setScale(0.6f, 0.6f);

}

void upgrade() override {

Building::upgrade();

damage += 3;

range += 20.0f;

fireRate += 0.2f;

}

void update(float deltaTime, Vector2f ghostPos, int& ghostHealth) {

fireTimer += deltaTime;

// 计算与猛鬼的距离

float distance = sqrt(pow(position.x - ghostPos.x, 2) + pow(position.y - ghostPos.y, 2));

// 如果在范围内且冷却结束

if (distance <= range && fireTimer >= 1.0f / fireRate) {

ghostHealth -= damage;

fireTimer = 0.0f;

// 显示攻击效果

attackEffect.setPosition(position);

attackEffect.setTarget(ghostPos);

attackEffect.active = true;

}

if (attackEffect.active) {

attackEffect.update(deltaTime);

}

}

void draw(RenderWindow& window) override {

Building::draw(window);

if (attackEffect.active) {

attackEffect.draw(window);

}

}

private:

class AttackEffect {

public:

Vector2f start;

Vector2f target;

float duration = 0.2f;

float timer = 0.0f;

bool active = false;

void setPosition(Vector2f pos) {

start = pos;

}

void setTarget(Vector2f tgt) {

target = tgt;

timer = 0.0f;

}

void update(float deltaTime) {

timer += deltaTime;

if (timer >= duration) {

active = false;

}

}

void draw(RenderWindow& window) {

float progress = timer / duration;

Vector2f current = start + (target - start) * progress;

CircleShape projectile(3);

projectile.setFillColor(Color::Yellow);

projectile.setOrigin(1.5f, 1.5f);

projectile.setPosition(current);

window.draw(projectile);

}

} attackEffect;

};

// 玩家类

class Player {

public:

Sprite sprite;

Vector2f position;

int coins = 50;

int power = 0;

bool isLying = false;

Bed* currentBed = nullptr;

Player(Vector2f pos) : position(pos) {

sprite.setTexture(ResourceManager::getInstance().playerTexture);

sprite.setPosition(pos);

sprite.setOrigin(ResourceManager::getInstance().playerTexture.getSize().x / 2.0f,

ResourceManager::getInstance().playerTexture.getSize().y / 2.0f);

sprite.setScale(0.6f, 0.6f);

}

void move(Vector2f offset) {

position += offset;

sprite.move(offset);

}

void lieDown(Bed& bed) {

if (!isLying && bed.occupied == false) {

isLying = true;

bed.occupied = true;

currentBed = &bed;

position = bed.position;

sprite.setPosition(position);

}

}

void standUp() {

if (isLying && currentBed) {

isLying = false;

currentBed->occupied = false;

currentBed = nullptr;

}

}

void draw(RenderWindow& window) {

window.draw(sprite);

}

};

// 猛鬼类

class Ghost {

public:

Sprite sprite;

Vector2f position;

Vector2f target;

int health = 100;

int maxHealth = 100;

int damage = 5;

float speed = 50.0f;

float attackTimer = 0.0f;

float attackCooldown = 1.0f;

Door* targetDoor = nullptr;

Ghost(Vector2f pos) : position(pos) {

sprite.setTexture(ResourceManager::getInstance().ghostTexture);

sprite.setPosition(pos);

sprite.setOrigin(ResourceManager::getInstance().ghostTexture.getSize().x / 2.0f,

ResourceManager::getInstance().ghostTexture.getSize().y / 2.0f);

sprite.setScale(0.7f, 0.7f);

}

void setTarget(Door& door) {

targetDoor = &door;

target = door.position;

}

void update(float deltaTime) {

// 移动到目标

if (targetDoor) {

Vector2f direction = target - position;

float distance = sqrt(direction.x * direction.x + direction.y * direction.y);

if (distance > 10.0f) {

direction /= distance;

position += direction * speed * deltaTime;

sprite.setPosition(position);

} else {

// 攻击门

attackTimer += deltaTime;

if (attackTimer >= attackCooldown) {

targetDoor->takeDamage(damage);

attackTimer = 0.0f;

}

}

}

// 更新健康条

healthBar.setSize(Vector2f(50.0f * (static_cast<float>(health) / maxHealth), 5.0f));

healthBar.setPosition(position.x - 25.0f, position.y - 50.0f);

}

void draw(RenderWindow& window) {

window.draw(sprite);

window.draw(healthBar);

}

private:

RectangleShape healthBar = RectangleShape(Vector2f(50.0f, 5.0f));

};

// 游戏类

class Game {

public:

RenderWindow window;

View view;

Player player;

Ghost ghost;

vector<unique_ptr<Building>> buildings;

vector<Bed> beds;

vector<Door> doors;

vector<Turret> turrets;

Clock gameClock;

Font font;

int coins = 50;

int power = 0;

Text coinsText;

Text powerText;

Text gameMessage;

RectangleShape coinIcon;

RectangleShape powerIcon;

Game() : window(VideoMode(1024, 768), "躺平发育"),

player(Vector2f(200, 300)),

ghost(Vector2f(800, 300)) {

window.setFramerateLimit(60);

view.setSize(1024, 768);

view.setCenter(512, 384);

font = ResourceManager::getInstance().font;

// 创建UI元素

coinsText.setFont(font);

coinsText.setCharacterSize(24);

coinsText.setFillColor(Color::Yellow);

coinsText.setPosition(40, 10);

powerText.setFont(font);

powerText.setCharacterSize(24);

powerText.setFillColor(Color::Cyan);

powerText.setPosition(40, 40);

gameMessage.setFont(font);

gameMessage.setCharacterSize(32);

gameMessage.setFillColor(Color::Red);

gameMessage.setPosition(300, 10);

gameMessage.setString("");

coinIcon.setSize(Vector2f(30, 30));

coinIcon.setFillColor(Color::Yellow);

coinIcon.setPosition(10, 10);

powerIcon.setSize(Vector2f(30, 30));

powerIcon.setFillColor(Color::Cyan);

powerIcon.setPosition(10, 40);

// 创建地图

createMap();

}

void createMap() {

// 创建宿舍房间

vector<Vector2f> roomPositions = {

Vector2f(200, 200), Vector2f(400, 200),

Vector2f(200, 400), Vector2f(400, 400)

};

// 为每个房间创建床和门

for (auto& pos : roomPositions) {

// 床在房间中央

beds.emplace_back(pos);

Bed& bed = beds.back();

// 门在床的右侧

Vector2f doorPos = pos + Vector2f(100, 0);

doors.emplace_back(doorPos);

}

// 设置玩家初始床

player.lieDown(beds[0]);

// 设置猛鬼目标

ghost.setTarget(doors[0]);

}

void run() {

while (window.isOpen()) {

float deltaTime = gameClock.restart().asSeconds();

processEvents();

update(deltaTime);

render();

}

}

void processEvents() {

Event event;

while (window.pollEvent(event)) {

if (event.type == Event::Closed) {

window.close();

}

if (event.type == Event::KeyPressed) {

// 玩家移动

if (!player.isLying) {

if (event.key.code == Keyboard::W) player.move(Vector2f(0, -5));

if (event.key.code == Keyboard::S) player.move(Vector2f(0, 5));

if (event.key.code == Keyboard::A) player.move(Vector2f(-5, 0));

if (event.key.code == Keyboard::D) player.move(Vector2f(5, 0));

}

// 躺下/站起

if (event.key.code == Keyboard::Space) {

if (player.isLying) {

player.standUp();

} else {

// 检查玩家是否在床附近

for (auto& bed : beds) {

float distance = sqrt(pow(player.position.x - bed.position.x, 2) +

pow(player.position.y - bed.position.y, 2));

if (distance < 50.0f) {

player.lieDown(bed);

break;

}

}

}

}

// 建筑升级

if (event.key.code == Keyboard::U) {

if (player.isLying && player.currentBed) {

if (coins >= player.currentBed->upgradeCost) {

coins -= player.currentBed->upgradeCost;

player.currentBed->upgrade();

}

}

}

// 建造炮台

if (event.key.code == Keyboard::T) {

if (coins >= 100) {

coins -= 100;

turrets.emplace_back(player.position + Vector2f(50, 0));

}

}

}

}

}

void update(float deltaTime) {

// 更新UI文本

coinsText.setString(to_string(coins));

powerText.setString(to_string(power));

// 玩家在床上时产生金币

if (player.isLying && player.currentBed) {

player.currentBed->generateCoins(coins);

}

// 更新猛鬼

ghost.update(deltaTime);

// 更新炮台

for (auto& turret : turrets) {

turret.update(deltaTime, ghost.position, ghost.health);

}

// 检查游戏结束条件

if (ghost.health <= 0) {

gameMessage.setString("胜利! 猛鬼已被击败!");

} else if (doors[0].health <= 0) {

gameMessage.setString("失败! 门被破坏了!");

}

}

void render() {

window.clear(Color(30, 30, 50));

// 绘制背景

Sprite background(ResourceManager::getInstance().backgroundTexture);

window.draw(background);

// 绘制床

for (auto& bed : beds) {

bed.draw(window);

}

// 绘制门

for (auto& door : doors) {

door.draw(window);

}

// 绘制炮台

for (auto& turret : turrets) {

turret.draw(window);

}

// 绘制玩家

player.draw(window);

// 绘制猛鬼

ghost.draw(window);

// 绘制UI

window.draw(coinIcon);

window.draw(powerIcon);

window.draw(coinsText);

window.draw(powerText);

window.draw(gameMessage);

// 显示控制提示

Text controls("WASD: 移动 空格: 躺下/站起 T: 建造炮台(100金币) U: 升级床", font, 20);

controls.setPosition(10, 700);

controls.setFillColor(Color::White);

window.draw(controls);

window.display();

}

};

int main() {

Game game;

game.run();

return 0;

}