Engine.monkey2 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. #Import "PoolMod"
  2. '******************************************************************************************
  3. '
  4. ' elastic/non elastic ball/cirlcle collision engine
  5. '
  6. '******************************************************************************************
  7. ' Collision storage.
  8. Class ElasticEngine
  9. Field wallList:List<VectorObject>
  10. Field ballList:List<Ball>
  11. Field colls:CollisionTrend[] = New CollisionTrend[99]
  12. Field totalCol:Int
  13. Field nearesBall:Ball
  14. Field colCount:Int
  15. Field firstCollision:Ball
  16. Method New()
  17. wallList= New List<VectorObject>
  18. ballList= New List<Ball>
  19. For Local i:Int=0 Until 99
  20. colls[i]= New CollisionTrend()
  21. End
  22. End
  23. Method SetGravity(vx:Float,vy:Float)
  24. VectorObject.SetGlobalGravity(vx,vy)
  25. End
  26. Method SetFriction(f:Float)
  27. VectorObject.SetGlobalFriction(f)
  28. End
  29. Method RemoveWalls()
  30. wallList.Clear()
  31. End
  32. Method AddWall:List<VectorObject>.Node(t_wall:VectorObject)
  33. Return wallList.AddLast(t_wall)
  34. End
  35. Method AddLineWallImage:LineWall(x1:Float,y1:Float,x2:Float,y2:Float,image:Image,color:Color)
  36. Local line:LineWall= New LineWall(x1,y1,x2,y2,Null,1.0,1.0)
  37. Local animation:AImageLineStained= New AImageLineStained(line.P,line.V.x,line.V.y,image,color)
  38. line.SetAnimation(animation)
  39. AddWall(line)
  40. Return line
  41. End
  42. Method AddLineWallOutline:LineWall(x1:Float,y1:Float,x2:Float,y2:Float,image:Image,color:Color)
  43. Local line:LineWall=New LineWall(x1,y1,x2,y2,Null,1.0,1.0)
  44. Local animation:APixelLine= New APixelLine(line.P,line.V.x,line.V.y,color)
  45. line.SetAnimation(animation)
  46. AddWall(line)
  47. Return line
  48. End
  49. Method AddArcWallImage:ArcWall(x:Float,y:Float,radius:Float,startAngle:Float,endAngle:Float,image:Image,color:Color)
  50. Local arc:ArcWall=New ArcWall(x,y,radius,startAngle,endAngle,Null,1.0,1.0)
  51. Local animation:AImageArcStained= New AImageArcStained(arc.P,image,color)
  52. arc.SetAnimation(animation)
  53. AddWall(arc)
  54. Return arc
  55. End
  56. Method AddArcWallOutline:ArcWall(x:Float,y:Float,radius:Float,startAngle:Float,endAngle:Float,color:Color)
  57. Local arc:ArcWall=New ArcWall(x,y,radius,startAngle,endAngle,Null,1.0,1.0)
  58. Local animation:APixelArc=New APixelArc(arc.P,radius,startAngle,endAngle,color)
  59. arc.SetAnimation(animation)
  60. AddWall(arc)
  61. Return arc
  62. End
  63. Method AddBall:List<Ball>.Node(ball:Ball)
  64. ball.node=ballList.AddLast(ball)
  65. Return ball.node
  66. End
  67. Method Add3DBall:Ball(x:Float,y:Float,radius:Float,vx:Float,vy:Float,image:Image,color:Color,txtColor:Color,number:Int,displayFloat:Int)
  68. Local ball:Ball=New Ball(x,y,radius,vx,vy,Null,1.0,1.0,1.0,number,False)
  69. Local animation:ObjectAnimation= New ABall3D(ball.P,radius,image,color,txtColor,number)
  70. ball.SetAnimation(animation)
  71. AddBall(ball)
  72. Return ball
  73. End
  74. Method Process()
  75. Local distance:Float=INVALID_DISTANCE
  76. Local done:Int=0
  77. nearesBall = Null
  78. Local nearestObject:VectorObject
  79. colCount = -1
  80. For Local ball:Ball = Eachin ballList
  81. For Local ball2:Ball = Eachin ballList.Backwards()
  82. If ball=ball2 Exit
  83. If(Not ball.IsMoving() And Not ball2.IsMoving()) Continue
  84. Local balla:Ball
  85. Local ballb:Ball
  86. If(ball.L>=ball2.L)
  87. balla=ball2
  88. ballb=ball
  89. Else
  90. balla=ball
  91. ballb=ball2
  92. End
  93. Local oldL:Float=ballb.L
  94. Local d:Float=balla.Distance(ballb)
  95. If d=INVALID_DISTANCE
  96. Continue
  97. Else
  98. If d<distance
  99. distance=d
  100. colCount=0
  101. colls[colCount].ball=ballb
  102. colls[colCount].obj= balla
  103. colls[colCount].cdx=balla.cdx
  104. colls[colCount].cdy=balla.cdy
  105. colls[colCount].oldL=oldL
  106. Else
  107. If d=distance
  108. colCount+=1
  109. colls[colCount].ball=ballb
  110. colls[colCount].obj= balla
  111. colls[colCount].cdx=balla.cdx
  112. colls[colCount].cdy=balla.cdy
  113. colls[colCount].oldL=oldL
  114. End
  115. End
  116. End
  117. End
  118. For Local t_wall:VectorObject = Eachin wallList
  119. Local d2:Float=t_wall.Distance(ball)
  120. If d2 = INVALID_DISTANCE
  121. Continue
  122. Else
  123. If d2 < distance
  124. distance=d2
  125. colCount=0
  126. colls[colCount].ball=ball
  127. colls[colCount].obj=t_wall
  128. colls[colCount].cdx=t_wall.cdx
  129. colls[colCount].cdy=t_wall.cdy
  130. colls[colCount].oldL=0
  131. Else
  132. If d2 = distance
  133. colCount+=1
  134. colls[colCount].ball=ball
  135. colls[colCount].obj=t_wall
  136. colls[colCount].cdx=t_wall.cdx
  137. colls[colCount].cdy=t_wall.cdy
  138. colls[colCount].oldL=0
  139. End
  140. End
  141. End
  142. End
  143. End
  144. If distance = INVALID_DISTANCE
  145. distance=1.0
  146. done=True
  147. End
  148. For Local ball3:Ball = Eachin ballList
  149. ball3.Advance(distance)
  150. End
  151. For Local i:Int=0 to colCount
  152. colls[i].obj.Bounce(colls[i].ball,colls[i].cdx,colls[i].cdy)
  153. If(Not((firstCollision)<>Null))
  154. Local b1:Ball=Cast<Ball>(colls[i].obj)
  155. Local b2:Ball=colls[i].ball
  156. If(((b1)<>Null) And b1.num=16)
  157. firstCollision=b2
  158. Else
  159. If b2.num = 16 And b1 firstCollision=b1
  160. End
  161. End
  162. End
  163. If totalCol>=0 totalCol+=colCount+1
  164. If Not done Process()
  165. End
  166. Method Update(timeFrame:Float)
  167. If(timeFrame = 0.0) Return
  168. If(timeFrame > 3.0) timeFrame=3.0
  169. For Local ball:Ball = Eachin ballList
  170. ball.updateIn(timeFrame)
  171. End
  172. totalCol = 0
  173. Process()
  174. For Local ball2:Ball = Eachin ballList
  175. ball2.updateOut(timeFrame)
  176. End
  177. End
  178. Method RemoveBall(ball:Ball)
  179. ball.node.Remove()
  180. End
  181. Method BallsMoving:Bool()
  182. For Local b:Ball = Eachin ballList
  183. If b.IsMoving() Return True
  184. End
  185. Return False
  186. End
  187. Method GetFirstCollision:Ball()
  188. Return firstCollision
  189. End
  190. Method ClearFirstCollision()
  191. firstCollision = Null
  192. End
  193. Method Render(canvas:Canvas)
  194. For Local ball:Ball = Eachin ballList
  195. If(ball.P.x<0.0 Or ball.P.x>DEVICE_WIDTH Or ball.P.y<0.0 Or ball.P.y>DEVICE_HEIGHT)
  196. RuntimeError("ball exited screen ")
  197. End
  198. ball.Render(canvas)
  199. End
  200. 'For Local wall := Eachin wallList
  201. ' wall.Render(canvas)
  202. 'Next
  203. Return
  204. End
  205. Method CollisionDistance2Ghost(ghost:GhostBall)
  206. Local distance:Float=INVALID_DISTANCE
  207. Local cdx:Float, cdy:Float
  208. For Local b:Ball = Eachin ballList
  209. cdx=ghost.cn.x
  210. cdy=ghost.cn.y
  211. Local dist:Float=b.CollisionDistance2Ghost(ghost)
  212. If(dist<distance)
  213. distance=dist
  214. ghost.colBall=b
  215. Else
  216. ghost.cn.x=cdx
  217. ghost.cn.y=cdy
  218. End
  219. End
  220. For Local w:VectorObject = Eachin wallList
  221. cdx=ghost.cn.x
  222. cdy=ghost.cn.y
  223. Local dist2:Float=w.CollisionDistance2Ghost(ghost)
  224. If(dist2<distance)
  225. ghost.colBall = Null
  226. distance=dist2
  227. Else
  228. ghost.cn.x=cdx
  229. ghost.cn.y=cdy
  230. End
  231. End
  232. ghost.distance=distance
  233. End
  234. End
  235. Class CollisionTrend
  236. Field temp:PVector2D
  237. Method New()
  238. temp=New PVector2D()
  239. End
  240. Field ball:Ball
  241. Field obj:VectorObject
  242. Field cdx:Float
  243. Field cdy:Float
  244. Field oldL:Float
  245. End