Legacy GM Arrow keys and joystick controls + platforming slopes [SOLVED]

S

SilverTom93

Guest
At the moment, the basic platform physics of my game are going well (it uses arrow keys). I'm currently trying to implement an optional gamepad input into my game, which uses the joystick for moving left/right and the A button to jump. But whenever I press an arrow key AND a joystick direction at the same time, the movement speed of the player doubles...
So for example, if I'm using the left arrow key to move left, I move at a speed of 4. If I then hold the joystick in the same direction, it adds an extra speed of 4 on top of that. So it's basically giving the player a weird speed boost :confused:

Below are the first few lines of the player's Step event (the rest of the code I followed from this tutorial:
)

Code:
/// Platform Physics

var rkey = keyboard_check_pressed(vk_right) || (gamepad_axis_value(0,gp_axislh) > 0);
var lkey = -keyboard_check_pressed(vk_left) || (gamepad_axis_value(0,gp_axislh) < 0);
var jkey = keyboard_check_pressed(vk_up) || (gamepad_button_check_pressed(0,gp_face1));
So that's basically saying "moving is when an arrow key is pressed, OR if the joystick is in a left/right direction"

Bear in mind that I'm still learning the basics of GML code, and there's most likely an incredibly simple solution to this which I don't know (much like in my last post XD) but if anyone knows a way to limit the left/right movement speed even if there's two buttons pressed simultaneously, then I'd be really thankful :)
 

GMWolf

aka fel666
I made a tutorial on this recently.
It explains how to use the gamepads, as well as how to allow multiple input devices properly. ie, not doubling the players speed.


Hope this helps!
please like and sub :)
 
S

SilverTom93

Guest
I made a tutorial on this recently.
It explains how to use the gamepads, as well as how to allow multiple input devices properly. ie, not doubling the players speed.


Hope this helps!
please like and sub :)
Just tried that tutorial, and it works! Thank you very much :)
Also, is there a way to make this compatible with slopes? I'm sorta familiar with slope code using Drag N' Drop commands in the past ("if there's a collision at relative x4, y-4", stuff like that) but I'm not sure how to remake that with GML code :confused:
 

GMWolf

aka fel666
Just tried that tutorial, and it works! Thank you very much :)
Also, is there a way to make this compatible with slopes? I'm sorta familiar with slope code using Drag N' Drop commands in the past ("if there's a collision at relative x4, y-4", stuff like that) but I'm not sure how to remake that with GML code :confused:
I also made a tutorial on slopes:

:)
 
S

SilverTom93

Guest
I also made a tutorial on slopes:

:)
That new code tutorial mostly worked (although jumping underneath platforms was quite glitchy). Thing is, the movement code in there is quite different than the Gamepad tutorial's code you sent me (which is what I am now using); so when I tried adding the m_speed and m_step things into the gamepad code, it messed up quite a lot and kept on giving me error messages :/

So this is the code I have from your Gamepad tutorial video (which works really well), and I was wondering if I can simply add something to this to make it work with slopes - I'm presuming I need to make another "if place_free" thing somewhere in the horizontal section? I'm not too sure haha XD

Code:
//Check inputs
var hor = absmax(gamepad.hor, keyboard.hor);
var up = absmax(gamepad.up, keyboard.up);

//move
//horizontal
var move_hor = hor * hor_speed;
if (place_free(x + move_hor, y)) {
    x += move_hor;
} else {
   var s = 0;
   for(var i = 0; (abs(i) < abs(move_hor)) and place_free(x + i, y); i += sign(move_hor)) {
       s += sign(move_hor);
   }
   x += s - sign(move_hor);
}

//vertical
if (up and !place_free(x, y + 1)) {
 v_speed = -jump_speed;
} else {
 v_speed += grav;
}
if (place_free(x, y + v_speed)) {
    y += v_speed;
} else {
   var s = 0;
   for(var i = 0; (abs(i) < abs(v_speed)) and place_free(x, y + i); i += sign(v_speed)) {
       s += sign(v_speed);
   }
   y += s - sign(v_speed);
   v_speed = 0;
}
Also your YT videos are pretty helpful, I've subscribed :)
 

