How do I limit speed on 2d vectors?

From the Asset Store
Have you ever dreamed of playing in a Speedball game or tournament?
  • I began an attempt at implementing steering vectors with the 8direction behavior, but seem to have run into a wall early on. I would expect that the sprite orbits around the target when approaching at an angle, but it intermittently cuts most (but not all) of its horizontal or vertical velocity upon passing the target, but only sometimes... Am I approaching this wrong in the following?

    + System: Every tick

    -> Sprite: Set 8Direction vector X to clamp(-1×abs(Self.8Direction.Maxspeed×cos(angle(Self.X,Self.Y,Target.X,Target.Y))),Self.8Direction.VectorX+Self.8Direction.Acceleration×dt×cos(angle(Self.X,Self.Y,Target.X,Target.Y)),abs(Self.8Direction.Maxspeed×cos(angle(Self.X,Self.Y,Target.X,Target.Y))))

    -> Sprite: Set 8Direction vector Y to clamp(-1×abs(Self.8Direction.Maxspeed×sin(angle(Self.X,Self.Y,Target.X,Target.Y))),Self.8Direction.VectorY+Self.8Direction.Acceleration×dt×sin(angle(Self.X,Self.Y,Target.X,Target.Y)),abs(Self.8Direction.Maxspeed×sin(angle(Self.X,Self.Y,Target.X,Target.Y))))

    dropbox.com/s/yyn5ab25aoq4vfb/steering.c3p

  • It’s a bit hard to debug big formulas like those, but basically you’re accelerating toward the target and limiting the the speed?

    I’d break it up into multiple steps and once that works you can combine it again.

    Local number a

    Local number speed

    Every tick

    Set a to angle(sprite.x, sprite.y, target.x, target.y)

    Set vectorX to vectorX + accel*dt*cos(a)

    Set vectorY to vectorY + accel*dt*sin(a)

    Set speed to sqrt(vectorX^2+vectorY^2)

    Compare: speed>maxspeed

    Set vectorX to vectorX/speed*maxspeed

    Set vectorY to vectorY/speed*maxspeed

  • I was thinking this was a good one for ROJOhound! :)

    that works nicely... we don't need to limit the speed because the 8Direction behavior does that automatically. it settles into an orbit around the target.

    I have a feeling oosyrag might want the sprite to converge on the target - as if it has gravity.

    how would you make the orbit shrink so that the sprite converges on the target?

    https://www.rieperts.com/games/forum/orbit3.c3p

  • Well originally I had thought that the built in speed limit was causing issues resulting in unnatural paths if either the x or y vectors were already near or at the speed limit when attempting a turn, and prevent acceleration on the other axis when setting the vectors manually.

    Eventually I was aiming for variable speed limits to allow for slingshotting and more responsive obstacle avoidance. But then when I tried to add a simple clamp for the max speed I already ran into more issues.

    Seems like (I think?) clamping the vector with the sin and cos functions were not symmetrical, causing irregularities. Guess that's why all the articles I read normalize the vector first.

    Regarding gravity and decay of orbit, that could be done with adding either an overall deceleration force, or a local one when near the target.

    Thanks for the help!

  • Oh true. I forgot about the behavior enforcing the max speed for you.

    He said he was expecting an orbit, but real gravity would be similar.

    To stop the orbit you could apply a brake to the tangent speed so it would fall straight down. The break could be just a velocity opposite the tangent velocity and you could make it inversely proportional to the distance. Basically that would make it brake faster the closer it is.

    a = angle(sprite to target)+90

    tanvel = vectorX*cos(a)+vectorY*sin(a)

    d = distance(sprite to target)

    If d>0

    vectorX = vectorX - tanvel/d*cos(a)

    VectorY = vectorY - tanvel/d*sin(a)

  • I've done similar code in a different context.Usually there are a lot of problems when you're

    using cos/sin with absolute values as well as switching between positive and negative manually(by mulitplying by *-1). The reason is what you just said. absolute values ONLY accept positive values(in your case it's only negative values I believe because you multiplied by *-1)

    Also, you should look at"maths and trigonometry cheat sheet for 2D and 3D games" online.The list contains the majority of math equations needed for practically everything (I believe it's on github.)

    Also, you're using the clamp function. The clamp functions uses these parameters (value,upper bound,lower bound) The value will be between upper and lower bound. THAT ALMOST always has problems with abruptness in cases like these. You're "clamping" between 2 points(an analogy is an oyster clamping a pearl in it's mouth)

    You should definitely use r0jhound's method.

    Just curious, what game are you making?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • Appreciate the advice!

    The concept is a mix between the old arcade game Rampart by Atari and 2d artillery type games, except slinging varying types of missiles through space, also with a variety of obstacles that affect the projectiles on the field.

    Although mostly I just like fooling around making different types of game mechanics. I've been loitering around here for years and have yet to actually finish any projects haha. Do not expect this to be different.

  • I searched Rampart and looks really interesting and unique!Let me know if you ever plan on posting anything.

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