BallAnimation.monkey2 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558
  1. #Import "PoolMod"
  2. Class ObjectAnimation
  3. Field P:PVector2D
  4. Field color:Color
  5. Method Reset:Void() Abstract
  6. Method Render:Void(canvas:Canvas) Abstract
  7. End
  8. Class AImageLineStained Extends ObjectAnimation
  9. Field angle:Float
  10. Field Length:Float
  11. Field image:Image
  12. Method New(P:PVector2D,vx:Float,vy:Float,image:Image,color:Color)
  13. Self.P=P
  14. Self.angle=-(ATan2(vy,vx))
  15. Self.Length=Sqrt(vx*vx+vy*vy)
  16. Self.image=image
  17. Self.color=color
  18. End
  19. Method Reset:Void() Override
  20. End
  21. Method Render:Void(canvas:Canvas) Override
  22. canvas.Color = color
  23. canvas.DrawImage(image,P.x,P.y,angle,Length,1.0)
  24. End
  25. End
  26. Class APixelLine Extends ObjectAnimation
  27. Field vx:Float
  28. Field vy:Float
  29. Method New(P:PVector2D,vx:Float,vy:Float,color:Color)
  30. self.P = P
  31. self.vx= vx
  32. self.vy= vy
  33. self.color=color
  34. End Method
  35. Method Reset:Void() Override
  36. End Method
  37. Method Rotate:Void(vx:Float,vy:float)
  38. End Method
  39. Method Render:Void(canvas:Canvas) Override
  40. canvas.Color = color
  41. canvas.DrawLine(P.x,P.y,P.x+vx,P.y+vy)
  42. End Method
  43. End Class
  44. Class AImageArcStained Extends ObjectAnimation
  45. Field image:Image
  46. Method New(P:PVector2D,image:Image,color:Color)
  47. self.P=P
  48. self.image=image
  49. self.color = color
  50. End Method
  51. Method Reset:Void() Override
  52. End Method
  53. Method Rotate:Void(vx:Float,vy:float)
  54. End Method
  55. Method Render:Void(canvas:Canvas) Override
  56. canvas.Color = color
  57. canvas.DrawImage(image,P.x,P.y) ',0)
  58. End Method
  59. End Class
  60. Class APixelArc Extends ObjectAnimation
  61. Field radius:Float
  62. Field startAngle:Float
  63. Field endAngle:Float
  64. Field stp:Float
  65. Method New(P:PVector2D,radius:Float,startAngle:Float,endAngle:Float,color:Color)
  66. Self.P=P
  67. self.radius=radius
  68. self.startAngle=startAngle
  69. self.endAngle=endAngle
  70. self.color = color
  71. Self.stp=1.0/(RTA * radius)
  72. End Method
  73. Method Reset:Void() Override
  74. End Method
  75. Method Rotate:Void(vx:Float,vy:float)
  76. End Method
  77. Method Render:Void(canvas:Canvas) Override
  78. canvas.Color = color
  79. If(startAngle = endAngle)
  80. Return
  81. Endif
  82. Local angle:Float=endAngle - startAngle
  83. Local AccumAngle:Float=startAngle
  84. Local rad2:Float=radius*2.0
  85. While(AccumAngle < startAngle+angle)
  86. canvas.DrawRect(P.x+Cos(AccumAngle*ATR)*radius-0.5,P.y+Sin(AccumAngle*ATR) * radius-0.5,1.0,1.0)
  87. AccumAngle += stp
  88. Wend
  89. End Method
  90. End Class
  91. Class Vec2D
  92. Field x:Float
  93. Field y:Float
  94. Field len:Float
  95. Field dx:Float
  96. Field dy:Float
  97. Method New(x1:Float, y1:Float, x2:Float, y2:Float)
  98. x = x1
  99. y = y1
  100. Local vx:Float = x2 - x1
  101. Local vy:Float = y2 - y1
  102. If (vx<>0.0) Or (vy <> 0.0)
  103. len = Sqrt(vx*vx + vy*vy)
  104. dx = vx / len
  105. dy = vy / len
  106. Else
  107. len = 0.0
  108. dx = 0.0
  109. dy = 0.0
  110. Endif
  111. End Method
  112. End Class
  113. Class Wall
  114. Field name:String=""
  115. Field image:Image
  116. Field x1:Float
  117. Field y1:Float
  118. Field color:Color
  119. End
  120. Class Arc Extends Wall
  121. Field radius:Float
  122. Field startAngle:Float
  123. Field endAngle:Float
  124. Field cx:Float
  125. Field cy:Float
  126. Method New(x1:Float,y1:Float,radius:Float,startAngle:Float,endAngle:Float,colx:Float,coly:Float,image:Image,color:Color)
  127. Self.name="Arc"
  128. Self.image=image
  129. Self.radius=radius
  130. Self.startAngle=startAngle
  131. Self.endAngle=endAngle
  132. Self.x1=x1
  133. Self.y1=y1
  134. Self.cx=colx
  135. Self.cy=coly
  136. Self.color=color
  137. End
  138. End
  139. Class Line Extends Wall
  140. Field x2:Float
  141. Field y2:Float
  142. Method New(x1:Float,y1:Float,x2:Float,y2:Float,image:Image,color:Color)
  143. Self.name="Line"
  144. Self.image=image
  145. Self.x1=x1
  146. Self.y1=y1
  147. Self.x2=x2
  148. Self.y2=y2
  149. Self.color=color
  150. End
  151. End
  152. Class ABall3D Extends ObjectAnimation
  153. Field oldP:PVector2D=New PVector2D()
  154. Field textColor:Color
  155. Field ball3d:Ball3d
  156. Field image:Image
  157. Method New(P:PVector2D,radius:Float,image:Image,ballColor:Color,textColor:Color,number:Int)
  158. Self.P=P
  159. Self.oldP.x=P.x
  160. Self.oldP.y=P.y
  161. Self.color= ballColor
  162. Self.textColor= textColor
  163. If number<16 ball3d = New Ball3d(number,radius-1.0)
  164. Self.image=image
  165. End
  166. Method Rotate:Void(vx:Float,vy:Float)
  167. If ball3d ball3d.Rotate(vx,vy)
  168. End
  169. Method Reset:Void() Override
  170. If ball3d ball3d.Reset()
  171. End
  172. Method Render:Void(canvas:Canvas) Override
  173. canvas.Color = New Color(0.0,0.0,0.0)
  174. canvas.Alpha = .3
  175. canvas.DrawImage(Self.image,P.x+3.0,P.y-1.0,0)
  176. canvas.Alpha = 1.0
  177. canvas.Color = color
  178. canvas.DrawImage(image,P.x,P.y,0)
  179. canvas.Color = textColor
  180. If ball3d ball3d.Display(canvas,P.x,P.y)
  181. End
  182. End
  183. Class Ball3d
  184. Field distance:Float
  185. Field radius:Float
  186. Field nodeList:List<Node3d>
  187. Global numbers:Int[][][]
  188. Method Decorate:Void(n:Int)
  189. If(n=0)
  190. Return
  191. End
  192. Local s:String=String(n)
  193. Local len:Float=(s.Length)
  194. For Local i:Float=0.0 Until len
  195. Local t:Int=s[i]-48
  196. For Local yaw:Float=0.0 Until 8.0
  197. For Local pitch:Float=0.0 Until 5.0
  198. If numbers[t][yaw][pitch]
  199. Local node:Node3d= New Node3d()
  200. node.z= -Cos((-20.0 + yaw*7.0)*ATR)*Cos((-20.0+pitch*7.0)*ATR)*(radius-1.0)
  201. node.y= Cos((-20.0 * len+i*32.0+yaw*7.0)*ATR)*Sin((-20.0*len+i*30.0+pitch*8.0)*ATR)*(radius-1.0)
  202. node.x= Sin((-20.0 + yaw*7.0)*ATR)*(radius-1.0)
  203. node.sx=node.x
  204. node.sy=node.y
  205. node.sz=node.z
  206. node.link=nodeList.AddLast(node)
  207. Local node2:Node3d=New Node3d()
  208. node2.x=node.x
  209. node2.y=-node.y
  210. node2.z=-node.z
  211. node2.sx=node2.x
  212. node2.sy=node2.y
  213. node2.sz=node2.z
  214. node2.link=nodeList.AddLast(node2)
  215. End
  216. End
  217. End
  218. End
  219. If(n>8)
  220. For Local i2:Float=0.0 Until 360.0
  221. Local node3:Node3d= New Node3d()
  222. node3.x=Cos(0.0)*Cos(i2*ATR)*radius
  223. node3.y=Cos(0.0)*Sin(i2*ATR)*radius
  224. node3.z=Sin(0.0)*radius
  225. node3.sx=node3.x
  226. node3.sy=node3.y
  227. node3.sz=node3.z
  228. node3.link=nodeList.AddLast(node3)
  229. End
  230. End
  231. End
  232. Method New(n:Int,rad:Float)
  233. distance=500.0
  234. radius=rad
  235. nodeList=New List<Node3d>()
  236. If Not numbers.Length
  237. numbers=New Int[][][](New Int[][](New Int[](0,0,1,1,0),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,0,1,1,0),New Int[](0,0,0,0,0)),
  238. New Int[][](New Int[](0,0,1,0,0),New Int[](0,1,1,0,0),New Int[](0,0,1,0,0),New Int[](0,0,1,0,0),New Int[](0,0,1,0,0),New Int[](0,0,1,0,0),New Int[](0,1,1,1,0),New Int[](0,0,0,0,0)),
  239. New Int[][](New Int[](0,1,1,1,0),New Int[](0,1,0,0,1),New Int[](0,0,0,0,1),New Int[](0,0,0,1,0),New Int[](0,0,1,0,0),New Int[](0,1,0,0,0),New Int[](0,1,1,1,1),New Int[](0,0,0,0,0)),
  240. New Int[][](New Int[](0,1,1,1,0),New Int[](0,0,0,0,1),New Int[](0,0,0,0,1),New Int[](0,0,1,1,0),New Int[](0,0,0,0,1),New Int[](0,0,0,0,1),New Int[](0,1,1,1,0),New Int[](0,0,0,0,0)),
  241. New Int[][](New Int[](0,0,0,1,0),New Int[](0,0,1,1,0),New Int[](0,1,0,1,0),New Int[](1,0,0,1,0),New Int[](1,1,1,1,1),New Int[](0,0,0,1,0),New Int[](0,0,0,1,0),New Int[](0,0,0,0,0)),
  242. New Int[][](New Int[](0,1,1,1,1),New Int[](0,1,0,0,0),New Int[](0,1,0,0,0),New Int[](0,0,1,1,0),New Int[](0,0,0,0,1),New Int[](0,0,0,0,1),New Int[](0,1,1,1,0),New Int[](0,0,0,0,0)),
  243. New Int[][](New Int[](0,0,1,1,0),New Int[](0,1,0,0,0),New Int[](0,1,0,0,0),New Int[](0,1,0,1,0),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,0,1,1,0),New Int[](0,0,0,0,0)),
  244. New Int[][](New Int[](0,1,1,1,1),New Int[](0,0,0,0,1),New Int[](0,0,0,1,0),New Int[](0,0,1,0,0),New Int[](0,0,1,0,0),New Int[](0,0,1,0,0),New Int[](0,0,1,0,0),New Int[](0,0,0,0,0)),
  245. New Int[][](New Int[](0,0,1,1,0),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,0,1,1,0),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,0,1,1,0),New Int[](0,0,0,0,0)),
  246. New Int[][](New Int[](0,0,1,1,0),New Int[](0,1,0,0,1),New Int[](0,1,0,0,1),New Int[](0,0,1,1,1),New Int[](0,0,0,0,1),New Int[](0,1,0,0,1),New Int[](0,0,1,1,0),New Int[](0,0,0,0,0)))
  247. End
  248. Decorate(n)
  249. End
  250. Method Rotate_z(a:Float)
  251. If nodeList.Empty Return
  252. Local cx:Float=Cos(a*ATR)
  253. Local cy:Float=Sin(a*ATR)
  254. Local link:List<Node3d>.Node=nodeList.First.link
  255. While link.Value
  256. Local node:Node3d=link.Value
  257. Local tx:Float=node.x*cx-node.y*cy
  258. Local ty:Float=node.x*cy+node.y*cx
  259. node.y=ty
  260. node.x=tx
  261. link=link.Succ
  262. End
  263. End
  264. Method Rotate_y(a:Float)
  265. If nodeList.Empty Return
  266. Local cx:Float=Cos(a*ATR)
  267. Local cy:Float=Sin(a*ATR)
  268. Local link:List<Node3d>.Node = nodeList.FirstNode()
  269. While link.Value
  270. Local node:Node3d=link.Value
  271. Local tz:Float=node.z*cx-node.x*cy
  272. Local tx:Float=node.z*cy+node.x*cx
  273. node.z=tz
  274. node.x=tx
  275. link=link.Succ
  276. End
  277. End
  278. Method Rotate(vx:Float,vy:Float)
  279. Local roll:Float=Sqrt(vx*vx+vy*vy)
  280. Local rot:Float= ATan2(vy,vx) * RTA
  281. Self.Rotate_z(-rot)
  282. Self.Rotate_y(roll*radius)
  283. Self.Rotate_z(rot)
  284. End
  285. Method Reset()
  286. If nodeList.Empty Return
  287. Local link:List<Node3d>.Node=nodeList.FirstNode()
  288. While link.Value
  289. Local node:Node3d=link.Value
  290. node.x=node.sx
  291. node.y=node.sy
  292. node.z=node.sz
  293. link=link.Succ
  294. End
  295. End
  296. Method Display:Void(canvas:Canvas,x:Float,y:Float)
  297. If nodeList.Empty Return
  298. Local link:List<Node3d>.Node=nodeList.FirstNode()
  299. While link.Value
  300. Local node:Node3d=link.Value
  301. If(node.z>-1.0) canvas.DrawOval(x+node.x,y+node.y,1.0,1.0)
  302. link=link.Succ
  303. End
  304. End
  305. End
  306. Class Node3d
  307. Field z:Float
  308. Field y:Float
  309. Field x:Float
  310. Field sx:Float
  311. Field sy:Float
  312. Field sz:Float
  313. Field link:List<Node3d>.Node
  314. End
  315. Class RailAnimation
  316. Field jobList:List<Ball>
  317. Field settledList:List<RailBall>
  318. Field movingList:List<RailBall>
  319. Field stopPVector2Ds:Vec2D[]
  320. Field finalStop:Int=0
  321. Field showStops:Int=0
  322. Field index:Int=0
  323. Method New()
  324. jobList= New List<Ball>
  325. settledList= New List<RailBall>
  326. movingList= New List<RailBall>
  327. stopPVector2Ds=New Vec2D[](New Vec2D(375.0,340.0,366.0,370.0),New Vec2D(366.0,370.0,355.0,380.0),New Vec2D(355.0,380.0,325.0,380.0),
  328. New Vec2D(325.0,380.0,305.0,380.0),New Vec2D(305.0,380.0,285.0,380.0),New Vec2D(285.0,380.0,265.0,380.0),
  329. New Vec2D(265.0,380.0,245.0,380.0),New Vec2D(245.0,380.0,225.0,380.0),New Vec2D(225.0,380.0,205.0,380.0),
  330. New Vec2D(205.0,380.0,185.0,380.0),New Vec2D(185.0,380.0,165.0,380.0),New Vec2D(165.0,380.0,145.0,380.0),
  331. New Vec2D(145.0,380.0,125.0,380.0),New Vec2D(125.0,380.0,105.0,380.0),New Vec2D(105.0,380.0, 85.0,380.0),
  332. New Vec2D( 85.0,380.0, 65.0,380.0),New Vec2D( 65.0,380.0, 45.0,380.0),New Vec2D( 45.0,380.0, 25.0,380.0),
  333. New Vec2D( 25.0,380.0, 25.0,380.0))
  334. finalStop=18
  335. End
  336. Method ShowStops:Void(show:Int)
  337. showStops=show
  338. End
  339. Method Reset:Void()
  340. jobList.Clear()
  341. movingList.Clear()
  342. settledList.Clear()
  343. index=0
  344. finalStop=18
  345. End
  346. Method AddJob:Void(b:Ball)
  347. jobList.AddFirst(b)
  348. End
  349. Method RemoveCueBall:Void()
  350. If Not jobList.Empty
  351. For Local b:Ball = Eachin jobList
  352. If(b.num=16)
  353. jobList.RemoveEach(b)
  354. Return
  355. End
  356. End
  357. End
  358. If Not movingList.Empty
  359. For Local b2:RailBall = Eachin movingList
  360. If(b2.ball.num=16)
  361. movingList.RemoveEach(b2)
  362. Return
  363. End
  364. End
  365. End
  366. If Not settledList.Empty
  367. For Local b3:RailBall = Eachin settledList
  368. If(b3.ball.num=16)
  369. settledList.RemoveEach(b3)
  370. finalStop=b3.index
  371. End
  372. End
  373. End
  374. If Not settledList.Empty
  375. Local c:Int=0
  376. For Local b4:RailBall = Eachin settledList.Backwards()
  377. If(b4.index<finalStop)
  378. settledList.RemoveEach(b4)
  379. movingList.AddLast(b4)
  380. End
  381. End
  382. End
  383. End
  384. Method Update:Void(spd:Float)
  385. If movingList.Empty And jobList.Empty
  386. Return
  387. End
  388. If movingList.Empty
  389. Local b:Ball=jobList.RemoveLast()
  390. If(b<>Null)
  391. Local rb:RailBall=New RailBall(b,stopPVector2Ds[0].x,stopPVector2Ds[0].y)
  392. movingList.AddLast(rb)
  393. End
  394. Else
  395. If Not jobList.Empty
  396. Local rb2:RailBall=movingList.Last
  397. If((rb2)<>Null)
  398. Local vx1:Float=rb2.ball.P.x-stopPVector2Ds[0].x
  399. Local vy1:Float=rb2.ball.P.y-stopPVector2Ds[0].y
  400. Local dp:Float=vx1*stopPVector2Ds[0].dx+vy1*stopPVector2Ds[0].dy
  401. If(Abs(dp)>rb2.ball.radius+20.0)
  402. Local b2:Ball=jobList.RemoveLast()
  403. movingList.AddLast(New RailBall(b2,stopPVector2Ds[0].x,stopPVector2Ds[0].y))
  404. End
  405. End
  406. End
  407. End
  408. Local vx:Float=.0
  409. Local vy:Float=.0
  410. For Local rb3:RailBall = Eachin movingList
  411. vx=stopPVector2Ds[rb3.index].dx*spd
  412. vy=stopPVector2Ds[rb3.index].dy*spd
  413. rb3.ball.P.x+=vx
  414. rb3.ball.P.y+=vy
  415. End
  416. For Local rb4:RailBall = Eachin movingList
  417. If(rb4.index<finalStop)
  418. Local vx12:Float=rb4.ball.P.x-stopPVector2Ds[rb4.index].x
  419. Local vy12:Float=rb4.ball.P.y-stopPVector2Ds[rb4.index].y
  420. Local dp1:Float=vx12*stopPVector2Ds[rb4.index].dx+vy12*stopPVector2Ds[rb4.index].dy
  421. If(Abs(dp1)>=stopPVector2Ds[rb4.index].len)
  422. Local len:Float=Abs(dp1)-stopPVector2Ds[rb4.index].len
  423. vx12=stopPVector2Ds[rb4.index].dx*stopPVector2Ds[rb4.index].len
  424. vy12=stopPVector2Ds[rb4.index].dy*stopPVector2Ds[rb4.index].len
  425. rb4.ball.P.x=stopPVector2Ds[rb4.index].x+vx12
  426. rb4.ball.P.y=stopPVector2Ds[rb4.index].y+vy12
  427. rb4.animation.Rotate(vx*1.2,vy*1.2)
  428. rb4.index+=1
  429. If(rb4.index=finalStop)
  430. movingList.RemoveEach(rb4)
  431. settledList.AddLast(rb4)
  432. rb4.animation.Rotate(vx*1.2,vy*1.2)
  433. If(finalStop<18)
  434. media.PlayBallCol(2)
  435. End
  436. finalStop-=1
  437. Else
  438. vx12=stopPVector2Ds[rb4.index].dx*len
  439. vy12=stopPVector2Ds[rb4.index].dy*len
  440. rb4.ball.P.x+=stopPVector2Ds[rb4.index].dx*len
  441. rb4.ball.P.y+=stopPVector2Ds[rb4.index].dy*len
  442. End
  443. Else
  444. rb4.animation.Rotate(vx,vy)
  445. End
  446. Else
  447. If(rb4.index=finalStop)
  448. movingList.RemoveEach(rb4)
  449. rb4.index=finalStop
  450. rb4.ball.P.x=stopPVector2Ds[finalStop].x
  451. rb4.ball.P.y=stopPVector2Ds[finalStop].y
  452. settledList.AddLast(rb4)
  453. End
  454. End
  455. End
  456. End
  457. Method Render:Void(canvas:Canvas)
  458. If showStops=1
  459. canvas.Color = New Color(.95,.95,.4) '(240.0,240.0,100.0)
  460. Local i:Int=0
  461. While(i < stopPVector2Ds.Length)
  462. Local stop:Vec2D=stopPVector2Ds[i]
  463. canvas.DrawCircle(stop.x,stop.y,3.0)
  464. canvas.DrawLine(stop.x,stop.y,stop.x+stop.dx*stop.len,stop.y+stop.dy*stop.len)
  465. i=i+1
  466. End
  467. End
  468. For Local railBall:RailBall = Eachin settledList
  469. railBall.Render(canvas)
  470. End
  471. For Local moving:RailBall = Eachin movingList
  472. moving.Render(canvas)
  473. End
  474. End
  475. End
  476. Class RailBall
  477. Field ball:Ball
  478. Field index:Int=0
  479. Field animation:ABall3D
  480. Method New(b:Ball,x:Float,y:Float)
  481. b.P.x=x
  482. b.P.y=y
  483. ball=b
  484. animation=Cast<ABall3D>(b.animation)
  485. index=0
  486. End
  487. Method Render:Void(canvas:Canvas)
  488. ball.Render(canvas)
  489. End
  490. End