
- •Credits
- •Foreword
- •About the Authors
- •About the Reviewers
- •www.PacktPub.com
- •Table of Contents
- •Preface
- •Introducing SFML
- •Downloading and installation
- •A minimal example
- •A few notes on C++
- •Developing the first game
- •The Game class
- •Game loops and frames
- •Input over several frames
- •Vector algebra
- •Frame-independent movement
- •Fixed time steps
- •Other techniques related to frame rates
- •Displaying sprites on the screen
- •File paths and working directories
- •Real-time rendering
- •Adapting the code
- •Summary
- •Defining resources
- •Resources in SFML
- •Textures
- •Images
- •Fonts
- •Shaders
- •Sound buffers
- •Music
- •A typical use case
- •Graphics
- •Audio
- •Acquiring, releasing, and accessing resources
- •An automated approach
- •Finding an appropriate container
- •Loading from files
- •Accessing the textures
- •Error handling
- •Boolean return values
- •Throwing exceptions
- •Assertions
- •Generalizing the approach
- •Compatibility with sf::Music
- •A special case – sf::Shader
- •Summary
- •Entities
- •Aircraft
- •Alternative entity designs
- •Rendering the scene
- •Relative coordinates
- •SFML and transforms
- •Scene graphs
- •Scene nodes
- •Node insertion and removal
- •Making scene nodes drawable
- •Drawing entities
- •Connecting entities with resources
- •Aligning the origin
- •Scene layers
- •Updating the scene
- •One step back – absolute transforms
- •The view
- •Viewport
- •View optimizations
- •Resolution and aspect ratio
- •View scrolling
- •Zoom and rotation
- •Landscape rendering
- •SpriteNode
- •Landscape texture
- •Texture repeating
- •Composing our world
- •World initialization
- •Loading the textures
- •Building the scene
- •Update and draw
- •Integrating the Game class
- •Summary
- •Polling events
- •Window events
- •Joystick events
- •Keyboard events
- •Mouse events
- •Getting the input state in real time
- •Events and real-time input – when to use which
- •Delta movement from the mouse
- •Playing nice with your application neighborhood
- •A command-based communication system
- •Introducing commands
- •Receiver categories
- •Command execution
- •Command queues
- •Handling player input
- •Commands in a nutshell
- •Implementing the game logic
- •A general-purpose communication mechanism
- •Customizing key bindings
- •Why a player is not an entity
- •Summary
- •Defining a state
- •The state stack
- •Adding states to StateStack
- •Handling updates, input, and drawing
- •Input
- •Update
- •Draw
- •Delayed pop/push operations
- •The state context
- •Integrating the stack in the Application class
- •Navigating between states
- •Creating the game state
- •The title screen
- •Main menu
- •Pausing the game
- •The loading screen – sample
- •Progress bar
- •ParallelTask
- •Thread
- •Concurrency
- •Task implementation
- •Summary
- •The GUI hierarchy, the Java way
- •Updating the menu
- •The promised key bindings
- •Summary
- •Equipping the entities
- •Introducing hitpoints
- •Storing entity attributes in data tables
- •Displaying text
- •Creating enemies
- •Movement patterns
- •Spawning enemies
- •Adding projectiles
- •Firing bullets and missiles
- •Homing missiles
- •Picking up some goodies
- •Collision detection and response
- •Finding the collision pairs
- •Reacting to collisions
- •An outlook on optimizations
- •An interacting world
- •Cleaning everything up
- •Out of view, out of the world
- •The final update
- •Victory and defeat
- •Summary
- •Defining texture atlases
- •Adapting the game code
- •Low-level rendering
- •OpenGL and graphics cards
- •Understanding render targets
- •Texture mapping
- •Vertex arrays
- •Particle systems
- •Particles and particle types
- •Particle nodes
- •Emitter nodes
- •Affectors
- •Embedding particles in the world
- •Animated sprites
- •The Eagle has rolled!
- •Post effects and shaders
- •Fullscreen post effects
- •Shaders
- •The bloom effect
- •Summary
- •Music themes
- •Loading and playing
- •Use case – In-game themes
- •Sound effects
- •Loading, inserting, and playing
- •Removing sounds
- •Use case – GUI sounds
- •Sounds in 3D space
- •The listener
- •Attenuation factor and minimum distance
- •Positioning the listener
- •Playing spatial sounds
- •Use case – In-game sound effects
- •Summary
- •Playing multiplayer games
- •Interacting with sockets
- •Socket selectors
- •Custom protocols
- •Data transport
- •Network architectures
- •Peer-to-peer
- •Client-server architecture
- •Authoritative servers
- •Creating the structure for multiplayer
- •Working with the Server
- •Server thread
- •Server loop
- •Peers and aircraft
- •Hot Seat
- •Accepting new clients
- •Handling disconnections
- •Incoming packets
- •Studying our protocol
- •Understanding the ticks and updates
- •Synchronization issues
- •Taking a peek in the other end – the client
- •Client packets
- •Transmitting game actions via network nodes
- •The new pause state
- •Settings
- •The new Player class
- •Latency
- •Latency versus bandwidth
- •View scrolling compensation
- •Aircraft interpolation
- •Cheating prevention
- •Summary
- •Index

Forge of the Gods – Shaping Our World
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.
[ 50 ]
www.it-ebooks.info

Chapter 3
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; |
||
}; |
|
|
|
|
|
|
|
|
|
[ 51 ] |
|
|
|
|
www.it-ebooks.info

Forge of the Gods – Shaping Our World
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.
[ 52 ]
www.it-ebooks.info