• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Megaman X Wall Jumping

R

Raptor_Guy

Guest
Hi, I'm in the middle of creating a Megaman X fan game, and I've got just about everything movement-wise, except for a good wall jumping system. When I'm touching a wall, my fall is slowed, and I can climb walls by jumping, getting pushed out, and grabbing back on. The problem comes when I try to jump off away from a wall; it's not very reliable. A lot of times, I'll start moving away from the wall slightly before I hit jump, and I fall.


Wall slide/jump code in step event:
Code:
if place_meeting(x+1, y, oSolid) && vspd > 0 {
    grav = .2;
    image_xscale = -1;
} else {
    grav = 1;
}

if place_meeting(x-1, y, oSolid) && vspd > 0 {
    grav = .2;
    image_xscale = 1;
} else {
    grav = 1;
}

if grav == .2 && keyboard_check_pressed(vk_up) && image_xscale == -1 {
    vspd += jheight;
    hspd += -16;
}

if grav == .2 && keyboard_check_pressed(vk_up) && image_xscale == 1 {
    vspd += jheight;
    hspd += 16;
}
Also: I can't wall jump/slide on right walls or find a way to dash off a wall. Thanks for your help!
 

CMAllen

Member
It's going to be very unreliable because your check range for an applicable wall surface is only 1 pixel. That means if your code executes the movement portion first, you'll already have moved beyond the range of the collision check and the code for the wall jump won't execute.

The 1 pixel range is fine initially. But you want to do a double-test with it. Instead of a hard 1-pixel value, you want a 'grab-range' value that you can modify based on what's going on. So initially, you can test against 1 pixel, then, once you confirm that the player object has 'grabbed' a wall, you can expand your grab range to ensure that the wall jump can still execute to within a reasonable distance from that wall.
 

Bentley

Member
Zack Bell has a great article on this, but I'll summarize what I can remember.

When a player jumps towards a wall, they often plan what they want to do after. This can cause problems. For example: the player jumps to a wall to his right. He wants to wall jump to the left, however, he presses the left / away key prior to pressing jump. He then detaches rather than jumps. You can deal with this with a timer. When the player collides with a wall, start a timer that lasts for a few frames. When the timer reaches 0, allow an away key press to detach him. This gives him the chance to wall jump without accidently detaching.

Code:
if (I just attached to a wall to the right)
{
    // Detach timer
    timer--;
    if (timer <= 0)
    {
        if (key_left)
        {
            detach;   
        }
    }
  
    // Wall jump
    if (key_jump)
    {
        hspd = -facing * something;
        vspd = something
    }
}
 
Last edited:
R

Raptor_Guy

Guest
I thought I had it, but it doesn't seem to work:
Code:
if place_meeting(x+1, y, oSolid) && vspd > 0 {
    grav = .2;
    image_xscale = -1;
    walljumptimer = 14;
} else {
    grav = 1;
    walljumptimer = -1;
}

if place_meeting(x-1, y, oSolid) && vspd > 0 {
    grav = .2;
    image_xscale = 1;
    walljumptimer = 14;
} else {
    grav = 1;
    walljumptimer = -1;
}

if !place_meeting(x+1, y, oSolid) || !place_meeting(x-1, y, oSolid) {
    walljumptimer --;
}

if walljumptimer < 0 {
    walljumptimer = -1;
}

if keyboard_check_pressed(vk_up) && image_xscale == -1 && walljumptimer !< 0 {
    vspd += jheight;
    hspd += -16;
}

if keyboard_check_pressed(vk_up) && image_xscale == 1 && walljumptimer !< 0 {
    vspd += jheight;
    hspd += 16;
}
(I set walljumptimer to 14 in the create event)
 

Bentley

Member
At first glance, your problem may be that jump_timer is being reset to 14 constantly. For example, let's say you're clinging to a wall to your right. The condition:
Code:
if (place_meeting(x + 1, y, obj_wall))
is true every step, thereby setting jump_timer to 14 every step.

I read your code kind of fast because I'm on the way out, so correct me if I'm misunderstanding.
 
Last edited:

CMAllen

Member
New code has a problem a problem in that it can only execute your wall jumping code until walljumptimer is 0. That takes a maximum of 7 steps (it's decreased twice per step event once the player object moves more than 1pix from the nearest wall). 7 steps, at 30fps, is less than 1/4th of a second, and I believe GMS2 defaults to 60fps for new projects. The code has a 'blink and you'll miss it' effect.
 

VacantShade

Member
You've been given some solid advice so far on how to implement what your looking for.
I've made a Mega Man X game myself, and I noticed your engine doesn't follow the same parameters as the original game. So I thought I'd share some data on the physics of the original. If you are trying to make your game have slightly different physics than the original, you can ignore the following. But if you are trying to emulate the original closely, I hope this will be useful to you. I got all this data from slow meticulous study from the real game.

First note that all blocks in the following gif images are 16 x 16 pixels.

( 1 ) Jump Height
Jump Height.gif
Mega Man's bounding box is just under 2 blocks, or 32 pixels. His jump height is about 3 1/4 blocks high. Or you could say about 52 pixels. This lets him clear a 3 block jump with a little room for error.

( 2 ) Wall Jumping
Wall Jump.gif
The height of a wall jump is nearly exactly the same as a normal jump, about 52 pixels. One important detail to note is how Mega Man is pushed from the wall. Without any player input, he will repel about 12 pixels away from the wall on his own after a wall jump. Even if the player is pushing back into the wall, he will still repel away slightly, giving a nice feel.
- - *NOTE* - -
About your initial question, if you go back to the original Mega Man X game, you'll find there isn't actually a frame window in which you can push away from the wall and then wall jump. At most, you can push away from the wall and jump on the same frame. The controls on the X games were pretty harsh on timing, but it lead to some really tight controls and gameplay. It's up to you which way you want to do it.
There is however, a leniency as far as when you can press and hold the dash button when doing a wall jump to do a dashing wall jump. As much as up to 2-3 frames after you preform your wall jump, you can switch to a dashing wall jump.

( 3 ) Ceiling Hit
Ceiling Hit.gif
Building on the above, if you hit a ceiling while wall jumping, that horizontal push will stop. Compare the horizontal movement of the longer jump with the lack of horizontal movement with the smaller jumps.

( 4 ) Dash Length
Dash Length.gif
I couldn't tell if your dashing had a length to it, but I thought I'd throw this in here in case it helps. A full dash lasts about 6 1/2 blocks along the ground. As a side note, the hit box shrinks in height by about 5 pixels during the dash.


Hope this data proves useful. I had a lot of fun myself putting a fan game together, and it was a great way to learn programming! Keep it up! ;)
 
Top