躺平发育.cpp

发布于:2025-08-07 ⋅ 阅读:(28) ⋅ 点赞:(0)

#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;
}


网站公告

今日签到

点亮在社区的每一天
去签到