官术网_书友最值得收藏!

Entities

An entity denotes a game element in the world. In our game, possible entities are friendly and enemy airplanes, bullets, missiles, or pickups that increase the player's strength. Entities interact with each other: enemy airplanes can fire missiles, the player's airplane may evade them, and the missiles may explode if they hit the player's plane, dealing damage to it. The player's aircraft can touch a pickup to collect it, as a result of which it gets a new ability. The possibilities are nearly unlimited, and they may occur between almost any pair of entity types.

In our code, we represent entities using the traditional approach of an entity hierarchy. We have a base class called Entity, which contains the data and functionality that all different kinds of entities have in common. We have multiple classes that derive from Entity, and that implement specific functionality. These derived classes could represent airplanes, projectiles (such as missiles), or pickups. One commonality between different entities is that they can move in our world with a certain velocity.

We implement the velocity attribute in the base class Entity, so each concrete entity has it. The velocity is represented using a two-dimensional vector. In addition to the member variable, we provide the get and set functions to access the velocity from outside the class. The setVelocity() method is overloaded to take either a vector or two separate floats. The header Entity.hpp contains the following class definition:

class Entity
{
    public:
        void                setVelocity(sf::Vector2f velocity);
        void                setVelocity(float vx, float vy);
        sf::Vector2f        getVelocity() const;

    private:
        sf::Vector2f        mVelocity;
};

After initialization, we want the velocity to be zero. Since the class sf::Vector2f has a default constructor, which initializes the vector to a zero vector, we need not define our own constructor; the compiler-generated one works fine.

The function definitions in the file Entity.cpp are not terribly surprising:

void Entity::setVelocity(sf::Vector2f velocity)
{
    mVelocity = velocity;
}

void Entity::setVelocity(float vx, float vy)
{
    mVelocity.x = vx;
    mVelocity.y = vy;
}

sf::Vector2f Entity::getVelocity() const
{
    return mVelocity;
}

Aircraft

Using the example of the aircraft, we need to define a concrete entity class. We derive it from Entity. Since we have different airplanes in our game, it would be nice to have a data type that can store them. An enumeration comes in handy; we call it Type and make it a member of the Aircraft class. Therefore, we can now refer to it as Aircraft::Type, which is quite expressive when we see it in the code. Up to now, we have two distinct airplanes, we call them Eagle and Raptor. Each type of aircraft corresponds to an enumerator in our enum.

Furthermore, we declare a constructor for the aircraft that takes its current type as parameter. We also declare a member variable for the type in the following code:

class Aircraft : public Entity
{
    public:
        enum Type
        {
            Eagle,
            Raptor,
        };

    public:
        explicit        Aircraft(Type type);

    private:
        Type            mType;
};

The constructor's definition is straightforward; we let it initialize our mType member variable:

Aircraft::Aircraft(Type type): mType(type)
{
}

Now this is the fundament for our Aircraft class. During this book, we will continuously extend it and add new functionality.

Alternative entity designs

You should be aware that a class hierarchy is not the only option to model game entities. There are always different possibilities to design a piece of software, all of which have its own advantages and drawbacks.

The hierarchy-based approach gets to its limits when we introduce many, slightly different entity types. Imagine a complex game with different kinds of vehicles, such as tanks, ships, submarines, airplanes, and more. Every entity type has different capabilities, such as flying, transporting people, carrying weapons, and diving. It may be tempting to create corresponding base classes TransportEntity, ArmedEntity, DivingEntity that all derive from Entity. A submarine could then inherit ArmedEntity and DivingEntity; an armed freighter could inherit TransportEntity and ArmedEntity. On one hand, this design leads hand to the so-called diamond of death, where the base class Entity is indirectly inherited multiple times, requiring virtual inheritance. On the other hand, the hierarchy becomes very deep and rigid. In order to reuse functionality for different entities, it is moved to base classes. This makes classes towards the root of the hierarchy a lot heavier than they should be. This in turn results in derived classes which inherit a lot of functions and data they never need. Eventually, objects become overly large, hence slower to process and more difficult to maintain.

In such a case, component-based design would be an alternative, meaning that abilities are aggregated as components in the single entities, instead of base classes. Each entity would then hold the abilities as members. But as you might expect, this approach is not the silver bullet, either. Components often depend more on each other than theory would like them to, and they need an efficient and flexible way to communicate with each other. While component-based approaches are certainly an option to consider for large-scale games, they are rather complex for the first game to develop. In our basic aircraft shooter, the typical problems of entity hierarchies do not show, so we chose this approach for the sake of simplicity.

If you are interested in a more detailed explanation on the topic of component-based game design, we recommend reading the article series on the following website:

http://stefan.boxbox.org/game-development-design.

主站蜘蛛池模板: 建昌县| 六枝特区| 宿州市| 图木舒克市| 重庆市| 抚松县| 平潭县| 兰西县| 玛多县| 耒阳市| 柳河县| 新化县| 沁阳市| 大埔区| 宣武区| 张家港市| 平江县| 斗六市| 海宁市| 晴隆县| 右玉县| 青神县| 天等县| 陵水| 郸城县| 房山区| 海伦市| 荣成市| 平利县| 桦川县| 洪湖市| 丘北县| 孟连| 朝阳区| 离岛区| 太保市| 乌拉特中旗| 杭锦旗| 泰顺县| 灌云县| 抚顺县|