Author Topic: Wall jumping  (Read 2339 times)

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Wall jumping
« on: Mon, Oct 4, 2010 »
I'm working on a platformer, and I'm trying to include wall jumping as a skill. To keep the player from bouncing straight up a wall, I make the character move away from the wall after every jump. However, this only seems to work when the wall is to the right of the player. Here's the code:
Code: [Select]
//[player coding]
else if (canWallJump)
{
play("slideOnWall");
if (FlxG.keys.justPressed("A"))
{
acceleration.y = 450;   //Resets gravity (lowered while sliding)
velocity.y = - acceleration.y * 0.5;  //Player jumps up
if (onLeftWall)  //Defined in the PlayState's update if colliding with the tiles on the left
velocity.x = maxVelocity.x;
if (onRightWall)
velocity.x = -maxVelocity.x;
}
}

I tried switching the order, but this only works on the right wall, and on the left wall the player  just goes straight up. Anybody see what's happening?

initials

  • Contributor
  • ****
  • Posts: 378
  • Karma: +0/-0
  • Initials
    • View Profile
    • Initials Blog. Code and other things.
Re: Wall jumping
« Reply #1 on: Mon, Oct 4, 2010 »
A few things to try.

Use an else if. This will stop it from running both commands.

Try adding some logs. hit the tilda key to get the dev mode on.





Code: [Select]
//[player coding]
else if (canWallJump)
{
play("slideOnWall");
if (FlxG.keys.justPressed("A"))
{
acceleration.y = 450;   //Resets gravity (lowered while sliding)
velocity.y = - acceleration.y * 0.5;  //Player jumps up
if (onLeftWall) {  //Defined in the PlayState's update if colliding with the tiles on the left
velocity.x = maxVelocity.x;
FlxG.log("On left wall, jumped");
}

else if (onRightWall)
velocity.x = -maxVelocity.x;
FlxG.log("On right wall, jumped");
}
}
}
Initials: Super Lemonade Factory, Super Lemonade Factory Part Two, Above The Clouds, Revvolvver, Four Chambers of the Human Heart

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Wall jumping
« Reply #2 on: Mon, Oct 4, 2010 »
I originally did have an else if statement, but I couldn't get it to work then either. I tried running the logs, and it is only recognizing the player as being on the right wall, no matter which one they're actually on.

I'm guessing it might be in the PlayState... maybe?
Code: [Select]
Player.onRightWall = false; //Resets being on walls
Player.onLeftWall = false;
//Checks that the player is touching the tilemap, in the air, and is going down(or up slowly)
if (player.collide(tiles) && !player.onFloor && player.velocity.y >= -50)
{
if (player.collideRight)
Player.onRightWall = true;
else if (player.collideLeft)
Player.onLeftWall = true;
}
It comes after super.update(), could that do anything?
*EDIT*: Nope, putting it before makes no wall jumping possible. Never mind that last line.
« Last Edit: Mon, Oct 4, 2010 by superbany »

ETG

  • Active Member
  • ***
  • Posts: 115
  • Karma: +0/-0
    • View Profile
Re: Wall jumping
« Reply #3 on: Mon, Oct 4, 2010 »
Doesn't Flixel by default just call collide right in it's collide left function?

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Wall jumping
« Reply #4 on: Mon, Oct 4, 2010 »
I don't see anything about that in the documentation...
I think I've found the problem. In PlayState.as, I have:

Code: [Select]
Player.onRightWall = Player.onLeftWall = false;
if (player.collide(tiles) && !player.onFloor && player.velocity.y >= -50)
{
if (player.collideRight)
Player.onRightWall = true;
else if (player.collideLeft)
Player.onLeftWall = true;
}
However, if I remove the "else", the game only recognizes the player as being on the left wall. I think since I'm using a FlxTilemap, it is recognizing the tiles as being over the entire game level, and so "player" will always have collideRight be true. I'll try making a requirement of having a key against the wall and see if that works.

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Wall jumping
« Reply #5 on: Mon, Oct 4, 2010 »
Changed it to:
Code: [Select]
Player.onRightWall = Player.onLeftWall = false;
if (player.collide(tiles) && !player.onFloor && player.velocity.y >= -50)
{
if (player.collideRight && FlxG.keys.pressed("RIGHT"))
Player.onRightWall = true;
else if (player.collideLeft && FlxG.keys.pressed("LEFT"))
Player.onLeftWall = true;
}
in PlayState.as and to:
Code: [Select]
else if (canWallJump)
{
play("slideOnWall");
if (FlxG.keys.justPressed("A"))
{
acceleration.y = 450;
velocity.y = - acceleration.y * 0.5;
if (onLeftWall)
{
velocity.x = maxVelocity.x;
FlxG.log("On left wall, jumped");
}
else if (onRightWall)
{
velocity.x = -maxVelocity.x;
FlxG.log("On right wall, jumped");
}
}
}
in Player.as, and it now works fine, with the correct rebound off each wall. Thanks for all the help!

