[bmx]Asteroid Thrust Mechanics

Started by TomToad, July 21, 2017, 12:51:16

Previous topic - Next topic

TomToad

This code shows how you can create thrust on a ship similar to Asteroids.  In this version, I added a singularity with a gravitational pull.  See if you can create a stable orbit around the singularity.
SuperStrict

Type TVector
Field x:Double
Field y:Double

'create a new vector
Function Create:TVector(x:Double,y:Double)
Local Vector:TVector = New TVector
Vector.x = x
Vector.y = y
Return Vector
End Function

'add another vector to this one
Method Add(Vector:TVector)
x :+ Vector.x
y :+ Vector.y
End Method

Method Set(sx:Double,sy:Double)
x = sx
y = sy
End Method
End Type

Type TShip
Const ThrustAmount:Double = .1 'amount of thrust to be applied when space is pressed
Const MaxDist:Double = 200.0 'The distance our singularity has effect
Const Force:Double = 0.5 'The gravitational force of the singularity
Const TurnSpeed:Double = 10.0 'how quickly the ship will turn

Global ShipImage:TImage

Field Position:TVector 'position of ship on screen
Field Angle:Double 'angle the ship is facing
Field Thrust:TVector 'amount of thrust affecting the ship
Field Speed:TVector 'the current speed of the ship
Field Singularity:TVector 'we will add a singularity to the screen

Method New()
Position = TVector.Create(400,300) 'center of the screen

' angle needs to be -90 degrees to point the ship upward.  Sin(), Cos()
' and Atan2() are mathimatical functions where 0 degrees point into
' the positive x axis (i.e. to the right)
Angle = -90

'Set thrust to 0
Thrust = TVector.Create(0,0)

Speed = TVector.Create(0,0) 'The ship is not moving

Singularity = TVector.Create(600,200) 'position the singularity
End Method

Method Update()
'Set thrust according to the space bar
If KeyDown(KEY_SPACE)
Thrust.set(Cos(Angle)*ThrustAmount,Sin(Angle)*ThrustAmount)
Else
Thrust.set(0,0)
End If

'alter thrust depending on how close to the singularity
Local DistanceX:Double = Singularity.x - Position.x
Local DistanceY:Double = Singularity.y - Position.y
Local SingularityAngle:Double = ATan2(DistanceY,DistanceX) 'note x and y are swapped in Atan2()

'interpolate the distance of the ship to the singularity, clip at MaxDist pixels, and multiply
' by the maximum force of the singularity. By messing with these parameters, you can
' affect the amount gravitational pull of the singularity as well as how quickly the
' pull drops off
Local Pull:Double = (MaxDist-Sqr(DistanceX^2+DistanceY^2))/MaxDist*Force
If Pull < 0.0 Then Pull = 0.0

'Now add the pull of the singularity To the thrust of the ship
Thrust.Add(TVector.Create(Cos(SingularityAngle)*Pull,Sin(SingularityAngle)*Pull))

'Now we add the resulting vector to the speed vector
Speed.Add(Thrust)

'now we update the position of the ship
Position.Add(Speed)

'Lastly, we wrap the ship arround if it goes off screen.  We allow the ship to go 30 pixels
' off (The width of the ship), which is why you see 30 and 60 here.
If Position.x >= 830.0 Then Position.x :- 860.0
If position.x < -30.0 Then Position.x :+ 860.0
If Position.y >= 630.0 Then Position.y :- 660
If Position.y < -30 Then Position.y :+ 660

'Now we need to check for the arrow keys and turn the ship accordingly.  Adjust the angle
' to the range of -180 to 180
If KeyDown(KEY_RIGHT)
Angle :+ TurnSpeed
If Angle > 180 Then Angle :- 360
End If

If KeyDown(KEY_LEFT)
Angle :- TurnSpeed
If Angle < -180 Then ANgle :+ 360
End If
End Method

Method Draw()
SetColor 255,255,0
DrawOval Singularity.x-5,Singularity.y-5,10,10

SetColor 0,0,255
SetRotation Angle
DrawImage ShipImage,Position.x,Position.y

SetRotation 0
End Method
End Type

'Now to put it all together
Graphics 800,600

'The Ship type
Local Ship:TShip = New TShip

'lets create the ship proceedurally, then grab it into a TImage
Cls
SetColor 255,255,255
Local Poly:Float[] = [30.0,15.0,0.0,30.0,7.5,15.0,0.0,0.0]
DrawPoly Poly

Ship.ShipImage = CreateImage(30,30)
GrabImage(Ship.ShipImage,0,0)
MidHandleImage Ship.ShipImage

'Now for the main loop
While Not KeyHit(KEY_ESCAPE) And Not AppTerminate()
Cls
Ship.Update()
Ship.Draw()
SetColor 255,0,0
DrawText "Arrow keys to turn, SPACE to thrust",10,10
DrawText "  Try and create a stable orbit around the singularity",10,50
Flip
Wend
------------------------------------------------
8 rabbits equals 1 rabbyte.

Hardcoal

I want to show my appreciation to your posts, but since there are no Like options.. I just wrote this reply..
Code

Derron

Pay attention that the sample code does not add any delta timing - so depending on how often you call "update", the faster it will move.


bye
Ron

3DzForMe

This is interesting... might have to dust off my copy of BMax ;)
BLitz3D, IDEal, AGK Studio, BMax, Java Code, Cerberus
Recent Hardware: Dell Laptop
Oldest Hardware: Commodore Amiga 1200 with 1084S Monitor & Blitz Basic 2.1