Weird physics question...

0 favourites
  • 9 posts
From the Asset Store
Simple yet very life-like rag doll made with Physics!
  • Okay, please bear with me as this takes some explaining.

    In a particular game I have (platformer using my own behavior), when I press a direction (left or right) I accelerate my character in that direction, but not exceeding its max speed. It is okay for the character to be above max speed, but not as a result of acceleration due to input (this allows for boosting, getting knocked back at expeditious speeds, etc) .

    the result of input is handled along this sort of idea:

    if speed.x > maxspeed.x then do nothing.

    else if speed.x + acceleration.x > maxspeed.x then speed.x = maxspeed.x

    else speed.x += acceleration.x

    Now, this all works fine in this game. X and Y are handled independently, essentially making this a 1 dimensional problem.

    In the game I am currently working on (top-down adventure), The problem is now 2d. If I handle the Axis seperatly, then I get a greater diagonal speed than either left or right so I need to handle them together.

    Solving the problem with a hard "max speed" and a constant deceleration against the current angle of travel and speed works fine and is an easy solution, but again, I would prefer to be able to implement a sort of "soft" max speed. But I really can't figure out how I go about this. I thought about having an acceleration to change angle of travel after getting input, but this sort of results in a race car like behavior and not something on foot.

    Any ideas how I can cort of check speed and then figure out how to change angle and resolve input?

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Couldn't you do the same logic but just consider the total speed?

    if distance(0, 0, vx, vy) > maxspeed


    //do nothing


    else if distance(0, 0, vx+ax, vy+ay) > maxspeed


    ang = angle(0, 0, vx+ax, vy+ay)

    vx = maxspeed*cos(ang)

    vy = maxspeed*sin(ang)




    vx += ax

    vy += ay


  • R0J0hound - I had thought about that, but as it stands there is a major drawback:

    if I am going max speed at angle 0 and the player inputs up, you get this sort of lerp angle change where the angle sort of halves towards -90 while the character remains at max velocity. Does this make sense? It basically (in this case) is the same as simply keeping velocity the same and doing lerpangle(current angle, desired angle, 0.6). If I apply deceleration every tick against the current angle and velocity before applying acceleration it isn't as obvious but it is still there. Maybe I'm being to picky or expecting something unreal (my brain model isn't reality possible)

  • R0J0hound - quick question... If I have 2 vectors, both expressing magnitude and direction, can I add them together without having to figure out their x,y components? I can't find anything abou thtis and it seems everbody solves this by finding Ax,Ay Bx,By then adding those together and then calculating angle and magnitude based on that.

  • Hmm... I'd have to think about it more. Instead of the gradual angle change what is the desired result?

    Yeah to add vectors together you need them in X y components.

  • R0J0hound - I'd share the results of whats going on now, but I use several custom plugins and behaviors that you'd need to run the capx and I think you get what I am saying?

    Iv'e tried describing what I want several times and each description I don't think gets the point across. Regardless of what I have done, the angle seems to lerp towards the new input angle to varying degrees. Its like I need to be able to come up with a way to doctor the angle as well. If I just handle the magnitudes and handle angle as a consequence (like you did in your example)... I dont know... Like I said maybe I want something that can't exist. I want it to be exactly like the 1 dimensional problem, but in 2D. In all practicality, I don't suppose to many people would notice... though I think it really depends on the style of input (sticky vs inertia based)... I've been playing around with a lot of top down games to see how they were all implemented, and it seems nobody has made what I am describing (usually because direction is sticky even if velocity isn't). Characters often time can reverse direction instantly.

    I suppose one could, as I said above, doctor the angle, but I want to avoid carrying the "overTheMAxSpeed" towards that new angle... WAIT, I think I may have had an epiphany: Why not treat velocity up to max speed different from the the remainder that goes above max speed!

    Get angle and distance of vx, vy.

    If distance > max speed get the x,y components that is the difference between max speed and current speed (I'll call this velocity spill over, or spill.x/y for shot)

    Now, calculate vx +ax, vy +ay If the result < max speed... ad spill over and you are done.

    Else, get check the input angle(ax,ay), and using a desired lerping method (ease in, ease out, linear, etc) change the angle to what you want it to be that tick. then add spill over back to the velocity.

    In this way, I can treat velocity changes that are a result of input separate from the rest of the spill over. and then add them together. I don't risk changeing the angle of speed > max but I can deliberately doctor the angle below that value. I can also decelerate spill over using different deceleration values (that way I don't have to constantly decelerate velocity by half of what acceleration is, and so on and affect both sides) Does this make sense at all? I'm going to go try and test it. I'll let you know how it goes.

  • R0J0hound , alas, the above method doesn't work... at least not without me learning more about angles or something. For example, if input is opposite to current velocity, you really don't want to be changing angle at all (not until speed is 0 and then angle is changes instantly to -180) I suppose I could try basing the degree to which one accelerates towards another angle could be scaled full if the two angles are perpendicular but be 0 if they are parallel.

    I think one might have to split the angle into several pieces and only adjust one of those pieces and then put it back together... problem with angles is I really know nothing about them (how to manipulate them with each other)... I don't know if quaterneons or whatever they are called could offer help...

  • R0J0hound - sorry for so many posts. Here is an image that shows the movement path of an object with input being angle 0 full acceleration, switched to angle down (90) at full acceleration.... you can see how the rat of angle change is fast but then slows down.

    My current thought, is that I can calculate the angle of input and then apply a constant deceleration towards 0 in the angle perpendicular to input angle like so:

    The deceleration vector would be a constant amount declared ahead of time but never pushing the result angle past the input angle in either direction. It would be calculated anytime the current angle mismatches the input angle. This is sort of neat because it would allow the character to resolve angle without affecting velocity though I think I would anly apply it if the character is traveling at or above max speed.

    I just remembered a game and in it they did deal with this problem though different goals means they probably found a different solution... , but I remembered each plane still had a max speed, a current angle/speed, and an input angle/acceleration. The direction the plane was pointing seemed to affect deceleration, but only when attempting to travel beyond max speed.


    As it turns out this works quite smoothly:

    The character was traveling from the left to the right leaving a red trail. The cool part is that this can be modified in a number of ways depending on when it is used and what you provide as a deceleration parameter.

  • It actually looks like the path the 8-direction behavior gives you. The soft max speed could be achieved by maybe setting the max speed higher and let it drop down with:

    max_speed = max(current_speed, normal_max_speed)

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)