SOLVED Help with certain acceleration?

V

Vetmatt89

Guest
Hey all whom use this forum! I was wondering if someone can help me tackle a problem? I have my acceleration and deceleration working the way I want it. I have a "sprint" button as well.
The problem that I'm having is my speed won't decelerate to the desired number, but instead jump to that number. I will post my code up and hopefully someone can help me out! Please and thank you!

if (move == 2)
{
hsp += 0.06
if (hsp > 1.3) && (key_run == 0) hsp = 1.3
}

if (key_run) && (hsp > 1)
{
hsp += 0.06
if (hsp > 2.2) hsp = 2.2
}


if (move == 0) && (hsp > 0)
{
hsp -= decel
if (hsp <= 0) hsp = 0
}

if (move == 2) && (key_run == 0) && (hsp > 1.3)
{
hsp -= decel
}
 

Nidoking

Member
What are these values? I'm seeing a bunch of variables and no explanation of what they mean or what values they hold.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
Releasing the run key is setting the key_run var to 0 (false), and so instantly the speed is being capped by that first block of code. If you want a smooth deceleration regardless of the value then you need to modify the code so this doesn't happen. Maybe something like this:

GML:
if (move == 0)
{
if (hsp > 0)
    {
    hsp = max(hsp - decel, 0);
    }
}
else if (move == 2)
{
hsp += 0.06;
if (key_run) && (hsp > 1)
    {
    hsp = min(hsp, 2.2)
    }
else if (hsp > 1.3)
    {
    hsp = max(hsp - decel, 1.3)
    }
else hsp = min(hsp, 1.3);
}
What are these values? I'm seeing a bunch of variables and no explanation of what they mean or what values they hold.
Sorry to say this, but this reply seems deliberately obtuse... It's pretty obvious what the code is intended to do and the actual values of the variables is pretty much irrelevant imho... I mean, that's what variables are for! So you don't NEED to know the exact values, and in this case they are obviously named and not obscure "a" or "kdhask" or something weird...


PS: Wrote the code a above in a hurry as I'm about to go out, so it might have an error somewhere, but hopefully it illustrates the point I'm trying to make...
 

Nidoking

Member
Sorry to say this, but this reply seems deliberately obtuse... It's pretty obvious what the code is intended to do and the actual values of the variables is pretty much irrelevant imho... I mean, that's what variables are for! So you don't NEED to know the exact values, and in this case they are obviously named and not obscure "a" or "kdhask" or something weird...
I resent your accusation. I'm trying to trace logic based on values of move and key_run that haven't been defined in the post, and there's a magic number for acceleration, but deceleration is another variable with no listed value. I believe you've spotted the logical flaw, and the whole "move == 2 and nothing else" clause certainly stood out as an interesting and potentially error-prone feature, but the problem could just as easily have been that decel was some weird value or that key_run isn't properly set. I want to encourage people to provide enough information to solve their problems all the time, not just when someone happens to make the correct assumptions.
 

Nocturne

Friendly Tyrant
Forum Staff
Admin
I resent your accusation.
Please don't as it wasn't an accusation as such. I said "seems" on purpose and did apologise first, as I know how much you help out around here and greatly appreciate it! This reply just seemed odd to me which is why I quoted it and said what I did hoping you'd clear up any misunderstanding (which you have). So, yeah, sorry if you feel offended, it wasn't meant that way, it just seemed like an oddly unhelpful reply from you!!!

I want to encourage people to provide enough information to solve their problems all the time, not just when someone happens to make the correct assumptions.
Okay! I get that now and that's great! I personally thought the OP did a fairly good job at expressing their issue, but I can definitely see where you're coming from. Help people to help themselves! :)
 
V

Vetmatt89

Guest
What are these values? I'm seeing a bunch of variables and no explanation of what they mean or what values they hold.
Sorry they are magic numbers since I was prototyping and trying to get the formula established before tidying up the code. I apologize for any confusion I may have caused.
 
V

Vetmatt89

Guest
Releasing the run key is setting the key_run var to 0 (false), and so instantly the speed is being capped by that first block of code. If you want a smooth deceleration regardless of the value then you need to modify the code so this doesn't happen. Maybe something like this:

