Chapter     9

Syncing the Background to Character Movement

In Chapter 8, solutions were presented for creating a multi-layered background that could scroll. However, you might be having problems if you tried to sync the scrolling of the background with the movement of the character.

In this chapter, you will be presented with two recipes—the first for scrolling a multi-image background in two directions, and the second for syncing the scrolling of that background with the movement of the playable character.

9.1 Scroll the Background in Two Directions

Problem

The background scrolls only in one direction when the player can run in two.

Solution

Modify the background class to track movement in two directions.

How It Works

This solution assumes that your game, possibly a platform-style game, has a character that can move in two directions. Thinking back to popular platform-style games (such as Super Mario Brothers), many times the playable character can move to the right to advance in the game. The character can also move to the left, often in a limited capacity, to retrace their steps.

Before the background can be synced with the character, it needs to be able to move in two directions. This solution will take a three-image background, load it, and scroll it to the right and then reverse it to scroll to the left.

The first step is to copy the three images that will be used as the background into the res/drawable folder. Figures 9-1 through 9-3 represent the three images that I used in this example. Notice that they are layers for a single background that have been pulled apart so that they can be scrolled at different speeds.

9781430257646_Fig09-01.jpg

Figure 9-1. The farthest background layer

9781430257646_Fig09-02.jpg

Figure 9-2. The middle-ground layer

9781430257646_Fig09-03.jpg

Figure 9-3. The ground layer

Note   The transparent portions of the images have been colored grey for the purpose of printing the images in thisbook.

Once the images are in the project, instantiate three instances of the SBGBackground() class—one for each layer of the background.

private SBGBackground background1 = new SBGBackground();
private SBGBackground background2 = new SBGBackground();
private SBGBackground background3 = new SBGBackground();

The next step is to create three sets of variables to control and track the speed and location of each layer of the background.

private float bgScroll1;
private float bgScroll2;
private float bgScroll3;
public static float SCROLL_BACKGROUND_1  = .002f;
public static float SCROLL_BACKGROUND_2  = .003f;
public static float SCROLL_BACKGROUND_3  = .004f;

In Chapter 7 (Listings 7-1 and 7-2), a solution was presented for creating a scrollBackground() method.

Change that method to allow the background to be scrolled either to the left or to the right, depending on which way the player is moving.

Early in the book, a solution was provided to allow a character to move across the screen (using a spritesheet). Part of this solution required the creation of a handful of variables for tracking the player’s movements. Use those same variables in this solution.

public static int playerAction = 0;
public static final int PLAYER_MOVE_LEFT = 1;
public static final int PLAYER_MOVE_RIGHT = 2;

Note   The aforementioned variable should be set when you collect the player’s input. For more information on doing this, see Chapters 5 and 6.

Add a new parameter to the scrollBackground() method that accepts the playerAction variable, using both OpenGL ES 1 and 2/3, as shown next.

For OpenGL ES 1:

private void scrollBackground1(GL10gl, int direction){

...

}

For OpenGL ES 2/3:

private void scrollBackground1(int direction){

...

}

The direction that is passed into the scrollBackground() method will be used to determine how to scroll the background image. In the current scrollBackground() method, the following line controls the scrolling of the image:

bgScroll1 +=  SCROLL_BACKGROUND_1;

The key part of this line is the +=. To change the direction of the scroll, the operator needs to be changed from += to -=. Create a switch...case statement to make this operator change based on the direction collected from the player input.

The scrollBackground() method for OpenGL ES 1 and OpenGL ES 2/3 is shown in Listings 9-1 and 9-2, respectively.

Listing 9-1.  scrollBackground() (OpenGL ES 1)

private void scrollBackground1(GL10gl, int direction){
if (bgScroll1 == Float.MAX_VALUE){
bgScroll1 = 0f;
}

gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glPushMatrix();
gl.glScalef(1f, 1f, 1f);
gl.glTranslatef(0f, 0f, 0f);

gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glTranslatef(bgScroll1,0.0f, 0.0f);

background1.draw(gl);
gl.glPopMatrix();
switch(direction)
{
case PLAYER_MOVE_RIGHT:
bgScroll1 +=  SCROLL_BACKGROUND_1;
break;
case PLAYER_MOVE_LEFT:
bgScroll1 -=  SCROLL_BACKGROUND_1;
break;
}
gl.glLoadIdentity();

}

Listing 9-2.  scrollBackground() (OpenGL ES 2/3)

private void scrollBackground1(int direction){
if (bgScroll1 == Float.MAX_VALUE){
bgScroll1 = 0f;
}

background1.draw(mMVPMatrix, bgScroll1);
switch(direction)
{
case PLAYER_MOVE_RIGHT:
bgScroll1 +=  SCROLL_BACKGROUND_1;
break;
case PLAYER_MOVE_LEFT:
bgScroll1 -=  SCROLL_BACKGROUND_1;
break;
}
}

The background will now scroll either to the right or to the left, based on what direction is passed into the scrollBackground() method. The next solution ties this method into the movement of the player.

9.2 Move the Background in Response to User Input

Problem

The background does not start or stop scrolling, based on the player movement.

Solution

The scrollBackground() method needs to be called in conjunction with the movePlayer() method to control the movement of both.

How It Works

In Chapter 6, Listing 6-7 presented a solution that created a movePlayer() method to facilitate the animation of the character. This method needs to be modified to allow the scrolling of the background to be synced to it. First, change the name of it to indicate its new purpose.

