November 24, 2020, 05:39:53 AM

### Author Topic: [bmx] 2D Collision Physics (bounce) by Arska [ 1+ years ago ]  (Read 913 times)

#### BlitzBot

• Jr. Member
• Posts: 1
##### [bmx] 2D Collision Physics (bounce) by Arska [ 1+ years ago ]
« on: June 29, 2017, 12:28:38 AM »
Title : 2D Collision Physics (bounce)
Author : Arska
Posted : 1+ years ago

Description : Here is simple bounce physics for asteroids game.

Asteroids game is made by Tibit. <a href="../Community/posts240f-2.html?topic=48800" target="_blank">http://www.blitzbasic.com/Community/posts.php?topic=48800[/url]

Here is package for code and all assets:
<a href="https://www.dropbox.com/s/74u5geibos6pm0p/CollisionPhysics.7z?dl=0" target="_blank">https://www.dropbox.com/s/74u5geibos6pm0p/CollisionPhysics.7z?dl=0[/url]

All improvements are welcome.

Code :
Code: BlitzMax
1. Strict
2. AppTitle = "Asteroid Wars Example"
3.
4. Rem
5.
6.         This is the file of a step by step example of how to make a simple asteroids clone.
7.         The guide can be found at www.blitzbasic.com - forums - blitzmax - tutorials
8.
9. EndRem
10.
11.
12.
13. Type TSpaceObject
14.
15.         Field X#,Y#
16.         Field XSpeed#,YSpeed#
17.         Field Direction
18.
19.         Function Create() EndFunction
20.
21.         Function UpdateAll() EndFunction
22.
23.         Method New() EndMethod
24.
25.         Method Update() EndMethod
26.
27.         Method Destroy() EndMethod
28.
29.         Method Draw() EndMethod
30.
31. End Type
32.
33. Type TPlayer Extends TSpaceObject
34.
35.         Global List:TList
36.         Global Image:Timage
37.
38.         Field TurnSpeed#
39.
40.         Function Create()
41.                 Local Ship:TPlayer = New TPlayer
42.                 If List = Null List = CreateList()
44.
45.                 If Not Image
47.                         MidHandleImage( Image )'Center
48.                 EndIf
49.         EndFunction
50.
51.         Method New()'Starting Values
52.                 X = 300
53.                 Y = 400
54.         EndMethod
55.
56.         Method Draw()
57.                 SetRotation( Direction )
58.                 DrawImage( Image,X,Y )
59.         EndMethod
60.
61.         Method Update()
62.                 Draw()
63.
64.                 'Possible Actions
65.                 Local Up,Down,Left,Right,Fire
66.
67.                 'Controls affect actions, Player 1
68.                 If KeyDown(Key_Up)              Up              = True
69.                 If KeyDown(Key_Down)    Down    = True
70.                 If KeyDown(Key_Left)    Left    = True
71.                 If KeyDown(Key_Right)   Right   = True
72.                 If KeyDown(Key_Space)  Fire     = True
73.
74.
75.                 ' P H Y S I C S
76.                 '---------------------------------------
77.                 'Alter these to alter the ships movement
78.
79.                         Local Acceleration#             = 0.04
80.                         Local Friction#                         = 0
81.                         Local TopSpeed#                         = 2.0
82.
83.                         Local TurnAcceleration# = 0.18
84.                         Local TurnFriction#                     = 0.0
85.                         Local TurnMax#                          = 5
86.
87.                 '---------------------------------------
88.
89.
90.                 'M O V E M E N T  P H Y S I C S
91.                 '--------------------------------------
92.                 '
93.                 If Up
94.                         'Create a Acceleration Vector and
95.                         'add it to the Speed Vector
96.                         XSpeed:+ Cos(Direction)*Acceleration
97.                         YSpeed:+ Sin(Direction)*Acceleration
98.                 EndIf
99.
100.                 If Down
101.                         'Create a Acceleration Vector and
102.                         'substract it from the Speed Vector
103.                         XSpeed:- Cos(Direction)*Acceleration
104.                         YSpeed:- Sin(Direction)*Acceleration
105.                 EndIf
106.
107.                 If Fire TShot.Fire( X, Y, Direction, XSpeed, YSpeed )
108.
109.                 'Calculate the length of the Speed Vector
110.                 Local SpeedVectorLength# = Sqr(XSpeed*XSpeed + YSpeed*YSpeed)
111.
112.                 If SpeedVectorLength > 0
113.                         'Decrease Speed with Friction if we are moving
114.                         XSpeed:- (XSpeed/SpeedVectorLength)*Friction
115.                         YSpeed:- (YSpeed/SpeedVectorLength)*Friction
116.                 EndIf
117.
118.                 If SpeedVectorLength > TopSpeed
119.                         'If we are going beyond the speed barrier then reduce our speed
120.                         'with the amount in which it surpases TopSpeed
121.                         XSpeed:+ (XSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength)
122.                         YSpeed:+ (YSpeed/SpeedVectorLength)*(TopSpeed - SpeedVectorLength)
123.                 EndIf
124.
125.                 If X > 800 X = 0
126.                 If Y > 600 Y = 0
127.                 If X < 0 X = 800
128.                 If Y < 0 Y = 600
129.
130.                 'Move
131.                 X:+ XSpeed
132.                 Y:+ YSpeed
133.
134.                 'Rem 'Visualize the vectors
135.                 SetRotation 0
136.                 SetColor 255,0,0 'Red
137.                         DrawLine X,Y,X,Y + YSpeed*50
138.                 SetColor 0,255,0 'Green
139.                         DrawLine X,Y,X+XSpeed*50,Y
140.                 SetColor 0,0,255 'Blue
141.                         'This is the SpeedVector's Length
142.                         'Note that this vector is built by
143.                         'Adding the Red and the Green
144.                         DrawLine X,Y,X+XSpeed*50,Y+YSpeed*50
145.                 SetColor 255,255,255
146.                 'EndRem
147.
148.                 'R O T A T I O N  P H Y S I C S
149.                 '--------------------------------------
150.                 '
151.                 If Left TurnSpeed:-TurnAcceleration
152.                 If Right        TurnSpeed:+TurnAcceleration
153.
154.                 'Limit TurnSpeed
155.                 If TurnSpeed >  TurnMax TurnSpeed =  TurnMax
156.                 If TurnSpeed < -TurnMax TurnSpeed = -TurnMax
157.
158.                 Direction:+TurnSpeed
159.
160.                 If Direction > 360      Direction:- 360
161.                 If Direction < 0        Direction:+ 360
162.
163.                 'Apply Friction To Rotation
164.                 If TurnSpeed >  TurnFriction    TurnSpeed:- TurnFriction
165.                 If TurnSpeed < -TurnFriction TurnSpeed:+ TurnFriction
166.
167.                 'If Friction is Greater than Speed then Stop
168.                 If TurnSpeed < TurnFriction And TurnSpeed > -TurnFriction TurnSpeed = 0
169.
170.         EndMethod
171.
172.         Function UpdateAll()
173.                 Local Ship:TPlayer
174.                 For Ship = EachIn List
175.                         Ship.Update()
176.                 Next
177.         EndFunction
178.
179. End Type
180.
181. Type TShot Extends TSpaceObject
182.
183.         Global List:TList
184.         Global Image:TImage
185.
186.         Function Fire( X, Y, Direction, XSpeed, YSpeed  )
187.                 Local Shot:TShot = New TShot
188.                 If List = Null List = CreateList()
190.
191.                 If Not Image'First Time
193.                         MidHandleImage( Image )
194.                 EndIf
195.
196.                 Local ShotSpeed#= 8
197.                 Shot.X                  = X
198.                 Shot.Y                  = Y
199.                 Shot.Direction  = Direction
200.
202.                 Shot.XSpeed= Cos(Direction)*ShotSpeed + XSpeed
203.                 Shot.YSpeed= Sin(Direction)*ShotSpeed + YSpeed
204.         EndFunction
205.
206.         Method Draw()
207.                 SetRotation( Direction )
208.                 DrawImage( Image,X,Y )
209.         EndMethod
210.
211.         Method Update()
212.                 Draw()
213.                 X:+ XSpeed
214.                 Y:+ YSpeed
215.                 If X > 800 Or Y > 600 Or X < 0 Or Y < 0 Destroy()
216.         EndMethod
217.
218.         Function UpdateAll()
219.                 If Not List Return
220.
221.                 Local Shot:TShot
222.                 For Shot = EachIn List
223.                         Shot.Update()
224.                 Next
225.         EndFunction
226.
227.         Method Destroy()
228.                 List.Remove( Self )
229.         EndMethod
230.
231. EndType
232.
233.
234. Type TRock Extends TSpaceObject
235.
236.         Global List:TList
237.         Global Image:TImage
238.         Field Size
239.         Field Rotation#
240.
241.         Const LARGE  = 3
242.         Const MEDIUM = 2
243.         Const SMALL = 1
244.
245.         Function Spawn( X, Y ,Size )
246.                 Local Rock:TRock = New TRock
247.                 If Not List List = CreateList()
249.
250.                 If Not Image'First Time
252.                         MidHandleImage( Image )
253.                 EndIf
254.
255.                 Local RockSpeed# = 0
256.                 Select Size
257.                         Case LARGE'Large
258.                                 RockSpeed = 0.2
259.                         Case MEDIUM'Medium
260.                                 RockSpeed = 0.5
261.                         Case SMALL'Small
262.                                 RockSpeed = 1
263.                 EndSelect
264.
265.                 Rock.X                   = X
266.                 Rock.Y                   = Y
267.                 Rock.Direction   = Rand(360)
268.                 Rock.Rotation    = Rock.Direction
269.                 Rock.Size                = Size
270.
272.                 Rock.XSpeed= Cos(Rock.Direction)*RockSpeed
273.                 Rock.YSpeed= Sin(Rock.Direction)*RockSpeed
274.         EndFunction
275.
276.         Method Draw()
277.
278.                 Select Self.Size
279.                         Case LARGE
280.                                 SetScale 1.2, 1.2
281.                         Case MEDIUM'Medium
282.                                 SetScale 0.8, 0.8
283.                         Case SMALL'Small
284.                                 SetScale 0.4, 0.4
285.                 EndSelect
286.
287.                 SetRotation( Rotation )
288.                 Rotation:+0.5
289.                 DrawImage( Image,X,Y )
290.                 SetScale 1,1
291.         EndMethod
292.
293.         Method Update()
294.                 Draw()
295.                 X:+ XSpeed
296.                 Y:+ YSpeed
297.
298.                 Collision()
299.
300.                 If X > 800 X = 0
301.                 If Y > 600 Y = 0
302.                 If X < 0 X = 800
303.                 If Y < 0 Y = 600
304.         EndMethod
305.
306.         Function UpdateAll()
307.                 If Not List Return
308.
309.                 For Local Rock:TRock = EachIn List
310.                         Rock.Update()
311.                 Next
312.         EndFunction
313.
314.         Method Destroy()
315.                 List.Remove( Self )
316.         EndMethod
317.
318.         Method Collision()
320.                 Select Size
321.                         Case LARGE
323.                         Case MEDIUM'Medium
325.                         Case SMALL
327.                 EndSelect
328.
329.                 ' Player collision to asteroid
330.                 If TPlayer.list
331.                         For Local Ship:TPlayer = EachIn TPlayer.list
332.
333.                                 If ImagesCollide(Image, X, Y, 0, ship.image, ship.X, ship.Y, 0)
334.
335.                                         Local collisionAngle:Float = AngleTO:Float( x, y, Ship.X, Ship.Y )
336.                                         Local collisionForce:Float = (XSpeed + YSpeed) - (Ship.XSpeed + Ship.YSpeed)
337.                                         If collisionForce < 0 Then collisionForce = collisionForce * - 1
338.
339.
340.                                         Ship.XSpeed:- ( Cos(collisionAngle) / 2)
341.                                         Ship.YSpeed:- ( Sin(collisionAngle) / 2)
342.
343.                                         ' If asteroid is small change also it's direction
344.                                         If size = SMALL Then
345.                                                 XSpeed:+ ( Cos(collisionAngle) / 2)
346.                                                 YSpeed:+ ( Sin(collisionAngle) / 2)
347.                                         EndIf
348.
349.                                 EndIf
350.
351.                         Next
352.                 EndIf
353.
354.
355.
356.                 'If a shot hit a rock
357.                 If Not TShot.List Return
358.                 For Local Shot:TShot = EachIn TShot.List
359.                         If Distance( X, Y, Shot.X, Shot.Y ) < Radius
360.
361.                                 Shot.Destroy()
362.
363.                                 Select Size
364.                                         Case LARGE
365.                                                 Destroy()'Destory the rock
366.                                                 Spawn( X, Y , MEDIUM )
367.                                                 Spawn( X, Y , MEDIUM )
368.                                         Case MEDIUM
369.                                                 Destroy()
370.                                                 Spawn( X, Y , SMALL )
371.                                                 Spawn( X, Y , SMALL )
372.                                         Case SMALL
373.                                                 Destroy()'
374.                                 EndSelect
375.
376.                         EndIf
377.                 Next
378.         EndMethod
379. EndType
380.
381.
382. Graphics 800,600,0
383.
384.
385. Const Intro     = 1
386. Const Death     = 2
387. Const Playing   = 3
388.
389. Global Mode = Intro
390. Global Score, HighestScore
391. Global Level , Rank\$
392.
393. TRock.Spawn( 50,50, TRock.LARGE )
394. For Local NR = 1 To 20
395.         TRock.Spawn( 400,300, TRock.SMALL )
396. Next
397.
398. 'Main Loop
399. Repeat' - - - - - - - - - - - - - - - - -
400.
401.         TShot.UpdateAll()
402.         TRock.UpdateAll()
403.
404.         Select Mode
405.
406.                 Case Intro
407.
408.                         DrawText "Welcome to Asteroids Wars Beta Version",50,100
409.
410.                         DrawText "Highest Score this run: "+HighestScore+" rocks.",50,130
411.
412.                         DrawText "Steer with LEFT, RIGHT      ",50,170
413.                         DrawText "Thrust with UP and DOWN     ",50,190
414.                         DrawText "Fire with SPACE             ",50,210
415.
416.                         DrawText " ---------  P R E S S   S P A C E   T O  S T A R T  ---------- ",50,260
417.
418.                         If KeyHit(Key_Space) StartGame()
419.
420.                 Case Playing
421.                         DrawText "Score: "+Score, 20, 20
422.                         TPlayer.UpdateAll()
423.                         If TPlayer.List.Count() = 0
424.                                 Mode = Death
425.                                 GetRanking()
426.                                 Level = 0
427.                                 FlushKeys
428.                         EndIf
429.                         If TRock.List.Count() = 0 StartGame()
430.
431.
432.                 Case Death
433.
434.                         DrawText "~~ You Lost Your Ship - G A M E  O V E R ~~ ",50,100
435.
436.                         DrawText "You managed to destroy "+Score+" rocks in "+level+" different zones.",50,130
437.
438.                         DrawText "------------------------  ",50,170
439.                         DrawText " Your RANK : "+Rank\$           ,50,190
440.                         DrawText "------------------------  ",50,210
441.
442.                         DrawText " ---------  P R E S S  [R]  T O   R E T R Y  ---------- ",50,260
443.
444.                         If KeyHit(KEY_R) Mode = Intro
445.
446.         EndSelect
447.
448. Flip
449. Cls
450.                 If KeyHit(Key_Q) End
451. Until KeyHit(Key_Escape)'- - - - - - - -
452. End
453. Function StartGame()
454.
455.         If TRock.List.Count() > 0 'First Time
456.                 'Clear
457.                 For Local Rock:TRock = EachIn TRock.List
458.                         Rock.Destroy()
459.                 Next
460.
461.                 'Start
462.                 TPlayer.Create()
463.
464.         Else'In play
465.
466.                 Level:+1
467.                 Score:+13
468.
469.         EndIf
470.
471.         CreateRocks()
472.
473.         Mode = Playing
474.
475. EndFunction
476.
477. Function CreateRocks()
478.
479.         Local Danger = Level*20 + Rand(0,10)
480.         Local Ship:TPlayer = TPlayer( TPlayer.List.First() )
481.
482.         Repeat
483.
484.                 Local X,Y
485.
486.                 Repeat
487.                         X = Rand(0,800)
488.                         Y = Rand(0,600)
489.                 Until Distance(Ship.X, Ship.Y, X, Y ) > 200
490.
491.                 Select Rand(1,2)
492.                         Case 1
493.                                 TRock.Spawn( X, Y, TRock.LARGE )  ;Danger:- 5
494.                         Case 2
495.                                 TRock.Spawn( X, Y, TRock.MEDIUM ) ;Danger:- 3
496.                 EndSelect
497.
498.         Until Danger <= 0
499.
500. EndFunction
501.
502. Function GetRanking()
503.
504.         Rank\$ = "Classified"
505.         If Level = 1 Rank = "You didn't get a single one?!"
506.         If Level = 1 Rank = "ROFL"
507.         If Level = 2 Rank = "LOL"
508.         If Level = 3 Rank = "Newbie"
509.         If Level = 4 Rank = "Beginner"
510.         If Level = 5 Rank = "Average"
511.         If Level = 6 Rank = "Fair"
512.         If Level = 7 Rank = "Almost got one"
513.         If Level = 8 Rank = "Starfighter"
514.         If Level = 9 Rank = "Rock Destroyer"
515.         If Level = 10 Rank = "Duplicator"
516.         '...
517.         '....
518.
519.         HighestScore = Score
520. EndFunction
521.
522. Function Distance#( X1, Y1, X2, Y2 )
523.         Local DX# = X2 - X1
524.         Local DY# = Y2 - Y1
525.         Return Sqr(Dx*Dx + Dy*Dy)
526. EndFunction
527.
528. Function AngleTO:Float(X1:Float, Y1:Float, X2:Float, Y2:Float)
529.         Local dx:Float=x2-x1
530.         Local dy:Float=y2-y1
531.         Local Angle:Float=(ATan2(dy,dx)) + 180
532.
533.         If Angle>0 Then
534.                 While(Angle>= 360)
535.                         Angle:-360
536.                 Wend
537.         ElseIf Angle<0 Then
538.                 While(Angle<0)
539.                         Angle:+360
540.                 Wend
541.         End If
542.         Return Angle
543. End Function