Hey all

So I'm making this simple 2D space game with Direct3D and VB.Net, and I've hit the strangest problem I've had yet. Basically, my "Ship" class has a "Thrust" subroutine that is called every iteration of the game loop, so long as the player is holding the forward mouse key. Also, the same class has an "Update" routine that is called every iteration regardless that I use to slowly speed down ships and set the place the value of the ship class' "mDirVelocity" member (Directional Velocity) over the plain "mVelocity" member, which is actually the member that affects movement within the main Sprite class that this class inherits from.

Here is the Thrust subroutine:

Code Snippet

Public Sub Thrust()

Dim accelX As Single

Dim accelY As Single

accelX = mTemplate.Accel * Math.Sin(Me.Rotation)

accelY = mTemplate.Accel * -Math.Cos(Me.Rotation)

Dim incX As Single

Dim incY As Single

incX = mDirVelocity.X + accelX

incY = mDirVelocity.Y + accelY

mDirVelocity.X = incX

mDirVelocity.Y = incY

End Sub

And the Update subroutine:

Code Snippet

Public Overrides Sub Update()

mDirVelocity.X = (mDirVelocity.X / 1.02)

mDirVelocity.Y = (mDirVelocity.Y / 1.02)

mVelocity = mDirVelocity

End Sub

Only one other of the ship's members are relevent to the issue, which is the "mAccel" member, which is a Single that simply indicates how much the ship should accelerate by this iteration, for the sake of explaining the problem, the ship's mAccel is 1.

Now here is the problem. As you can see, I've arbitrarily chosen 1.02 as the number to divide by in the Update() routine to bring ships to a gradual halt, and here is what confuses the heck out of me, with no code to prevent the ship from exceeding a maximum speed, the velocity always speeds up fine, until a point... The ship gradually slows its acceleration so that it never exceeds 50 times its acceleration (if mAccel is 1). The only number in my entire project that relates at all to the number 50 is 1.02 here, and it really is affecting this uncoded maximum velocity, because if I set it to 1.01, then the ship reacts similarly, the speed will then not exceed 100. Furthermore, this problem does consider the Sin and Cos maths, so it will not exceed 50 speed in any direction, not just north, south, east and west.

I'm hoping that I'm just being stupid, because I honest to god can not see any connection between that 1.02 number, and the ship's mAccel value that would cause it to behave in such a way. Help. Sad

Re: Game Technologies: General Mind-boggling Sprite 2D issue

Richard Coxson II

The problem that you are having, is that your deceleration is not a constant rate, but rather a percentage rate. That and the fact that it is always on.

Let me explain. We tap the acceleration key once. We rise to a speed of .980 (rounded) because the speed is immediately equal to 1 / 1.02. This seems to be subtraction. Well, lets go to the next run. We do not renew the acceleration, and so our new speed is .961 (rounded). To get a better picture. Here are the next few runs:
What we see is a curved path of reduction, not a steady rate of drop off. Which is all well and good, but your question was about your max speed. Ok. Lets go back to acceleration again for a moment. When the speed is equal to 1 the deceleration is equivalent to .02 (to make it exactly .02 you should have it as *.98 not /1.02, but I digress). Well, what about when the speed is 10 It is equivalent to .2. If we progress this to the end, we see that at a speed of 50, our deceleration has become equivalent to 1. Which is the same as our acceleration. Those cancel each other out, which leaves us at a constant rate of speed, not unlike a car with the pedal to the metal on a straight stretch of highway.

So, without realizing it, you have coded a maximum speed, because you have coded friction. Now, you could fix this in one of two ways:
Fiddle with the acceleration til you get the maximum speed you want...
...or turn off deceleration while accelerating.

Re: Game Technologies: General Mind-boggling Sprite 2D issue


Ooh! When I read ".. our deceleration has become equivalent to 1." my eyes widened, I didn't think of that! Thanks for the enlightenment.Smile

In my confusion, I simply gave in and tried to make the bug work for me, since I had intended to code maximum speed anyway. I used this little line here, and plugged in the new variable in place of the 1.02.

Code Snippet
mDecel = 1 + (1 / (pMaxVelocity / pAccel))

It works well enough, but if my logic is correct, then it means that spacecraft will all decelerate at different speeds. Just thinking about it now, optimally I'd want to keep the functionality caused by my "bug" so that spacecraft will still smoothly reach their maximum speed, but also have them all decelerate at the same rate. So.. brb.


Code Snippet

If mThrusting Then

mDirVelocity.X = (mDirVelocity.X + (mAccel * Math.Sin(Me.Rotation))) / mDecel

mDirVelocity.Y = (mDirVelocity.Y + (mAccel * -Math.Cos(Me.Rotation))) / mDecel


mDirVelocity.X = IIf(Math.Abs(mDirVelocity.X) < 0.1, 0, mDirVelocity.X * SPACE_FRICTION)

mDirVelocity.Y = IIf(Math.Abs(mDirVelocity.Y) < 0.1, 0, mDirVelocity.Y * SPACE_FRICTION)

End If

That does the trick. mDecel is still calculated as previously and when the spacecraft's thrust is not on, the ship slows based on a constant value. I actually tried adjusting the mDecel initialisation so that I could multiply the velocity by as you recommended, but the spacecraft ended up not being able to exceed a speed that was apparently equal to the maximum velocity subtract the acceleration; seeing as my maths skills seem to be lacking, I suppose I'll just stick with my division for now. Big Smile

Thanks again. :]