In OpenGL ES 1:

private void movePlayerAndBackground(GL10gl){

...

}

In OpenGL ES 2/3:

private void movePlayerAndBackground(){

...

}

Notice that in the existing movePlayer() method, there is a switch statement that moves the player (using a spritesheet). The switch statement needs to be rewritten so that when the character reaches roughly the middle of the screen, it does not move any further (see Listings 9-3 and 9-4). The character should appear to run in place at this point and the background should scroll to approximate movement.

Listing 9-3.  movePlayerAndBackground()(OpenGL ES 1)

private void movePlayerAndBackground(GL10gl){
background1.draw(gl);
if(!goodguy.isDead)
{
switch(playerAction){
case PLAYER_MOVE_RIGHT:

currentStandingFrame = STANDING_RIGHT;

currentRunAniFrame += .25f;
if (currentRunAniFrame> .75f)
{
currentRunAniFrame = .0f;
}

if(playerCurrentLocation>= 3f)
{
scrollBackground1(gl, playerAction);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glPushMatrix();
gl.glScalef(.15f, .15f, 1f);
gl.glTranslatef(playerCurrentLocation, .75f, 0f);
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glTranslatef(currentRunAniFrame,.50f, 0.0f);
goodguy.draw(gl,spriteSheets,SBG_RUNNING_PTR);
gl.glPopMatrix();
gl.glLoadIdentity();

}else{
playerCurrentLocation += PLAYER_RUN_SPEED;
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glPushMatrix();
gl.glScalef(.15f, .15f, 1f);
gl.glTranslatef(playerCurrentLocation, .75f, 0f);
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glTranslatef(currentRunAniFrame,.50f, 0.0f);
goodguy.draw(gl,spriteSheets,SBG_RUNNING_PTR);
gl.glPopMatrix();
gl.glLoadIdentity();

}

break;

case PLAYER_MOVE_LEFT:

currentStandingFrame = STANDING_LEFT;

currentRunAniFrame += .25f;
if (currentRunAniFrame> .75f)
{
currentRunAniFrame = .0f;
}

if(playerCurrentLocation<= 2.5f)
{
scrollBackground1(gl, playerAction);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glPushMatrix();
gl.glScalef(.15f, .15f, 1f);
gl.glTranslatef(playerCurrentLocation, .75f, 0f);
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glTranslatef(currentRunAniFrame,.75f, 0.0f);
goodguy.draw(gl,spriteSheets,SBG_RUNNING_PTR);
gl.glPopMatrix();
gl.glLoadIdentity();

}else{
playerCurrentLocation -= PLAYER_RUN_SPEED;
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glPushMatrix();
gl.glScalef(.15f, .15f, 1f);
gl.glTranslatef(playerCurrentLocation, .75f, 0f);
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glTranslatef(currentRunAniFrame,.75f, 0.0f);
goodguy.draw(gl,spriteSheets,SBG_RUNNING_PTR);
gl.glPopMatrix();
gl.glLoadIdentity();

}
break;

case PLAYER_STAND:
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glPushMatrix();
gl.glScalef(.15f, .15f, 1f);
gl.glTranslatef(playerCurrentLocation, .75f, 0f);
gl.glMatrixMode(GL10.GL_TEXTURE);
gl.glLoadIdentity();
gl.glTranslatef(currentStandingFrame,.25f, 0.0f);
goodguy.draw(gl,spriteSheets,SBG_RUNNING_PTR);
gl.glPopMatrix();
gl.glLoadIdentity();
break;
}
}
}

Listing 9-4.  movePlayerAndBackground()(OpenGL ES 2/3)

private void movePlayerAndBackground(){
background1.draw(mMVPMatrix, bgScroll1);
if(!goodguy.isDead)
{
switch(playerAction){
case PLAYER_MOVE_RIGHT:

currentStandingFrame = STANDING_RIGHT;

currentRunAniFrame += .25f;
if (currentRunAniFrame> .75f)
{
currentRunAniFrame = .0f;
}

if(playerCurrentLocation>= 3f)
{
scrollBackground1(playerAction);
goodguy.draw(spriteSheets,SBG_RUNNING_PTR, currentRunAniFrame, .75f);
}else{
playerCurrentLocation += PLAYER_RUN_SPEED;
goodguy.draw(spriteSheets,SBG_RUNNING_PTR, currentRunAniFrame, .50f);
}

break;

case PLAYER_MOVE_LEFT:
currentStandingFrame = STANDING_LEFT;

currentRunAniFrame += .25f;
if (currentRunAniFrame> .75f)
{
currentRunAniFrame = .0f;
}

if(playerCurrentLocation<= 2.5f)
{
scrollBackground1(playerAction);
goodguy.draw(spriteSheets,SBG_RUNNING_PTR, currentRunAniFrame, .75f);

}else{
playerCurrentLocation -= PLAYER_RUN_SPEED;
goodguy.draw(spriteSheets,SBG_RUNNING_PTR, currentRunAniFrame, .50f);
}
break;

case PLAYER_STAND:
goodguy.draw(spriteSheets,SBG_RUNNING_PTR, currentStandingFrame, .25f);

break;
}
}
}

The character animation stops progressing across the screen about midway. The method then calls the scrollBackground() method to begin moving the background.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.191.202.240