Code archives/Miscellaneous/2D Collision Physics (bounce)
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
Here is simple bounce physics for asteroids game. Asteroids game is made by Tibit. http://www.blitzbasic.com/Community/posts.php?topic=48800 Here is package for code and all assets: https://www.dropbox.com/s/74u5geibos6pm0p/CollisionPhysics.7z?dl=0 All improvements are welcome. | |||||
Strict AppTitle = "Asteroid Wars Example" Rem This is the file of a step by step example of how to make a simple asteroids clone. The guide can be found at www.blitzbasic.com - forums - blitzmax - tutorials EndRem Type TSpaceObject Field X#,Y# Field XSpeed#,YSpeed# Field Direction Function Create() EndFunction Function UpdateAll() EndFunction Method New() EndMethod Method Update() EndMethod Method Destroy() EndMethod Method Draw() EndMethod End Type Type TPlayer Extends TSpaceObject Global List:TList Global Image:Timage Field TurnSpeed# Function Create() Local Ship:TPlayer = New TPlayer If List = Null List = CreateList() List.AddLast Ship 'Add Ship Last in List If Not Image Image = LoadImage("ship.png") MidHandleImage( Image )'Center EndIf EndFunction Method New()'Starting Values X = 300 Y = 400 EndMethod Method Draw() SetRotation( Direction ) DrawImage( Image,X,Y ) EndMethod Method Update() Draw() 'Possible Actions Local Up,Down,Left,Right,Fire 'Controls affect actions, Player 1 If KeyDown(Key_Up) Up = True If KeyDown(Key_Down) Down = True If KeyDown(Key_Left) Left = True If KeyDown(Key_Right) Right = True If KeyDown(Key_Space) Fire = True ' P H Y S I C S '--------------------------------------- 'Alter these to alter the ships movement Local Acceleration# = 0.04 Local Friction# = 0 Local TopSpeed# = 2.0 Local TurnAcceleration# = 0.18 Local TurnFriction# = 0.0 Local TurnMax# = 5 '--------------------------------------- 'M O V E M E N T P H Y S I C S '-------------------------------------- ' If Up 'Create a Acceleration Vector and 'add it to the Speed Vector XSpeed:+ Cos(Direction)*Acceleration YSpeed:+ Sin(Direction)*Acceleration EndIf If Down 'Create a Acceleration Vector and 'substract it from the Speed Vector XSpeed:- Cos(Direction)*Acceleration YSpeed:- Sin(Direction)*Acceleration EndIf If Fire TShot.Fire( X, Y, Direction, XSpeed, YSpeed ) 'Calculate the length of the Speed Vector Local SpeedVectorLength# = Sqr(XSpeed*XSpeed + YSpeed*YSpeed) If SpeedVectorLength > 0 'Decrease Speed with Friction if we are moving XSpeed:- (XSpeed/SpeedVectorLength)*Friction YSpeed:- (YSpeed/SpeedVectorLength)*Friction EndIf If SpeedVectorLength > TopSpeed 'If we are going beyond the speed barrier then reduce our speed 'with the amount in which it surpases TopSpeed XSpeed:+ (XSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength) YSpeed:+ (YSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength) EndIf If X > 800 X = 0 If Y > 600 Y = 0 If X < 0 X = 800 If Y < 0 Y = 600 'Move X:+ XSpeed Y:+ YSpeed 'Rem 'Visualize the vectors SetRotation 0 SetColor 255,0,0 'Red DrawLine X,Y,X,Y + YSpeed*50 SetColor 0,255,0 'Green DrawLine X,Y,X+XSpeed*50,Y SetColor 0,0,255 'Blue 'This is the SpeedVector's Length 'Note that this vector is built by 'Adding the Red and the Green DrawLine X,Y,X+XSpeed*50,Y+YSpeed*50 SetColor 255,255,255 'EndRem 'R O T A T I O N P H Y S I C S '-------------------------------------- ' If Left TurnSpeed:-TurnAcceleration If Right TurnSpeed:+TurnAcceleration 'Limit TurnSpeed If TurnSpeed > TurnMax TurnSpeed = TurnMax If TurnSpeed < -TurnMax TurnSpeed = -TurnMax Direction:+TurnSpeed If Direction > 360 Direction:- 360 If Direction < 0 Direction:+ 360 'Apply Friction To Rotation If TurnSpeed > TurnFriction TurnSpeed:- TurnFriction If TurnSpeed < -TurnFriction TurnSpeed:+ TurnFriction 'If Friction is Greater than Speed then Stop If TurnSpeed < TurnFriction And TurnSpeed > -TurnFriction TurnSpeed = 0 EndMethod Function UpdateAll() Local Ship:TPlayer For Ship = EachIn List Ship.Update() Next EndFunction End Type Type TShot Extends TSpaceObject Global List:TList Global Image:TImage Function Fire( X, Y, Direction, XSpeed, YSpeed ) Local Shot:TShot = New TShot If List = Null List = CreateList() List.AddLast Shot If Not Image'First Time Image = LoadImage("bullet2.png") MidHandleImage( Image ) EndIf Local ShotSpeed#= 8 Shot.X = X Shot.Y = Y Shot.Direction = Direction 'Add Shot Start Speed Shot.XSpeed= Cos(Direction)*ShotSpeed + XSpeed Shot.YSpeed= Sin(Direction)*ShotSpeed + YSpeed EndFunction Method Draw() SetRotation( Direction ) DrawImage( Image,X,Y ) EndMethod Method Update() Draw() X:+ XSpeed Y:+ YSpeed If X > 800 Or Y > 600 Or X < 0 Or Y < 0 Destroy() EndMethod Function UpdateAll() If Not List Return Local Shot:TShot For Shot = EachIn List Shot.Update() Next EndFunction Method Destroy() List.Remove( Self ) EndMethod EndType Type TRock Extends TSpaceObject Global List:TList Global Image:TImage Field Size Field Rotation# Const LARGE = 3 Const MEDIUM = 2 Const SMALL = 1 Function Spawn( X, Y ,Size ) Local Rock:TRock = New TRock If Not List List = CreateList() List.AddLast Rock If Not Image'First Time Image = LoadImage("asteroid01.png") MidHandleImage( Image ) EndIf Local RockSpeed# = 0 Select Size Case LARGE'Large RockSpeed = 0.2 Case MEDIUM'Medium RockSpeed = 0.5 Case SMALL'Small RockSpeed = 1 EndSelect Rock.X = X Rock.Y = Y Rock.Direction = Rand(360) Rock.Rotation = Rock.Direction Rock.Size = Size 'Add Rock Start Speed Rock.XSpeed= Cos(Rock.Direction)*RockSpeed Rock.YSpeed= Sin(Rock.Direction)*RockSpeed EndFunction Method Draw() Select Self.Size Case LARGE SetScale 1.2, 1.2 Case MEDIUM'Medium SetScale 0.8, 0.8 Case SMALL'Small SetScale 0.4, 0.4 EndSelect SetRotation( Rotation ) Rotation:+0.5 DrawImage( Image,X,Y ) SetScale 1,1 EndMethod Method Update() Draw() X:+ XSpeed Y:+ YSpeed Collision() If X > 800 X = 0 If Y > 600 Y = 0 If X < 0 X = 800 If Y < 0 Y = 600 EndMethod Function UpdateAll() If Not List Return For Local Rock:TRock = EachIn List Rock.Update() Next EndFunction Method Destroy() List.Remove( Self ) EndMethod Method Collision() Local Radius Select Size Case LARGE Radius = 100 Case MEDIUM'Medium Radius = 50 Case SMALL Radius = 20 EndSelect ' Player collision to asteroid If TPlayer.list For Local Ship:TPlayer = EachIn TPlayer.list If ImagesCollide(Image, X, Y, 0, ship.image, ship.X, ship.Y, 0) Local collisionAngle:Float = AngleTO:Float( x, y, Ship.X, Ship.Y ) Local collisionForce:Float = (XSpeed + YSpeed) - (Ship.XSpeed + Ship.YSpeed) If collisionForce < 0 Then collisionForce = collisionForce * - 1 Ship.XSpeed:- ( Cos(collisionAngle) / 2) Ship.YSpeed:- ( Sin(collisionAngle) / 2) ' If asteroid is small change also it's direction If size = SMALL Then XSpeed:+ ( Cos(collisionAngle) / 2) YSpeed:+ ( Sin(collisionAngle) / 2) EndIf EndIf Next EndIf 'If a shot hit a rock If Not TShot.List Return For Local Shot:TShot = EachIn TShot.List If Distance( X, Y, Shot.X, Shot.Y ) < Radius Shot.Destroy() Select Size Case LARGE Destroy()'Destory the rock Spawn( X, Y , MEDIUM ) Spawn( X, Y , MEDIUM ) Case MEDIUM Destroy() Spawn( X, Y , SMALL ) Spawn( X, Y , SMALL ) Case SMALL Destroy()' EndSelect EndIf Next EndMethod EndType Graphics 800,600,0 Const Intro = 1 Const Death = 2 Const Playing = 3 Global Mode = Intro Global Score, HighestScore Global Level , Rank$ TRock.Spawn( 50,50, TRock.LARGE ) For Local NR = 1 To 20 TRock.Spawn( 400,300, TRock.SMALL ) Next 'Main Loop Repeat' - - - - - - - - - - - - - - - - - TShot.UpdateAll() TRock.UpdateAll() Select Mode Case Intro DrawText "Welcome to Asteroids Wars Beta Version",50,100 DrawText "Highest Score this run: "+HighestScore+" rocks.",50,130 DrawText "Steer with LEFT, RIGHT ",50,170 DrawText "Thrust with UP and DOWN ",50,190 DrawText "Fire with SPACE ",50,210 DrawText " --------- P R E S S S P A C E T O S T A R T ---------- ",50,260 If KeyHit(Key_Space) StartGame() Case Playing DrawText "Score: "+Score, 20, 20 TPlayer.UpdateAll() If TPlayer.List.Count() = 0 Mode = Death GetRanking() Level = 0 FlushKeys EndIf If TRock.List.Count() = 0 StartGame() Case Death DrawText "~~ You Lost Your Ship - G A M E O V E R ~~ ",50,100 DrawText "You managed to destroy "+Score+" rocks in "+level+" different zones.",50,130 DrawText "------------------------ ",50,170 DrawText " Your RANK : "+Rank$ ,50,190 DrawText "------------------------ ",50,210 DrawText " --------- P R E S S [R] T O R E T R Y ---------- ",50,260 If KeyHit(KEY_R) Mode = Intro EndSelect Flip Cls If KeyHit(Key_Q) End Until KeyHit(Key_Escape)'- - - - - - - - End Function StartGame() If TRock.List.Count() > 0 'First Time 'Clear For Local Rock:TRock = EachIn TRock.List Rock.Destroy() Next 'Start TPlayer.Create() Else'In play Level:+1 Score:+13 EndIf CreateRocks() Mode = Playing EndFunction Function CreateRocks() Local Danger = Level*20 + Rand(0,10) Local Ship:TPlayer = TPlayer( TPlayer.List.First() ) Repeat Local X,Y Repeat X = Rand(0,800) Y = Rand(0,600) Until Distance(Ship.X, Ship.Y, X, Y ) > 200 Select Rand(1,2) Case 1 TRock.Spawn( X, Y, TRock.LARGE ) ;Danger:- 5 Case 2 TRock.Spawn( X, Y, TRock.MEDIUM ) ;Danger:- 3 EndSelect Until Danger <= 0 EndFunction Function GetRanking() Rank$ = "Classified" If Level = 1 Rank = "You didn't get a single one?!" If Level = 1 Rank = "ROFL" If Level = 2 Rank = "LOL" If Level = 3 Rank = "Newbie" If Level = 4 Rank = "Beginner" If Level = 5 Rank = "Average" If Level = 6 Rank = "Fair" If Level = 7 Rank = "Almost got one" If Level = 8 Rank = "Starfighter" If Level = 9 Rank = "Rock Destroyer" If Level = 10 Rank = "Duplicator" '... '.... HighestScore = Score EndFunction Function Distance#( X1, Y1, X2, Y2 ) Local DX# = X2 - X1 Local DY# = Y2 - Y1 Return Sqr(Dx*Dx + Dy*Dy) EndFunction Function AngleTO:Float(X1:Float, Y1:Float, X2:Float, Y2:Float) Local dx:Float=x2-x1 Local dy:Float=y2-y1 Local Angle:Float=(ATan2(dy,dx)) + 180 If Angle>0 Then While(Angle>= 360) Angle:-360 Wend ElseIf Angle<0 Then While(Angle<0) Angle:+360 Wend End If Return Angle End Function |
Comments
None.
Code Archives Forum