- •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
Chapter 10
|
Peer |
Peer |
Peer |
|
Peer |
These inter-connections between all the clients, which somehow resemble a spider's web, mean that every client has a connection with every client. This way, they effectively communicate correctly, allowing chatting with each other, seeing each other's movements, and other actions. When a client means to do something, such as when the jump key is pressed and the character should jump, it notifies every other client of this, so they can see it happen too.
However, while this approach can be efficient, as the network processing is done among all clients, it introduces a nasty set of disadvantages that unfortunately can't be avoided.
The major problem with the technique is that cheating cannot be prevented. A client will just do whatever it wants to do and notify all the others of it. Players can and they will exploit your game's weaknesses whenever there are any and destroy the fun of the game to other players.
So, how will we make sure the clients can't do anything outside of the allowed actions? That's where the other network architecture kicks in!
Client-server architecture
Alright, this is a very, very important subject. This is nearly the standard as far as multiplayer gaming goes. Learn this concept well and you're gold. This will be particularly useful for nearly all networking tasks you will be doing and not exclusively games.
[ 243 ]
www.it-ebooks.info
Company Atop the Clouds – Co-op Multiplayer
Why is it so important? First, because it allows a central instance to control everything, and therefore provides the possibility to implement means of security.
The following figure shows how computers are laid in such architecture:
|
Server |
|
Peer |
Peer |
Peer |
Here, you see there is a central server, or group of servers (distributed systems) that communicate with all the clients. Now, a client does not know, under any
circumstances, about other client's address or information. The server acts as a proxy, or a bridge between the client's communications. However, saying the server is merely a bridge for communication is a reductive view of what it really does.
Authoritative servers
In reality, having one server manage all of the clients and be in charge of all their
communications easily puts the server application under a heavy processing and networking load. It is hard to develop and maintain efficient and fast servers that can hold many clients at once. However, this cost is easily compensated by the advantages this architecture inherently gives us. The most notable feature is the authority of the
server, entirely preventing the cheating and exploiting by the players.
How is this achieved, you may ask? It is easy to explain and a bit harder to get right while developing, but what happens, in essence, is that the server holds the true and absolute state of the simulation, and only the data being simulated in the server application is considered valid. This way, each client will only receive valid
state information about the server and will always have correct and proper values in the simulation.
On the other hand, the server may check for every packet received from clients, and easily deduce what is possible to do under the constraints of the simulation. When the server checks a client input, it is possible to analyze it in order to know if that input is valid or is an attempt at cheating. If the server is programmed well to do these checks, its internal state remains valid and accurate. A player may modify
its client to do weird things that were not programmed that way initially, that we cannot prevent, but as long as the input that comes from that client is checked, the
other players won't even notice a difference, because what the cheating client sees is merely a local version and the server, which is still intact.
[ 244 ]
www.it-ebooks.info