GML:
if (move == 0)
{
if (hsp > 0)
    {
    hsp = max(hsp - decel, 0);
    }
}
else if (move == 2)
{
hsp += 0.06;
if (key_run) && (hsp > 1)
    {
    hsp = min(hsp, 2.2)
    }
else if (hsp > 1.3)
    {
    hsp = max(hsp - decel, 1.3)
    }
else hsp = min(hsp, 1.3);
}

Sorry to say this, but this reply seems deliberately obtuse... It's pretty obvious what the code is intended to do and the actual values of the variables is pretty much irrelevant imho... I mean, that's what variables are for! So you don't NEED to know the exact values, and in this case they are obviously named and not obscure "a" or "kdhask" or something weird...


PS: Wrote the code a above in a hurry as I'm about to go out, so it might have an error somewhere, but hopefully it illustrates the point I'm trying to make...
Thank you for your help! I will try this out late tonight and let you know the result by tomorrow morning.
 

Nidoking

Member
There's definitely something in the original post that hints at more wrongness afoot - as Nocturne pointed out, the final case will never be true, because if all of those conditions are met, then hsp will be set to 1.3 in the first case. The things that are specifically unclear from this include:
Does move 2 mean that the player is sprinting? Does that imply that the player is holding down the run key, as presumably contained in the key_run variable? If so, why would it ever be the case that move is 2 and key_run is false? A case could be made for preserving the "sprint" status until the player's speed falls below the 1.3 threshold, but this code isn't doing that. It isn't changing any of the input variables to the logic, apart from hsp. Perhaps it should be impossible for move to be 2 while key_run is true. If not, then what IS the relation between these two variables, if any?
The second case doesn't even check the value of the move variable. If you're holding the run key, the character speeds up to 2.2, if it was moving at least 1. What if it's moving slower than 1? Can it ever move? Surely, something else in the game must be affecting the hsp variable, or this would never work at all. What convinces us that the error isn't in that part?
Using move values of 0 and 2 suggests that there is a move value of 1, representing some form of movement that isn't even checked here. (I know, three greased pigs in a crowded room and all that, but this appears deliberate.) What happens in those cases that might affect this?

As you can see, the problem is often that you've asked the wrong question because you don't understand what's happening well enough to know what question to ask that would lead to a correct solution. Hopefully, your problem is what's been addressed above, but I'm going to go out on a limb and say that I'm absolutely confident there are more problems lurking elsewhere that you just might not have found yet. I speak from experience - there are too many times that something appears to be working correctly, only because the errors I've made don't cause visible symptoms in the configurations where I've used them. I try putting a new instance somewhere, a new interaction results, and suddenly everything is broken and I have to dig a long way to find the underlying cause. Here, I suspect that there's not likely a need for a separate move variable if the speed relates to the movement type. However, like I said, there is no explanation provided to suggest how I might propose any improvements to the system. This is why my answer seems unhelpful. There is help needed, but not enough information to provide it.
 
V

Vetmatt89

Guest
Releasing the run key is setting the key_run var to 0 (false), and so instantly the speed is being capped by that first block of code. If you want a smooth deceleration regardless of the value then you need to modify the code so this doesn't happen. Maybe something like this:

GML:
if (move == 0)
{
if (hsp > 0)
    {
    hsp = max(hsp - decel, 0);
    }
}
else if (move == 2)
{
hsp += 0.06;
if (key_run) && (hsp > 1)
    {
    hsp = min(hsp, 2.2)
    }
else if (hsp > 1.3)
    {
    hsp = max(hsp - decel, 1.3)
    }
else hsp = min(hsp, 1.3);
}

Sorry to say this, but this reply seems deliberately obtuse... It's pretty obvious what the code is intended to do and the actual values of the variables is pretty much irrelevant imho... I mean, that's what variables are for! So you don't NEED to know the exact values, and in this case they are obviously named and not obscure "a" or "kdhask" or something weird...


PS: Wrote the code a above in a hurry as I'm about to go out, so it might have an error somewhere, but hopefully it illustrates the point I'm trying to make...
Thank you so much! That's exactly what I was looking for and it works perfectly! It took me over a week to try to wrap my head around how to implement it, but the more I tinkered the more confused I became with it. Again thank you for responding so fast, and taking some time to help me out.
 
V

Vetmatt89

Guest
Hey found another issue. It seems to be when I change my "decel" variable. When I have it set to 0.4 it works, but when I change it to 0.07, and releasing my run key while walking
it drops instantly. Is there a reason for this?
 

Nidoking

