none
Newb Question: Moving My Car. RRS feed

  • 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 
    
    Box = Shapes.AddRectangle (50,100)
    
    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

Answers

  • 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 
    
    Box = Shapes.AddRectangle (20,50)
    
    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 = Math.GetRadians (PlayerAngle)
      PlayerAngleCopy = PlayerAngle
      Shapes.Rotate (Box,PlayerAngleCopy)
      newX = Math.sin (Math.GetRadians(PlayerAngleCopy))*PlayerSpeedCopy 
      newY = -Math.cos (Math.GetRadians(PlayerAngleCopy))*PlayerSpeedCopy 
      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 Stendec 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.

    Here is my edited subroutine, taking both your comments into account.

    Sub Movement
      PlayerSpeedCopy = Playerspeed
      PlayerAngleCopy = Math.GetRadians (PlayerAngle)
      Shapes.Rotate (Box,PlayerAngleCopy)
      newX = (Math.Sin (Math.GetRadians(PlayerAngleCopy)))*PlayerSpeedCopy 
      newY = (Math.Cos (Math.GetRadians(PlayerAngleCopy)))*PlayerSpeedCopy 
      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 
    
    Box = Shapes.AddRectangle (20,50)
    
    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 = Math.GetRadians (PlayerAngle)
      PlayerAngleCopy = PlayerAngle
      Shapes.Rotate (Box,PlayerAngleCopy)
      newX = Math.sin (Math.GetRadians(PlayerAngleCopy))*PlayerSpeedCopy 
      newY = -Math.cos (Math.GetRadians(PlayerAngleCopy))*PlayerSpeedCopy 
      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
  • Thank you very much bigdaddy, very well explained.
    cheers for the response, this helped a huge amount tyty.

    A++++ :D
    Wednesday, June 24, 2009 11:27 AM