carls

  • Member
  • **
  • Posts: 16
  • Karma: +0/-0
    • View Profile
Re: Wall jumping
« Reply #6 on: Mon, Oct 4, 2010 »
Nice!
At somedays ago I was wondering in a method to do this in a flixel game.
Nice to see that the forum helps you and you got your game works...makes me happy =)
congratulations and good luck!

Nimja

  • Member
  • **
  • Posts: 88
  • Karma: +0/-0
  • Just a toy
    • View Profile
    • Nimja's Domain
Re: Wall jumping
« Reply #7 on: Tue, Oct 5, 2010 »
Actually better method is this:

override hitLeft / hitRight function, check if you're in the air and set your walljump var to something. And a sliding var to true.

1 for left,
-1 for right
0 for not sliding.

Now, the cool thing is that it will work WHILE you press left/right to slide against the wall. And if you jump, you can just multiply the velocity.x with the walljump var. (instead of more if functions)

And the walljump var can also be used for using the right animation.
Life's too short to mope.

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Wall jumping
« Reply #8 on: Tue, Oct 5, 2010 »
I'm not really understanding your train of thought. What exactly are you suggesting? [could you list your proposed code?]

Nimja

  • Member
  • **
  • Posts: 88
  • Karma: +0/-0
  • Just a toy
    • View Profile
    • Nimja's Domain
Re: Wall jumping
« Reply #9 on: Wed, Oct 6, 2010 »
Example:
http://dev.nimja.com/shadow/4

Code (all in your player.as, based on FlxSprite:
Code: [Select]
//Enable wall-jumping.
private var _wall:int = 0;
override public function hitLeft(Contact:FlxObject, Velocity:Number):void {
super.hitLeft(Contact, Velocity);
if (!onFloor) _wall = 1;
}
override public function hitRight(Contact:FlxObject, Velocity:Number):void {
super.hitLeft(Contact, Velocity);
if (!onFloor) _wall = -1;
}

//Update function
override public function update():void {
//Jump button just pressed.
var jump:Boolean = FlxG.keys.justPressed("UP");

//Jumping against wall.
if (_wall != 0 && jump) {
velocity.y = -JUMP;
velocity.x = JUMP * _wall;
}

//Reset wall-jump var, by resetting it only activates when user 'pushes' against wall.
_wall = 0;

super.update();
}

You'll have to do the animation code yourself. As I have a somewhat weird setup. My jumping mechanic is based on non-linear movement, which makes it feel much nicer. I'll post my code when it's a bit cleaner ;)
Life's too short to mope.

superbany

  • Member
  • **
  • Posts: 53
  • Karma: +0/-0
  • [Please enter text here]
    • View Profile
    • Superbany's games
Re: Wall jumping
« Reply #10 on: Wed, Oct 6, 2010 »
I see your point, with cleaning it up and having the wall jumping mechanics inside Player.as, but I want it to only work with the current state's tiles, and it looks like your version will let them wall jump off anything. However, I did use your idea with the 0,1, or -1:
PlayState.as:
Code: [Select]
Player.onWall = 0;
if (player.collide(tiles) && !player.onFloor && player.velocity.y >= -50)
{
if (player.collideRight && FlxG.keys.pressed("RIGHT"))
Player.onWall = -1;
else if (player.collideLeft && FlxG.keys.pressed("LEFT"))
Player.onWall = 1;
}
Player.as:
Code: [Select]
if (inWater) //Handles water physics
{
acceleration.y = 100;
if (onFloor)
maxVelocity.x = 25;
else
maxVelocity.x = 100;
}
else
{
maxVelocity.x = 100;
var canWallJump: Boolean;
if (onWall && powerup_walljump) //Wall jumping is an upgrade, and won't be default
{
acceleration.y = 75; //Slower sliding down wall
canWallJump = true;
}
else
{
acceleration.y = 450;
canWallJump = false;
}
}

//[other stuff]....

else if (canWallJump)
{
play("slideOnWall");
if (FlxG.keys.justPressed("A"))
{
acceleration.y = 450;
velocity.y = - acceleration.y * 0.35;
velocity.x = maxVelocity.x * onWall;
}
}

.. and it works perfectly fine. I might want to figure out a way to get the detection for colliding with the tiles within Player.as, so the object is self-sufficient.

Nimja

  • Member
  • **
  • Posts: 88
  • Karma: +0/-0
  • Just a toy
    • View Profile
    • Nimja's Domain
Re: Wall jumping
« Reply #11 on: Tue, Oct 12, 2010 »
A sidenote:
HitLeft and HitRight are automatically called when you hit something on the side (not just maptiles, but other things as well, like vertical platforms.

And they only work WHILE you press the movement key towards them, because you only hit them once, then you fall.

So it already does it, all in the Player.as hence my solution.
Life's too short to mope.