Member
Is there a reason for this?
Yes.

While it's tempting to leave that as my entire answer, I suspect that you want to know what that reason might be. I've asked a number of questions in this thread that haven't been answered, and it also appears that you've made some changes since you lasted posted any code, so instead of working with barely enough information, we're now working with essentially no information. This is, however, a very good time to learn how to use the debugger. If you can put a break point where the run key is released, then step through and look at the values of your variables, you may see something happening that you didn't expect. Then you can solve the problem. Then you can solve almost all of your problems.
 
V

Vetmatt89

Guest
Yes.

While it's tempting to leave that as my entire answer, I suspect that you want to know what that reason might be. I've asked a number of questions in this thread that haven't been answered, and it also appears that you've made some changes since you lasted posted any code, so instead of working with barely enough information, we're now working with essentially no information. This is, however, a very good time to learn how to use the debugger. If you can put a break point where the run key is released, then step through and look at the values of your variables, you may see something happening that you didn't expect. Then you can solve the problem. Then you can solve almost all of your problems.
Should I just post up the code from the create event along with my step event?
 
V

Vetmatt89

Guest
Create Event:
hsp = 0;
vsp = 0;
grav = 0.23;
decel = 0.07;
sprint = 0;
global.pause = false;
jumpspeed = 5.5;
spin = true;
canpause = true;

gamepad_set_axis_deadzone(4,0.3)

Step Event:

// Setup Input
key_right = gamepad_axis_value(4,gp_axislh > 0);
key_left = gamepad_axis_value(4,gp_axislh < 0);
key_jump = gamepad_button_check_pressed(4,gp_face3);
key_run = gamepad_button_check(4,gp_face4);
key_spin = gamepad_button_check_pressed(4,gp_face2);
key_pause = gamepad_button_check_pressed(4,gp_start)
key_duck = gamepad_button_check(4,gp_padu)
// Pause Control
if (canpause) && (key_pause)
{
if (!global.pause)
{
global.pause = true;
if (!audio_is_playing(snd_pause)) audio_play_sound(snd_pause,0,false)
image_speed = 0;
canpause = false;
if (alarm[0] == -1)&& (canpause == false) alarm[0] = 70;
}
else
{
global.pause = false
if (!audio_is_playing(snd_pause)) audio_play_sound(snd_pause,0,false)
image_speed = 1;
canpause = false;
}
}

if (global.pause)
{
exit;
}


//Initiate Variables
move = key_right + key_left;
if (vsp < 4) vsp += grav;

//Movement
if (move == 0) && (place_meeting(x,y+1,obj_groundparent))
{
if (hsp > 0)
{
hsp = max(hsp - decel,0);
image_speed = 1;
}
}

if (move == 0) && (place_meeting(x,y+1,obj_groundparent))
{
if (hsp < 0)
{
hsp = min(hsp + decel,0);
image_speed = 1;
}
}


else if (move == 2)
{
hsp += 0.20;
if (key_run) && (hsp > 1)
{
hsp = min(hsp,2.2);
image_speed = 1.6;
}
else if (hsp > 1.3)
{
hsp = min(hsp - decel, 1.3);
image_speed = 1;
}
else hsp = min(hsp, 1.3);
}


else if (move == -2)
{
hsp -= 0.20;
if (key_run) && (hsp < -1.3)
{
hsp = max(hsp,-2.2);
image_speed = 1.6;
}
else if (hsp < -1.3)
{
hsp = max(hsp + decel,-1.3)
image_speed = 1;
}
else hsp = max(hsp,-1.3);
}

//Sprinting
if (move == 2) && (hsp == 2.2)
{
sprint ++
}

if (move == -2) && (hsp == -2.2)
{
sprint ++
}

if (!key_run) && (sprint > 0) && (place_meeting(x,y+1,obj_groundparent))
{
sprint --;

}
if (sprint >= 50) sprint = 50
if (move == 0) && (sprint > 0) && (place_meeting(x,y+1,obj_groundparent)) sprint --

if (sprint == 50) && (move == 2)
{
hsp = 3;
}

if (sprint == 50) && (move == -2)
{
hsp = -3;
}
 

Nidoking

Member
key_right = gamepad_axis_value(4,gp_axislh > 0);
key_left = gamepad_axis_value(4,gp_axislh < 0);
See, this is why I said from the very beginning that you needed to define some things. Someone could have told you many posts ago that passing a boolean expression as an axis value is not going to give you anything nearly resembling what you want. Which is why your move values:

