Read Foundation Game Design with ActionScript 3.0, Second Edition Online
Authors: Rex van der Spuy
The first thing the code does is define the inner boundary with these four new variables. You first declared these new variables in the class definition.
public var rightInnerBoundary:uint;
public var leftInnerBoundary:uint;
public var topInnerBoundary:uint;
public var bottomInnerBoundary:uint;
You then set their value in the constructor method.
rightInnerBoundary
= (stage.stageWidth / 2) + (stage.stageWidth / 4);
leftInnerBoundary
= (stage.stageWidth / 2) - (stage.stageWidth / 4);
topInnerBoundary
= (stage.stageHeight / 2) - (stage.stageHeight / 4);
bottomInnerBoundary
= (stage.stageHeight / 2) + (stage.stageHeight / 4);
This is the first time you've written code that uses the division operator. It's represented by a forward slash (/) character and means “divided by.”
Can you figure out how the boundaries were calculated? (Try it; it's not that hard!) What you end up with is an inner area that's half the size of the stage.
The following is the new code from theenterFrameHandler
that really makes this whole system work:
//Move the player
character.x += vx
character.y += vy;
//Stop character at inner the boundary edges
if (character.x < leftInnerBoundary)
{
character.x = leftInnerBoundary;
background.x -= vx;
}
else if (character.x + character.width > rightInnerBoundary)
{
character.x = rightInnerBoundary - character.width
background.x -= vx;
}
if (character.y < topInnerBoundary)
{
character.y = topInnerBoundary;
background.y -= vy;
}
else if (character.y + character.height > bottomInnerBoundary)
{
character.y = bottomInnerBoundary - character.height;
background.y -= vy;
}
You can see that you're back to moving the character again. But it is allowed to move only while it's within the inner boundaries. Let's have a look at how the first if statement works.
if (character.x < leftInnerBoundary)
{
character.x = leftInnerBoundary;
background.x -= vx;
}
The conditional statement checks to see whether the left edge of the player is less than the left inner boundary. If it is, the player is forced back to that edge. This is exactly the same logic used to stop the character at the edges of the stage.
But the next line is interesting.
background.x -= vx;
The background starts moving! And that's really all there is to it. The code is quite simple, but the effect it produces seems complex when the program runs.
You still have one more problem to solve. The character still can't move all the way to the edges of the stage when the scrolling background has reached its limit. To do this, you need to temporarily extend the boundaries and then move them back if the player returns to the center of the stage again. A few lines of very simple code in the right place are all you need to achieve this.
enterFrameHandler
:public function enterFrameHandler(event:Event):void
{
//Move the player
character.x += vx
character.y += vy;
//Check the inner boundaries
if (character.x < leftInnerBoundary)
{
character.x = leftInnerBoundary;
rightInnerBoundary
= (stage.stageWidth / 2) + (stage.stageWidth / 4);
background.x -= vx;
}
else if (character.x + character.width > rightInnerBoundary)
{
character.x = rightInnerBoundary - character.width
leftInnerBoundary
= (stage.stageWidth / 2) - (stage.stageWidth / 4);
background.x -= vx;
}
if (character.y < topInnerBoundary)
{
character.y = topInnerBoundary;
bottomInnerBoundary
= (stage.stageHeight / 2) + (stage.stageHeight / 4);
background.y -= vy;
}
else if
(character.y + character.height > bottomInnerBoundary)
{
character.y = bottomInnerBoundary - character.height;
topInnerBoundary
= (stage.stageHeight / 2) - (stage.stageHeight / 4);
background.y -= vy;
}
//Check the stage boundaries
if (background.x > 0)
{
background.x = 0;
leftInnerBoundary = 0;
}
else if (background.y > 0)
{
background.y = 0;
topInnerBoundary = 0;
}
else if
(background.x < stage.stageWidth - background.width)
{
background.x = stage.stageWidth - background.width;
rightInnerBoundary = stage.stageWidth;
}
else if
(background.y < stage.stageHeight - background.height)
{
background.y = stage.stageHeight - background.height;
bottomInnerBoundary = stage.stageHeight;
}
}
This code works by extending the inner boundaries to the stage edges when the background has reached the limit of its movement. Let's look at how this works with the first if statement in the code (the new code is highlighted in bold).
if (background.x > 0)
{
background.x = 0;
leftInnerBoundary = 0;
}
If you press the left arrow key, thebackground
object moves until the conditional statement detects that it has reached its limit. When that happens, it stops thebackground
object from moving and then gives theleftInnerBoundary
variable a new value that is equivalent to the x value of the left side of the stage. You know that the very left edge of the stage has an x position value of zero. That allows the character to move all the way to the stage edge.
Figure 5-15
illustrates how this works.
Figure 5-15.
When the background object stops moving, the boundary is extended to allow the character to travel to the edge of the stage.
Problem solved! But you just created another one. How can you move the boundary back to its original position if the player moves back to the center of the stage?
Think about it this way. Imagine that the character has traveled to the leftmost edge of the stage, as shown in
Figure 5-15
. When it travels back to the center of the stage, you don't have to start moving the background object again until the character has reached the inner-right boundary. If it does, you know that you can safely reset the inner-left boundary to its original position. That's what this new line of code in bold does:
else if (character.x + character.width > rightInnerBoundary)
{
character.x = rightInnerBoundary - character.width
leftInnerBoundary
= (stage.stageWidth / 2) - (stage.stageWidth / 4);
background.x -= vx;
}
Figure 5-16
illustrates what is happening.
Figure 5-16.
The left boundary resets to its original position when the character reaches the right boundary.
The other bits of new code that you added in this section follow exactly the same logic for each of the three other boundaries.
You can find the entire working example of this code in the EvenBetterScrolling folder in the chapter's source files.
You'll be able to get quite a bit of mileage out of these examples of scrolling for your games. Any type of scrolling system you can dream up will use these same techniques in some kind of combination. You've actually tackled the most difficult type of scrolling, combined vertical and horizontal scrolling, so if you need to make a game that requires only horizontal scrolling, it should be a piece of cake. The techniques are exactly the same; you just need half the amount of code because you'll only need to check boundaries on the x axis.
This is not the last word on scrolling; it's really just the beginning. Have a look at some of your favorite games and study very carefully how they've implemented scrolling. You'll notice that many of them modify how and when scrolling takes place in very subtle ways. The core of all this, however, is based on the examples you looked at in this chapter.
Things get a little more complex when you need to scroll the background and foreground game objects at the same time. You'll take a look at how to do that in
Chapter 7
.
There's one additional scrolling technique that you should look at briefly because it's very widely used and extremely effective:
parallax scrolling
.
Parallax
is a visual effect in which the position of an object appears to change depending on the point of view from which it's being observed. The effect of parallax scrolling in games is used to create the illusion of shallow depth. It's a simple 3D effect in which distant background objects move at a slower rate than closer foreground objects, creating the illusion that slower-moving objects are farther away. Parallax scrolling can give even simple 2D games very strong visual impact.
It's very to easy to do. First, you need split your background scene into two separate images. The first will be for things that are far away, like mountains or clouds. Perhaps you could call this thedistantBackground
. Make its height the same as the stage, (400 pixels), but make it really long, with a width of perhaps over 2000 pixels.
Figure 5-17
illustrates what this could look like.
Figure 5-17.
A distant background object for things that are far away
Next, you need an image for things that are closer. Perhaps you could call it theforeground
. Make it exactly the same size as the distant background.
Figure 5-18
shows what this might look like.
Figure 5-18.
A foreground object for things that are closer
Add them to both to the stage, center them, and add your game character to create a single scene (
Figure 5-19
).