Sidescrolling Platformer ~Part 3~ The Player

In our last tutorial we programmed the background so that it scrolls when we control it with the arrow keys. But as cool as that is, it isn’t enough. Right now the player is nothing more than a a static object on the side of the stage. What we’re going to do in this tutorial is program the player to interact with the background.

Player Mechanics

What code do we add for the player? That’s a BIG question… the fate of our entire game pretty much depends upon how the player interacts with the environment. In order to stay organized, I’ll outline all the basic concepts the player should follow:

  • Smooth Movement: The player should accelerate smoothly upon pressing the arrow key, and glide to a stop due to friction when the arrow key is released.
  • Collisions: The player should not be able to walk through walls, fall through the ground, or jump through ceilings.
  • Gravity: The player should be pulled downwards unless he is standing on the ground.
  • Jumping: If the player is standing on the ground, he should be able to jump upwards.

Smooth Movement, and Fixing the Background

In order to make the player movement be smooth and efficient, we need to make a fix to some of the clumsy code from last tutorial, as well as add a few new features.

First, change the instance name of the background on the stage to just be “back“. It’s my fault that I named it background last tutorial, because there is already a property in actionscript 3 called “background”. This might cause problems or confusions in the code, so change the instance name to avoid any issues.

Also, give the player the instance name “player“. We will need to access this later.

Next, create two variables to keep track of the x and y positions of the background. Currently the background moves around, but we have no easy way to keep track of where it is (and where the player is relative to the background — which is very useful to know).


var scrollX:int = 0;
var scrollY:int = 0;

Next, rename the variables xScrollSpeed and yScrollSpeed to be xSpeed and ySpeed, respectively, and set them to equal zero. While our old variable names work for the simple demo we have running, a more advanced game will require more versatile variables.

They should look like this:


var ySpeed:int = 0;
var xSpeed:int = 0;

Finally create two new variables to hold constant values we will use in the loop function. Create a speedConstant of 5 which we will set the xSpeed and ySpeed variables to when the proper keys are pressed. And create a friction value of 0.95, which we will constantly multiply the player’s speed by to slow him down.


var speedConstant:int = 5;

var friction:Number = 0.95;

Now we can update the loop function. The old loop looked like this:


function loop(e:Event):void{

	if(leftPressed){
		background.x += xScrollSpeed;

	} else if(rightPressed){
		background.x -= xScrollSpeed;

	}

	if(upPressed){
		background.y += yScrollSpeed;

	} else if(downPressed){
		background.y -= yScrollSpeed;

	}
}

Here’s the new loop function in its entirety. I’ll explain afterwards.


function loop(e:Event):void{

	if(leftPressed){
		xSpeed -= speedConstant;

	} else if(rightPressed){
		xSpeed += speedConstant;

	}

	if(upPressed){
		ySpeed -= speedConstant;

	} else if(downPressed){
		ySpeed += speedConstant;

	}

	xSpeed *= friction;
	ySpeed *= friction;

	scrollX -= xSpeed;
	scrollY -= ySpeed;

	back.x = scrollX;
	back.y = scrollY;
}

Here’s what the loop function does, starting from the top. Whenever the left or right keys are pressed, the player’s xSpeed is increased in that direction by the speedConstant (which is 5). The same thing happens for the ySpeed if the up or down arrows are pressed. Then the xSpeed and ySpeed are immediately decreased by multiplying them by friction (which is 0.95). This will slowly bring the player to a halt if no keys are pressed, and it will also cause the player to have a maximum speed even if the keys are still pressed. Next, the scrollX and scrollY variables are negatively updated by the player’s speed variables, and the background’s position is set to these final variables.

This code makes the scrolling of the background more smooth, more efficient, and more versatile.

On top of all this programming, I also slightly updated the graphics of my background. The configuration is the same, but I scaled everything up a little bit to make it larger, and I cleaned up the lines. I also repositioned the player to about the center of the stage.

Run your game and be amazed by the silky-smoothness of your movement system….

…Or just click on the preview below and use the arrow keys to check out the new improvements!

Collisions

So our movement is all polished up… but we can still run through walls. Something tells me we need to add collision detection.

This is the trickiest topic we have to cover today, and let me explain why. In a traditional tile-based platformer, where everything is laid out in nice grids, we can use code to calculate whether or not the player is colliding with floors, walls, etc. But we are not making a tile-based game — they are more complicated to set up, and your art and background environment is generally limited to a specific style. However, in exchange for the freedom that art-based platformers enjoy, we lose out on the perfectly calculated solution to collisions.

Our best choice at this point is to settle for a less-than-perfect collisions system, and try to improve it as we go along. Time to begin.