move = key_right + key_left;
make absolutely no sense at all. I don't know how you've made sense of any of this to begin with.

If you want to compare a function return value to a number, the comparison goes OUTSIDE the function call. And you can't just change max to min when you're changing directions if you're working with absolute values. So

hsp = min(hsp - decel, 1.3);
will drop you right to 1.3 if you're higher than that, which is what you asked about. Still, you've got a lot to fix before you need to worry about that.

See how helpful I can be when you provide the information I need?
 

chamaeleon

Member
As @Nidoking says, you need to make sense of the second argument to gamepad_axis_value() (it should only be one of the available constants). Second, using an expression like key_right - key_left (typically not addition) makes sense when you have two competing inputs like two different keys. For a gamepad, you only have one input which can return a value anywhere between -1 and 1 (the extremes the subtraction method results in when using keys), and it is the result of a single call to the function, not two calls that you use with each other (assuming the horizontal and vertical gamepad values are not supposed to interact with each other).
 
V

Vetmatt89

Guest
As @Nidoking says, you need to make sense of the second argument to gamepad_axis_value() (it should only be one of the available constants). Second, using an expression like key_right - key_left (typically not addition) makes sense when you have two competing inputs like two different keys. For a gamepad, you only have one input which can return a value anywhere between -1 and 1 (the extremes the subtraction method results in when using keys), and it is the result of a single call to the function, not two calls that you use with each other (assuming the horizontal and vertical gamepad values are not supposed to interact with each other).
[/QUO
See, this is why I said from the very beginning that you needed to define some things. Someone could have told you many posts ago that passing a boolean expression as an axis value is not going to give you anything nearly resembling what you want. Which is why your move values:



make absolutely no sense at all. I don't know how you've made sense of any of this to begin with.

If you want to compare a function return value to a number, the comparison goes OUTSIDE the function call. And you can't just change max to min when you're changing directions if you're working with absolute values. So



will drop you right to 1.3 if you're higher than that, which is what you asked about. Still, you've got a lot to fix before you need to worry about that.

See how helpful I can be when you provide the information I need?
When I release my movement key it decelerates as I want. I've been trying to have the same effect when I release my sprint key. So what you're saying is the booleans that are causing the problem?
 

Nidoking

Member
The booleans are A problem. Using the wrong function is another problem. There are probably more - I assume from what you've shown here that you don't really understand what you're doing, and are just tweaking things until you get a result that looks something like what you want. That is the wrong way to make things. This is like trying to solve a maze, running into a dead end, and thinking "I can't go back because that would take me farther from the exit." Sometimes, the fastest way to get to where you're going is to set it aside, do some proper tutorials that will teach you how to make a game, and then make a game.
 
V

Vetmatt89

Guest
The booleans are A problem. Using the wrong function is another problem. There are probably more - I assume from what you've shown here that you don't really understand what you're doing, and are just tweaking things until you get a result that looks something like what you want. That is the wrong way to make things. This is like trying to solve a maze, running into a dead end, and thinking "I can't go back because that would take me farther from the exit." Sometimes, the fastest way to get to where you're going is to set it aside, do some proper tutorials that will teach you how to make a game, and then make a game.
I have watched many tutorials especially on acceleration,but they don't give me the desired results. Making a standard platform game is pretty simple. When you try to make your own physics similar to Super Mario World it gets a little more complex. I came for help not to be insulted. There is no Tutorial out there for what I'm trying to accomplish, and many give up when attempting this kind of engine.
 

Nidoking

Member
I have watched many tutorials especially on acceleration,but they don't give me the desired results.
You skipped a step. You need some tutorials on basic Game Maker syntax and logic. I mean, what's this?

if (move == 0) && (place_meeting(x,y+1,obj_groundparent))
{
if (hsp > 0)
{
hsp = max(hsp - decel,0);
image_speed = 1;
}
}

if (move == 0) && (place_meeting(x,y+1,obj_groundparent))
{
if (hsp < 0)
{
hsp = min(hsp + decel,0);
image_speed = 1;
}
}
You're checking the same thing twice in a row. Don't Repeat Yourself doesn't just apply to putting repeated logic in functions. With proper nesting, you condense a lot of what you're doing and make more sense of it.

canpause = false;
if (alarm[0] == -1)&& (canpause == false) alarm[0] = 70;
Here, you're setting canpause to false and then checking to see whether it's false. What else do you expect it to be? This is either extreme paranoia, a deep misunderstanding of how variables work, or a clumsy redesign that you didn't finish. In any case, you reached the end of your own patience and chose to display this as an example of your work. I didn't tell you it would be a good time to stop fixing your problems and post on a forum. You chose to do that. Yes, making a simple platformer is simple if you understand the basic tools you're using to do it. Honestly, making a complicated platformer isn't much more difficult, if you understand the basic tools and how to plan how you're going to use them. It just means doing more of them, managing more information, and designing systems that work well together. You haven't even mastered the art of reading input properly. Tutorials don't make your game for you - if you want that, try the Commissions subforum. They teach you how to perform basic operations, with the intention that you learn how to do the things they teach and then, gasp, modify the methods yourself using the skills you've learned to achieve a novel result. I think you didn't understand that, or perhaps you willfully chose to ignore it and hoped you'd be able to skate by without actually learning anything, judging by what you've produced here. I'm sure you find that equally insulting, but it's no less true. I was originally going to tell you that the best thing to do is delete your game folder and start from scratch, but I think that if you actually learn what you need to learn from the tutorials, you'll reach that conclusion yourself. Then, it will be time for you to make the game of your dreams.
 

Yal

🐧 *penguin noises*
GMC Elder
if (hsp > 2.2) hsp = 2.2
Right now you're capping the value at the max value, instantly chopping it down from whatever it is to 2.2. If you want to gradually slow down, you should change the code to gradually reduce the value instead of overwriting it entirely:

if (hsp > 2.2) hsp -= 0.1
 
V

Vetmatt89

Guest
You skipped a step. You need some tutorials on basic Game Maker syntax and logic. I mean, what's this?



You're checking the same thing twice in a row. Don't Repeat Yourself doesn't just apply to putting repeated logic in functions. With proper nesting, you condense a lot of what you're doing and make more sense of it.



Here, you're setting canpause to false and then checking to see whether it's false. What else do you expect it to be? This is either extreme paranoia, a deep misunderstanding of how variables work, or a clumsy redesign that you didn't finish. In any case, you reached the end of your own patience and chose to display this as an example of your work. I didn't tell you it would be a good time to stop fixing your problems and post on a forum. You chose to do that. Yes, making a simple platformer is simple if you understand the basic tools you're using to do it. Honestly, making a complicated platformer isn't much more difficult, if you understand the basic tools and how to plan how you're going to use them. It just means doing more of them, managing more information, and designing systems that work well together. You haven't even mastered the art of reading input properly. Tutorials don't make your game for you - if you want that, try the Commissions subforum. They teach you how to perform basic operations, with the intention that you learn how to do the things they teach and then, gasp, modify the methods yourself using the skills you've learned to achieve a novel result. I think you didn't understand that, or perhaps you willfully chose to ignore it and hoped you'd be able to skate by without actually learning anything, judging by what you've produced here. I'm sure you find that equally insulting, but it's no less true. I was originally going to tell you that the best thing to do is delete your game folder and start from scratch, but I think that if you actually learn what you need to learn from the tutorials, you'll reach that conclusion yourself. Then, it will be time for you to make the game of your dreams.
Yes I agree with you some of it I don't 100% understand and yes my code could be better. I'm not trying to ask anyone to do anything for me, I want to know what the function of the code is doing. Some tutorials some of the guys check the solid checkbox when there are more experienced guys like pixelatedpope who says don't do that because we don't understand what the engine is doing behind scenes.
 

Yal

🐧 *penguin noises*
GMC Elder
What solid does is "when there is a collision and at least one of the involvees are solid, move both of them back to their previous position". It's a cheap and unreliable way to prevent two things from moving through each other, but it quickly starts to get in the way of your code when you want to do more advanced things (e.g. if your platforms are solid, it will interfere with both jump-through platforms and moving platforms)
 

Nidoking

Member
It's also required for place_free and other related functions. It does things for you if you're willing to settle for what it can do, but it's usually better to write your own equivalents if you need them.
 
V

Vetmatt89

Guest
Sorry for the late reply, but thank you all that has gave their insight on my problem. I have it working the way it should. I don't know how to put solved on this forum or if that's for the moderator. Again thank you all!
 
Top