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

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.

主站蜘蛛池模板: 盱眙县| 朝阳区| 濮阳市| 新和县| 汤原县| 常德市| 三原县| 南乐县| 灵山县| 南京市| 郑州市| 尼木县| 张家川| 桑日县| 大名县| 晴隆县| 广州市| 莎车县| 梁河县| 南雄市| 磐安县| 建德市| 化德县| 磐安县| 安新县| 博湖县| 梅州市| 吉隆县| 濮阳县| 嘉义县| 色达县| 尚义县| 广宗县| 诸城市| 威信县| 北安市| 卢氏县| 延安市| 新竹县| 化德县| 武宁县|