First things first, create 4 new variables at the top of your code so we can keep track of whether or not the player is colliding with the background on each side. For example, we will check the value of downBumping to check if the player is on the floor, and rightBumping to check if the right side of the player is touching a wall.


var leftBumping:Boolean = false;
var rightBumping:Boolean = false;
var upBumping:Boolean = false;
var downBumping:Boolean = false;

Now that we have these variables, we need to figure out how to check if the player is indeed colliding with the background on that side. To do so, we will use the built-in flash method: hitTestPoint.

Hit-testing inside of flash is a pretty unglamorous topic, due to the fact that there are two types of hit-testing, and neither work the way you wish they did. The first is hitTestObject (which we are NOT using). To use hitTestObject between the background and the player, we would simply say:

if( background.hitTestObject(player) ){
//do whatever we need
}

Sounds good, right? Wrong. The problem with hitTestObject is that is checks for a collision between the bounding boxes of each object, not each object itself. This means that if either of the objects is within a rectangular area that bounds the other object, the hit test will return true, even if there is nothing drawn at that specific point. In our game, even if the player isn’t touching any platforms, as long as he is within the overall perimeter of the background object, the game will think they are colliding.

This won't work.

The second method built into flash is hitTestPoint. This is similar to hitTestObject, but differs on a couple big issues. The first is that it checks for collisions between one object, and a specific point on the screen, NOT another entire object. This seems strange and unappealing, but there is a benefit: we get to test the actual object, NOT its bounding box. If you are confused, don’t worry — here’s an example. To use hitTestObject between the background and the player, we would say:

if( background.hitTestPoint(player.x, player.y, true) ){
//do whatever we need
}

The first parameter — player.x — is the x-coordinate to check, and the second parameter — player.y — is the y-coordinate to check. The final parameter — true — is called the “shapeFlag“. This fancy name simply lets us specify if we want to hitTest against the entire bounding box of the background (false), or a pixel-perfect collision (true) between the background and the coordinate point of the player. We obviously want to pick true, so we don’t end up with the same problem as with hitTestObject.

This is all fine and dandy, but remember that this still only checks one single point of the player. How could this possibly work? The answer is that it doesn’t work perfectly, but we can achieve a pretty good effect by using a combination of hitTestPoints which check one point on each side of the player. This image should clear things up.

This WILL work.

The green dots represent a collision between the background and the point located at the corresponding coordinates. A red dot means there is no collision detected at that point. While this isn’t a perfect solution, we will be able to know whether the player is bumping against the background on each side. From there, we can make sure that the player stops moving in that direction so he doesn’t move past a wall. (P.S. No need to draw those colorful dots — they’re just a visualization.)

Wow. That was a lot of theory. It’s code time.

Underneath the Boolean variables you created earlier this tutorial, add four new variables to keep track of the collision points.

var leftBumpPoint:Point = new Point(-30, -55);
var rightBumpPoint:Point = new Point(30, -55);
var upBumpPoint:Point = new Point(0, -120);
var downBumpPoint:Point = new Point(0, 0);

You probably noticed that those aren’t our standard integer or boolean variables. They are Points. Points are defined with two values, set up like a standard coordinate on a graph. The first is the x-value, and the second is its y-value. If you wanted to access the x and y values of leftBumpPoint, you would use leftBumpPoint.x and leftBumpPoint.y.

Now that we’ve set the coordinates which we need to check, lets edit the loop function and tie everything together. At the very top of the loop function, before any of the movement code, add the following 4 chunks of hit-testing goodness:

	if(back.hitTestPoint(player.x + leftBumpPoint.x, player.y + leftBumpPoint.y, true)){
		trace("leftBumping");
		leftBumping = true;
	} else {
		leftBumping = false;
	}

	if(back.hitTestPoint(player.x + rightBumpPoint.x, player.y + rightBumpPoint.y, true)){
		trace("rightBumping");
		rightBumping = true;
	} else {
		rightBumping = false;
	}

	if(back.hitTestPoint(player.x + upBumpPoint.x, player.y + upBumpPoint.y, true)){
		trace("upBumping");
		upBumping = true;
	} else {
		upBumping = false;
	}

	if(back.hitTestPoint(player.x + downBumpPoint.x, player.y + downBumpPoint.y, true)){
		trace("downBumping");
		downBumping = true;
	} else {
		downBumping = false;
	}

If you run your program now and move through a platform you will see the trace statements pop up in your output panel confirming that the collisions are working!

There is one last step we need to add in order to make everything work. Right now we correctly set the “bumping” variables to true or false whenever the player collides with the background. All that’s left to do is to make the player react to these variable. We will program this by changing the player’s velocity in whatever direction the collision is sensed. Instead of setting the velocity to 0, for the moment we are going to make the player bounce off the walls he collides with, and slow down.