GMWolf

aka fel666
So at the start of the video, i explain how the concept behind moving up slopes.
what you have to do, is first move up, then move across, and then move back down.

before the horizontal movement code of the controller tutorial, add the moving up part.
then afrte the horizontal movent code, add the moving down part.

good luck!

btw, the code i included with the controller tut was thrown together for demostration porpouses. I think it should work just fine, but keep that in mind.
 
S

SilverTom93

Guest
So at the start of the video, i explain how the concept behind moving up slopes.
what you have to do, is first move up, then move across, and then move back down.

before the horizontal movement code of the controller tutorial, add the moving up part.
then afrte the horizontal movent code, add the moving down part.

good luck!

btw, the code i included with the controller tut was thrown together for demostration porpouses. I think it should work just fine, but keep that in mind.
The moving up part (before the horizontal movement code) seemed to work! It took some time, but the character can now move up and down slopes pretty well :D
But now there's another problem with the moving down part (after the horizontal movement code) which basically makes it so that the character's jumps are quick hops. It's making the player move down all the time and it's not allowing jumping.

So I wonder if I can try and replace this "move_contact_solid" to something different :/ Here's all the code I have in the Step event:
Code:
///Moving and jumping

//Check inputs
var hor = absmax(gamepad.hor, keyboard.hor);
var up = absmax(gamepad.up, keyboard.up);


move_contact_solid(90,20); //This part makes the "up" movement for the slopes apparently


//move
//horizontal
var move_hor = hor * hor_speed;
if (place_free(x + move_hor, y)) {
    x += move_hor;
} else {
   var s = 0;
   for(var i = 0; (abs(i) < abs(move_hor)) and place_free(x + i, y); i += sign(move_hor)) {
       s += sign(move_hor);
   }
   x += s - sign(move_hor);
  
}

//                          This part below needs fixing! 

move_contact_solid(270,-4); //This is the part which moves the player down onto slopes, but this stops you from jumping.
 
//vertical
if (up and !place_free(x, y + 1)) {
 v_speed = -jump_speed;
} else {
 v_speed += grav;
}
if (place_free(x, y + v_speed)) {
    y += v_speed;
} else {
   var s = 0;
   for(var i = 0; (abs(i) < abs(v_speed)) and place_free(x, y + i); i += sign(v_speed)) {
       s += sign(v_speed);
   }
   y += s - sign(v_speed);
   v_speed = 0;
}
I really hope there's a solution to the downward-moving part! It was going so well until I tried jumping :(
 

GMWolf

aka fel666
Only move up and back down if hor_speed is not 0. There is no point in moving up and down if you don't move side to side.
The reason you get small hops is that the code to move back down uses a value of -4 in the distance parameter.
This effectively means infinity.
Replace that with 20, just like in the moving up part.
 
S

SilverTom93

Guest
Only move up and back down if hor_speed is not 0. There is no point in moving up and down if you don't move side to side.
The reason you get small hops is that the code to move back down uses a value of -4 in the distance parameter.
This effectively means infinity.
Replace that with 20, just like in the moving up part.
That seems to work a lot better now! :D There's just another problem again: if I jump and hit a solid wall from underneath, the character sorta sticks there in the air before falling down. If I jump somewhere in the open instead, it works fine (a smooth bounce). I screen-recorded the game to show you how the jumping looks:
This glitch also blocks me from entering a small section of the room, which is strange :confused:

The only thing I've added to the code is "and hor_speed !=0" before the two "move_contact_direction" parts, so is it perhaps something to do with those which makes the jumping weird when the player hits the ceiling?
 

GMWolf

aka fel666
When colliding with a wall object, make sure you have the vspeed=0 bit before you move out of the solid.
 
