0
点赞
收藏
分享

微信扫一扫

C++/SFML面向对象课程设计,坦克大战

一、 设计任务及需求分析

《坦克大战》是由日本南梦宫Namco游戏公司开发的一款平面射击游戏,于1985年发售。游戏以坦克战斗及保卫基地为主题,属于策略型联机类。以二战坦克为题材,既保留了射击类游戏的操作性,也改进了射击类游戏太过于复杂难玩的高门槛特点,集休闲与竞技于一身。
使用第三方图形库SFML还原FC经典坦克大战,用13*13的方块组成游戏地图,地形包括空气,钢板,砖墙,实现原版坦克大战中坦克行走,坦克与墙壁之间碰撞,坦克发射子弹,敌军生成,敌军随机走动,子弹与实体之间互动,游戏键盘操作,游戏结束界面
游戏操作,WASD控制玩家坦克上下左右移动,J发射子弹

二、总体设计方案

用Game类作为中介类,内存有所有游戏对象的指针,而每个游戏对象都有Game类的指针,用于不同游戏模块之间的通信,Game类又负责了整个游戏的运行(Run()成员函数用于处理每一帧的要处理的事件,PushEvent将每个要处理的键盘事件交给Control对象处理)

Control类用于处理键盘输入信息,使得游戏对象对于每个得到的事件做出相应的反应,例如WASD改变玩家的转向以及移动

Drawer类用于绘制所有地图中的游戏对象,控制绘制顺序

GameObject类作为所有游戏对象的父类,内涵纹理以及纹理对象的属性,以及纯虚函数Draw()接口

Block类作为所有方块对象的父类,内含枚举类型方块种类BlockType,WallBlock构造函数为BlockType赋值,其他方块同理
Map类是Block类的聚合,构造函数为其初始化每个方块的位置,用字符串数组来快速编辑地图方块布局,setLostMap()为设置游戏结束之后地图显示的界面

Player类内含speed,isDead,isMoving, direction属性,
Move()方法:按照direction方向以speed速度运动,每次运动判断是否与所有游戏对象发生碰撞,若碰撞退回去且不再运动
Turn(Direction dir)方法:设置运动方向,贴图旋转

Enemy类内含静态属性StartPos设置每次生成位置,属性sf::Clock计时器用于控制每个敌方坦克的发射子弹的时间

Bullet抽象类内含speed,isDead属性,Move方法每次运动都会去判断是否有碰撞到游戏对象,若发生碰撞,则设置Bullet和该对“死亡”,在game->Run()中将其清除,PlayerBullet实现了Move函数,EnemyBullet实现了Move函数

Home类为游戏中基地对象,若isDead属性为True则游戏结束

UML 类图

源代码

//main.cpp
#include <SFML/Graphics.hpp>
#include <iostream>
#include "Game.h"
using namespace std;

int main() {
    sf::RenderWindow window(sf::VideoMode(832, 832), "BattleCity");
    window.setFramerateLimit(60);
    window.setKeyRepeatEnabled(false);
    Game game(&window);
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            game.PushEvent(event);
        }
        game.Run();
        window.clear();
        game.drawer->DrawAll();
        window.display();
    }
    return 0;
}

//Game.h
#pragma once
#include <iostream>
#include <list>
#include <vector>
#include <SFML/Graphics.hpp>
#include "Player.h"
#include "Block.h"
#include "Drawer.h"
#include "Enemy.h"
#include "Control.h"
#include "Map.h"
#include "Bullet.h"
#include "Home.h"
class Player;
class Bullet;
class Enemy;
class Block;
class Drawer;
class Control;
class Map;
class Home;
enum class Direction {
    Up,
    Down,
    Left,
    Right
};
class Game {
public:
    Game(sf::RenderWindow* window);
    sf::Clock* clock;
    Player* player;
    std::list<Bullet*> bulletList;
    sf::RenderWindow* window;
    std::list<Enemy*> enemyList;
    Drawer* drawer;
    Control* control;
    Map* map;
    Home* home;
    bool isFailed;
    void PushEvent(sf::Event event);
    void Run();
    void Over();
};


