pool.monkey2 43 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763
  1. #Import "PoolMod/PoolMod"
  2. Function Main()
  3. New AppInstance
  4. New Game
  5. App.Run()
  6. End
  7. Class Game Extends Window
  8. Field state:Int=0
  9. Field fontImg:Image[]
  10. Field frame1:FrameAnimation
  11. Field frame2:FrameAnimation
  12. Field pvcBtn:Button2
  13. Field pvpBtn:Button2
  14. Field soloBtn:Button2
  15. Field scores:Button2
  16. Field pool8:Pool
  17. Field poolSolo:Pool
  18. Field alpha:Float=.0
  19. Field started:Int=0
  20. Field down:Int=0
  21. Field pool:Pool
  22. Method New(title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null)
  23. Super.New( title,width,height,flags )
  24. state=1
  25. atlasImg=Image.Load("asset::poolAtlasb.png")
  26. If atlasImg = Null RuntimeError("Unable to load poolatlasb.png")
  27. media=New Media(atlasImg)
  28. LargeText=New VaryFont(atlasImg)
  29. fontImg=LoadFrames(atlasImg,0,512,10,16,96)
  30. If Not fontImg RuntimeError("Unable to load fontImg.png")
  31. SetFont(fontImg,32)
  32. Text=New BitmapText(fontImg,77)
  33. frame1=New FrameAnimation(media,50,50,DEVICE_WIDTH-100,DEVICE_HEIGHT-100,2,40)
  34. frame2=New FrameAnimation(media,50,20,DEVICE_WIDTH-100,DEVICE_HEIGHT-40,0,40)
  35. Local buttonImg:Image[]=media.buttonImg
  36. pvcBtn=New Button2(buttonImg,(DEVICE_WIDTH-buttonImg[0].Width)/2,120,"VS Computer",Null)
  37. pvpBtn=New Button2(buttonImg,(DEVICE_WIDTH-buttonImg[0].Width)/2,200,"VS Player",Null)
  38. soloBtn=New Button2(buttonImg,(DEVICE_WIDTH-buttonImg[0].Width)/2,280,"VS Time",Null)
  39. scores=New Button2(buttonImg,(DEVICE_WIDTH-buttonImg[0].Width)/2,360,"Scores",Null)
  40. inputName=New TextFieldGui(150,150,"Player 1",Null,200)
  41. pool8= New EightBall()
  42. poolSolo= New PoolSoloTime()
  43. scoreTableVsTime= New ScoreTable("scoreTable.dat")
  44. alpha=0.0
  45. started=1
  46. frame1.Init()
  47. End
  48. Method OnUpdate:Int()
  49. If Mouse.ButtonDown(MouseButton.Left) Self.down=1
  50. If state=1
  51. If(Mouse.ButtonDown(MouseButton.Left)=0 And down=1)
  52. frame2.Init()
  53. alpha=0
  54. down=0
  55. state=2
  56. End
  57. ElseIf state=2
  58. pvcBtn.Update()
  59. pvpBtn.Update()
  60. soloBtn.Update()
  61. scores.Update()
  62. If True = pvcBtn.GetState()
  63. pool=pool8
  64. pool.SetupPVC()
  65. state=6
  66. pool.Reset()
  67. Elseif True = pvpBtn.GetState()
  68. pool = pool8
  69. pool.SetupPVP()
  70. state = 6
  71. pool.Reset()
  72. Elseif True = soloBtn.GetState()
  73. pool = poolSolo
  74. pool.SetupTimed()
  75. state=6
  76. pool.InitGame()
  77. Elseif True = scores.GetState()
  78. state=7
  79. scoreTableVsTime.InitFrame()
  80. End
  81. ElseIf(state=6)
  82. If pool.Update()=0
  83. Self.state=7
  84. Local record:Record=Self.pool.GetRecord()
  85. scoreTableVsTime.SetRecord(record)
  86. scoreTableVsTime.SaveTable()
  87. scoreTableVsTime.InitFrame()
  88. End
  89. ElseIf state=7
  90. If scoreTableVsTime.Update()=False
  91. Self.frame2.Init()
  92. Self.alpha=0
  93. Self.down=0
  94. Self.state=2
  95. End
  96. Elseif(state=4)
  97. End
  98. Return 1
  99. End
  100. Method OnRender(canvas:Canvas) Override
  101. OnUpdate()
  102. App.RequestRender()
  103. canvas.Color = New Color(1,1,1)
  104. canvas.DrawImage(media.titleImg,0.0,0.0)
  105. If(state=1)
  106. Self.frame1.Render(canvas)
  107. If(started=1)
  108. canvas.Color = New Color(1,1,1)
  109. canvas.DrawImage(media.titleImg,0.0,0.0)
  110. Self.started=0
  111. Else
  112. If Self.frame1.Update()=0
  113. canvas.DrawImage(media.logoImg,180.0,60.0)
  114. Local str:String="HEXOBOT"
  115. Local x:Int=(DEVICE_WIDTH-LargeText.TextWidth(str))/2
  116. Local y:Int=340
  117. If(Self.alpha<1.0)
  118. canvas.Alpha = alpha
  119. Self.alpha+=.02
  120. End
  121. str="Touch To Continue"
  122. canvas.Color = New Color(1,1,1)
  123. x= (DEVICE_WIDTH-Text.Width(str))/2
  124. y=DEVICE_HEIGHT-80
  125. Text.Draw(canvas,str,x,y)
  126. End
  127. End
  128. canvas.Alpha = 1.0
  129. ElseIf(state=2)
  130. Self.frame2.Render(canvas)
  131. If(Self.frame2.Update()=0)
  132. canvas.DrawImage(media.logoImg,180.0,60.0,0)
  133. If(Self.alpha<1.0)
  134. canvas.Alpha = alpha
  135. alpha+=0.02
  136. End
  137. pvcBtn.Render(canvas)
  138. pvpBtn.Render(canvas)
  139. soloBtn.Render(canvas)
  140. scores.Render(canvas)
  141. End
  142. canvas.Alpha = 1.0
  143. Elseif(state=6)
  144. Self.pool.Render(canvas)
  145. Elseif(state=7)
  146. scoreTableVsTime.Render(canvas)
  147. End
  148. End
  149. End
  150. Global atlasImg:Image
  151. Global inputName:TextFieldGui
  152. Class Pool
  153. Field engine:ElasticEngine
  154. Field ballList:List<Ball>
  155. Field arcList:List<ArcWall>
  156. Field pottedList:List<Ball>
  157. Field turnList:List<Ball>
  158. Field tableImg:Image
  159. Field arrowsImg:Image
  160. Field ballImg:Image
  161. Field railAnimation:RailAnimation
  162. Field Exiting:Int=0
  163. Field player:Record
  164. Field state:Int=0
  165. Field cue:Ball
  166. Field activePlayer:User
  167. Field otherPlayer:User
  168. Field incrementer:Int=0
  169. Field scoreLevel:Int=1
  170. Field maxLevel:Int=15
  171. Field decrementer:Int=0
  172. Field user:User
  173. Field minLevel:Int
  174. Method Setup16()
  175. For Local a:ArcWall = Eachin arcList
  176. Select a.num
  177. Case 1 a.SetTarget(a.P.x+16.0,a.P.y+16.0)
  178. Case 2 a.SetTarget(a.P.x,a.P.y+15.0)
  179. Case 3 a.SetTarget(a.P.x-16.0,a.P.y+16.0)
  180. Case 4 a.SetTarget(a.P.x-16.0,a.P.y-16.0)
  181. Case 5 a.SetTarget(a.P.x,a.P.y-15.0)
  182. Case 6 a.SetTarget(a.P.x+16.0,a.P.y-16.0)
  183. End Select
  184. Next
  185. Self.engine.Add3DBall(180.8,180.0,10.0,0.0,0.0,media.ballImg,new Color(1,1,.1),new Color(.6,.2,.6),1,0)
  186. Self.engine.Add3DBall(162.6,170.0,10.0,0.0,0.0,media.ballImg,new Color(.3,.3,1),new Color(1,1,0),2,0)
  187. Self.engine.Add3DBall(162.6,190.0,10.0,0.0,0.0,media.ballImg,new Color(1,.25,.25),new Color(1,1,0),3,0)
  188. Self.engine.Add3DBall(144.4,160.0,10.0,0.0,0.0,media.ballImg,new Color(.35,.2,1),new Color(1,1,0),4,0)
  189. Self.engine.Add3DBall(144.4,200.0,10.0,0.0,0.0,media.ballImg,new Color(1,.35,.12),new Color(0,1,1),5,0)
  190. Self.engine.Add3DBall(126.2,150.0,10.0,0.0,0.0,media.ballImg,new Color(.12,.8,.12),New Color(0,0,1),6,0)
  191. Self.engine.Add3DBall(126.2,170.0,10.0,0.0,0.0,media.ballImg,new Color(.8,.1,.1),new Color(.9,.9,.9),7,0)
  192. Self.engine.Add3DBall(144.4,180.0,10.0,0.0,0.0,media.ballImg,new Color(.35,.35,.35),new Color(.93,.93,.93),8,0)
  193. Self.engine.Add3DBall(126.2,190.0,10.0,0.0,0.0,media.ballImg,new Color(1,1,.1),new Color(.6,.2,.6),9,0)
  194. Self.engine.Add3DBall(126.2,210.0,10.0,0.0,0.0,media.ballImg,new Color(.3,.3,1),new Color(1,1,0),10,0)
  195. Self.engine.Add3DBall(108.0,140.0,10.0,0.0,0.0,media.ballImg,new Color(1,.25,.25),new Color(1,1,0),11,0)
  196. Self.engine.Add3DBall(108.0,160.0,10.0,0.0,0.0,media.ballImg,new Color(.35,.2,1),new Color(1,1,0),12,0)
  197. Self.engine.Add3DBall(108.0,180.0,10.0,0.0,0.0,media.ballImg,new Color(1,.35,.12),new Color(0,1,1),13,0)
  198. Self.engine.Add3DBall(108.0,200.0,10.0,0.0,0.0,media.ballImg,new Color(.12,.8,.12),New Color(0,0,1),14,0)
  199. Self.engine.Add3DBall(108.0,220.0,10.0,0.0,0.0,media.ballImg,new Color(.8,.1,.1),new Color(.9,.9,.9),15,0)
  200. Self.cue=Self.engine.Add3DBall(490.0,180.0,10.0,-15.0,0.05,media.ballImg,new Color(1,1,1),new Color(.6,.2,.6),16,0)
  201. End
  202. Method SetupPVC() Abstract
  203. Method Reset() Abstract
  204. Method SetupPVP() Abstract
  205. Method SetupTimed() Abstract
  206. Method InitGame() Abstract
  207. Method Update:Int() Abstract
  208. Method GetRecord:Record()
  209. Return Self.player
  210. End
  211. Method Render(canvas:Canvas) Abstract
  212. Method BallInHole()
  213. For Local a:ArcWall = Eachin arcList
  214. For Local b:Ball = Eachin ballList
  215. If(a.BallInside(b))
  216. engine.RemoveBall(b)
  217. pottedList.AddLast(b)
  218. turnList.AddLast(b)
  219. railAnimation.AddJob(b)
  220. media.PlayPocketCol()
  221. If(b.num<16)
  222. incrementer+=5000
  223. player.score+=scoreLevel*100
  224. scoreLevel+=1
  225. If scoreLevel>maxLevel scoreLevel=maxLevel
  226. player.IncrementPocketed()
  227. Else
  228. decrementer += 30000
  229. media.PlayScratch()
  230. End
  231. End
  232. End
  233. End
  234. End
  235. Method ListContains:Bool(list:List<Ball>,num:Int)
  236. For Local b2:Ball = Eachin list
  237. If(b2.num=num)
  238. Return True
  239. End
  240. End
  241. Return False
  242. End
  243. Method ListContains:Bool(list:List<Ball>,b:Ball)
  244. For Local b2:Ball = Eachin list
  245. If(b2=b) Return True
  246. Next
  247. Return False
  248. End
  249. Method RestoreCue() Virtual
  250. state=9
  251. cue.Init(0,0)
  252. cue.SetPosition(490,180)
  253. turnList.RemoveEach(cue)
  254. pottedList.RemoveEach(cue)
  255. railAnimation.RemoveCueBall()
  256. engine.AddBall(cue)
  257. End
  258. Method ListContainsSolids:Bool(list:List<Ball>)
  259. For Local b:Ball = Eachin list
  260. If(b.num<8) Return True
  261. End
  262. Return False
  263. End
  264. Method ListContainsStripes:Bool(list:List<Ball>)
  265. For Local b:Ball = Eachin list
  266. If(b.num>8 And b.num<16) Return True
  267. End
  268. Return False
  269. End
  270. End
  271. Class EightBall Extends Pool
  272. Field inacuracy:Float
  273. Field timeFrame:Float
  274. Field lastTime:Float
  275. Field down:Int=0
  276. Field finalText1:String=""
  277. Field finalText2:String=""
  278. Method Init()
  279. Self.Exiting=1
  280. End
  281. Method New()
  282. inacuracy=0.4
  283. engine=New ElasticEngine()
  284. engine.SetGravity(0.0,0.0)
  285. engine.SetFriction(0.98)
  286. ballList=Self.engine.ballList
  287. arcList=New List<ArcWall>
  288. pottedList= New List<Ball>
  289. turnList=New List<Ball>
  290. tableStorage= New TableStorage()
  291. tableStorage.GetTable(0,Self.engine,Self.arcList)
  292. tableImg=media.tableImg
  293. arrowsImg=media.arrowsImg
  294. ballImg=media.ballImg
  295. railAnimation=New RailAnimation()
  296. railAnimation.ShowStops(0)
  297. Init()
  298. player=New Record()
  299. state=1
  300. Setup16()
  301. lastTime = Millisecs()
  302. End
  303. Method SetupTimed() Override
  304. RuntimeError("invald attemp to create 8ball pool timed")
  305. End
  306. Method SetupPVC() Override
  307. Self.activePlayer= New Player("Player 1",cue,engine,media.ghostImg,media.ballImg,media.stickImg,media.rotatorImg,media.buttonImg,media.stripImg,media.frameTopImg,media.frameBotImg,media.topImg,media.botImg,media.lrImg,media.meterImg,media.stretchImg,media.sliderImg)
  308. Self.otherPlayer= New Cpu("Cpu",cue,engine,arcList,media.stickImg,media.ballImg,inacuracy)
  309. End
  310. Method SetupPVP() Override
  311. Self.activePlayer=New Player("Player 1",cue,engine,media.ghostImg,media.ballImg,media.stickImg,media.rotatorImg,media.buttonImg,media.stripImg,media.frameTopImg,media.frameBotImg,media.topImg,media.botImg,media.lrImg,media.meterImg,media.stretchImg,media.sliderImg)
  312. Self.otherPlayer=New Player("Player 2",cue,engine,media.ghostImg,media.ballImg,media.stickImg,media.rotatorImg,media.buttonImg,media.stripImg,media.frameTopImg,media.frameBotImg,media.topImg,media.botImg,media.lrImg,media.meterImg,media.stretchImg,media.sliderImg)
  313. End
  314. Method InitGame() Override
  315. End
  316. Method Reset() Override
  317. For Local b:Ball= Eachin Self.pottedList
  318. Self.engine.AddBall(b)
  319. Self.pottedList.RemoveEach(b)
  320. End
  321. Self.turnList.Clear()
  322. Self.railAnimation.Reset()
  323. For Local b2:Ball = Eachin Self.ballList
  324. b2.Init(0.0,0.0)
  325. If(b2.num=1)
  326. b2.SetPosition(180.8,180.0)
  327. ElseIf(b2.num=2)
  328. b2.SetPosition(162.6,170.0)
  329. ElseIf(b2.num=3)
  330. b2.SetPosition(162.6,190.0)
  331. ElseIf(b2.num=4)
  332. b2.SetPosition(144.4,160.0)
  333. ElseIf(b2.num=5)
  334. b2.SetPosition(144.4,200.0)
  335. ElseIf(b2.num=6)
  336. b2.SetPosition(126.2,150.0)
  337. ElseIf(b2.num=7)
  338. b2.SetPosition(126.2,170.0)
  339. ElseIf(b2.num=8)
  340. b2.SetPosition(144.4,180.0)
  341. ElseIf(b2.num=9)
  342. b2.SetPosition(126.2,190.0)
  343. ElseIf(b2.num=10)
  344. b2.SetPosition(126.2,210.0)
  345. ElseIf(b2.num=11)
  346. b2.SetPosition(108.0,140.0)
  347. ElseIf(b2.num=12)
  348. b2.SetPosition(108.0,160.0)
  349. ElseIf(b2.num=13)
  350. b2.SetPosition(108.0,180.0)
  351. ElseIf(b2.num=14)
  352. b2.SetPosition(108.0,200.0)
  353. ElseIf(b2.num=15)
  354. b2.SetPosition(108.0,220.0)
  355. ElseIf(b2.num=16)
  356. b2.SetPosition(490.0,180.0)
  357. End
  358. b2.ResetAnimation()
  359. Next
  360. Self.state=2
  361. Self.Exiting=1
  362. Self.down=False
  363. End
  364. Method AssignBalls()
  365. For Local b:Ball = Eachin Self.turnList
  366. If(Self.activePlayer.OwnsSolids())
  367. If(b.num<=8)
  368. Self.activePlayer.AddBall(b)
  369. Else
  370. If(b.num>8)
  371. Self.otherPlayer.AddBall(b)
  372. End
  373. End
  374. Else
  375. If(Self.activePlayer.OwnsStripes())
  376. If(b.num>=8)
  377. Self.activePlayer.AddBall(b)
  378. Else
  379. Self.otherPlayer.AddBall(b)
  380. End
  381. Else
  382. If(b.num<8)
  383. Self.activePlayer.SetToSolids()
  384. Self.otherPlayer.SetToStripes()
  385. Self.activePlayer.AddBall(b)
  386. Else
  387. If(b.num>8)
  388. Self.activePlayer.SetToStripes()
  389. Self.otherPlayer.SetToSolids()
  390. Self.activePlayer.AddBall(b)
  391. Else
  392. Self.activePlayer.AddBall(b)
  393. End
  394. End
  395. End
  396. End
  397. End
  398. End
  399. Method ResolveTurn()
  400. If Self.turnList.Empty
  401. Self.Exiting=0
  402. Self.state=10
  403. Return
  404. End
  405. Self.state=3
  406. If(Self.Exiting=1)
  407. For Local b:Ball = Eachin turnList
  408. If(b.num<8)
  409. activePlayer.SetToSolids()
  410. otherPlayer.SetToStripes()
  411. Exit
  412. End
  413. If(b.num>8 And b.num<16)
  414. activePlayer.SetToStripes()
  415. otherPlayer.SetToSolids()
  416. Exit
  417. End
  418. End
  419. If ListContains(turnList,cue)
  420. state=9
  421. If ListContains(turnList,8)
  422. state=7
  423. Else
  424. RestoreCue()
  425. End
  426. Else
  427. If(ListContains(Self.turnList,8))
  428. state=6
  429. End
  430. End
  431. For Local b2:Ball = Eachin turnList
  432. If(activePlayer.OwnsSolids())
  433. If b2.num<=8
  434. activePlayer.AddBall(b2)
  435. Elseif b2.num>8 And b2.num<16
  436. otherPlayer.AddBall(b2)
  437. Else
  438. RestoreCue()
  439. End
  440. Else
  441. If activePlayer.OwnsStripes()
  442. If b2.num>=8 And b2.num<16
  443. activePlayer.AddBall(b2)
  444. Elseif b2.num<8
  445. otherPlayer.AddBall(b2)
  446. Else
  447. RestoreCue()
  448. End
  449. ElseIf b2.num=8
  450. activePlayer.AddBall(b2)
  451. End
  452. End
  453. End
  454. Self.Exiting=0
  455. Else
  456. Local b3:Ball=engine.GetFirstCollision()
  457. If activePlayer.CompletedSet()=True
  458. If ListContains(turnList,8)
  459. state=6
  460. If ListContains(turnList,cue) state=7
  461. If activePlayer.OwnsSolids()
  462. If b3.num>8 And b3.num<16 state=7
  463. Else
  464. If b3.num<8 Self.state=7
  465. End
  466. Else
  467. If ListContains(turnList,cue)
  468. state=7
  469. Else
  470. state=10
  471. End
  472. End
  473. Else
  474. If b3<>Null
  475. If b3.num<8 And activePlayer.OwnsStripes() state=10
  476. If b3.num>8 And b3.num<16 And activePlayer.OwnsSolids() state=10
  477. End
  478. If activePlayer.OwnsSolids()
  479. If ListContainsSolids(turnList)=False state=10
  480. Else
  481. If activePlayer.OwnsStripes()
  482. If ListContainsStripes(turnList)=False state=10
  483. End
  484. End
  485. If ListContains(turnList,cue) RestoreCue()
  486. If ListContains(turnList,8) state=7
  487. Self.AssignBalls()
  488. End
  489. End
  490. Self.turnList.Clear()
  491. Return
  492. End
  493. Method SwitchPlayers()
  494. Self.user=activePlayer
  495. Self.activePlayer=otherPlayer
  496. Self.otherPlayer=user
  497. End
  498. Method Update:Int() Override
  499. Local SelfTime:Float = Millisecs()
  500. timeFrame=(SelfTime-lastTime)/30.0
  501. lastTime=SelfTime
  502. Local done:Int=0
  503. If state=1
  504. state=2
  505. activePlayer.SetButtonText("position")
  506. activePlayer.Init()
  507. ElseIf state=2
  508. If Not activePlayer.Positioning()
  509. state=3
  510. activePlayer.SetButtonText("Shoot")
  511. activePlayer.Init()
  512. End
  513. ElseIf state=3
  514. If Not activePlayer.Aiming()
  515. state=4
  516. End
  517. ElseIf state=4
  518. If Not activePlayer.ShootingAnimating()
  519. lastTime=(Millisecs())
  520. state=5
  521. End
  522. ElseIf state=5
  523. engine.Update(timeFrame)
  524. BallInHole()
  525. If Not engine.BallsMoving()
  526. ResolveTurn()
  527. engine.ClearFirstCollision()
  528. activePlayer.Init()
  529. End
  530. ElseIf state=10
  531. SwitchPlayers()
  532. activePlayer.Init()
  533. state=3
  534. ElseIf state=9
  535. SwitchPlayers()
  536. activePlayer.SetButtonText("position")
  537. activePlayer.Init()
  538. state=2
  539. ElseIf state=6
  540. finalText1=activePlayer.name+" WINS GAME"
  541. finalText2=otherPlayer.name+" LOST GAME"
  542. state=8
  543. ElseIf state=7
  544. finalText1=otherPlayer.name+" WINS GAME"
  545. finalText2=activePlayer.name+" LOST GAME"
  546. state=8
  547. ElseIf state=8
  548. If Mouse.ButtonDown(MouseButton.Left) down=1
  549. If Not Mouse.ButtonDown(MouseButton.Left) And down=1 done=1
  550. Endif
  551. railAnimation.Update(timeFrame*2.0)
  552. Return Not done
  553. End Method
  554. Method Render(canvas:Canvas) Override
  555. canvas.DrawImage(media.railImg,5.0,360.0,0)
  556. Self.railAnimation.Render(canvas)
  557. canvas.Color = New Color(1,1,1)
  558. canvas.DrawImage(Self.tableImg,0.0,0.0,0)
  559. Self.engine.Render(canvas)
  560. canvas.Color = New Color(1,1,1)
  561. If(state=2)
  562. canvas.Alpha = .2
  563. canvas.DrawRect(466.0,37.0,140.0,288.0)
  564. canvas.Alpha = .3
  565. canvas.DrawImage(arrowsImg,cue.P.x,cue.P.y,0)
  566. canvas.Alpha = 1.0
  567. activePlayer.RenderButton(canvas)
  568. Elseif state=4 Or state=3
  569. activePlayer.Render(canvas,1)
  570. ElseIf state=8
  571. Text.Draw(canvas,finalText1,200,100)
  572. Text.Draw(canvas,finalText2,200,150)
  573. End
  574. Local x:Float=25.0
  575. canvas.Color = New Color(1,1,1)
  576. End
  577. End
  578. Class TableStorage
  579. Field currentTable:Int=0
  580. Method New()
  581. Self.currentTable=-1
  582. End
  583. Field table:Table
  584. Method GetTable:Table(index:Int,engine:ElasticEngine,arcList:List<ArcWall>)
  585. If currentTable=index
  586. Return Self.table
  587. Else
  588. If(index<1 And index>-1)
  589. If index = 0
  590. engine.RemoveWalls()
  591. Local wall:Wall[]=New Wall[](New Arc(28.0,28.0,17.0,135.0,315.0,0.0,0.0,media.arcImg,New Color(1,0,0)),
  592. New Line(41.0,17.0,58.0,34.0,media.lineImg,new Color(1,0,0)),
  593. New Line(59.0,34.0,296.0,34.0,media.lineImg,new Color(1,0,0)),
  594. New Line(296.0,33.0,303.0,25.0,media.lineImg,new Color(1,0,0)),
  595. New Line(303.0,24.0,303.0,19.0,media.lineImg,new Color(1,0,0)),
  596. New Arc(320.0,18.0,17.0,180.0,360.0,0.0,0.0,media.arcImg,new Color(1,0,0)),
  597. New Line(338.0,19.0,338.0,24.0,media.lineImg,new Color(1,0,0)),
  598. New Line(337.0,25.0,345.0,33.0,media.lineImg,new Color(1,0,0)),
  599. New Line(345.0,34.0,582.0,34.0,media.lineImg,new Color(1,0,0)),
  600. New Line(583.0,33.0,599.0,17.0,media.lineImg,new Color(1,0,0)),
  601. New Arc(612.0,28.0,17.0,225.0,405.0,0.0,0.0,media.arcImg,new Color(1,0,0)),
  602. New Line(624.0,41.0,609.0,57.0,media.lineImg,new Color(1,0,0)),
  603. New Line(608.0,57.0,608.0,304.0,media.lineImg,new Color(1,0,0)),
  604. New Line(609.0,305.0,624.0,320.0,media.lineImg,new Color(1,0,0)),
  605. New Arc(613.0,333.0,17.0,-45.0,135.0,0.0,0.0,media.arcImg,new Color(1,0,0)),
  606. New Line(599.0,344.0,584.0,328.0,media.lineImg,new Color(1,0,0)),
  607. New Line(584.0,327.0,345.0,327.0,media.lineImg,new Color(1,0,0)),
  608. New Line(344.0,328.0,338.0,335.0,media.lineImg,new Color(1,0,0)),
  609. New Line(338.0,336.0,338.0,341.0,media.lineImg,new Color(1,0,0)),
  610. New Arc(320.0,342.0,17.0,0.0,180.0,0.0,0.0,media.arcImg,new Color(1,0,0)),
  611. New Line(303.0,341.0,303.0,336.0,media.lineImg,new Color(1,0,0)),
  612. New Line(303.0,335.0,296.0,328.0,media.lineImg,new Color(1,0,0)),
  613. New Line(295.0,327.0,59.0,327.0,media.lineImg,new Color(1,0,0)),
  614. New Line(58.0,328.0,41.0,344.0,media.lineImg,new Color(1,0,0)),
  615. New Arc(27.0,333.0,17.0,45.0,225.0,0.0,0.0,media.arcImg,new Color(1,0,0)),
  616. New Line(16.0,320.0,31.0,305.0,media.lineImg,new Color(1,0,0)),
  617. New Line(33.0,304.0,33.0,58.0,media.lineImg,new Color(1,0,0)),
  618. New Line(32.0,57.0,17.0,43.0,media.lineImg,new Color(1,0,0)))
  619. table=New Table(wall,engine,arcList)
  620. Return table
  621. End
  622. End
  623. End
  624. Return Null
  625. End
  626. End
  627. Global tableStorage:TableStorage
  628. Class Table
  629. Method New(wall:Wall[],engine:ElasticEngine,arcList:List<ArcWall>)
  630. Local n:Int=1, t:Int=0
  631. While(t < wall.Length)
  632. Local w:Wall=wall[t]
  633. t=t+1
  634. If w.name ="Line"
  635. Local l:Line=Cast<Line>(w)
  636. If l.image
  637. engine.AddLineWallImage(l.x1,l.y1,l.x2,l.y2,w.image,New Color(0,0,0))
  638. Else
  639. engine.AddLineWallOutline(l.x1,l.y1,l.x2,l.y2,Null,l.color)
  640. Endif
  641. ElseIf w.name ="Arc"
  642. Local a:Arc=Cast<Arc>(w)
  643. If a.image
  644. Local w:ArcWall=engine.AddArcWallImage(a.x1,a.y1,a.radius,a.startAngle,a.endAngle,a.image,New Color(1,1,1))
  645. arcList.AddLast(w)
  646. w.num=n
  647. n+=1
  648. Else
  649. Local w:ArcWall=engine.AddArcWallOutline(a.x1,a.y1,a.radius,a.startAngle,a.endAngle,a.color)
  650. If arcList = Null Then RuntimeError("arclist not initialized")
  651. arcList.AddLast(w)
  652. w.num=n
  653. n+=1
  654. Endif
  655. ElseIf(w.name ="Circle")
  656. Endif
  657. End
  658. End
  659. End
  660. Class PoolSoloTime Extends Pool
  661. Field blinkOn:Int=0
  662. Field timed:Int
  663. Field minutes:Int
  664. Field seconds:Int
  665. Field lastTime:Float
  666. Field timeFrame:Float
  667. Field blinkTime:Int
  668. Field blink:Int
  669. Field oldTime:Int
  670. Field endTime:Int=0
  671. Field time:Int=0
  672. Field down:Int=0
  673. Method New()
  674. Self.engine=New ElasticEngine()
  675. Self.engine.SetGravity(0.0,0.0)
  676. ' Self.engine.SetFriction(0.970)
  677. Self.ballList=Self.engine.ballList
  678. Self.arcList=New List<ArcWall>
  679. Self.pottedList= New List<Ball>
  680. Self.turnList= New List<Ball>
  681. tableStorage= New TableStorage()
  682. tableStorage.GetTable(0,Self.engine,Self.arcList)
  683. Self.tableImg=media.tableImg
  684. Self.arrowsImg=media.arrowsImg
  685. Self.ballImg=media.ballImg
  686. Self.railAnimation=New RailAnimation()
  687. Self.railAnimation.ShowStops(0)
  688. Self.Exiting=1
  689. Self.Setup16()
  690. Self.player=New Record()
  691. Self.player.SetName("Player")
  692. Self.blinkOn=0
  693. End
  694. Method SetupPVC() Override
  695. RuntimeError("invalid Setup in Solo Play")
  696. End
  697. Method SetupPVP() Override
  698. RuntimeError("invalid Setup in Solo Play")
  699. End
  700. Method InitTime()
  701. Self.endTime=Millisecs()+180000
  702. Self.time=180000
  703. End
  704. Method SetupTimed() Override
  705. Self.activePlayer= New Player("",cue,engine,media.ghostImg, media.ballImg,media.stickImg,media. rotatorImg,media.buttonImg,media.stripImg, media.frameTopImg,media. frameBotImg,media. topImg,media. botImg, media.lrImg, media.meterImg,media.stretchImg,media.sliderImg)
  706. Self.InitTime()
  707. End
  708. Method Reset() Override
  709. For Local b:Ball = Eachin Self.pottedList
  710. Self.engine.AddBall(b)
  711. Self.pottedList.RemoveEach(b)
  712. End
  713. Self.turnList.Clear()
  714. Self.railAnimation.Reset()
  715. For Local b2:Ball = Eachin Self.ballList
  716. b2.Init(0.0,0.0)
  717. If b2.num=1
  718. b2.SetPosition(180.8,180.0)
  719. Elseif(b2.num=2)
  720. b2.SetPosition(162.6,170.0)
  721. Elseif(b2.num=3)
  722. b2.SetPosition(162.6,190.0)
  723. Elseif(b2.num=4)
  724. b2.SetPosition(144.4,160.0)
  725. Elseif(b2.num=5)
  726. b2.SetPosition(144.4,200.0)
  727. Elseif(b2.num=6)
  728. b2.SetPosition(126.2,150.0)
  729. Elseif(b2.num=7)
  730. b2.SetPosition(126.2,170.0)
  731. Elseif(b2.num=8)
  732. b2.SetPosition(144.4,180.0)
  733. Elseif(b2.num=9)
  734. b2.SetPosition(126.2,190.0)
  735. Elseif(b2.num=10)
  736. b2.SetPosition(126.2,210.0)
  737. Elseif(b2.num=11)
  738. b2.SetPosition(108.0,140.0)
  739. Elseif(b2.num=12)
  740. b2.SetPosition(108.0,160.0)
  741. Elseif(b2.num=13)
  742. b2.SetPosition(108.0,180.0)
  743. Elseif(b2.num=14)
  744. b2.SetPosition(108.0,200.0)
  745. Elseif(b2.num=15)
  746. b2.SetPosition(108.0,220.0)
  747. End
  748. b2.ResetAnimation()
  749. End
  750. Exiting=1
  751. End
  752. Method InitGame() Override
  753. player.Reset()
  754. activePlayer.ResetBalls()
  755. Reset()
  756. Exiting=1
  757. state=12
  758. cue.SetPosition(490.0,180.0)
  759. InitTime()
  760. End
  761. Method RestoreCue() Override
  762. state=9
  763. cue.Init(0.0,0.0)
  764. cue.SetPosition(320.0,180.0)
  765. turnList.RemoveEach(cue)
  766. pottedList.RemoveEach(cue)
  767. railAnimation.RemoveCueBall()
  768. engine.AddBall(cue)
  769. End
  770. Method ResolveTurn()
  771. Self.state=3
  772. If Not turnList.Empty
  773. For Local b:Ball = Eachin Self.turnList
  774. If(b.num<16)
  775. activePlayer.AddBall(b)
  776. Else
  777. RestoreCue()
  778. player.UpdateBallSinRow(Self.scoreLevel)
  779. scoreLevel=Self.minLevel
  780. End
  781. End
  782. Self.turnList.Clear()
  783. Else
  784. Self.scoreLevel=Self.minLevel
  785. End
  786. If(Self.activePlayer.CompletedAll()=True)
  787. player.IncrementCompletedSets()
  788. activePlayer.ResetBalls()
  789. Reset()
  790. End
  791. Self.Exiting=0
  792. End
  793. Method Update:Int() Override
  794. If(decrementer>0)
  795. decrementer-=500
  796. endTime-=500
  797. End
  798. If incrementer>0
  799. incrementer-=200
  800. endTime+=500
  801. timed+=500
  802. If(timed>=2000)
  803. media.PlayBeep()
  804. timed=0
  805. End
  806. End
  807. time= (endTime-Millisecs())/1000
  808. minutes= time/60
  809. seconds=time Mod 60
  810. Local SelfTime:Float= Millisecs()
  811. timeFrame=(SelfTime-lastTime)/30.0
  812. lastTime=SelfTime
  813. If time<=0
  814. player.UpdateBallSinRow(Self.scoreLevel)
  815. state=6
  816. blinkOn=0
  817. Else
  818. If time<=10
  819. blinkOn=1
  820. If Millisecs()>= blinkTime+300
  821. blink = Not (blink<>0)
  822. blinkTime = Millisecs()
  823. End
  824. If time<oldTime media.PlayBeepB()
  825. oldTime = time
  826. Else
  827. oldTime=time
  828. blinkTime=Millisecs()
  829. blinkOn=0
  830. End
  831. End
  832. Local done:Int=0
  833. If state=12
  834. state = 1
  835. Local t_7:Int=inputName.Update()
  836. If(t_7=-1)
  837. Return 0
  838. Else
  839. If(t_7=0)
  840. player.SetName(inputName.GetText())
  841. state=1
  842. End
  843. End
  844. Elseif state=1
  845. state=2
  846. activePlayer.SetButtonText("position")
  847. activePlayer.Init()
  848. Elseif state=2
  849. If activePlayer.Positioning()=False
  850. state=3
  851. activePlayer.SetButtonText("Shoot")
  852. activePlayer.Init()
  853. InitTime()
  854. End
  855. Elseif state=3
  856. If activePlayer.Aiming()=False state=4
  857. Elseif state=4
  858. If activePlayer.ShootingAnimating()=False state=5
  859. Elseif state=5
  860. engine.Update(timeFrame)
  861. BallInHole()
  862. If engine.BallsMoving()=False
  863. ResolveTurn()
  864. engine.ClearFirstCollision()
  865. activePlayer.Init()
  866. End
  867. Elseif state=9
  868. activePlayer.SetButtonText("Shoot")
  869. activePlayer.Init()
  870. state=3
  871. Elseif state=6
  872. If Mouse.ButtonDown(MouseButton.Left)<>0 down=1
  873. If Mouse.ButtonDown(MouseButton.Left)=0 And down=1
  874. down=0
  875. done=1
  876. End
  877. Elseif state=8
  878. Endif
  879. Self.railAnimation.Update(timeFrame*3.0)
  880. Return Not done
  881. End
  882. Method Render(canvas:Canvas) Override
  883. canvas.DrawImage(media.railImg,5.0,360.0,0)
  884. railAnimation.Render(canvas)
  885. canvas.Color = New Color(1,1,1)
  886. canvas.DrawImage(tableImg,0.0,0.0,0)
  887. engine.Render(canvas)
  888. If(state=12)
  889. canvas.Color = New Color(1,1,1)
  890. inputName.Render(canvas)
  891. Elseif(state=2)
  892. canvas.Alpha = .2
  893. canvas.DrawRect(466.0,37.0,140.0,288.0)
  894. canvas.Alpha = .3
  895. canvas.DrawImage(arrowsImg,cue.P.x,cue.P.y,0)
  896. canvas.Alpha = 1.0
  897. activePlayer.RenderButton(canvas)
  898. ElseIf(state=4 Or state=3)
  899. If decrementer>0
  900. canvas.Color = New Color(1,.4,0)
  901. Else
  902. canvas.Color = New Color(1,1,1)
  903. End
  904. Local sec:String=String(seconds)
  905. If(sec.Length = 1) sec="0"+sec
  906. If blinkOn
  907. If blink Text.Draw(canvas,"Time Left "+String(minutes)+":"+sec,400,370)
  908. Else
  909. Text.Draw(canvas,"Time Left "+String(minutes)+":"+sec,400,370)
  910. End
  911. canvas.Color = New Color(1,1,1)
  912. Text.Draw(canvas,"Score "+String(player.score),400,400)
  913. Text.Draw(canvas,"Multiplier 100 x"+String(scoreLevel),400,430)
  914. activePlayer.Render(canvas,0)
  915. ElseIf(state=5)
  916. If decrementer > 0
  917. canvas.Color = New Color(1,.4,0)
  918. Else
  919. canvas.Color = New Color(1,1,1)
  920. End
  921. Local sec2:String=String(seconds)
  922. If sec2.Length=1 sec2="0"+sec2
  923. If blinkOn<>0
  924. If blink Text.Draw(canvas,"Time Left "+String(minutes)+":"+sec2,400,370)
  925. Else
  926. Text.Draw(canvas,"Time Left "+String(minutes)+":"+sec2,400,370)
  927. End
  928. canvas.Color = New Color(1,1,1)
  929. Text.Draw(canvas,"Score "+String(player.score),400,400)
  930. Text.Draw(canvas,"Multiplier 100 x"+String(scoreLevel),400,430)
  931. ElseIf(state=6)
  932. Local tx:Int=120
  933. Local ty:Int=100
  934. canvas.Alpha = .7
  935. canvas.Color = New Color(.2,0,1)
  936. canvas.DrawRect(tx-20,ty-20,400.0,240.0)
  937. canvas.Alpha = 1.0
  938. canvas.Color = New Color(1,1,1)
  939. canvas.DrawText("Name "+player.name,tx,ty+0,0.0,0.0)
  940. canvas.DrawText("Score "+String(player.score),tx,ty+30,0.0,0.0)
  941. canvas.DrawText("completed Sets "+String(player.mostCompletedSets),tx,ty+60,0.0,0.0)
  942. canvas.DrawText("Most Balls In A Row "+String(player.mostBallSinRow),tx,ty+90,0.0,0.0)
  943. canvas.DrawText("Most Pocketed "+String(player.mostPocketed),tx,ty+120,0.0,0.0)
  944. canvas.DrawText(" Press to exit ",tx+100,ty+170,0.0,0.0)
  945. ElseIf(state=8)
  946. End
  947. End
  948. End
  949. Global scoreTableVsTime:ScoreTable
  950. Class User
  951. Field ballList:List<Ball>
  952. Field cue:Ball
  953. Field position:PVector2D
  954. Field ballImg:Image
  955. Field ghostImg:Image[]
  956. Field cueStick:CueStick
  957. Field name:String=""
  958. Global firstShot:Int
  959. Field completedSet:Int=0
  960. Field engine:ElasticEngine
  961. Field ghostBall:GhostBall
  962. Field control:Control
  963. Field button:Button2
  964. Field ballOwnerType:Int=0
  965. Field angle:Float
  966. Field oldAngle:Float
  967. Method New()
  968. ballList=New List<Ball>
  969. End
  970. Method SetButtonText(str:String) Virtual
  971. Return
  972. End
  973. Method Init() Abstract
  974. Method Positioning:Bool() Abstract
  975. Method Aiming:Bool() Abstract
  976. Method ShootingAnimating:Bool() Abstract
  977. Method SetToSolids()
  978. ballOwnerType=2
  979. End
  980. Method SetToStripes()
  981. ballOwnerType=1
  982. End
  983. Method OwnsSolids:Bool()
  984. Return ballOwnerType=2
  985. End
  986. Method AddBall(b:Ball)
  987. Self.ballList.AddLast(b)
  988. End
  989. Method OwnsStripes:Bool()
  990. Return Self.ballOwnerType=1
  991. End
  992. Method CompletedSet:Bool()
  993. Return Self.ballList.Count()=7
  994. End
  995. Method RenderButton(canvas:Canvas) Abstract
  996. Method Render(canvas:Canvas,state:Int) Virtual
  997. canvas.Color = New Color(0.0,0.0,0.0)
  998. Text.Draw(canvas, name,544,371)
  999. canvas.Color = New Color(1,1,1)
  1000. Text.Draw(canvas,Self.name,545,370)
  1001. Local lowy:Float=370.0
  1002. Local hiy:Float=371.0
  1003. Local lowx:Float=400.0
  1004. Local hix:Float=401.0
  1005. Local t_1:Int=ballOwnerType
  1006. If ballOwnerType = 2
  1007. canvas.Color = New Color(0,0,0)
  1008. Text.Draw(canvas,"SOLIDS",lowx,hiy)
  1009. canvas.Color = New Color(1,1,1)
  1010. Text.Draw(canvas,"SOLIDS",hix,lowy)
  1011. ElseIf ballOwnerType = 1
  1012. canvas.Color = New Color(0,0,0)
  1013. Text.Draw(canvas,"STRIPES",lowx,hiy)
  1014. canvas.Color = New Color(1,1,1)
  1015. Text.Draw(canvas,"STRIPES",hix,lowy)
  1016. Else
  1017. canvas.Color = New Color(0.0,0.0,0.0)
  1018. Text.Draw(canvas,"Game Is Open",lowx,hiy)
  1019. canvas.Color = New Color(1,1,1)
  1020. Text.Draw(canvas,"Game Is Open",hix,lowy)
  1021. End
  1022. End
  1023. Method ResetBalls()
  1024. Self.ballList.Clear()
  1025. End
  1026. Method CompletedAll:Bool()
  1027. Return Self.ballList.Count()=15
  1028. End
  1029. End Class
  1030. Class Player Extends User
  1031. Field oldTouch:Int=0
  1032. Field oldMouseDown:Int=0
  1033. Field oldMouseX:Int=0
  1034. Field oldMouseY:Int=0
  1035. Field rotatorImg:Image
  1036. Method New(name:String,cue:Ball,engine:ElasticEngine,t_ghostImg:Image[],ballImg:Image,stickImg:Image[],rotatorImg:Image,buttonImg:Image[],stripImg:Image,frameTopImg:Image[],frameBotImg:Image[],topImg:Image,botImg:Image,lrImg:Image[],meterImg:Image,stretchImg:Image,sliderImg:Image)
  1037. Self.cue=cue
  1038. Self.position=cue.P
  1039. Self.ballImg=ballImg
  1040. Self.ghostImg=t_ghostImg
  1041. Self.cueStick=New CueStick(cue.P,cue.radius+1.0,stickImg,180.0)
  1042. Self.name=name
  1043. User.firstShot=1
  1044. Self.completedSet=0
  1045. Self.engine=engine
  1046. Self.ghostBall=New GhostBall(cue.P,cue.radius,t_ghostImg,180.0,stripImg)
  1047. Self.control=New Control(cue,5,420,.5,meterImg,stretchImg,sliderImg,40)
  1048. Self.oldTouch=0
  1049. Self.button=New Button2(buttonImg,360,400,"shoot",Null)
  1050. Self.rotatorImg = rotatorImg
  1051. End
  1052. Method Init() Override
  1053. ghostBall.dx=Cos(cueStick.angle)
  1054. ghostBall.dy=Sin(cueStick.angle)
  1055. cueStick.SetAngle(cueStick.angle)
  1056. engine.CollisionDistance2Ghost(ghostBall)
  1057. End
  1058. Method Positioning:Bool() Override
  1059. button.Update()
  1060. If button.GetState()
  1061. Local overlapping:Int=0
  1062. For Local b:Ball = Eachin engine.ballList
  1063. If b=cue Continue
  1064. Local vx:Float=Self.cue.P.x-b.P.x
  1065. Local vy:Float=Self.cue.P.y-b.P.y
  1066. If(vx*vx+vy*vy<=4.0*b.radius*b.radius)
  1067. overlapping=1
  1068. End
  1069. End
  1070. If overlapping=0 Return False
  1071. End
  1072. If Mouse.ButtonDown(MouseButton.Left)
  1073. If oldMouseDown
  1074. engine.CollisionDistance2Ghost(Self.ghostBall)
  1075. cue.P.x+=Mouse.X-(oldMouseX)
  1076. cue.P.y+=Mouse.Y-(oldMouseY)
  1077. If cue.P.x<476.0 cue.P.x=476.0
  1078. If cue.P.x>596.0 cue.P.x=596.0
  1079. If cue.P.y<47.0 cue.P.y=47.0
  1080. If cue.P.y>315.0 cue.P.y=315.0
  1081. End
  1082. End
  1083. oldMouseDown=Mouse.ButtonDown(MouseButton.Left)
  1084. oldMouseX=Mouse.X
  1085. oldMouseY=Mouse.Y
  1086. Return True
  1087. End
  1088. Method SetButtonText(str:String) Override
  1089. button.SetText(str)
  1090. End
  1091. Method Aiming:Bool() Override
  1092. If control.Update()
  1093. angle=control.angle
  1094. cueStick.SetAngle(angle)
  1095. If control.Length<0.0
  1096. cueStick.SetDistance(0.0)
  1097. Else
  1098. If control.Length>40.0
  1099. cueStick.SetDistance(40.0)
  1100. Else
  1101. cueStick.SetDistance(control.Length)
  1102. End
  1103. End
  1104. ghostBall.dx=Cos(angle)
  1105. ghostBall.dy=Sin((angle))
  1106. engine.CollisionDistance2Ghost(ghostBall)
  1107. oldAngle=angle
  1108. Else
  1109. If(control.Length>0.0)
  1110. cueStick.SetAnimation2()
  1111. control.Length=0.0
  1112. Return False
  1113. End
  1114. End
  1115. Return True
  1116. End
  1117. Method ShootingAnimating:Bool() override
  1118. If cueStick.Update()=0
  1119. cue.Init(cueStick.dx*40.0*control.volume,cueStick.dy*40.0*control.volume)
  1120. media.PlayShootCol()
  1121. Return False
  1122. End
  1123. Return True
  1124. End
  1125. Method RenderButton(canvas:Canvas) Override
  1126. button.Render(canvas)
  1127. End
  1128. Method Render(canvas:Canvas,status:Int) Override
  1129. control.Render(canvas)
  1130. canvas.DrawImage(rotatorImg,position.x,position.y,-angle-1.6,1.0,1.0)
  1131. ' If status Render(canvas,1)
  1132. ghostBall.Render(canvas)
  1133. cueStick.Render(canvas)
  1134. End
  1135. End
  1136. Class CueStick
  1137. Field position:PVector2D
  1138. Field len:Float=.0
  1139. Field image:Image[]
  1140. Field rotatorImg:Image
  1141. Field offset:Float=.0
  1142. Field angle:Float=.0
  1143. Field dx:Float=.0
  1144. Field dy:Float=.0
  1145. Field offsetx:Float=.0
  1146. Field offsety:Float=.0
  1147. Field distance:Float=.0
  1148. Field animStep:Float=.0
  1149. Field animx:Float=.0
  1150. Field animy:Float=.0
  1151. Field animAngle:Float=.0
  1152. Field animDelay:Int=0
  1153. Field power:Float=.0
  1154. Method SetAngle(ang:Float)
  1155. If ang<>angle
  1156. angle=ang
  1157. dx=Cos(angle)
  1158. dy=Sin(angle)
  1159. offsetx=-dx*len
  1160. offsety=-dy*len
  1161. End
  1162. End
  1163. Method New(pos:PVector2D,offset:Float,image:Image[],angle:Float)
  1164. Self.position=pos
  1165. Self.len=offset
  1166. Self.image=image
  1167. Self.offset=offset
  1168. Self.SetAngle(angle)
  1169. Self.rotatorImg = rotatorImg
  1170. End
  1171. Method SetDistance(d:Float)
  1172. distance=d
  1173. animStep=30.0
  1174. animx=-dx*distance
  1175. animy=-dy*distance
  1176. End
  1177. Method SetAnimation2()
  1178. animAngle=0
  1179. animDelay=Millisecs()+1
  1180. End
  1181. Method Update:Int()
  1182. If animDelay<Millisecs()
  1183. If animAngle >= 90.0
  1184. animx=0.0
  1185. animy=0.0
  1186. distance=0.0
  1187. animAngle=0.0
  1188. Return 0
  1189. Else
  1190. Local Length:Float=Cos(animAngle*ATR)* distance
  1191. animx=-dx*Length
  1192. animy=-dy*Length
  1193. If animAngle < 90.0 animAngle += animStep
  1194. End
  1195. animDelay=Millisecs()+1
  1196. End
  1197. Return 1
  1198. End
  1199. Method Render(canvas:Canvas)
  1200. canvas.Color = New Color(1,1,1)
  1201. Local x:Float=position.x+offsetx+animx
  1202. Local y:Float=position.y+offsety+animy
  1203. canvas.DrawImage(image[0],x,y,-angle,1.0,1.0)
  1204. End
  1205. Method SetAngleCpu(ang:Float)
  1206. If ang<>Self.angle
  1207. angle=ang
  1208. dx=Cos(angle)
  1209. dy=Sin(angle)
  1210. offsetx=-dx*len
  1211. offsety=-dy*len
  1212. End
  1213. End
  1214. Method Init(d:Float)
  1215. animStep=d/4.0
  1216. animx=0.0
  1217. animy=0.0
  1218. End
  1219. Method UpdateCpu:Int()
  1220. If(Self.animDelay<Millisecs())
  1221. If(animAngle>=90.0)
  1222. animx=0.0
  1223. animy=0.0
  1224. animAngle=0.0
  1225. Return 0
  1226. Else
  1227. Local Length:Float=-Sin(animAngle*ATR)*30.0
  1228. animx=Length*dx
  1229. animy=Length*dy
  1230. If animAngle>90.0
  1231. Local pwr:Float = power/4.0
  1232. If pwr<1.0 pwr=1.0
  1233. animAngle += animStep*pwr
  1234. Else
  1235. animAngle += animStep
  1236. End
  1237. End
  1238. animDelay=Millisecs()+1
  1239. End
  1240. Return 1
  1241. End
  1242. End
  1243. Class Control
  1244. Field x:Int
  1245. Field y:Int
  1246. Field width:Float
  1247. Field height:Float
  1248. Field meterImg:Image
  1249. Field stretchImg:Image
  1250. Field sliderImg:Image
  1251. Field volume:Float
  1252. Field sliderx:Int
  1253. Field framed:Int
  1254. Field active:Int
  1255. Field oldMouseDown:Int
  1256. Field maxValue:Float
  1257. Field stp:Float
  1258. Field cue:Ball
  1259. Field topLRImg:Image[]
  1260. Field botLRImg:Image[]
  1261. Field midTopImg:Image
  1262. Field midBotImg:Image
  1263. Field midLRImg:Image[]
  1264. Field tw:Float
  1265. Field th:Float
  1266. Field x2:Float
  1267. Field vx:Float
  1268. Field y2:Float
  1269. Field vy:Float
  1270. Field dx:Float
  1271. Field dy:Float
  1272. Field Length:Float
  1273. Field activeVolume:Float
  1274. Field angle:Float
  1275. Method New(cue:Ball,x:Int,y:Int,volume:Float,meterImg:Image,stretchImg:Image,sliderImg:Image,maxValue:Int)
  1276. Self.x=x
  1277. Self.y=y
  1278. Self.width= meterImg.Width
  1279. Self.height= meterImg.Height
  1280. Self.meterImg=meterImg
  1281. Self.stretchImg=stretchImg
  1282. Self.sliderImg=sliderImg
  1283. Self.stretchImg=stretchImg
  1284. If volume>1.0 volume=1.0
  1285. If volume<0.0 volume=0.0
  1286. Self.volume=volume
  1287. Self.sliderx= volume*Self.width
  1288. Self.framed = 0
  1289. Self.active = 0
  1290. Self.oldMouseDown = 0
  1291. Self.maxValue=(maxValue)
  1292. Self.stp=Self.width/maxValue
  1293. Self.cue=cue
  1294. End
  1295. Method SetFrame(tlrImg:Image[],blrImg:Image[],mtImg:Image,mbImg:Image,mlrImg:Image[])
  1296. Self.topLRImg=tlrImg
  1297. Self.botLRImg=blrImg
  1298. Self.midTopImg=mtImg
  1299. Self.midBotImg=mbImg
  1300. Self.midLRImg=mlrImg
  1301. Self.tw= tlrImg[0].Width
  1302. Self.th= tlrImg[0].Height
  1303. Self.framed=1
  1304. End
  1305. Method Update:Int()
  1306. Local state:Int=1
  1307. If Mouse.ButtonDown(MouseButton.Left)
  1308. If Self.oldMouseDown
  1309. Self.vx=Mouse.X-Self.x2
  1310. Self.vy=Mouse.Y-Self.y2
  1311. Self.Length=Self.vx*-Self.dx+Self.vy*-Self.dy
  1312. If(Self.Length>Self.maxValue)
  1313. Self.volume=Self.maxValue*Self.stp/Self.width
  1314. Else
  1315. If(Self.Length<0.0)
  1316. Self.volume=0.0
  1317. Else
  1318. Self.volume=Self.Length*Self.stp/Self.width
  1319. End
  1320. End
  1321. Else
  1322. Self.x2=Mouse.X
  1323. Self.y2=Mouse.Y
  1324. End
  1325. Else
  1326. If Self.oldMouseDown
  1327. Self.vx=Mouse.X-Self.x2
  1328. Self.vy=Mouse.Y-Self.y2
  1329. Self.Length=Self.vx*-Self.dx+Self.vy*-Self.dy
  1330. If(Self.Length>Self.maxValue And Self.Length>=0.0)
  1331. Self.volume=Self.maxValue*Self.stp/Self.width
  1332. Else
  1333. If(Self.Length<0.0)
  1334. Self.volume=0.0
  1335. Else
  1336. Self.volume=Self.Length*Self.stp/Self.width
  1337. End
  1338. End
  1339. Self.oldMouseDown=Mouse.ButtonDown(MouseButton.Left)
  1340. Return 0
  1341. Else
  1342. Self.volume=Self.activeVolume
  1343. Self.vx=Mouse.X-Self.cue.P.x
  1344. Self.vy=Mouse.Y-Self.cue.P.y
  1345. Self.angle=(ATan2(Self.vy,Self.vx))
  1346. Self.dx=Cos((Self.angle))
  1347. Self.dy=Sin((Self.angle))
  1348. End
  1349. End
  1350. Self.oldMouseDown=Mouse.ButtonDown(MouseButton.Left)
  1351. Self.sliderx=((Self.volume*Self.width))
  1352. Return 1
  1353. End
  1354. Method Render(canvas:Canvas)
  1355. If framed
  1356. Local px:Float=x-tw
  1357. Local py:Float=y-th
  1358. canvas.DrawImage(topLRImg[0],px,py)
  1359. canvas.DrawImage(midTopImg,px+tw,py,0.0,width,1.0)
  1360. canvas.DrawImage(topLRImg[1],px+width+tw,py)
  1361. canvas.DrawImage(midLRImg[0],px,py+th,0.0,1.0,height)
  1362. canvas.DrawImage(midLRImg[1],px+tw+width,py+th,0.0,1.0,height)
  1363. canvas.DrawImage(botLRImg[0],px,py+th+height)
  1364. canvas.DrawImage(midBotImg,px+tw,py+th+height,0.0,width,1.0)
  1365. canvas.DrawImage(botLRImg[1],px+tw+width,py+th+height)
  1366. End
  1367. canvas.DrawImage(meterImg,x,y,0)
  1368. Local w:Float=(1.0-volume)*width
  1369. canvas.DrawImage(stretchImg,x+sliderx,y,0.0,w,1.0)
  1370. canvas.DrawImage(sliderImg,x+sliderx,y,0)
  1371. Text.Draw(canvas,"POWER",x+50,y+10)
  1372. End
  1373. End
  1374. Class Cpu Extends User
  1375. Field pocketList:List<ArcWall>
  1376. Field activeBallList:List<Ball>
  1377. Field aimWait:Int=0
  1378. Field delay:Int=0
  1379. Field inacuracy:Float=.0
  1380. Field power:Float=.0
  1381. Method New(name:String,cue:Ball,engine:ElasticEngine,arcList:List<ArcWall>,stickImg:Image[],ballImg:Image,inacuracy:Float)
  1382. Self.cue=cue
  1383. Self.position=cue.P
  1384. Self.cueStick= New CueStick(cue.P,cue.radius+1.0,stickImg,180.0)
  1385. Self.ballImg=ballImg
  1386. Self.pocketList=arcList
  1387. Self.activeBallList=engine.ballList
  1388. Self.aimWait=100
  1389. Self.delay=Millisecs()+Self.aimWait
  1390. Self.inacuracy=inacuracy
  1391. Self.name=name
  1392. Self.engine=engine
  1393. End
  1394. Method Init() Override
  1395. End
  1396. Method Positioning:Bool() Override
  1397. Repeat
  1398. cue.P.x=Rnd(476,596)
  1399. cue.P.y=Rnd( 47,315)
  1400. Local overlapped:Int=0
  1401. For Local b:Ball = Eachin engine.ballList
  1402. If b=cue
  1403. Continue
  1404. End
  1405. Local vx:Float=b.P.x-Self.cue.P.x
  1406. Local vy:Float=b.P.y-Self.cue.P.y
  1407. If (vx*vx+vy*vy<=4.0*b.radius*b.radius)
  1408. overlapped=1
  1409. Exit
  1410. End
  1411. End
  1412. If overlapped=0 Exit
  1413. Forever
  1414. cue.Init(0.0,0.0)
  1415. Return False
  1416. End
  1417. Method Get8Ball:Ball()
  1418. For Local b:Ball = Eachin activeBallList
  1419. If(b.num=8)
  1420. Return b
  1421. End
  1422. End
  1423. Return Null
  1424. End
  1425. Method PathToPocket:Bool(b1:Ball,dx:Float,dy:Float)
  1426. For Local b2:Ball = Eachin Self.activeBallList
  1427. If(b2=b1 Or b2=Self.cue)
  1428. Continue
  1429. End
  1430. Local vx:Float=b2.P.x-b1.P.x
  1431. Local vy:Float=b2.P.y-b1.P.y
  1432. Local dp:Float=vx*dy-vy*dx
  1433. If(Abs(dp)<b1.radius+b2.radius)
  1434. Local dp2:Float=vx*dx+vy*dy
  1435. If(dp2>0.0)
  1436. Return False
  1437. End
  1438. End
  1439. End
  1440. Return True
  1441. End
  1442. Method PathToBall:Bool(b1:Ball,dx:Float,dy:Float,skipBall:Ball)
  1443. Local vx:Float=skipBall.P.x-b1.P.x
  1444. Local vy:Float=skipBall.P.y-b1.P.y
  1445. Local len:Float=vx*dx+vy*dy
  1446. For Local b3:Ball = Eachin activeBallList
  1447. If(b3=b1 Or b3=skipBall) Continue
  1448. Local vx2:Float=b3.P.x-b1.P.x
  1449. Local vy2:Float=b3.P.y-b1.P.y
  1450. Local dp:Float=vx2*dy-vy2*dx
  1451. If(Abs(dp)<b1.radius+b3.radius)
  1452. Local dp2:Float=vx2*dx+vy2*dy
  1453. If(dp2>0.0 And dp2<Abs(len)) Return False
  1454. End
  1455. End
  1456. Return True
  1457. End
  1458. Method FindBestPocket:ArcWall(ball:Ball)
  1459. Local distance:Float=INVALID_DISTANCE
  1460. Local pocket:ArcWall
  1461. For Local arc:ArcWall = Eachin pocketList
  1462. Local dx1:Float
  1463. Local dy1:Float
  1464. Local vx1:Float=arc.target.x-ball.P.x
  1465. Local vy1:Float=arc.target.y-ball.P.y
  1466. Local vx2:Float=cue.P.x-ball.P.x
  1467. Local vy2:Float=cue.P.y-ball.P.y
  1468. Local dp:Float=vx1*vx2+vy1*vy2
  1469. If(dp<0.0)
  1470. Local d1:Float=Sqrt(vx1*vx1+vy1*vy1)
  1471. If(d1>0.0)
  1472. dx1=vx1/d1
  1473. dy1=vy1/d1
  1474. End
  1475. If(d1=0.0 Or Self.PathToPocket(ball,dx1,dy1))
  1476. Local px:Float=ball.P.x-dx1*(arc.radius+ball.radius)
  1477. Local py:Float=ball.P.y-dy1*(arc.radius+ball.radius)
  1478. vx1=px-cue.P.x
  1479. vy1=py-cue.P.y
  1480. d1=Sqrt(vx1*vx1+vy1*vy1)
  1481. Local ang:Float=(ATan2(vy1,vx1))
  1482. If(PathToBall(cue,Cos((ang)),Sin((ang)),ball))
  1483. If(d1<distance)
  1484. distance=d1
  1485. angle=ang
  1486. pocket=arc
  1487. End
  1488. End
  1489. End
  1490. End
  1491. End
  1492. Return pocket
  1493. End
  1494. Method GetRndSolidBall:Ball()
  1495. Local counter:Int=0
  1496. For Local b:Ball = Eachin activeBallList
  1497. If(b.num<8)
  1498. counter+=1
  1499. Else
  1500. Continue
  1501. End
  1502. End
  1503. If counter
  1504. If counter>1 counter=Rnd(1.0,(counter+1))
  1505. Local n:Int=1
  1506. For Local b2:Ball = Eachin activeBallList
  1507. If b2.num < 8
  1508. If(n=counter) Return b2
  1509. n+=1
  1510. Endif
  1511. End
  1512. End
  1513. Return Null
  1514. End
  1515. Method GetRndStripedBall:Ball()
  1516. Local counter:Int=0
  1517. Local low:Int=0
  1518. For Local b:Ball = Eachin activeBallList
  1519. If(b.num>=8 And b.num<16)
  1520. counter+=1
  1521. Else
  1522. low+=1
  1523. End
  1524. End
  1525. counter=(((low)+Rnd(1.0,(counter+1))))
  1526. Local n:Int=1
  1527. For Local b2:Ball = Eachin activeBallList
  1528. If n=counter Return b2
  1529. n+=1
  1530. End
  1531. Return Null
  1532. End
  1533. Method GetRndBall:Ball()
  1534. Local counter:Int=Self.activeBallList.Count()
  1535. counter=((Rnd(0.0,(counter-1))))
  1536. Local n:Int=0
  1537. For Local b:Ball = Eachin activeBallList
  1538. If n=counter Return b
  1539. n+=1
  1540. End
  1541. Return Null
  1542. End
  1543. Method Aiming:Bool() Override
  1544. Local vx:Float
  1545. Local vy:Float
  1546. If ballList.Count() = 7
  1547. Local b:Ball=Get8Ball()
  1548. Local pocket:ArcWall=FindBestPocket(b)
  1549. If pocket
  1550. vx=b.P.x-pocket.target.x
  1551. vy=b.P.y-pocket.target.y
  1552. Local len:Float=Sqrt(vx*vx+vy*vy)
  1553. Local px:Float=b.P.x+vx/len*(b.radius+cue.radius)
  1554. Local py:Float=b.P.y+vy/len*(b.radius+cue.radius)
  1555. vx=px-cue.P.x
  1556. vy=py-cue.P.y
  1557. Else
  1558. vx=b.P.x-cue.P.x
  1559. vy=b.P.y-cue.P.y
  1560. End
  1561. Else
  1562. Local ball:Ball
  1563. Local pocket2:ArcWall
  1564. Local distance:Float=INVALID_DISTANCE
  1565. For Local b2:Ball = Eachin activeBallList
  1566. If(ballOwnerType=2 And b2.num>7) Continue
  1567. If(ballOwnerType=1 And b2.num<9) Continue
  1568. If(b2.num=8 Or b2=cue) Continue
  1569. Local pkt:ArcWall=FindBestPocket(b2)
  1570. If pkt
  1571. vx=pkt.target.x-b2.P.x
  1572. vy=pkt.target.y-b2.P.y
  1573. Local ln:Float=Sqrt(vx*vx+vy*vy)
  1574. If(ln<distance)
  1575. distance=ln
  1576. pocket2=pkt
  1577. ball=b2
  1578. End
  1579. End
  1580. End
  1581. If distance < INVALID_DISTANCE
  1582. vx=ball.P.x-pocket2.target.x
  1583. vy=ball.P.y-pocket2.target.y
  1584. angle= ATan2(vy,vx)
  1585. Local px2:Float = ball.P.x+Cos(angle)*(cue.radius+ball.radius)
  1586. Local py2:Float = ball.P.y+Sin(angle)*(cue.radius+ball.radius)
  1587. vx=px2-cue.P.x
  1588. vy=py2-cue.P.y
  1589. Else
  1590. Local t:Int=Self.ballOwnerType
  1591. If t = 2
  1592. ball = GetRndSolidBall()
  1593. Elseif t = 1
  1594. ball=GetRndStripedBall()
  1595. Else
  1596. ball=GetRndBall()
  1597. End
  1598. If ball
  1599. vx=ball.P.x-cue.P.x
  1600. vy=ball.P.y-cue.P.y
  1601. Else
  1602. vx = Cos(cueStick.angle)
  1603. vy = Sin(cueStick.angle)
  1604. Endif
  1605. End
  1606. End
  1607. angle=ATan2(vy,vx)
  1608. cueStick.SetAngleCpu(angle)
  1609. power=Rnd(10.0,50.0)
  1610. cueStick.Init(power)
  1611. Return False
  1612. End
  1613. Method SetButtonText(str:String) Override
  1614. End
  1615. Method ShootingAnimating:Bool() Override
  1616. If Self.cueStick.UpdateCpu()=0
  1617. cue.Init(Self.cueStick.dx*power,cueStick.dy*power)
  1618. Return False
  1619. End
  1620. Return True
  1621. End
  1622. Method RenderButton(canvas:Canvas) Override
  1623. End
  1624. Method Render(canvas:Canvas,status:Int) Override
  1625. If status Super.Render(canvas,1)
  1626. cueStick.Render(canvas)
  1627. End
  1628. End