Add the following code to the game loop. Be sure to position it correctly, because the order that the code gets executed in the loop will affect how the player behaves. Place these directly before the line where we multiply the speed by friction. This is after we add/subtract the speedConstant depending on the arrow keys that are pressed.


	if(leftBumping){
		if(xSpeed < 0){
			xSpeed *= -0.5;
		}
	}

	if(rightBumping){
		if(xSpeed > 0){
			xSpeed *= -0.5;
		}
	}

	if(upBumping){
		if(ySpeed < 0){
			ySpeed *= -0.5;
		}
	}

	if(downBumping){
		if(ySpeed > 0){
			ySpeed *= -0.5;
		}
	}

If you’ve typed everything correctly so far, and you run your program, the player should stop and bounce off of walls instead of running through them!

Try it out here:

That’s a big improvement over our last demo. ‘Ye olde scrolling background is finally beginning to act like a sidescrolling game. However, there is still a long, long, LONG way to go before we can call this a complete platformer.

If you tested the new demo for more than a couple seconds, you probably realize that while our current hit-testing does an OK job, it has a few major problems.

First and foremost, you are only blocked if a single point on each side of the player happens to bump into the background — this is a problem, for example, because you can have the left edge of the player’s body fall through the floor as long as the bottom-center point isn’t touching the floor, or you can easily run the player’s head sideways through a platform because the collision is checked farther down.

The second issue is that if you speed up enough, sometimes you are able to slip through the background! This is because if the player’s speed is greater than the thickness of a platform, the hit-test point might skip over the entire platform between two frames. This would mean the game was never notified that the player should stop moving in that direction.

There are a few different solutions to improve our collision detection, but we will save those for another day. I don’t know about you, but personally after 1500 words of collision-craziness, I need a break.

On that note, I’m going to bring this post to a close. There’s so much more I want to discuss, but this tutorial part is already my longest yet, by far. The next part will cover the 2 sections of player interaction we outlined but didn’t get to: gravity and jumping.

Here is the customary source code.

You can subscribe HERE to be notified about any new posts. If you have any questions, or requests for game features or future tutorials, leave me a comment below. Thanks for your continued support!

Up next: Part 4: Gravity and Jumping