//Game.cpp
#include "Game.h"
Game::Game(sf::RenderWindow* window) {
    this->control = new Control(this);
    this->map = new Map(this);
    this->drawer = new Drawer(this);
    this->player = new Player(this);
    this->window = window;
    this->clock = new sf::Clock;
    this->home = new Home(this);
    this->isFailed = false;
}
void Game::PushEvent(sf::Event event) {
    control->Input(event);
}
void Game::Run() {
    if(isFailed == true){
        this->map->setLostMap();
    }
    else {
        player->Move();
        for (auto& item : bulletList) {
            item->Move();
        }
        for (auto& item : enemyList) {
            item->Move();
        }
        for (auto& item : enemyList) {
            item->Shoot();
        }
        for (std::list<Bullet*>::iterator iter = bulletList.begin(); iter != bulletList.end();) {
            if ((*iter)->isDead) {
                delete (*iter);
                bulletList.erase(iter);
                iter = bulletList.begin();
            }
            else
                iter++;
        }
        for (std::list<Enemy*>::iterator iter = enemyList.begin(); iter != enemyList.end();) {
            if ((*iter)->isDead) {
                delete (*iter);
                enemyList.erase(iter);
                iter = enemyList.begin();
            }
            else
                iter++;
        }
        if (this->clock->getElapsedTime().asSeconds() >= 3.0f && this->enemyList.size() < 4) {
            Enemy* enemy = new Enemy(this);
            enemyList.push_back(enemy);
            this->clock->restart();
        }
        if (this->player->isDead || this->home->isDead) {
            this->isFailed = true;
        }
    }
    
}
void Game::Over() {
    this->map->setLostMap();
    this->player->sprite.setPosition(-10.0f, -10.0f);
    for (std::list<Enemy*>::iterator iter = enemyList.begin(); iter != enemyList.end(); iter++) {
        delete (*iter);
    }
    enemyList.clear();
    delete this->player;
}

//Block.h
#pragma once
#include <SFML/Graphics.hpp>
#include "Game.h"
#include "GameObject.h"
class Game;
enum class BlockType {
    Empty,
    Wall,
    Iron
};
class Block : public GameObject {
protected:
    Block(Game* game);
    Game* game;
public:
    BlockType type;
    void setPosition(float x, float y);
    void Draw();
};
class WallBlock: public Block {
public:
    WallBlock(Game* game);
};
class EmptyBlock : public Block {
public:
    EmptyBlock(Game* game);
};
class IronBlock : public Block {
public:
    IronBlock(Game* game);
};

//Block.cpp
#include "Block.h"
Block::Block(Game* game) {
    this->game = game;
}
void Block::setPosition(float x, float y) {
    this->sprite.setPosition(x, y);
}
void Block::Draw() {
    game->window->draw(this->sprite);
}
WallBlock::WallBlock(Game* game): Block(game) {
    
    this->texture.loadFromFile("Src\\Wall.png");
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->type = BlockType::Wall;
}
EmptyBlock::EmptyBlock(Game* game):Block(game) {
    this->texture.loadFromFile("Src\\Empty.png");
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->type = BlockType::Empty;
}
IronBlock::IronBlock(Game* game):Block(game) {
    this->texture.loadFromFile("Src\\Iron.png");
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->type = BlockType::Iron;
}
//Bullet.h
#pragma once
#include "Game.h"
class Game;
enum class Direction;
class Bullet : public GameObject {
protected:
    Game* game;
public:
    Direction dir;
    float speed;
    bool isDead;
    Bullet(Game* game, Direction dir);
    virtual void Move() = 0;
    void Draw();
};

