The MagPi - July 2018

(Steven Felgate) #1

Tutorial


raspberrypi.org/magpi July 2018 61


and how the control system will change depending on
the state. For example, we can’t really jump or climb if
we are currently falling.
Separating the actions of our character into states
means we can focus on the control that is relevant to
that state and, where needed, signal a change in state



  • from walking to jumping, for example.
    By defining each action as a state, we are making
    our first attempts at a state machine, where different
    code is called depending on the setting of that stage.
    That code can also change the state, allowing us to
    switch back and forward between states depending on
    whatever conditions we want to test. A good example
    might be when falling: we are only going to test to see
    if we should stop falling, and if we find ground under
    our feet, we switch into a standing frame, or perhaps
    even a duck-and-roll landing sequence state. Or a
    splatting into a bloody mess state if we are feeling a
    bit nasty and our hero fell a long way. Sadly, we don’t
    really have enough graphics to let our imagination
    loose just yet.
    Simple state management can be done with
    sequences of if-then-else conditions, but C/C++ gives
    us a much neater concept called a switch, which calls
    different code based on different ‘case’ statements.
    Refer to Figure 2.
    Generally speaking, being able to keep the code for
    a specific state lets us focus on only dealing with the
    conditions that relate to that state. For example, when
    walking, we do not need to worry about jumping code,
    but we do need to test if we should be falling down.
    Our code becomes more about managing the state we
    are in at given points than trying to work out which of
    the five or six different abilities we give our character.
    This allows for expansion of ability and isolation of
    the code to provide those abilities.


Using maps
Our bat-and-ball game touched on the concept of
maps, since our screen was basically made up of an
array which we interacted with. That array was a map,
where each cell related to a specific tile on screen.
But platform games take the concept of a map to a
new level. Consider how many levels you can have in
a game like Super Mario Bros; all these levels use the
same quite limited and basic tile set, yet clearly there
are thousands of cells making up each map. A cell in
a map, however, can be represented by a single byte
(though more typically a 32-bit integer) and allow
us to have arrays of any size to represent quite huge
numbers of levels.
What’s more, those levels can be larger than the
screen size, and by simply moving a screen view
area – under the control of the principal character in
our game – we can create scrolling. The view screen
area moves as we want it to, but generally under the
control of our principal character who drags the view
along. We’ll tackle that next time.


CODING GAMES ON THE RASPBERRY PI IN C/C++


We’ll start with a single screen map for now,
which is called Map2 in the code. As you can see
in Figure 3 over the page, this is a fairly simple
platform game layout, but drawn the exact same
way as our bat/ball map, which does create some
issues we will discuss soon.
Remember that our characters do not interact
directly with the screen: our screen only gives us
a visual interpretation of what happens during
the map interaction. So as long as we keep our
code focused on the characters’ interaction with
the map, we can move our screen around any way
we want.

Our main character
Our new character is called Bob. The Bob class inherits
from our simple objects and, like our previous balls,
has some information on graphics and position which
lets us draw him. Take a moment to review the code
and the comments that explain what it’s doing.
Bob’s class is a little like our old Bat class: Bob is
the only one who cares about the keys, so he’s going
to read the keys, move around, jump, and test if he’s
standing on something; if not, he’s going to obey the
laws of gravity and fall, though we won’t splat him if
he falls too far.
Gravity in game worlds acts very similarly to gravity
in the real world: it’s always there and pulling you
down, but as long as there’s ground beneath us we
don’t fall through. So we need to test if there’s ground
under our feet during our normal, non-gravity-
defying states.
Gravity is usually represented as a speed in platform
games: 0 when on the ground and whatever amount we
find works best when not on the ground. To jump, we

Language
>C++

NAME:
MagPiHelloTriangle.
cpp
SimpleObj.h/cpp
Game.h/cpp
OGL.h/cpp
Ball.h/cpp
NewBall.h/cpp
Paddle.h/cpp
Input.h/cpp

DOWNLOAD:
magpi.cc/YUdxXy

Figure 2 How a switch keeps states separated

KEEP CODE
READABLE

Comments
are great, but
readable, self-
descriptive
code is better.
Free download pdf