65 comments on “Sidescrolling Platformer ~Part 3~ The Player

  1. Michael says:

    That looks a lot better. More of a “real feel”. That was a long one indeed. Haha. Thanks for the tutorial as always!

    • Ben Reynolds says:

      No problem, glad to be of assistance :-)

      • Michael says:

        Hey I was wonder if you can add in how to advance to the next level. I added a frame after the current level and tried some codes I found and tried adjusting them but only found failure! :( If your able to add that little bit somewhere in the future tutorial that would be awesome! Thanks bro!!

        • Ben Reynolds says:

          Sure, I can definitely add that in a future tutorial. I don’t think it will make it into part 4, but definitely part 5.

          • Annonymous says:

            I need some help. I created my character of dimensions 40 X 40 pixels circle because wont it solve the problem of the head going through the wall. When i try to declare the points, it doesn’t work :-

            //vars
            var leftBumpPoint:Point = new Point(-25, -15);
            var rightBumpPoint:Point = new Point(25, -15);
            var upBumpPoint:Point = new Point(0, -40);
            var downBumpPoint:Point = new Point(0, 0);

            //if then else
            if(back.hitTestPoint(char.x + leftBumpPoint.x, char.y + leftBumpPoint.y, true)) {

            trace(“left bumping”);
            leftBumping = true;

            } else {

            leftBumping = false;

            }

            if(back.hitTestPoint(char.x + rightBumpPoint.x, char.y + rightBumpPoint.y,true)) {

            trace(“right bumping”);
            rightBumping = true;

            } else {

            rightBumping = false;

            }

            if(back.hitTestPoint(char.x + upBumpPoint.x, char.x + upBumpPoint.y,true)) {

            trace(“upBumping”);
            upBumping = true;

            } else {

            upBumping = false;

            }

            if(back.hitTestPoint(char.x + downBumpPoint.x, char.y + downBumpPoint.y, true)) {

            trace(“down Bumping”);
            downBumping = false;

            } else {

            downBumping = false;

            }

            Please Help, I am stuck.

      • Annonymous says:

        “Next, the scrollX and scrollY variables are negatively updated by the player’s speed variables”
        What exactly do you mean by that sentence.
        Many Thanks

  2. Adam says:

    When I try to try it for the first time after the first changes I get the error “Scene 1, Layer ‘Layer 1’, Frame 1, Line 82 1120: Access of undefined property back.”
    and then again..
    “Scene 1, Layer ‘Layer 1’, Frame 1, Line 83 1120: Access of undefined property back.”
    Please Help! Thank You!!

    • Ben Reynolds says:

      I can’t be sure, but it sounds like you may have forgotten to give the background the instance name “back” in the Flash editor. If this is the problem, click on the background object on the stage, and then go to the Properties panel. On the top there should be a blank text field which you can enter a name which your code can use to refer to the object. If this doesn’t work, try downloading my source code and see if you can recognize any differences.

      • Michal says:

        change the instance name of the level to ‘back’
        or change it back to background and change the code so that it says
        background instead of back. then change it to back.

  3. GoodBoy says:

    This is really helpful tnx :)

  4. GoodBoy says:

    I hope you can add the gravity of this tutorial :D so the player will be able to jump. I need to have a good reference for it cause we are also creating a side scroll game and we are having trouble with the jump. Again thabk you for your helpful turorials :D I will wait for your new posts.

  5. Jansen says:

    Good Tutorial sir! .. But when you will post the last tutorial about the gravity ?? Because I like to make this as a Pattern for my first game on flash ..

  6. Ben Reynolds says:

    Part 4 of the Sidescrolling Platformer series has just been released. Check it out and tell me what you think! :-)

  7. Its too good. But I have a problem. The width of the player is 52 and height is 120. Then why have you taken the points in the middle as 30 and 55 ?

  8. Jonathan says:

    I’m confused with the hitTestPoint function. Does it automatically just check to see if our character makes contact with any of the lines within the background which have been predefined by us? So this function can distinguish between drawn lines and empty space in a movieclip?

    • Ben Reynolds says:

      Yes, that’s the great thing about hitTestPoint. For some reason, Adobe decided to make hitTestObject only check the rectangular bounding box of an object, with no regard to whether or not there is empty space or drawn lines. But hitTest*Point*, on the other hand, knows whether or not anything has been drawn at a certain location. HitTestPoint knows the difference between empty space, and drawn lines. Sorry if I didn’t make this clear in the tutorial.

  9. Tim says:

    uh im getting an error 1120 : Access of undefined property scrollX
    Access of undefined property scrollY
    could you plz help:)

  10. lee bissell says:

    Hi first of all can i just say this is awersome!!!! i am having a problem though im upto the collision test and get the following message:
    1120: access of undefined property for all the BumpPoints
    please help!

  11. Jamie says:

    If I were to make a top down tile based game, if I wanted the player to not walk through tress, I need to do, if( tree.hitTestObject( player ) ) — how do I make the player stop so he doesn’t walk through trees like a classic rpg

  12. FlashGamer says:

    Im pretty sure i did everything right…. i got all the code in, execpt for the fact that my background’s name is Background and not back, and im not getting any errors or warning, but it seems that the player runs through every wall there is, only sometimes bouncing off a wall when i go rreally slow. i knnow that the hittestpoint works because the trace comes out fine, and my fps is set to 30, but the skipping the walls are really an issue. also my character accellerates at an alarmingly fast speed, although nothing has changed in the code (i copied and pasted most of it, with the exeptions of changing every letter e. to “event”.) any help would be apreciated. thnx!

  13. FlashGamer says:

    here is the code to the above mentioned issue (by FlashGamer)

    /*The x and y scroll speeds are just constant numbers which will determine how
    fast the background moves when it is scrolling.
    The Boolean variables will be used to tell whether or not a key is pressed.
    If it is currently held down, the respective variable will equal true. Otherwise,
    it will equal false.
    */
    var leftPressed:Boolean = false;
    var rightPressed:Boolean = false;
    var upPressed:Boolean = false;
    var downPressed:Boolean = false;

    var leftBumping:Boolean = false;
    var rightBumping:Boolean = false;
    var upBumping:Boolean = false;
    var downBumping:Boolean = false

    var leftBumpPoint:Point = new Point(-30, -55);
    var rightBumpPoint:Point = new Point(30, -55);
    var upBumpPoint:Point = new Point(0, -120);
    var downBumpPoint:Point = new Point(0, 0);

    var gravityConstant:Number = 2.5;

    var xSpeed:Number = 0;
    var ySpeed:Number = 0;

    stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
    stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);

    //Both of these lines add event listeners to the stage. The first one will run the “keyDownHandler” function every time any keyboard key is pressed. And the second one will run the “keyUpHandler” function every time you release one of those keys.
    //One problem… those functions don’t exist yet. So let’s add them underneath the listeners:

    /*Right now we only have the shell of each function — they don’t contain the
    actual code we need to run yet. If you’re still new to event listeners,
    make special note of the parameter of the function: (e:KeyboardEvent).
    The letter e doesn’t really mean anything beyond just being an abbreviation of “event”
    (you could use any word or letter in that spot as long as you use that same word
    throughout your program). However, we are assigning it to hold all of the information
    of the KeyboardEvent which triggered this function, so we can use e to figure out which
    key was pressed.
    Time to add the real code of the functions.
    */

    function keyDownHandler(event:KeyboardEvent):void{
    if(event.keyCode == Keyboard.LEFT){
    leftPressed = true;

    } else if(event.keyCode == Keyboard.RIGHT){
    rightPressed = true;

    } else if(event.keyCode == Keyboard.UP){
    upPressed = true;

    } else if(event.keyCode == Keyboard.DOWN){
    downPressed = true;
    }
    }

    function keyUpHandler(event:KeyboardEvent):void{
    if(event.keyCode == Keyboard.LEFT){
    leftPressed = false;

    } else if(event.keyCode == Keyboard.RIGHT){
    rightPressed = false;

    } else if(event.keyCode == Keyboard.UP){
    upPressed = false;

    } else if(event.keyCode == Keyboard.DOWN){
    downPressed = false;
    }
    }

    /*
    behind the scenes, your program now knows which keys
    are being pressed, which is essential to making your game.
    */

    stage.addEventListener(Event.ENTER_FRAME, loop);

    function loop(event:Event):void{

    if(Background.hitTestPoint(player.x + leftBumpPoint.x, player.y + leftBumpPoint.y, true)){

    leftBumping = true;
    } else {
    leftBumping = false;
    }

    if(Background.hitTestPoint(player.x + rightBumpPoint.x, player.y + rightBumpPoint.y, true)){

    rightBumping = true;
    } else {
    rightBumping = false;
    }

    if(Background.hitTestPoint(player.x + upBumpPoint.x, player.y + upBumpPoint.y, true)){

    upBumping = true;
    } else {
    upBumping = false;
    }

    if(Background.hitTestPoint(player.x + downBumpPoint.x, player.y + downBumpPoint.y, true)){

    downBumping = true;
    } else {
    downBumping = false;
    }

    if(leftPressed){
    xSpeed -= speedConstant;

    } else if(rightPressed){
    xSpeed += speedConstant;

    }
    if(upPressed){
    ySpeed -= speedConstant;

    } else if(downPressed){
    ySpeed += speedConstant;

    // the first problematic code i encountered -.O

    if(leftBumping){
    if(xSpeed 0){
    xSpeed *= -0.5;
    }
    }

    if(upBumping){
    if(ySpeed 0){
    ySpeed *= -0.5;
    }
    } else { //if we are not touching the floor
    ySpeed += gravityConstant; //accelerate downwards
    }

    }
    xSpeed *= friction;
    ySpeed *= friction;

    scrollX -= xSpeed;
    scrollY -= ySpeed;

    Background.x = scrollX;
    Background.y = scrollY;
    }

    /*
    This will run 30 times every second, giving a pretty smooth animation to anything
    we update inside the function. It’s finally time to make our game do something visual!
    Inside the loop function, we updated the position of the background depending on which
    key-Pressed variables are true…
    Test your game and marvel at the magical effect!

    Here’s what the loop function does, starting from the top. Whenever the left or right
    keys are pressed, the player’s xSpeed is increased in that direction by the speedConstant
    (which is 5). The same thing happens for the ySpeed if the up or down arrows are pressed.
    Then the xSpeed and ySpeed are immediately decreased by multiplying them by friction
    (which is 0.95). This will slowly bring the player to a halt if no keys are pressed, and
    it will also cause the player to have a maximum speed even if the keys are still pressed.
    Next, the scrollX and scrollY variables are negatively updated by the player’s speed variables,
    and the background’s position is set to these final variables.
    */

    /*
    create two variables to keep track of the x and y positions of the background.
    Currently the background moves around, but we have no easy way to keep track of where it is
    (and where the player is relative to the background — which is very useful to know).
    */

    var scrollX:Number = 0;
    var scrollY:Number = 0;

    /*
    Next, rename the variables xScrollSpeed and yScrollSpeed to be xSpeed and ySpeed,
    respectively, and set them to equal zero. While our old variable names work for the
    simple demo we have running, a more advanced game will require more versatile variables.
    */

    /*
    Finally create two new variables to hold constant values we will
    use in the loop function. Create a speedConstant of 5 which we will set the
    xSpeed and ySpeed variables to when the proper keys are pressed. And create a friction
    value of 0.95, which we will constantly multiply the player’s speed by to slow him down.
    */

    var speedConstant:int = 5;

    var friction:Number = 0.95;

    /*
    Run your game and be amazed by the silky-smoothness of your movement system…
    */

    /*
    So our movement is all polished up… but we can still run through walls. Something
    tells me we need to add collision detection.
    This is the trickiest topic we have to cover today, and let me explain why. In a
    traditional tile-based platformer, where everything is laid out in nice grids, we
    can use code to calculate whether or not the player is colliding with floors, walls,
    etc. But we are not making a tile-based game — they are more complicated to set up,
    and your art and background environment is generally limited to a specific style.
    However, in exchange for the freedom that art-based platformers enjoy, we lose out
    on the perfectly calculated solution to collisions.
    Our best choice at this point is to settle for a less-than-perfect collisions system,
    and try to improve it as we go along. Time to begin.
    First things first, create 4 new variables at the top of your code so we can keep
    track of whether or not the player is colliding with the background on each side.
    For example, we will check the value of downBumping to check if the player is on the floor,
    and rightBumping to check if the right side of the player is touching a wall.
    */

    //Now that we’ve set the coordinates which we need to check, lets edit the loop
    //function and tie everything together.

    /*
    If you run your program now and move through a platform you will see the trace statements pop
    up in your output panel confirming that the collisions are working!
    There is one last step we need to add in order to make everything work. Right
    now we correctly set the “bumping” variables to true or false whenever the player
    collides with the background. All that’s left to do is to make the player react to these
    variable. We will program this by changing the player’s velocity in whatever direction the
    collision is sensed. Instead of setting the velocity to 0, for the moment we are going to make
    the player bounce off the walls he collides with, and slow down.
    Add the following code to the game loop. Be sure to position it correctly, because the order
    that the code gets executed in the loop will affect how the player behaves. Place these directly
    before the line where we multiply the speed by friction. This is after we add/subtract the
    speedConstant depending on the arrow keys that are pressed.

    That’s a big improvement over our last demo. ‘Ye olde scrolling background is finally beginning
    to act like a sidescrolling game. However, there is still a long, long, LONG way to go before we
    can call this a complete platformer.

    If you tested the new demo for more than a couple seconds, you probably realize that while our
    current hit-testing does an OK job, it has a few major problems.

    First and foremost, you are only blocked if a single point on each side of the player happens
    to bump into the background — this is a problem, for example, because you can have the left edge
    of the player’s body fall through the floor as long as the bottom-center point isn’t touching the
    floor, or you can easily run the player’s head sideways through a platform because the collision
    is checked farther down.

    The second issue is that if you speed up enough, sometimes you are able to slip through the
    background! This is because if the player’s speed is greater than the thickness of a platform,
    the hit-test point might skip over the entire platform between two frames. This would mean the
    game was never notified that the player should stop moving in that direction.

    */

  14. dennis says:

    i dont know why but my the bottom and right collision detection dont work, my character keep on falling through the ground and going out of bound on the right side

  15. Nico B says:

    How easily can this code be transposed into actionscrhip 2.0, or is it impossible?

    • Ben Reynolds says:

      I’m sure it’s possible, but I only ever learned 3.0, not 2.0, so I’m not sure exactly what you’d do. Most of the fundamental game logic is the same regardless of what language you use, but you’ll need to figure out how to convert it to 2.0, which might be tricky — it depends how experienced you are with 2.0 or 3.0.

  16. charlie says:

    Just wondering if there is anyway you can stop the character from going through the right hand walls. I have the same code as you have here (great tutorial by the way!) but I can’t seem to stop my character from going through the right wall.
    Thanks so much in advance!

  17. Zim_of_rite says:

    I’m having an issue, the character will go through anything , except for on his head. I even tried copy/pasting your code, and the issue still remains.

    I’m using Flash CS6 (the 30 day trial if that changes anything).

  18. Jamie Morris says:

    How do you find the points of an object??? I’m having trouble to figure it out. For example, I have a 32×32 picture (registration point placed in the middle) and if I want to find 4 points of the picture then how do i do that???

    • Ben Reynolds says:

      It’s all mathematical. If your registration point is in the center, and the image is 32×32 pixels, you know that the right edge is at 16 pixels in the x direction, and the left side is at -16 pixels. The top would be at -16 px in the y direction, and the bottom would be at 16 px. I believe in your case the points would be: right (16,0), top (0,-16), left (-16, 0), bottom (0,16).

  19. Adam Emerson says:

    Hey, I’m learning a lot from the tutorials! Thanks for posting them. I made it this far with no problems, but after adding the hitTestPoints and running a test on the game, my player image no longer displays. The background displays fine and the bumping works as if the player is there, I just can’t see him. Any ideas on what could be causing this? I’ve been working for a while and it’s getting late, so I’ll check my work again tomorrow, but any and all help is appreciated!

    • Ben Reynolds says:

      Sorry, I can’t think of what might be causing this. Do you get any error messages, or is the player just missing?

      • adamgemerson says:

        I managed to fix that problem. I can’t remember exactly what caused it but it was just some typos here and there. Now I am faced with a totally new issue. After typing out all the code and testing the program my player only responds to the down and right arrows, but moves very slowly and in the oposite direction (so the right key makes him move left and the down key makes him move up.) I’m know that the error is the last step because when I take the actually collision bumping part out all the keys respond like they are supposed to. I think what is happening is that some how the player is stuck in the bounding box and the down and right arrow are causing him to move backwards due to the bounce effect, but it’s just happening over and over as opposed to just one time. I’ve retyped the code multiple times, deleted the background and player and reinserted them, and I even scrapped the entire project and started back from stage 1 once already only to get the same results. Maybe it has to do with my graphics? They are the only thing I can find different about ours. I even copied and pasted the entire source code in to the action panel and received the same problem. Think I could email you the .fla for you to take a look at?

  20. adamgemerson says:

    Okay, I figured out that problem too.

    The issue was that I was using a png as my background. I had converted it to a symbol, but apparently that doesn’t work. I went ahead and drew the background directly into flash and everything works fine.

    Is there a way to bring png’s or gif’s into and use them as a proper background?

    • Ben Reynolds says:

      I’m glad you fixed your problem! :-)

      I’m don’t think there’s a way to use gif’s/png’s as a background in this type of game, because hitTestPoint only returns false if there is actually nothing there — and I’m pretty sure even a blank pixel in a png counts as being “something”. You could probably modify the collision detection system to allow for this, somehow (I’m not sure how, to be honest), but it’s probably more effort to convert the code than it would be to just redraw things as vector art in Flash.

      However, you should still be able to use png/gif background art in the “visuals” layer that we add in part 6: https://as3gametuts.com/2012/02/17/platformer-6/

  21. dannie says:

    Hi there! I stumbled across this site the other day and I’ve made it through your Pong tutorial and to this third step in the sidescrolling tutorial. You are doing a great job teaching beginners like myself.

    But I am having serious issues understanding the hitTestPoint function. Like, can you explain to me why you are setting the bumping points to these coordinates(-30, -55)? What does the leftbumping point coordinate stand for? The left side of the background? And if so, how do you know this?

    And also, when if(back.hitTestPoint(player.x + leftBumpPoint.x, player.y + leftBumpPoint.y, true)) is running, I cannot seem to understand what exactly is happening. The current x-coordinate of the player object is checked + the leftBumpPoint x-coordinate. But why in addition to eachother? I’ve read your description about it and watched the picture a million times, but it’s driving me nuts.

    I’m sorry if I sound like, really stupid, but this has been troubling me all day.

    Thanks in advance.

  22. drdannie says:

    Hi there! I stumbled across this site the other day and I’ve made it through your Pong tutorial and to this third step in the sidescrolling tutorial. You are doing a great job teaching beginners like myself.

    But I am having serious issues understanding the hitTestPoint function. Like, can you explain to me why you are setting the bumping points to these coordinates(-30, -55)? What does the leftbumping point coordinate stand for? The left side of the background? And if so, how do you know this?

    And also, when if(back.hitTestPoint(player.x + leftBumpPoint.x, player.y + leftBumpPoint.y, true)) is running, I cannot seem to understand what exactly is happening. The current x-coordinate of the player object is checked + the leftBumpPoint x-coordinate. But why in addition to eachother? I’ve read your description about it and watched the picture a million times, but it’s driving me nuts.

    I’m sorry if I sound like, really stupid, but this has been troubling me all day.

    Thanks in advance.

  23. zane says:

    Hey Ben, I really appreciate the tutorial and the work you have given us.
    The hitTestPoint is good and all, but bugs can happen to where the platform will go through the character, and i thought that if we added more points to each side it would work.
    so instead of 1 point for each side, i put 3.
    here is where i get confused, in the
    if(level.hitTestPoint(player.x + leftBumpPoint.x, player.y + leftBumpPoint.y,true)){
    leftBumping = true;
    }
    where would i put the || (or) in the condition to add more points?

  24. Gats B says:

    Hi! I came across your tutorial before and I’m encountering a problem – the player won’t move in the slightest. Whenever I hold down buttons, it just twitches in that direction for a second, unless I hold it for longer to which it continues twitching in that direction. With the tutorial beforehand, pressing a direction would cause it to jerk in that direction, stop, and then start moving slowly, as if it was constantly starting and stopping.
    Help?

  25. Mike says:

    Everytime i press left or right, the speed exponentially increasing.. how do we make it constant?

  26. Colt K says:

    Hi, your tutorial has been very helpful, however every time I try to run my game I find that several of the objects in the background are in the wrong place.

  27. Colt K says:

    Oh, lol, never mind I figured it out… sorry…

  28. Jed says:

    What code can I use to correctly position my background and player? thanks..

  29. James P says:

    I have a problem concerning scrolling. Everything is fine up till I went into collisions. The problem is when I scroll, going up and left makes the character go in that direction very fast and when I go down and right, I scroll in the opposite direction, just slowly. Is this a problem in my coding or where I placed my character (bottom left region)? I Thank you in advanced.

  30. michal says:

    i have a question to the points before i add them to the code –
    are they for the points of the character so that i have to find the ones for myself?

  31. DooMaan says:

    u must know the loop of ENTER_FRAME function that make this page too much laag —- i mean we need to rethink about use if and else with this loop…. why we dont use switch and case it chek for one time and go out … i hope u understand me …. just try to open this page for one h and see the slow down of mouse scroll speed

  32. micha says:

    i just don’t know what to do

  33. Mike says:

    I am confused on the bump points for up down left right. Quick question: How do you find them?
    player position is x:100 y:450, and it is 52W and 68H.

  34. Mike says:

    and reg point is bottom center

  35. Spencer says:

    I need help, I have the hitpoints correctly set on my character and I’ve followed your tutorial as closely as I can so mine works, but there seem to be invisible hitboxes that my character is bouncing off of, everything is always about 100px off so I seem to bounce off of nothing alot/

  36. TonyD says:

    Yea, this tutorial isnt working for me. You fail to specify where the chunks of code are going in, do I apply them to the player? Do I put the terrain and player on separate layers?
    Completely new to actionscripting..you should specify how to compile your scripts as well.
    I downloaded your source file and changed the symbols to my custom objects and still no luck.

  37. Connor says:

    tonyD, thats why he added the source code to download, also wouldnt it be more accurate to add your own hittesting method instead of using a premade one?

  38. Anon26 says:

    Hi Ben,
    Thanks a dozen for this tutorial
    I am that guy who had that weird trouble in the Pong game.

    Guess what? I have about the same thing happening with this tutorial as well.
    Everything was rocking till the friction part.

    When I did that part, my character did’nt move, but pressing buttons make him move him in the particular direction, and than he sort of re appear at the original position, so it appears he is shaking in the very place.

    When I did the good ol’ Control, “step forward one frame” it worked.

    Again, copying your code in my project didnt solved it,
    Downloading your source code, and running it worked.

    The shaking thing was very similar to what was happening in the pong tutorial.

    Now let me elaborate a bit how I followed your tutorial.

    1. I read your mechanics in theory.
    2. Skim over your code
    3. Try to write code myself (usually fail)
    4.Look at your code carefully, type it up
    5.It works

    Something I did:
    1. I named the variables same as yours, but I did not capitalised anything.

    Now I will do so again from scratch tomorrow, It was a bit frustrating to be honest, but nevertheless…

    Again thanks for the tutorial.
    It was great of you to reply to my comment.

    Also, Last night I was going through your Kong profile. I liked how your games just got better. You are an inspiration.

    :)

    • Jamal Jones says:

      I actually found an interesting way to increase the hit detection with the points.
      Instead of having 4 variables, I made 8.

      Then put them in the corners.
      (Naming them lupBumping, rupBumping, etc…)

      It added some extra points, and I think you can just keep adding more and more points to sharpen the accuracy. Hope this helps! :D

    • Jeff says:

      I know I’m replying way late to this, but I had the same thing happen, and wanted to post the solution just in case anyone else has it happen.

      This problem comes from having an extra frame in your timeline – to fix it, you’ll need to delete the extra frame and run the program again.

  39. Rachal N. says:

    My player’s image size is 30 x 56 and I can’t for the life of me figure out the correct variables for it. I’ve tried a number of combinations and with different ones it causes the player to “fly” off the screen in a number of different manners or move in the wrong direction in a jagged sort of way. Any help would be much appreciated!

  40. Patrick says:

    Hello,

    If my player bumps into the wall, it keeps it’s speed reversed with *-0.5. How can I only run that function once without keeping it’s speed at * -0.5?

  41. rick says:

    How can i correct the position of my background I’m using a different background style so when i start it the floor line(background) is above my character how how do i fix it so the floor is under my character’s feet not above it? sorry i’m very new at this please help.

Leave a comment