class PlayerBullet : public Bullet {
public:
    PlayerBullet(Game* game, Direction dir);
    void Move();
};
class EnemyBullet : public Bullet {
public:
    EnemyBullet(Game* game, Direction dir);
    void Move();
};
//Bullet.cpp
#include "Bullet.h"

Bullet::Bullet(Game* game, Direction dir) {
    this->game = game;
    this->texture.loadFromFile("Src\\Bullet.png");
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->speed = 16.0f;
    this->sprite.setOrigin(1.5f, 2.0f);
    this->dir = dir;
    switch (dir) {
    case Direction::Up:
        this->sprite.setRotation(0);
        break;
    case Direction::Down:
        this->sprite.setRotation(180);
        break;
    case Direction::Left:
        this->sprite.setRotation(270);
        break;
    case Direction::Right:
        this->sprite.setRotation(90);
        break;
    }
    this->isDead = false;
}
PlayerBullet::PlayerBullet(Game* game, Direction dir) :Bullet(game, dir) {}
EnemyBullet::EnemyBullet(Game* game, Direction dir) : Bullet(game, dir) {}

void Bullet::Draw() {
    game->window->draw(this->sprite);
}

void PlayerBullet::Move() {
    switch (dir) {
    case Direction::Up:
        this->sprite.move(0, -this->speed); break;
    case Direction::Down:
        this->sprite.move(0, this->speed); break;
    case Direction::Left:
        this->sprite.move(-this->speed, 0); break;
    case Direction::Right:
        this->sprite.move(this->speed, 0); break;
    }
    for (int i = 0; i < game->map->Block2D.size(); i++) {
        for (int j = 0; j < game->map->Block2D[0].size(); j++) {
            if (game->map->Block2D[i][j]->type == BlockType::Wall && this->sprite.getGlobalBounds().intersects(game->map->Block2D[i][j]->sprite.getGlobalBounds())) {
                this->isDead = true;
                delete game->map->Block2D[i][j];
                game->map->Block2D[i][j] = new EmptyBlock(game);
            }
            if (game->map->Block2D[i][j]->type == BlockType::Iron && this->sprite.getGlobalBounds().intersects(game->map->Block2D[i][j]->sprite.getGlobalBounds())) {
                this->isDead = true;
            }
        }
    }
    if (this->sprite.getPosition().x > 830 || this->sprite.getPosition().x < 0 || this->sprite.getPosition().y > 832 || this->sprite.getPosition().y < 0)
        this->isDead = true;
    for (auto itm : game->enemyList) {
        if (this->sprite.getGlobalBounds().intersects(itm->sprite.getGlobalBounds())) {
            this->isDead = true;
            itm->isDead = true;
        }
    }
    if (this->sprite.getGlobalBounds().intersects(game->home->sprite.getGlobalBounds()))
        game->home->isDead = true;
}

void EnemyBullet::Move() {
    switch (dir) {
    case Direction::Up:
        this->sprite.move(0, -this->speed); break;
    case Direction::Down:
        this->sprite.move(0, this->speed); break;
    case Direction::Left:
        this->sprite.move(-this->speed, 0); break;
    case Direction::Right:
        this->sprite.move(this->speed, 0); break;
    }
    for (int i = 0; i < game->map->Block2D.size(); i++) {
        for (int j = 0; j < game->map->Block2D[0].size(); j++) {
            if (game->map->Block2D[i][j]->type == BlockType::Wall && this->sprite.getGlobalBounds().intersects(game->map->Block2D[i][j]->sprite.getGlobalBounds())) {
                this->isDead = true;
                delete game->map->Block2D[i][j];
                game->map->Block2D[i][j] = new EmptyBlock(game);
            }
            if (game->map->Block2D[i][j]->type == BlockType::Iron && this->sprite.getGlobalBounds().intersects(game->map->Block2D[i][j]->sprite.getGlobalBounds())) {
                this->isDead = true;
            }
        }
    }
    if (this->sprite.getPosition().x > 830 || this->sprite.getPosition().x < 0 || this->sprite.getPosition().y > 832 || this->sprite.getPosition().y < 0)
        this->isDead = true;
    if (this->sprite.getGlobalBounds().intersects(game->player->sprite.getGlobalBounds())) {
        this->isDead = true;
        game->player->isDead = true;
    }
    if (this->sprite.getGlobalBounds().intersects(game->home->sprite.getGlobalBounds()))
        game->home->isDead = true;
}

