# Newb Question: Moving My Car.

• ### Question

• Hi, after looking at asteroids I am still having some trouble understand whats going on with the way the author gets the spacecraft to move.

I have a basic Rectangle which i am trying to move as if it were a car/spacecraft.

Hers my Code/Understanding of the movements.

gameWidth =400
gameHeight = 400

GraphicsWindow.Height = gameHeight
GraphicsWindow.Width = gameWidth

W = "W"
A = "A"
S = "S"
D = "D"

PlayerAngle = 0
PlayerSpeed = 0

GraphicsWindow.KeyDown = KeyDown
Game = 1

While Game=1
Movement ()
endwhile

Sub KeyDown
If GraphicsWindow.LastKey = W then
PlayerSpeed = PlayerSpeed - 0.001
ElseIf GraphicsWindow.LastKey = S then
PlayerSpeed = PlayerSpeed+ 0.001
elseif GraphicsWindow.LastKey = A Then
PlayerAngle = PlayerAngle -1
ElseIf GraphicsWindow.LastKey = D then
PlayerAngle = PlayerAngle +1
EndIf
endsub

Sub Movement

Shapes.Rotate (Box,PlayerAngle)
newX = (Math.Sin (PlayerAngle))*PlayerSpeed
newY = (Math.Cos (PlayerAngle))*PlayerSpeed
X = Shapes.GetLeft (Box)
Y = Shapes.GetTop (Box)
TotalX = X + newX
TotalY = Y + newY
Shapes.Move (Box,TotalX,TotalY)

EndSub

Its probably really messy Please tell me where i am going wrong with my movements.

Cheers,
Plute.
Tuesday, June 23, 2009 10:07 AM

• I had to do three things mainly, change your increments to new values, negate cosine, and you had converted playerangle twice to radians.  I also reshaped your box, maybe didnt have to.  This setup has zero degrees playerangle going up, and positive speed going in the direction of playerangle.  Trigonometry is extremely useful for games!

gameWidth =400
gameHeight = 400

GraphicsWindow.Height = gameHeight
GraphicsWindow.Width = gameWidth

W = "W"
A = "A"
S = "S"
D = "D"

PlayerAngle = 0
PlayerSpeed = 0

GraphicsWindow.KeyDown = KeyDown
Game = 1

While Game=1
Movement ()
endwhile

Sub KeyDown
If GraphicsWindow.LastKey = W then
PlayerSpeed = PlayerSpeed + 0.1
ElseIf GraphicsWindow.LastKey = S then
PlayerSpeed = PlayerSpeed - 0.1
elseif GraphicsWindow.LastKey = A Then
PlayerAngle = PlayerAngle - 10
ElseIf GraphicsWindow.LastKey = D then
PlayerAngle = PlayerAngle + 10
EndIf
endsub

Sub Movement
PlayerSpeedCopy = Playerspeed
PlayerAngleCopy = PlayerAngle
Shapes.Rotate (Box,PlayerAngleCopy)
X = Shapes.GetLeft (Box)
Y = Shapes.GetTop (Box)
TotalX = X + newX
TotalY = Y + newY
Shapes.Move (Box,TotalX,TotalY)
endsub
Wednesday, June 24, 2009 8:41 AM

### All replies

• Part of the problem is that Math.Sin and Math.Cos expect the angle to be given in radians (2*pi radians = 360°). You are changing PlayerAngle in steps of about 57°. Try dividing PlayerAngle by (2 * pi) / 360 to get radians.
Could you please supply more information. Do you intend the box to move like a car with one short side always the front?
• Edited by Tuesday, June 23, 2009 5:25 PM Formula correction.
Tuesday, June 23, 2009 5:20 PM
• One problem you'll run into is the Keydown subroutine is modifying PlayerSpeed, which can occur anytime you press a key at any point in execution of the rest of the code.  I think most people will do this until they find out the effects of it, i found out the hard way too, I'm not sure it's explained anywhere.  In this case your Movement subroutine might use two different values of PlayerSpeed if a keypress occurs in the middle of the execution of these two lines:

newX = (Math.Sin (PlayerAngle))*PlayerSpeed
newY = (Math.Cos (PlayerAngle))*PlayerSpeed

What you want to do in this case is in Movement make a copy of PlayerSpeed, and use that instead in there.  Then it wont change on you between the two lines above.

From what Stendec says, you'll want to change your increment of PlayerAngle instead of +/-1 to something like +/- 0.1 or smaller.  Remember there are about 6.28 radians for one revolution or 360 degrees of rotation.

Also PlayerSpeed is incremented in too small of a number, i would change that to +/-1 or so.  This is in units of pixels per update period of your Movement routine.

I bet it'll work after you do the above.

After you do get it working, you probably want to make sure that any input into sin/cos function is within +/- 2 * pi = about 6.2832.  Often a compiler will generate growing errors of the returned value if you go too far out.  To do this, use the Math.Remainder(x, 6.2832)
Tuesday, June 23, 2009 6:45 PM
• Ok. first off thank you for replying.

Sub Movement
PlayerSpeedCopy = Playerspeed
Shapes.Rotate (Box,PlayerAngleCopy)
X = Shapes.GetLeft (Box)
Y = Shapes.GetTop (Box)
TotalX = X + newX
TotalY = Y + newY
Shapes.Move (Box,TotalX,TotalY)
I wasn't sure of how to get an accurate pi on the computer. (without just typing 3.14) So i used the getradians command.

Thanks for the tip on the changing playerspeed, i Made the copies as you can see.
However, even using the tips, my guy still has A LOT of bugs.

If i change the increment on playerspeed, my box just goes flying off the graphicswindow :\

Here is the movement from Asteroids:

x = Math.Remainder(Shapes.GetLeft(player) + (Math.Cos(Math.GetRadians(playerAngle - 90)) * playerSpeed) + gameWidth, gameWidth)
y = Math.Remainder(Shapes.GetTop(player) + (Math.Sin(Math.GetRadians(playerAngle - 90)) * playerSpeed) + gameHeight, gameHeight)
Shapes.Move(player, x, y)
Can someone please explain, how this works :) cheers.

Wednesday, June 24, 2009 7:41 AM
• I had to do three things mainly, change your increments to new values, negate cosine, and you had converted playerangle twice to radians.  I also reshaped your box, maybe didnt have to.  This setup has zero degrees playerangle going up, and positive speed going in the direction of playerangle.  Trigonometry is extremely useful for games!

gameWidth =400
gameHeight = 400

GraphicsWindow.Height = gameHeight
GraphicsWindow.Width = gameWidth

W = "W"
A = "A"
S = "S"
D = "D"

PlayerAngle = 0
PlayerSpeed = 0

GraphicsWindow.KeyDown = KeyDown
Game = 1

While Game=1
Movement ()
endwhile

Sub KeyDown
If GraphicsWindow.LastKey = W then
PlayerSpeed = PlayerSpeed + 0.1
ElseIf GraphicsWindow.LastKey = S then
PlayerSpeed = PlayerSpeed - 0.1
elseif GraphicsWindow.LastKey = A Then
PlayerAngle = PlayerAngle - 10
ElseIf GraphicsWindow.LastKey = D then
PlayerAngle = PlayerAngle + 10
EndIf
endsub

Sub Movement
PlayerSpeedCopy = Playerspeed
PlayerAngleCopy = PlayerAngle
Shapes.Rotate (Box,PlayerAngleCopy)