S

SilverTom93

Guest
When colliding with a wall object, make sure you have the vspeed=0 bit before you move out of the solid.
What code should I use to do that? Again I'm quite new to GML so I'm not too sure what I should be writing here xD
 

GMWolf

aka fel666
the collusion event with a wall, put v_speed = 0.

The problem on entering the hole is due to the character first moving up before moving horizontally.
There is a fix, which I did implement for one of my games.
I think it counted how many pixles you moved after moving up, and tried to move the remainder after moving back down.
I'll check out the exact implementation and post it here when I get back to my PC.
 

GMWolf

aka fel666
Here is the code:
Code:
///move
hor_speed = input_move_h * move_speed;


//vertical speed
if place_free(x, y + 1)
{
 ver_speed += grav;
 ver_speed = min(ver_speed, max_vspeed);
}

//vertical move
if ver_speed != 0
{
 move_contact_solid(-(sign(ver_speed) * 90), abs(ver_speed));
}

//horizontal move
if hor_speed != 0
{
 if place_free(x, y + 1)
 {
  move_contact_solid(90 - (sign(hor_speed) * 90), abs(hor_speed));
 }
 else//has ground to step
 {
  //if blocked step
  if !place_free(x + hor_speed, y)
  {
   move_contact_solid(90, up_step);
   move_contact_solid(90 - (sign(hor_speed) * 90), abs(hor_speed));
   move_contact_solid(270, up_step);
  }
  else //if not blocked, walk normally.
  {
   move_contact_solid(90 - (sign(hor_speed) * 90), abs(hor_speed));
  }
 }
}

//jump
if (input_jump) and !place_free(x, y + 1)
{
 ver_speed = -jump_speed;
}
unfortunately its not exactly the same variable names and all, but im sure you can figure it out!

good luck!
 
S

SilverTom93

Guest
Here is the code:
Code:
///move
hor_speed = input_move_h * move_speed;


//vertical speed
if place_free(x, y + 1)
{
 ver_speed += grav;
 ver_speed = min(ver_speed, max_vspeed);
}

//vertical move
if ver_speed != 0
{
 move_contact_solid(-(sign(ver_speed) * 90), abs(ver_speed));
}

//horizontal move
if hor_speed != 0
{
 if place_free(x, y + 1)
 {
  move_contact_solid(90 - (sign(hor_speed) * 90), abs(hor_speed));
 }
 else//has ground to step
 {
  //if blocked step
  if !place_free(x + hor_speed, y)
  {
   move_contact_solid(90, up_step);
   move_contact_solid(90 - (sign(hor_speed) * 90), abs(hor_speed));
   move_contact_solid(270, up_step);
  }
  else //if not blocked, walk normally.
  {
   move_contact_solid(90 - (sign(hor_speed) * 90), abs(hor_speed));
  }
 }
}

//jump
if (input_jump) and !place_free(x, y + 1)
{
 ver_speed = -jump_speed;
}
unfortunately its not exactly the same variable names and all, but im sure you can figure it out!

good luck!
After a few minutes tweaking variables, it works!! Thanks so much for the help :D
There's still a few things that need adding (such as being able to jump whilst going downhill...dunno why that isn't working...?) and the character still sorta sticks to the ceiling for a few milliseconds if you jump right underneath it, but other than that everything is working pretty fantastically :)
 

GMWolf

aka fel666
After a few minutes tweaking variables, it works!! Thanks so much for the help :D
There's still a few things that need adding (such as being able to jump whilst going downhill...dunno why that isn't working...?) and the character still sorta sticks to the ceiling for a few milliseconds if you jump right underneath it, but other than that everything is working pretty fantastically :)
the sticking issue is a wierd one. not all my projects have that problem.
as for jumping when going down hill, you could try making the going down distance greater so that it sticks to the slope.
another (better?) option is to put the jump code below the vertical movement code. and update the y position after updating the vertical speed.
 
Top