//Control.h
#pragma once
#include "Game.h"
class Game;
class Control {
public:
    Game* game;
    Control(Game* game);
    void Input(sf::Event event);
};
//Control.cpp
#include "Control.h"
#include <iostream>
Control::Control(Game* game) {
    this->game = game;
}
void Control::Input(sf::Event event) {
    if (event.type == sf::Event::Closed || (event.type == sf::Event::KeyPressed &&event.key.code == sf::Keyboard::Escape)) {
        game->window->close();
    }
    if (game->isFailed == false) {
        if (event.type == sf::Event::KeyPressed) {
            if (event.key.code == sf::Keyboard::A) {
                if (game->player->dir != Direction::Left)
                    game->player->Turn(Direction::Left);
                game->player->isMoving = true;
            }
            if (event.key.code == sf::Keyboard::W) {
                if (game->player->dir != Direction::Up)
                    game->player->Turn(Direction::Up);
                game->player->isMoving = true;
            }
            if (event.key.code == sf::Keyboard::S) {
                if (game->player->dir != Direction::Down)
                    game->player->Turn(Direction::Down);
                game->player->isMoving = true;
            }
            if (event.key.code == sf::Keyboard::D) {
                if (game->player->dir != Direction::Right)
                    game->player->Turn(Direction::Right);
                game->player->isMoving = true;
            }
            if (event.key.code == sf::Keyboard::J) {
                float tx, ty;
                Bullet* bullet = NULL;
                tx = game->player->sprite.getPosition().x;
                ty = game->player->sprite.getPosition().y;
                switch (game->player->dir) {
                case Direction::Up:
                    bullet = new PlayerBullet(game, Direction::Up);
                    ty -= 16; break;
                case Direction::Down:
                    bullet = new PlayerBullet(game, Direction::Down);
                    ty += 16; break;
                case Direction::Left:
                    bullet = new PlayerBullet(game, Direction::Left);
                    tx -= 16; break;
                case Direction::Right:
                    bullet = new PlayerBullet(game, Direction::Right);
                    tx += 16; break;
                }
                bullet->sprite.setPosition(tx, ty);
                game->bulletList.push_back(bullet);
            }
        }
        if (event.type == sf::Event::KeyReleased) {
            game->player->isMoving = false;
        }
    }
}
//Drawer.h
#pragma once
#include "Game.h"
class Game;
class Drawer {
    Game* game;
public:
    Drawer(Game* game);
    void DrawAll();
};
//Drawer.cpp
#include "Drawer.h"
Drawer::Drawer(Game* game) {
    this->game = game;
}
void Drawer::DrawAll() {
    this->game->map->Draw();
    if (game->isFailed == false) {
        this->game->player->Draw();
        for (std::list<Bullet*>::iterator iter = game->bulletList.begin(); iter != game->bulletList.end(); iter++) {
            (*iter)->Draw();
        }
        for (std::list<Enemy*>::iterator iter = game->enemyList.begin(); iter != game->enemyList.end(); iter++) {
            (*iter)->Draw();
        }
        this->game->home->Draw();
    }
}
//Enemy.h
#pragma once
#include "Game.h"
#include "GameObject.h"
class Game;
enum class Direction;
enum class StartPos {
    Left,
    Middle,
    Right
};
class Enemy : public GameObject {
    Game* game;
public:
    sf::Clock clock;
    static int remain;
    static StartPos spos;
    Direction dir;
    float speed;
    bool isDead;
    bool isFrozen;
    Enemy(Game* game);
    void Draw();
    void Move();
    void Shoot();
};
//Enemy.cpp
#include "Enemy.h"
Enemy::Enemy(Game* game) {
    this->game = game;
    this->texture.loadFromFile("Src\\TankEnemy.png");
    this->isDead = false;
    this->speed = 4.0f;
    this->dir = Direction::Down;
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->sprite.setOrigin(6.5f, 7.5f);
    this->isFrozen = false;
    switch (this->spos)
    {
    case StartPos::Left:
        this->sprite.setPosition(32.0f, 32.0f);
        this->spos = StartPos::Middle;
        break;
    case StartPos::Middle:
        this->sprite.setPosition(416.0f, 32.0f);
        this->spos = StartPos::Right;
        break;
    case StartPos::Right:
        this->sprite.setPosition(800.0f, 32.0f);
        this->spos = StartPos::Left;
        break;
    }
}
void Enemy::Draw() {
    game->window->draw(this->sprite);
}
void Enemy::Move() {
    if (isFrozen == false) {
        if (clock.getElapsedTime().asSeconds() > 1) {
            dir = (Direction)(rand() % 4);
            clock.restart();
        }
        switch (dir) {
        case Direction::Up:
            this->sprite.setRotation(0); this->dir = Direction::Up; break;
        case Direction::Down:
            this->sprite.setRotation(180); this->dir = Direction::Down; break;
        case Direction::Left:
            this->sprite.setRotation(270); this->dir = Direction::Left; break;
        case Direction::Right:
            this->sprite.setRotation(90); this->dir = Direction::Right; break;
        }
        float dx, dy;
        switch (this->dir) {
        case Direction::Up:
            dx = 0; dy = -speed; break;
        case Direction::Down:
            dx = 0; dy = speed; break;
        case Direction::Left:
            dx = -speed; dy = 0; break;
        case Direction::Right:
            dx = speed; dy = 0; break;
        }
        this->sprite.move(dx, dy);
        for (int i = 0; i < game->map->Block2D.size(); i++) {
            for (int j = 0; j < game->map->Block2D[0].size(); j++) {
                if (game->map->Block2D[i][j]->type != BlockType::Empty && this->sprite.getGlobalBounds().intersects(game->map->Block2D[i][j]->sprite.getGlobalBounds())) {
                    this->sprite.move(-dx, -dy);
                }
            }
        }
        for (auto itm : game->enemyList) {
            if(this->sprite.getGlobalBounds().intersects(itm->sprite.getGlobalBounds()) && itm != this)
                this->sprite.move(-dx, -dy);
        }
        if (this->sprite.getPosition().x - 28.0f < 0 || this->sprite.getPosition().y - 28.0f < 0 || this->sprite.getPosition().x + 28.0f > 832 || this->sprite.getPosition().y + 28.0f > 832)
            this->sprite.move(-dx, -dy);
        if(this->sprite.getGlobalBounds().intersects(game->player->sprite.getGlobalBounds()))
            this->sprite.move(-dx, -dy);
    }
    else {
        if (clock.getElapsedTime().asSeconds() > 8) {
            this->isFrozen = false;
            this->clock.restart();
        }
    }
}
void Enemy::Shoot() {
    if ((int)clock.getElapsedTime().asMicroseconds() % 500 < 5 && this->isFrozen == false) {
        float tx, ty;
        Bullet* bullet = NULL;
        tx = this->sprite.getPosition().x;
        ty = this->sprite.getPosition().y;
        switch (this->dir) {
        case Direction::Up:
            bullet = new EnemyBullet(game, Direction::Up);
            ty -= 16; break;
        case Direction::Down:
            bullet = new EnemyBullet(game, Direction::Down);
            ty += 16; break;
        case Direction::Left:
            bullet = new EnemyBullet(game, Direction::Left);
            tx -= 16; break;
        case Direction::Right:
            bullet = new EnemyBullet(game, Direction::Right);
            tx += 16; break;
        }
        bullet->sprite.setPosition(tx, ty);
        game->bulletList.push_back(bullet);
        clock.restart();
    }
}
StartPos Enemy::spos = StartPos::Left;
//GameObject.h
#pragma once
#include <SFML/Graphics.hpp>
class GameObject {
public:
    sf::Texture texture;
    sf::Sprite sprite;
    virtual void Draw() = 0;
};
//Home.h
#pragma once
#include "Game.h"
#include "GameObject.h"
class Game;
class Home : public GameObject {
    Game* game;
public:
    bool isDead;
    Home(Game* game);
    void Draw();
};
//Home.cpp
#include "Home.h"
Home::Home(Game* game) {
    this->game = game;
    this->texture.loadFromFile("Src\\Home.png");
    this->isDead = false;
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->sprite.setPosition(384.0, 768.0f);
}
void Home::Draw() {
    game->window->draw(this->sprite);
}
//Map.h
#pragma once
#include <vector>
#include "Block.h"
#include "Game.h"
class Game;
class Block;
class Map {
    Game* game;
public:
    std::vector<std::vector<Block*>> Block2D;
    Map(Game* game);
    void Draw();
    void setLostMap();
};
//Map.cpp
#include "Map.h"
Map::Map(Game* game) {
    this->game = game;
    std::vector<std::string> tMap = {
        "..........................",
        "..........................",
        "..##..##..##..##..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..##%%##..##..##..",
        "..##..##..##%%##..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..........##..##..",
        "..##..##..........##..##..",
        "..........##..##..........",
        "..........##..##..........",
        "##..####..........####..##",
        "%%..####..........####..%%",
        "..........##..##..........",
        "..........######..........",
        "..##..##..######..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..##..##..##..##..",
        "..##..##..........##..##..",
        "..##..##..........##..##..",
        "..##..##...####...##..##..",
        "...........#..#...........",
        "...........#..#..........."
    };
    this->Block2D.resize(26);
    for (auto& itm : this->Block2D) {
        itm.resize(26);
    }
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < 26; j++) {
            if (tMap[i][j] == '.') {
                this->Block2D[j][i] = new EmptyBlock(game);
                this->Block2D[j][i]->setPosition(j * 32, i * 32);
            }
            else if (tMap[i][j] == '#') {
                this->Block2D[j][i] = new WallBlock(game);
                this->Block2D[j][i]->setPosition(j * 32, i * 32);
            }
            else if (tMap[i][j] == '%') {
                this->Block2D[j][i] = new IronBlock(game);
                this->Block2D[j][i]->setPosition(j * 32, i * 32);
            }
        }
    }
}
void Map::Draw() {
    for (int i = 0; i < this->Block2D.size(); i++) {
        for (int j = 0; j < this->Block2D.size(); j++) {
            Block2D[i][j]->Draw();
        }
    }
}
void Map::setLostMap() {
    std::vector<std::string> rMap = {
        "..........................",
        "..........................",
        "..###...###...##.##..####.",
        ".#.....#...#.#..#..#.#....",
        ".#.....#####.#..#..#.####.",
        ".#..##.#...#.#..#..#.#....",
        ".#...#.#...#.#..#..#.#....",
        "..###..#...#.#..#..#.####.",
        "..........................",
        "..........................",
        "..###..#...#.####.###..#..",
        ".#...#.#...#.#....#..#.#..",
        ".#...#.#...#.####.#..#.#..",
        ".#...#.#...#.#....###..#..",
        ".#...#..#.#..#....#..#....",
        "..###....#...####.#..#.#..",
        "..........................",
        "..%..........%%%..........",
        "..%.........%...%.......%.",
        "..%%..%.%.%.%...%.%.%..%..",
        "..%.%.%.%...%...%.%.%.%%%.",
        "..%%...%%.%..%%%...%%..%..",
        "........%.......%...%..%..",
        "........%...........%..%..",
        ".......%...........%..%...",
        ".........................."
    };
    for (int i = 0; i < 26; i++) {
        for (int j = 0; j < 26; j++) {
            if (rMap[i][j] == '.') {
                delete this->Block2D[j][i];
                this->Block2D[j][i] = new EmptyBlock(game);
                this->Block2D[j][i]->setPosition(j * 32, i * 32);
            }
            else if (rMap[i][j] == '#') {
                delete this->Block2D[j][i];
                this->Block2D[j][i] = new WallBlock(game);
                this->Block2D[j][i]->setPosition(j * 32, i * 32);
            }
            else if (rMap[i][j] == '%') {
                delete this->Block2D[j][i];
                this->Block2D[j][i] = new IronBlock(game);
                this->Block2D[j][i]->setPosition(j * 32, i * 32);
            }
        }
    }
}
//Player.h
#pragma once
#include <SFML/Graphics.hpp>
#include "Game.h"
#include "GameObject.h"
class Game;
enum class Direction;
class Player : public GameObject {
    Game* game;
public:
    Direction dir;
    bool isDead;
    float speed;
    bool isMoving;
    Player(Game* game);
    void Move();
    void Turn(Direction dir);
    void Draw();
};
//Player.cpp
#include "Player.h"
Player::Player(Game* game) {
    this->speed = 8.0f;
    this->isDead = false;
    this->texture.loadFromFile("Src\\TankPlayer.png");
    this->sprite.setTexture(texture);
    this->sprite.setScale(4.0f, 4.0f);
    this->sprite.setOrigin(6.5f, 6.5f);
    this->sprite.setPosition(288.0f, 768.0f);
    this->dir = Direction::Up;
    this->isMoving = false;
    this->game = game;
}
void Player::Move() {
    if (!this->isMoving)
        return;
    float dx, dy;
    switch (this->dir) {
    case Direction::Up:
        dx = 0; dy = -speed; break;
    case Direction::Down:
        dx = 0; dy = speed; break;
    case Direction::Left:
        dx = -speed; dy = 0; break;
    case Direction::Right:
        dx = speed; dy = 0; break;
    }
    this->sprite.move(dx, dy);
    for (int i = 0; i < game->map->Block2D.size(); i++) {
        for (int j = 0; j < game->map->Block2D[0].size(); j++) {
            if (game->map->Block2D[i][j]->type != BlockType::Empty&&this->sprite.getGlobalBounds().intersects(game->map->Block2D[i][j]->sprite.getGlobalBounds())) {
                this->sprite.move(-dx, -dy);
            }
        }
    }
    if (this->sprite.getPosition().x - 28.0f < 0 || this->sprite.getPosition().y - 28.0f < 0 || this->sprite.getPosition().x + 28.0f > 832 || this->sprite.getPosition().y + 28.0f > 832)
        this->sprite.move(-dx, -dy);
    for (auto itm : game->enemyList) {
        if (this->sprite.getGlobalBounds().intersects(itm->sprite.getGlobalBounds()))
            this->sprite.move(-dx, -dy);
    }
}
void Player::Turn(Direction dir) {
    switch (dir) {
    case Direction::Up:
        this->sprite.setRotation(0); this->dir = Direction::Up; break;
    case Direction::Down:
        this->sprite.setRotation(180); this->dir = Direction::Down; break;
    case Direction::Left:
        this->sprite.setRotation(270); this->dir = Direction::Left; break;
    case Direction::Right:
        this->sprite.setRotation(90); this->dir = Direction::Right; break;
    }
}
void Player::Draw() {
    game->window->draw(this->sprite);
}

程序运行效果截图

请添加图片描述

请添加图片描述

举报

相关推荐

0 条评论