PromptInvasion.monkey2 57 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591
  1. #Import "<mojo>"
  2. #Import "<std>"
  3. #Import "font"
  4. #Import "vector"
  5. #Import "data/aliens.png"
  6. '#Import "asset::background.png"
  7. #Import "data/chalky.fnt"
  8. #Import "data/chalky.png"
  9. #Import "data/shoota.ogg"
  10. #Import "data/hita.ogg"
  11. #Import "data/fireball.ogg"
  12. #Import "data/hit.ogg"
  13. #Import "data/explosion.ogg"
  14. #Import "data/bomb0.ogg"
  15. #Import "data/laser.ogg"
  16. #Import "data/woop.ogg"
  17. #Import "data/kickshock.ogg"
  18. Using mojo..
  19. Using std..
  20. Function Main()
  21. New AppInstance
  22. New Game
  23. App.Run()
  24. End
  25. Const ATR := 3.14159265/180.0
  26. Global currentTime:Int
  27. Global activeStage:StageBase
  28. Global nextStage:StageBase
  29. Global introStage:Intro
  30. Global menuStage:Menu
  31. Global gameStage:GalVadors
  32. Global optionsStage:Options
  33. Global creditsStage:Credits
  34. Global player:Player
  35. Global enemyBulletList := New List<Bullet>
  36. Global playerBulletList := New List<Bullet>
  37. Global explosionList := New List<Explosion>
  38. Global shipParticleList := New List<Particle>
  39. Global aparticleList:List<ParticleA>
  40. Global specialList:List<Special>
  41. Global bulletStore := New BulletStore(150)
  42. Global explosionStore := New ExplosionStore(50)
  43. Global particleStore := New ParticleStore(50)
  44. Global aparticleStore:AParticleStore
  45. Global media:Media
  46. Global score:Int
  47. Global hiScore:Int
  48. Global mousex:Int
  49. Global mousey:Int
  50. Global mouseDown:Int
  51. Global lapsedTime:Int
  52. Global DeviceWidth:Int
  53. Global DeviceHeight:int
  54. Class Game Extends Window
  55. Field stars:Stars
  56. Method New( title:String="Simple mojo app",width:Int=640,height:Int=480,flags:WindowFlags=Null )
  57. Super.New( title,width,height,flags )
  58. DeviceWidth = width
  59. DeviceHeight = height
  60. media = New Media
  61. introStage = New Intro
  62. activeStage = introStage
  63. nextStage = activeStage
  64. Local tstl:Font= SetAFont("chalky")
  65. aparticleList =New List<ParticleA>
  66. aparticleStore = New AParticleStore(20)
  67. stars = New Stars()
  68. End
  69. Method OnRender( canvas:Canvas ) Override
  70. mousex = Mouse.X
  71. mousey = Mouse.Y
  72. mouseDown = Mouse.ButtonDown(MouseButton.Left)
  73. currentTime = Millisecs()
  74. If activeStage <> nextStage
  75. activeStage = nextStage
  76. Endif
  77. activeStage.Update()
  78. stars.Update()
  79. App.RequestRender()
  80. canvas.Clear(New Color(0,0,0))
  81. stars.Render(canvas)
  82. activeStage.Render(canvas)
  83. canvas.DrawImage(media.trailImg[0],50,50)
  84. End
  85. End
  86. Class StageBase
  87. Method Update:Void() Abstract
  88. Method Render:Void(canvas:Canvas) Abstract
  89. End Class
  90. Class Intro Extends StageBase
  91. Field startTime:Int
  92. Field delayAmount:Int
  93. Field oldScape:Int
  94. Field image:Image
  95. Method New()
  96. image = media.alienImg
  97. Init()
  98. End Method
  99. Method Init:Void()
  100. startTime = currentTime
  101. delayAmount = 2000
  102. End Method
  103. Method Update:Void() override
  104. Local scape:Int = Keyboard.KeyDown(Key.Escape) Or Mouse.ButtonDown(MouseButton.Left)
  105. If currentTime > startTime+delayAmount Or (oldScape And Not scape)
  106. If Not menuStage
  107. menuStage = New Menu
  108. Endif
  109. nextStage = menuStage
  110. Endif
  111. oldScape = scape
  112. End Method
  113. Method Render:Void(canvas:Canvas) Override
  114. canvas.DrawImage(image,150,100)
  115. RenderText(canvas," PROMPT INVASION",190,230)
  116. End Method
  117. End Class
  118. Class Menu Extends StageBase
  119. Field index:Int
  120. Field totalOptions:Int
  121. Field options:String[]
  122. Field hoverColor:Color
  123. Field defaultColor:Color
  124. Field clickColor:Color
  125. Field inactiveColor:Color
  126. Field currentColor:Color
  127. Field oldMouseDown:Int
  128. Field alienImg:Image
  129. Const cINTRO:Int = 0
  130. Const cPLAY:Int = 1
  131. Const cCONTINUE:Int = 2
  132. Const cSCORESTABLE:Int = 3
  133. Const cOPTIONS:Int = 4
  134. Const cCREDITS:Int = 5
  135. Field px:Float
  136. Field py:Float
  137. Method New()
  138. totalOptions = 2
  139. options = New String[totalOptions]
  140. options[cINTRO] = " INTRO"
  141. options[cPLAY] = "PLAY GAME"
  142. defaultColor = New Color(1,1,1) '$FFFFFF
  143. hoverColor = New Color(1,1,0) '$FFFF00
  144. clickColor = New Color(0,1,0) '$00ff00
  145. inactiveColor = New Color(.5,.5,.5)'$888888
  146. currentColor = New Color(1,1,1) '$FFFFFF
  147. index = -1
  148. End Method
  149. Method Update:Void() Override
  150. px = mousex - 200
  151. py = mousey - 150
  152. index = -1
  153. Local y:Int = py / 40.0
  154. currentColor = defaultColor
  155. If y >= 0 And y < totalOptions
  156. Local n:Int = py Mod 40.0
  157. If n >= 0 And n < 45 And px > 0 And px < 200
  158. currentColor = hoverColor
  159. index = y
  160. If mouseDown
  161. currentColor = clickColor
  162. Endif
  163. Endif
  164. Endif
  165. If oldMouseDown And Not mouseDown
  166. If index > - 1
  167. Select index
  168. Case cINTRO
  169. nextStage = introStage
  170. introStage.Init()
  171. Case cPLAY
  172. gameStage = New GalVadors
  173. nextStage = gameStage
  174. End Select
  175. Endif
  176. Endif
  177. oldMouseDown = mouseDown
  178. End Method
  179. Method Render:Void(canvas:Canvas) Override
  180. canvas.DrawImage(media.alienImg,150,100)
  181. RenderText(canvas,"MENU",270,50)
  182. For Local i:Int = 0 Until totalOptions
  183. If i = cCONTINUE
  184. If i = index
  185. If gameStage
  186. canvas.Color = currentColor
  187. Else
  188. canvas.Color = inactiveColor
  189. Endif
  190. Elseif gameStage
  191. canvas.Color = defaultColor
  192. Else
  193. canvas.Color = inactiveColor
  194. Endif
  195. Elseif i = index
  196. canvas.Color = currentColor
  197. Else
  198. canvas.Color = New Color(1,1,1) ' 255,255,255
  199. Endif
  200. RenderText(canvas,options[i],240,150+i*40)
  201. Next
  202. canvas.Color = New Color(1,1,0) '255, 255, 0
  203. RenderText(canvas,"Music by Kevin MacLeod - incompetech.com",50,400)
  204. RenderText(canvas,"controlls Z, Left, Right",150,430)
  205. canvas.Color = New Color(1,1,1) '255,255,255
  206. End Method
  207. End Class
  208. Class GalVadors Extends StageBase
  209. Field oldScape:Int
  210. Field wave:Wave
  211. Field shipExplosionImg:Image
  212. Field explosionImg:Image
  213. Field gameTimer:Timer
  214. Field meteorList:List<Meteor>
  215. Field passedLevel:Int
  216. Field trailImg:Image
  217. Field Level:Int
  218. Field ufo:Ufo
  219. Method New()
  220. player = New Player()
  221. wave = New Wave(0)
  222. meteorList = New List<Meteor>
  223. For Local i:Int = 0 Until 10
  224. Local m:Meteor = New Meteor(Rnd(-16,656),Rnd(-16,494),Rnd(0,360),Rnd(1,5))
  225. meteorList.AddLast(m)
  226. Next
  227. gameTimer = New Timer(60000,10,10)
  228. ufo = New Ufo(-50,50)
  229. media.PlayTune()
  230. passedLevel = False
  231. specialList = New List<Special>
  232. score = 0
  233. Level = 0
  234. End Method
  235. Method Update:Void() Override
  236. player.Update()
  237. UpdateBullets()
  238. wave.Update()
  239. If player.state <> player.DEAD
  240. ProcessCollisions()
  241. Endif
  242. ProcessExplosions()
  243. If player.state <> player.PASSEDLEVEL And player.state <> player.DEAD
  244. If KilledAll() = True
  245. If wave.level < 5
  246. passedLevel = True
  247. player.state = player.PASSEDLEVEL
  248. Else
  249. player.state = player.PASSEDGAME
  250. Endif
  251. Elseif gameTimer.Update() = False
  252. player.state = player.DEAD
  253. Endif
  254. Endif
  255. If Not aparticleList.Empty
  256. Local node := aparticleList.FirstNode()
  257. While node.Value
  258. Local nextNode := node.Succ
  259. If node.Value.Update()
  260. node.Remove()
  261. aparticleStore.ReturnItem(node.Value)
  262. Endif
  263. node = nextNode
  264. Wend
  265. Endif
  266. For Local m:Meteor = Eachin meteorList
  267. m.Update()
  268. Next
  269. If Not specialList.Empty
  270. Local node := specialList.FirstNode()
  271. While node.Value
  272. Local nextNode := node.Succ
  273. Local s := node.Value
  274. If s.Update() = False
  275. node.Remove()
  276. Endif
  277. node = nextNode
  278. Wend
  279. Endif
  280. ufo.Update()
  281. Local key:Int = Keyboard.KeyDown(Key.Escape)
  282. If oldScape And Not key
  283. If Cast<GalVadors>(nextStage)
  284. media.StopMusic()
  285. Endif
  286. nextStage = menuStage
  287. Endif
  288. oldScape = key
  289. If passedLevel = True
  290. If Keyboard.KeyDown(Key.Space) And player.state <> player.PASSEDGAME
  291. wave.SetNextLevel()
  292. gameTimer.Reset()
  293. player.state = player.ACTIVE
  294. passedLevel = False
  295. ufo.Reset()
  296. enemyBulletList.Clear()
  297. playerBulletList.Clear()
  298. explosionList.Clear()
  299. shipParticleList.Clear()
  300. aparticleList.Clear()
  301. specialList.Clear()
  302. Endif
  303. Endif
  304. End Method
  305. Method KilledAll:Int()
  306. Return wave.KilledAll()
  307. End Method
  308. Method UpdateBullets:Void()
  309. For Local b := Eachin playerBulletList
  310. b.Update()
  311. Next
  312. For Local b := Eachin enemyBulletList
  313. b.Update()
  314. Next
  315. End Method
  316. Method ProcessCollisions:Void()
  317. If Not specialList.Empty
  318. Local node := specialList.FirstNode()
  319. While node.Value
  320. Local nextNode := node.Succ
  321. Local s := node.Value
  322. If player.Collided(s.pos.x,s.pos.y,s.hitBox)
  323. Select s.type
  324. Case Special.HEART
  325. If player.lifes < 5
  326. player.lifes += 1
  327. Endif
  328. Case Special.SHIELD
  329. player.shieldTimer.Reset()
  330. Case Special.GUN
  331. player.bulletTimer.Reset()
  332. End Select
  333. media.WoopSnd()
  334. node.Remove()
  335. Endif
  336. node = nextNode
  337. Wend
  338. Endif
  339. If Not playerBulletList.Empty
  340. Local node := playerBulletList.FirstNode()
  341. While node.Value
  342. Local nextNode := node.Succ
  343. wave.CollideBullet(node)
  344. node = nextNode
  345. Wend
  346. Endif
  347. If ufo.active = True
  348. If Not playerBulletList.Empty
  349. Local node := playerBulletList.FirstNode()
  350. While node.Value
  351. Local nextNode := node.Succ
  352. Local b := node.Value
  353. If ufo.Collided(b.pos.x,b.pos.y,b.hitBox)
  354. Local e:= explosionStore.GetItem()
  355. e.Init(ufo.pos.x,ufo.pos.y,100)
  356. explosionList.AddLast(e)
  357. ufo.ReleaseSpecial(player)
  358. ufo.DeActivate()
  359. media.ExplodeSnd2()
  360. node.Remove()
  361. bulletStore.ReturnItem(node.Value)
  362. Exit
  363. Endif
  364. node = nextNode
  365. Wend
  366. Endif
  367. Endif
  368. If player.state = player.ACTIVE
  369. If player.shielded = False
  370. If wave.CollidedPlayer(player)
  371. CreateShipExplosion(player.pos.x,player.pos.y)
  372. Local e := explosionStore.GetItem()
  373. e.Init(player.pos.x,player.pos.y,100)
  374. explosionList.AddLast(e)
  375. If player.lifes = 0
  376. player.state = player.DEAD
  377. Else
  378. player.state = player.SPAWNING
  379. player.SpawnReset()
  380. Endif
  381. Endif
  382. Endif
  383. Endif
  384. If player.state = player.ACTIVE
  385. If player.shieldTimer.Update() = False
  386. If Not enemyBulletList.Empty
  387. Local node := enemyBulletList.FirstNode()
  388. While node.Value
  389. Local nextNode := node.Succ
  390. Local b := node.Value
  391. If player.Collided(b.pos.x,b.pos.y,b.hitBox)
  392. node.Remove()
  393. bulletStore.ReturnItem(b)
  394. CreateShipExplosion(player.pos.x,player.pos.y)
  395. Local e := explosionStore.GetItem()
  396. e.Init(player.pos.x,player.pos.y,100)
  397. explosionList.AddLast(e)
  398. player.state = player.SPAWNING
  399. media.ExplodeSnd2()
  400. player.SpawnReset()
  401. Endif
  402. node = nextNode
  403. Wend
  404. Endif
  405. Endif
  406. Endif
  407. Local dw:Float = DeviceWidth
  408. Local dh:Float = DeviceHeight
  409. If Not playerBulletList.Empty
  410. Local node:List<Bullet>.Node = playerBulletList.FirstNode()
  411. while node.Value
  412. Local nextNode := node.Succ
  413. Local b:= node.Value
  414. If (b.pos.x < 0) Or (b.pos.y < 0) Or (b.pos.x > dw) Or (b.pos.y > dh)
  415. node.Remove()
  416. bulletStore.ReturnItem(b)
  417. Endif
  418. node = nextNode
  419. Wend
  420. Endif
  421. If Not enemyBulletList.Empty
  422. Local node := enemyBulletList.FirstNode()
  423. While node.Value
  424. Local nextNode := node.Succ
  425. Local b := node.Value
  426. If (b.pos.x < 0) Or (b.pos.y < 0) Or (b.pos.x > dw) Or (b.pos.y > dh)
  427. node.Remove()
  428. bulletStore.ReturnItem(b)
  429. Endif
  430. node = nextNode
  431. Wend
  432. Endif
  433. End Method
  434. Method ProcessExplosions:Void()
  435. If Not explosionList.Empty
  436. Local node := explosionList.FirstNode()
  437. While node.Value
  438. Local nextNode := node.Succ
  439. Local e := node.Value
  440. e.Update()
  441. If e.Done()
  442. node.Remove()
  443. explosionStore.ReturnItem(e)
  444. Endif
  445. node = nextNode
  446. Wend
  447. Endif
  448. If Not shipParticleList.Empty
  449. Local node := shipParticleList.FirstNode()
  450. While node.Value
  451. Local nextNode := node.Succ
  452. Local e := node.Value
  453. e.Update()
  454. If e.Done()
  455. node.Remove()
  456. particleStore.ReturnItem(e)
  457. Endif
  458. node = nextNode
  459. Wend
  460. Endif
  461. End Method
  462. Method Render:Void(canvas:Canvas) Override
  463. canvas.Color = New Color(.6,.6,.6) '150,150,150
  464. For Local m:Meteor = Eachin meteorList
  465. m.Render(canvas)
  466. Next
  467. canvas.Color = New Color(1,1,1) '255,255,255
  468. player.Render(canvas)
  469. wave.Render(canvas)
  470. canvas.BlendMode = BlendMode.Additive
  471. For Local p:= Eachin aparticleList
  472. p.Render(canvas)
  473. Next
  474. canvas.Alpha = 1.0
  475. For Local b := Eachin playerBulletList
  476. b.Render(canvas)
  477. Next
  478. For Local b := Eachin enemyBulletList
  479. b.Render(canvas)
  480. Next
  481. For Local ex := Eachin explosionList
  482. ex.Render(canvas)
  483. Next
  484. canvas.Color = New Color(1,1,1) ' 255,255,255
  485. For Local pa := Eachin shipParticleList
  486. pa.Render(canvas)
  487. Next
  488. For Local s := Eachin specialList
  489. s.Render(canvas)
  490. Next
  491. ufo.Render(canvas)
  492. gameTimer.Render(canvas)
  493. RenderText(canvas,score,500,10)
  494. canvas.Color = New Color(1,0,1) '255,0,255
  495. Select player.state
  496. Case player.PASSEDLEVEL
  497. RenderText(canvas," Level Completed!",140,180)
  498. RenderText(canvas," Final Score "+score,150,220)
  499. RenderText(canvas,"Press SPACE to CONTINUE.",150,300)
  500. Case player.DEAD
  501. RenderText(canvas," Game Over - You Lost!",150,180)
  502. RenderText(canvas," Final Score "+score,150,220)
  503. RenderText(canvas," Press 'ESC' to Exit.",150,300)
  504. Case player.PASSEDGAME
  505. RenderText(canvas," Game WON",150,180)
  506. RenderText(canvas," Final Score "+score,150,220)
  507. RenderText(canvas,"Press 'ESC' to Exit.",150,300)
  508. End Select
  509. canvas.Color = New Color(1,1,1) '255,255,255
  510. If player.shielded = True
  511. canvas.DrawImage(media.specialImg[Special.SHIELD],280,25)
  512. Endif
  513. If player.fastRate = True
  514. canvas.DrawImage(media.specialImg[Special.GUN],280,25)
  515. Endif
  516. End Method
  517. End Class
  518. Class Options Extends StageBase
  519. Field oldScape:Int
  520. Method New()
  521. End Method
  522. Method Update:Void() Override
  523. Local key:Int = Keyboard.KeyDown(Key.Escape)
  524. If oldScape And Not key
  525. nextStage = menuStage
  526. Endif
  527. oldScape = key
  528. End Method
  529. Method Render:Void(canvas:Canvas) Override
  530. canvas.DrawText("This is the Options Stage",300,240)
  531. End Method
  532. End Class
  533. Class Credits Extends StageBase
  534. Field oldScape:Int
  535. Method New()
  536. End Method
  537. Method Update:Void() Override
  538. Local key:Int = Keyboard.KeyDown(Key.Escape)
  539. If oldScape And Not key
  540. nextStage = menuStage
  541. Endif
  542. oldScape = key
  543. End Method
  544. Method Render:Void(canvas:Canvas) Override
  545. canvas.DrawText("This is the credits Section",300,240)
  546. End Method
  547. End Class
  548. Class ScoresTable Extends StageBase
  549. Field oldScape:Int
  550. Method New()
  551. End Method
  552. Method Update:Void() Override
  553. Local key:Int =Int(Keyboard.KeyDown(Key.Escape))
  554. If oldScape And Not key
  555. nextStage = menuStage
  556. Endif
  557. oldScape = key
  558. End Method
  559. Method Render:Void(canvas:Canvas) Override
  560. canvas.DrawText("This is the Scores Table Section",250,240)
  561. End Method
  562. End Class
  563. Class ScoreKeeper
  564. Field total:Int
  565. End Class
  566. '**********************************************************************
  567. Class HitBox
  568. Field min:PVector2D
  569. Field max:PVector2D
  570. Method New()
  571. End Method
  572. Method New(minx:Float,miny:Float,maxx:Float,maxy:Float)
  573. Self.min = New PVector2D(minx, miny)
  574. Self.max = New PVector2D(maxx, maxy)
  575. End Method
  576. Method Set:Void(minx:Float,miny:Float,maxx:Float,maxy:Float)
  577. If min = Null min = New PVector2D
  578. If max = Null max = New PVector2D
  579. Self.min.Set(minx, miny)
  580. Self.max.Set(maxx, maxy)
  581. End Method
  582. Method Render:Void(canvas:Canvas,x:Float,y:Float)
  583. canvas.DrawLine(x+min.x,y+min.y,x+max.x,y+min.y)
  584. canvas.DrawLine(x+max.x,y+min.y,x+max.x,y+max.y)
  585. canvas.DrawLine(x+max.x,y+max.y,x+min.x,y+max.y)
  586. canvas.DrawLine(x+min.x,y+max.y,x+min.x,y+min.y)
  587. End Method
  588. End Class
  589. Class Entity
  590. Field parent:PVector2D
  591. Field mainv:PVector2D
  592. Field pos:PVector2D
  593. Field hitBox:HitBox
  594. Field startTime:Int
  595. Field frameDelay:Int
  596. Field totalFrames:Int
  597. Field angle:Float
  598. Field d:PVector2D
  599. Field state:Int
  600. Field image:Image[]
  601. Field value:Int
  602. Const IN_FORMATION:Int = 1
  603. Const ALIGNING_OUT:Int = 2
  604. Const LEAVING:Int = 3
  605. Const ATTACKING:Int = 4
  606. Const TURNING:Int = 5
  607. Const RETURNING:Int = 6
  608. Const ALIGNING_IN:Int = 7
  609. Const SWEEPING:Int = 8
  610. Const ACTIVE:Int = 9
  611. Const SPAWNING:Int = 10
  612. Const DEAD:Int = 11
  613. Const PASSEDLEVEL:Int = 12
  614. Const PASSEDGAME:Int = 13
  615. Method Update:Void() Abstract
  616. Method Render:Void(canvas:Canvas) Abstract
  617. Method UnRegister:Void() Abstract
  618. Method New()
  619. parent = New PVector2D
  620. mainv = New PVector2D
  621. pos = New PVector2D
  622. d = New PVector2D
  623. End Method
  624. Method Collided:Int(px:Float,py:Float,hb:HitBox)
  625. Local b2x1:Float,b2y1:Float,b2x2:Float,b2y2:Float
  626. Local b1x1:Float = px + hb.min.x
  627. Local b1y1:Float = py + hb.min.y
  628. Local b1x2:Float = px + hb.max.x
  629. Local b1y2:Float = py + hb.max.y
  630. Select state
  631. Case IN_FORMATION,ALIGNING_OUT,ALIGNING_IN
  632. b2x1 = parent.x + hitBox.min.x
  633. b2y1 = parent.y + hitBox.min.y
  634. b2x2 = parent.x + hitBox.max.x
  635. b2y2 = parent.y + hitBox.max.y
  636. Default
  637. b2x1 = pos.x + hitBox.min.x
  638. b2y1 = pos.y + hitBox.min.y
  639. b2x2 = pos.x + hitBox.max.x
  640. b2y2 = pos.y + hitBox.max.y
  641. End Select
  642. If b1x1 > b2x2 Return False
  643. If b1x2 < b2x1 Return False
  644. If b1y1 > b2y2 Return False
  645. If b1y2 < b2y1 Return False
  646. Return True
  647. End Method
  648. Method SetHitBox:Void(minx:Float,miny:Float,maxx:Float,maxy:Float)
  649. If hitBox= Null
  650. hitBox = New HitBox(minx,miny,maxx,maxy)
  651. Else
  652. hitBox.Set(minx, miny, maxx, maxy)
  653. Endif
  654. End Method
  655. End Class
  656. Class Player Extends Entity
  657. Field minx:Float
  658. Field maxx:Float
  659. Field direction:Int
  660. Field delay:Int
  661. Field StartTime:Int
  662. Field passedLevel:Int
  663. Field lifes:Int
  664. Field trailImg:Image[]
  665. Field shieldTimer:Timer
  666. Field bulletTimer:Timer
  667. Field bulletRateUp:Int
  668. Field fastRate:int
  669. Field shielded:Int
  670. Field decrementRate:int
  671. Field spawnTimer:Timer
  672. Field bulletImg:Image[]
  673. Const SPAWNDELAY:Int = 2000
  674. Method New()
  675. image = media.playerImg
  676. bulletImg = media.bulletImg
  677. trailImg = media.trailImg
  678. delay = 500
  679. decrementRate = 400
  680. startTime = currentTime
  681. minx = image[0].Handle.X
  682. Local img:Image = image[0]
  683. maxx = DeviceWidth -(img.Width/2)
  684. hitBox = New HitBox(6-img.Width/2,4-img.Height/2, img.Width/2 -6, img.Height/2)
  685. minx = image[0].Handle.X
  686. pos.Set(DeviceWidth / 2,DeviceHeight - 40)
  687. lifes = 3
  688. state = ACTIVE
  689. spawnTimer = New Timer(SPAWNDELAY,0,0)
  690. bulletTimer = New Timer(5000,0,0)
  691. shieldTimer = New Timer(5000,0,0)
  692. bulletTimer.Expire()
  693. shieldTimer.Expire()
  694. shielded = False
  695. End Method
  696. Method UnRegister:Void() Override
  697. End Method
  698. Method SpawnReset:Void()
  699. spawnTimer.Reset()
  700. End Method
  701. Method Update:Void() Override
  702. Local dt:Int = decrementRate
  703. If bulletTimer.Update() = False
  704. fastRate = False
  705. dt = 0
  706. Else
  707. fastRate = True
  708. Endif
  709. If shieldTimer.Update() = False
  710. shielded = False
  711. Else
  712. shielded = True
  713. Endif
  714. Select state
  715. Case ACTIVE
  716. direction = Int(Keyboard.KeyDown(Key.Right)) - Int(Keyboard.KeyDown(Key.Left))
  717. If (startTime+(delay-dt)) < currentTime
  718. If Keyboard.KeyDown(Key.Z)
  719. Local b:Bullet = bulletStore.GetItem()
  720. b.Init(bulletImg,trailImg,pos.x,pos.y-12,0,-1,10)
  721. Local bImg:Image = bulletImg[0]
  722. b.SetHitBox(-bImg.Width/2,-bImg.Height/2,bImg.Width/2,bImg.Height/2)
  723. playerBulletList.AddLast(b)
  724. startTime = currentTime
  725. media.ShootSnd1()
  726. Endif
  727. Endif
  728. pos.x += direction * 5
  729. If pos.x < minx pos.x = minx
  730. If pos.x > maxx pos.x = maxx
  731. Case SPAWNING
  732. direction = Int(Keyboard.KeyDown(Key.Right)) - Int(Keyboard.KeyDown(Key.Left))
  733. pos.x += direction * 5
  734. If pos.x < minx pos.x = minx
  735. If pos.x > maxx pos.x = maxx
  736. If spawnTimer.Update() = False
  737. If lifes > 1
  738. state = ACTIVE
  739. Else
  740. state = DEAD
  741. Endif
  742. lifes -= 1
  743. Elseif lifes = 1
  744. lifes -= 1
  745. state = DEAD
  746. Endif
  747. Case DEAD
  748. End Select
  749. End Method
  750. Method Render:Void(canvas:Canvas) Override
  751. Select state
  752. Case ACTIVE
  753. If shielded = False
  754. canvas.DrawImage(image[1],pos.x,pos.y)
  755. Else
  756. canvas.Alpha = .8
  757. canvas.DrawImage(image[0],pos.x,pos.y)
  758. Endif
  759. Case SPAWNING
  760. canvas.Alpha = .6
  761. canvas.DrawImage(image[0],pos.x,pos.y)
  762. End Select
  763. canvas.Alpha = 1.0
  764. For Local i:Int = 0 Until lifes
  765. canvas.DrawImage(image[1],370+i*28,30)
  766. Next
  767. 'hitBox.Render(canvas,pos.x,pos.y)
  768. End Method
  769. End Class
  770. Class Gripper Extends Entity
  771. Field index:Int
  772. Method New()
  773. image = media.gripperImg
  774. pos.Set(100, 50)
  775. SetHitBox(-image[0].Handle.X,-image[0].Handle.Y,image[0].Width-image[0].Handle.X,image[0].Height - image[0].Handle.Y)
  776. startTime = currentTime
  777. frameDelay = 500
  778. totalFrames = 2
  779. state = IN_FORMATION = True
  780. value = 200
  781. End Method
  782. Method Update:Void() Override
  783. If currentTime > startTime+frameDelay
  784. index = (index + 1) Mod totalFrames
  785. startTime = currentTime
  786. Endif
  787. End Method
  788. Method UnRegister:Void() Override
  789. End Method
  790. Method Render:Void(canvas:Canvas) Override
  791. If state = IN_FORMATION
  792. canvas.DrawImage(image[index],parent.x,parent.y,0,1.3,1.3)
  793. Else
  794. canvas.DrawImage(image[index],pos.x,pos.y,0,1.3,1.3)
  795. Endif
  796. End Method
  797. End Class
  798. Class Lazer Extends Entity
  799. Method Update:Void() Override
  800. End Method
  801. Method UnRegister:Void() Override
  802. End Method
  803. Method Render:Void(canvas:Canvas) Override
  804. End Method
  805. End Class
  806. Class Tesla Extends Entity
  807. Field p:PVector2D
  808. Field posx:Float
  809. Field posy:Float
  810. Field direction:Int
  811. Field dist:PVector2D
  812. Field index:Int
  813. Field shootTime:Int
  814. Field shootDelay:Int
  815. Field shootAngle:Float
  816. Field shootAngleStep:Float
  817. Field attackCount:Int
  818. Field bulletImg:Image[]
  819. Field length:Float
  820. Field speed:Float
  821. Global divingCount:Int
  822. Global attackDelay:Int
  823. Global attackTime:Int
  824. Global trailImg:Image[]
  825. Method New(firstAttackTime:Int,attackRate:int)
  826. image = media.teslaImg
  827. trailImg = media.trailImg
  828. bulletImg = media.bulletImg
  829. Local img:Image = image[0]
  830. SetHitBox(-img.Width/2,-img.Height/2,img.Width/2,img.Height/2)
  831. pos.Set(50,50)
  832. startTime = currentTime
  833. frameDelay = attackRate
  834. totalFrames = 2
  835. state = IN_FORMATION
  836. divingCount = 0
  837. attackDelay = 1000
  838. attackTime = currentTime+firstAttackTime
  839. shootDelay = 100
  840. value = 150
  841. dist = New PVector2D
  842. p = New PVector2D
  843. End Method
  844. Method Update:Void() Override
  845. If currentTime > startTime+frameDelay
  846. index = (index + 1) Mod totalFrames
  847. startTime = currentTime
  848. Endif
  849. Select state
  850. Case IN_FORMATION
  851. If divingCount < 2 And player.state = player.ACTIVE
  852. If attackTime+attackDelay < currentTime
  853. If Rnd(10) > 9.5
  854. pos.Set(parent)
  855. p.Set(pos.x,pos.y)
  856. state = LEAVING
  857. posy = 250.0
  858. posx = Rnd(60,580)
  859. dist.Set( posx - pos.x, posy - pos.y)
  860. length = dist.Magnitude()
  861. Local ang:Float = dist.GetAngle()
  862. d.Set(Cos(ang), Sin(ang))
  863. dist.Set(0, 0)
  864. divingCount += 1
  865. attackTime = currentTime
  866. attackCount = 0
  867. speed = 3
  868. Endif
  869. Endif
  870. Endif
  871. Case LEAVING
  872. dist.Add(d.x * speed,d.y * speed)
  873. Local len:Float = dist.Magnitude()
  874. If len < length
  875. pos.Set(p.x + dist.x, p.y + dist.y)
  876. Else
  877. pos.Set(p.x + d.x * length, p.y + d.y * length)
  878. p.Set(pos.x,pos.y)
  879. state = ATTACKING
  880. shootAngle = 45
  881. shootAngleStep = 12
  882. shootTime = currentTime
  883. attackCount = 0
  884. dist.Set(0,0)
  885. Endif
  886. Case ATTACKING
  887. If shootTime + shootDelay < currentTime
  888. If attackCount < 10
  889. Local tdx:Float = Cos(shootAngle)
  890. Local tdy:Float = Sin(shootAngle)
  891. Local b:Bullet = bulletStore.GetItem()
  892. b.Init(bulletImg,trailImg,pos.x+tdx*15.0,pos.y+tdy*15,tdx,tdy,5)
  893. enemyBulletList.AddLast(b)
  894. attackCount += 1
  895. shootAngle += shootAngleStep
  896. shootTime = currentTime
  897. Else
  898. state = RETURNING
  899. Endif
  900. Endif
  901. Case RETURNING
  902. dist.Set(parent.x - pos.x, parent.y - pos.y)
  903. Local targetAngle:Float = dist.GetAngle()
  904. pos.Add(Cos(targetAngle) * speed,Sin(targetAngle) * speed)
  905. angle = targetAngle
  906. If pos.y <= parent.y
  907. pos.Set(parent)
  908. divingCount -= 1
  909. state = IN_FORMATION
  910. Endif
  911. End Select
  912. End Method
  913. Method UnRegister:Void() Override
  914. If state <> IN_FORMATION
  915. divingCount -= 1
  916. Endif
  917. End Method
  918. Method Render:Void(canvas:Canvas) Override
  919. If state = IN_FORMATION
  920. canvas.DrawImage(image[index],parent.x,parent.y,0,1.1,1.1)
  921. Else
  922. canvas.DrawImage(image[index],pos.x,pos.y,0,1.1,1.1)
  923. Endif
  924. End Method
  925. End Class
  926. Class Boxed Extends Entity
  927. Field index:Int
  928. Field posx:Float
  929. Field posy:Float
  930. Field vx:Float
  931. Field vy:Float
  932. Field speed:Float
  933. Field length:Float
  934. Field px:Float
  935. Field py:Float
  936. Field laserImg:Image
  937. Field gunImg:Image
  938. Field lazer:Lazer
  939. Field time:Int
  940. Field delay:Int
  941. Field shake:float
  942. Global divingCount:Int = 0
  943. Global attackDelay:Int
  944. Global attackTime:Int
  945. Method New(firstAttackTime:Int,attackRate:int)
  946. image = media.boxedImg
  947. laserImg = media.lazerImg
  948. gunImg = media.gunbImg
  949. Local img := image[0]
  950. SetHitBox(-img.Width/2,-img.Height/2,img.Width/2,img.Height/2)
  951. state = IN_FORMATION
  952. attackDelay = attackRate
  953. attackTime = currentTime + firstAttackTime
  954. speed = 3
  955. lazer = New Lazer
  956. lazer.hitBox = New HitBox(-6,0,6,100)
  957. value = 100
  958. time = currentTime
  959. delay = 100
  960. index = 0
  961. shake = 0
  962. End Method
  963. Method Update:Void() Override
  964. Select state
  965. Case IN_FORMATION
  966. If divingCount < 2 And player.state = player.ACTIVE
  967. If attackTime+attackDelay < currentTime
  968. If Rnd(10) > 9.0
  969. pos.x = parent.x
  970. pos.y = parent.y
  971. px = pos.x
  972. py = pos.y
  973. state = LEAVING
  974. posy = 350.0
  975. posx = Rnd(60,580)
  976. vx = posx - pos.x
  977. vy = posy - pos.y
  978. length = Sqrt(vx*vx+vy*vy)
  979. Local ang:Float = ATan2(vy,vx)
  980. d.Set( Cos(ang),Sin(ang))
  981. vx = 0
  982. vy = 0
  983. divingCount += 1
  984. attackTime = currentTime
  985. Endif
  986. Endif
  987. Endif
  988. Case LEAVING
  989. vx += d.x * speed
  990. vy += d.y * speed
  991. Local len:Float = Sqrt(vx*vx+vy*vy)
  992. If len < length
  993. pos.x = px + vx
  994. pos.y = py + vy
  995. Else
  996. pos.Set(px + d.x * length, py + d.y * length)
  997. px = pos.x
  998. py = pos.y
  999. state = SWEEPING
  1000. If player.pos.x < px
  1001. If pos.x > 120
  1002. d.x = -1
  1003. Else
  1004. d.x = 1
  1005. Endif
  1006. Else
  1007. If pos.x < 520
  1008. d.x = 1
  1009. Else
  1010. d.x = -1
  1011. Endif
  1012. Endif
  1013. d.y = 0
  1014. length = 120.0
  1015. vx = 0
  1016. vy = 0
  1017. media.LaserSnd()
  1018. Endif
  1019. Case SWEEPING
  1020. vx += d.x*speed
  1021. Local len:Float = Sqrt(vx*vx+vy*vy)
  1022. If len < length
  1023. pos.Set(px + vx, py)
  1024. Else
  1025. pos.Set(px + d.x * length,py)
  1026. state = RETURNING
  1027. Endif
  1028. Case RETURNING
  1029. vx = parent.x - pos.x
  1030. vy = parent.y - pos.y
  1031. Local targetAngle:Float = ATan2(vy,vx)
  1032. pos.Add(Cos(targetAngle) * speed, Sin(targetAngle) * speed)
  1033. angle = targetAngle
  1034. If pos.y <= parent.y
  1035. pos.Set(parent.x, parent.y)
  1036. divingCount -= 1
  1037. state = IN_FORMATION
  1038. Endif
  1039. End Select
  1040. If time + delay <Millisecs()
  1041. index = (index + 1) Mod 3
  1042. time = Millisecs()
  1043. Endif
  1044. shake = (shake - (3.0*ATR)) Mod TwoPi
  1045. End Method
  1046. Method UnRegister:Void() Override
  1047. If state <> IN_FORMATION
  1048. divingCount -= 1
  1049. Endif
  1050. End Method
  1051. Method Render:Void(canvas:Canvas) Override
  1052. If state = IN_FORMATION
  1053. canvas.DrawImage(image[index],parent.x+3*Cos(shake),parent.y+1*Sin(shake),0,1.3,1.3)
  1054. Else
  1055. canvas.DrawImage(image[index],pos.x,pos.y,0,1.3,1.3)
  1056. If state = SWEEPING
  1057. canvas.DrawImage(gunImg,pos.x,pos.y,0,1.3,1.3)
  1058. canvas.DrawImage(laserImg,pos.x,pos.y,0,1,100)
  1059. Endif
  1060. Endif
  1061. 'hitBox.Render(canvas,parent.x,parent.y)
  1062. End Method
  1063. End Class
  1064. Class Micron Extends Entity
  1065. Field index:Int
  1066. Field targetAngle:Float
  1067. Field vx:Float
  1068. Field vy:Float
  1069. Field length:Float
  1070. Field px:Float
  1071. Field py:Float
  1072. Field pivotx:Float
  1073. Field pivoty:Float
  1074. Field rotate:Float
  1075. Field speed:Float
  1076. Field direction:Int
  1077. Field life:int
  1078. Field bulletImg:Image[]
  1079. Field trailImg:Image[]
  1080. Const LEFT:Int = 1
  1081. Const RIGHT:Int = 2
  1082. Const TURN_RADIUS:Float = 40.0
  1083. Const RTA:Float = Pi/180.0
  1084. Const STP:Float = 1.0/(RTA * 20)
  1085. Global divingCount:Int = 0
  1086. Global attackDelay:Int
  1087. Global attackTime:Int
  1088. Global shootTime:Int
  1089. Global shootDelay:Int
  1090. Method New(firstShotStart:Int,firstAttackStart:int)
  1091. image = media.micronImg
  1092. bulletImg = media.bulletImg
  1093. trailImg = media.trailImg
  1094. Local img := image[0]
  1095. SetHitBox(-img.Width/2,-img.Height/2,img.Width/2,img.Height/2)
  1096. pos.Set(50, 100)
  1097. startTime = currentTime
  1098. frameDelay = 100
  1099. totalFrames = 4
  1100. state = IN_FORMATION
  1101. speed = 3
  1102. attackDelay = 1000
  1103. attackTime = currentTime + firstAttackStart 'first petential attack after 3 seconds
  1104. shootDelay = 700
  1105. shootTime = currentTime + firstShotStart'first potential shot after two seconds.
  1106. value = 50
  1107. divingCount = 0
  1108. End Method
  1109. Method ShootAttempt:Void()
  1110. If shootTime + shootDelay < currentTime
  1111. If state = IN_FORMATION
  1112. If Abs(parent.x - player.pos.x) < 6
  1113. Local b:Bullet = bulletStore.GetItem()
  1114. b.Init(bulletImg,trailImg,parent.x,parent.y,0,1,10)
  1115. enemyBulletList.AddLast(b)
  1116. shootTime = currentTime
  1117. Else
  1118. If Rnd(10) > 7
  1119. Local b:Bullet = bulletStore.GetItem()
  1120. b.Init(bulletImg,trailImg,parent.x,parent.y,0,1,10)
  1121. enemyBulletList.AddLast(b)
  1122. shootTime = currentTime
  1123. Endif
  1124. Endif
  1125. Elseif state = ATTACKING
  1126. If Abs(pos.x - player.pos.x) < 2
  1127. Local b:Bullet = bulletStore.GetItem()
  1128. Local tdx:Float = Cos(angle)
  1129. Local tdy:Float = Sin(angle)
  1130. b.Init(bulletImg,trailImg,pos.x+tdx*10.0,pos.y+tdy*10.0,tdx,tdy,10.0)
  1131. enemyBulletList.AddLast(b)
  1132. shootTime = currentTime
  1133. Elseif Rnd(10) > 9
  1134. Local b:Bullet = bulletStore.GetItem()
  1135. Local tdx:Float = Cos(angle)
  1136. Local tdy:Float = Sin(angle)
  1137. b.Init(bulletImg,trailImg,pos.x+tdx*10.0,pos.y+tdy*10.0,tdx,tdy,10.0)
  1138. enemyBulletList.AddLast(b)
  1139. shootTime = currentTime
  1140. Endif
  1141. Endif
  1142. Endif
  1143. End Method
  1144. Method Update:Void() Override
  1145. Select state
  1146. Case IN_FORMATION
  1147. If currentTime > startTime+frameDelay
  1148. index = (index + 1) Mod totalFrames
  1149. startTime = currentTime
  1150. Endif
  1151. If divingCount < 4 And player.state = player.ACTIVE
  1152. If attackTime+attackDelay < currentTime
  1153. If Rnd(1000) > 900.0
  1154. pos.Set(parent)
  1155. state = ALIGNING_OUT
  1156. divingCount += 1
  1157. attackTime = currentTime
  1158. Else
  1159. Endif
  1160. Else
  1161. ShootAttempt()
  1162. Endif
  1163. Endif
  1164. Case ALIGNING_OUT
  1165. angle = (angle + TwoPi) Mod TwoPi
  1166. vx = player.pos.x - parent.x
  1167. vy = player.pos.y - parent.y
  1168. px = parent.x
  1169. py = parent.y
  1170. length = Sqrt(vx*vx+vy*vy)
  1171. targetAngle = (ATan2(vy,vx)+TwoPi) Mod TwoPi
  1172. Local difference:Float = Abs(targetAngle-angle)
  1173. 'turn toward target
  1174. Local stp := 5 * ATR
  1175. If targetAngle < angle
  1176. If difference > Pi
  1177. angle += stp
  1178. Elseif difference < Pi
  1179. angle -= stp
  1180. Endif
  1181. Elseif targetAngle > angle
  1182. If difference > Pi
  1183. angle -= stp
  1184. Elseif difference < Pi
  1185. angle += stp
  1186. Endif
  1187. Endif
  1188. 'If found stop turning
  1189. If difference < 5
  1190. angle = targetAngle
  1191. d.Set(Cos(angle), Sin(angle))
  1192. vx = 0
  1193. vy = 0
  1194. pos.x = parent.x
  1195. pos.y = parent.y
  1196. state = ATTACKING
  1197. Endif
  1198. Case ATTACKING
  1199. vx += d.x * speed
  1200. vy += d.y * speed
  1201. Local len:Float = Sqrt(vx*vx+vy*vy)
  1202. If len >= length
  1203. pos.x = px + vx
  1204. pos.y = py + vy
  1205. state = TURNING
  1206. If player.pos.x < pos.x
  1207. pivotx = pos.x - d.y * TURN_RADIUS
  1208. pivoty = pos.y + d.x * TURN_RADIUS
  1209. rotate = angle - (Pi/2)
  1210. direction = RIGHT
  1211. Else
  1212. pivotx = pos.x + d.y * TURN_RADIUS
  1213. pivoty = pos.y - d.x * TURN_RADIUS
  1214. rotate = angle + (Pi/2)
  1215. direction = LEFT
  1216. Endif
  1217. Else
  1218. pos.Set(px + vx, py + vy)
  1219. ShootAttempt()
  1220. Endif
  1221. Case TURNING
  1222. If direction = RIGHT
  1223. angle += STP * 2
  1224. rotate += STP * 2
  1225. pos.x = pivotx + Cos(rotate) * TURN_RADIUS
  1226. pos.y = pivoty + Sin(rotate) * TURN_RADIUS
  1227. If rotate >= Pi state = RETURNING
  1228. Else
  1229. angle -= STP * 2
  1230. rotate -= STP * 2
  1231. pos.x = pivotx + Cos(rotate) * TURN_RADIUS
  1232. pos.y = pivoty + Sin(rotate) * TURN_RADIUS
  1233. If rotate <= 0 state = RETURNING
  1234. Endif
  1235. Case RETURNING
  1236. vx = parent.x - pos.x
  1237. vy = parent.y - pos.y
  1238. targetAngle = ATan2(vy,vx)
  1239. pos.Add(Cos(targetAngle) * speed,Sin(targetAngle) * speed)
  1240. angle = targetAngle
  1241. If pos.y <= parent.y
  1242. pos.Set(parent.x, parent.y)
  1243. targetAngle = Pi * 1.5
  1244. state = ALIGNING_IN
  1245. Endif
  1246. Case ALIGNING_IN
  1247. angle = (angle + TwoPi) Mod TwoPi
  1248. Local difference:Float = Abs(targetAngle - angle)
  1249. If angle < targetAngle
  1250. If difference < Pi
  1251. angle += 5 * ATR
  1252. Else
  1253. angle -= 5 * ATR
  1254. Endif
  1255. Elseif angle > targetAngle
  1256. If difference < Pi
  1257. angle -= 5.0 * ATR
  1258. Else
  1259. angle += 5.0 * ATR
  1260. Endif
  1261. Endif
  1262. If difference < (5 * ATR)
  1263. divingCount -= 1
  1264. angle = targetAngle
  1265. state = IN_FORMATION
  1266. Endif
  1267. End Select
  1268. End Method
  1269. Method UnRegister:Void() Override
  1270. If state <> IN_FORMATION
  1271. divingCount -= 1
  1272. Endif
  1273. End Method
  1274. Method Render:Void(canvas:Canvas) Override
  1275. Select state
  1276. Case IN_FORMATION
  1277. canvas.DrawImage(image[index],parent.x,parent.y,0,1.3,1.3)
  1278. Case ALIGNING_OUT
  1279. canvas.DrawImage(image[index],parent.x,parent.y,-angle-90,1.3,1.3)
  1280. Case ALIGNING_IN
  1281. canvas.DrawImage(image[index],parent.x,parent.y,-angle-90,1.3,1.3)
  1282. Case TURNING
  1283. If direction = RIGHT
  1284. canvas.DrawImage(image[2],pos.x,pos.y,-angle-90,1.3,1.3)
  1285. Else
  1286. canvas.DrawImage(image[2],pos.x,pos.y,-angle-90,1.3,1.3)
  1287. Endif
  1288. Default
  1289. canvas.DrawImage(image[2],pos.x,pos.y,-angle-90,1.3,1.3)
  1290. End Select
  1291. 'hitBox.Render(canvas,parent.x,parent.y)
  1292. End Method
  1293. End Class
  1294. Class Ufo Extends Entity
  1295. Field frame:Float
  1296. Field speed:Float
  1297. Field dir:Float
  1298. Field delay:Int
  1299. Field stage:Int
  1300. Field active:Int
  1301. Field time:Int
  1302. Field lifes:Int
  1303. Field gunImg:Image
  1304. Field heartImg:Image
  1305. Field shieldImg:Image
  1306. Field specialImg:Image[]
  1307. Field released:Int
  1308. Field nstate:int
  1309. Const STARTLEFT:Int = 1
  1310. Const STARTRIGHT:Int = 2
  1311. Const LEFT:Int = - 1
  1312. Const RIGHT:Int = 1
  1313. Method New(x:Float,y:Float)
  1314. Self.image = media.ufoImg
  1315. specialImg = New Image[3]
  1316. Self.specialImg[Special.HEART] = media.heartImg
  1317. Self.specialImg[Special.GUN] = media.gunImg
  1318. Self.specialImg[Special.SHIELD] = media.shieldImg
  1319. Local img:Image = image[0]
  1320. SetHitBox(-img.Width/2,-img.Height/2+2,img.Width/2,img.Height/2-2)
  1321. pos = New PVector2D(x,y)
  1322. speed = 1.5
  1323. dir = 1
  1324. active = False
  1325. delay = 5000+Rnd(10000)
  1326. active = False
  1327. time = Millisecs()
  1328. lifes = 3
  1329. End Method
  1330. Method Update:Void() Override
  1331. If lifes > 0
  1332. If active = True
  1333. frame = (frame + .2) Mod 4
  1334. If nstate = STARTLEFT
  1335. If pos.x > 680
  1336. active = False
  1337. time = currentTime
  1338. lifes -= 1
  1339. Else
  1340. pos.x += dir * speed
  1341. Endif
  1342. Elseif pos.x < -40
  1343. dir = -dir
  1344. active = False
  1345. time = currentTime
  1346. lifes -= 1
  1347. Else
  1348. pos.x += dir * speed
  1349. Endif
  1350. Else
  1351. If time + delay < currentTime
  1352. If Rnd(2) < 1
  1353. nstate = STARTLEFT
  1354. dir = 1
  1355. pos.x = -40
  1356. Else
  1357. nstate = STARTRIGHT
  1358. dir = -1
  1359. pos.x = 680
  1360. Endif
  1361. active = True
  1362. Endif
  1363. End If
  1364. Endif
  1365. End Method
  1366. Method DeActivate:Void()
  1367. pos.x = -40
  1368. active = False
  1369. delay = 5000+Rnd(10000)
  1370. time = currentTime
  1371. lifes -= 1
  1372. End Method
  1373. Method Reset:Void()
  1374. pos.x = -40
  1375. active = False
  1376. delay = 500+Rnd(10000)
  1377. time = currentTime
  1378. lifes = 3
  1379. End Method
  1380. Method ReleaseSpecial:Void(p:Player)
  1381. Local type:Int
  1382. Local n:Float = Rnd(3.0)
  1383. If n < 1.0
  1384. If p.lifes < 5
  1385. type = Special.HEART
  1386. Else
  1387. type = Special.SHIELD
  1388. Endif
  1389. Elseif n < 2.0
  1390. type = Special.SHIELD
  1391. Else
  1392. type = Special.GUN
  1393. Endif
  1394. Local s:Special = New Special(pos.x,pos.y,2,type)
  1395. specialList.AddLast(s)
  1396. End Method
  1397. Method UnRegister:Void() Override
  1398. End Method
  1399. Method Render:Void(canvas:Canvas) Override
  1400. If active = True
  1401. canvas.DrawImage(image[frame],pos.x,pos.y)
  1402. 'hitBox.Render(canvas,pos.x,pos.y)
  1403. Endif
  1404. End Method
  1405. End Class
  1406. Class Special
  1407. Field pos:PVector2D
  1408. Field D:PVector2D
  1409. Field speed:Float
  1410. Field type:Int
  1411. Field active:Int
  1412. Field timer:Timer
  1413. Field done:Int
  1414. Field image:Image
  1415. Field g:Float
  1416. Const HEART:Int = 0
  1417. Const GUN:Int = 1
  1418. Const SHIELD:Int = 2
  1419. Global hitBox:HitBox = New HitBox
  1420. Method New(x:Float,y:Float,speed:Float,type:Float)
  1421. Self.image = media.specialImg[type]
  1422. pos = New PVector2D(x,y)
  1423. D = New PVector2D(0,1)
  1424. Self.speed = -speed
  1425. active = True
  1426. Self.type = type
  1427. timer = New Timer(1000,0,0)
  1428. g = .2
  1429. done = False
  1430. SetHitBox()
  1431. End Method
  1432. Method SetHitBox:Void()
  1433. hitBox.Set(-image.Handle.X,-image.Handle.Y,image.Width - image.Handle.X,image.Height - image.Handle.Y)
  1434. End Method
  1435. Method Update:Int()
  1436. If done = False
  1437. If active = True
  1438. pos.Add(D.x*speed,D.y*speed)
  1439. speed += g
  1440. If pos.y > 430
  1441. pos.y = 430
  1442. active = False
  1443. timer.Reset()
  1444. Endif
  1445. Else
  1446. If timer.Update() = False
  1447. done = True
  1448. Endif
  1449. Endif
  1450. Endif
  1451. Return Not done
  1452. End Method
  1453. Method UnRegister:Void()
  1454. End Method
  1455. Method Render:Void(canvas:Canvas)
  1456. canvas.DrawImage(image,pos.x,pos.y)
  1457. ' hitBox.Render(pos.x,pos.y)
  1458. End Method
  1459. End Class
  1460. Class Level
  1461. Method Update:Void() Abstract
  1462. Method Render:Void(canvas:Canvas) Abstract
  1463. End Class
  1464. Class Wave Extends Level
  1465. Field grid:Entity[][]
  1466. Field rows:Int
  1467. Field columns:Int
  1468. Field state:Int
  1469. Field angle:Float
  1470. Field direction:Float
  1471. Field speed:Float
  1472. Field cx:Float
  1473. Field cy:Float
  1474. Field explosionImg:Image[]
  1475. Field trailImg:Image[]
  1476. Field level:int
  1477. Const EXPANDING:Int = 1
  1478. Const MOVING:Int = 2
  1479. Method New(level:Int = 0)
  1480. rows = 9
  1481. columns = 6
  1482. Self.explosionImg = media.explosionImg
  1483. trailImg = media.trailImg
  1484. grid = New Entity[columns][]
  1485. InitLevel(level)
  1486. speed = 2.2
  1487. Self.level = level
  1488. End Method
  1489. Method InitLevel:Void(lvl:Int)
  1490. cx = 330
  1491. cy = 50
  1492. state = MOVING
  1493. Print lvl
  1494. Select lvl
  1495. Case 0
  1496. For Local i:Int = 0 Until columns
  1497. grid[i] = New Entity[rows]
  1498. For Local j:Int = 0 Until rows
  1499. grid[i][j] = New Micron(2000,60000)
  1500. grid[i][j].parent.Set(140 + j * 41, 130 + i * 24)
  1501. grid[i][j].mainv.x = grid[i][j].parent.x-cx
  1502. grid[i][j].mainv.y = grid[i][j].parent.y-cy
  1503. Next
  1504. Next
  1505. Case 1
  1506. For Local i:Int = 0 Until columns
  1507. grid[i] = New Entity[rows]
  1508. For Local j:Int = 0 Until rows
  1509. If i < 2
  1510. grid[i][j] = New Boxed(30000,1000)
  1511. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1512. Else
  1513. grid[i][j] = New Micron(1000,60000)
  1514. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1515. Endif
  1516. grid[i][j].mainv.x = grid[i][j].parent.x-cx
  1517. grid[i][j].mainv.y = grid[i][j].parent.y-cy
  1518. Next
  1519. Next
  1520. Case 2
  1521. For Local i:Int = 0 Until columns
  1522. grid[i] = New Entity[rows]
  1523. For Local j:Int = 0 Until rows
  1524. If (i Mod 2) = 0
  1525. grid[i][j] = New Boxed(15000,1000)
  1526. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1527. Else
  1528. grid[i][j] = New Micron(1000,60000)
  1529. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1530. Endif
  1531. grid[i][j].mainv.x = grid[i][j].parent.x-cx
  1532. grid[i][j].mainv.y = grid[i][j].parent.y-cy
  1533. Next
  1534. Next
  1535. Case 3
  1536. For Local i:Int = 0 Until columns
  1537. grid[i] = New Entity[rows]
  1538. For Local j:Int = 0 Until rows
  1539. If i < 2
  1540. grid[i][j] = New Tesla(45000,2000)
  1541. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1542. Elseif i < 4
  1543. grid[i][j] = New Boxed(30000,1000)
  1544. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1545. Else
  1546. grid[i][j] = New Micron(1000,60000)
  1547. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1548. Endif
  1549. grid[i][j].mainv.x = grid[i][j].parent.x-cx
  1550. grid[i][j].mainv.y = grid[i][j].parent.y-cy
  1551. Next
  1552. Next
  1553. Case 4
  1554. For Local i:Int = 0 Until columns
  1555. grid[i] = New Entity[rows]
  1556. For Local j:Int = 0 Until rows
  1557. If i = 0
  1558. grid[i][j] = New Gripper()
  1559. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1560. Elseif i = 1
  1561. grid[i][j] = New Tesla(30000,2000)
  1562. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1563. Elseif i = 2
  1564. grid[i][j] = New Boxed(20000,1000)
  1565. grid[i][j].parent.Set(140 + j * 41, 100 + i * 35)
  1566. Else
  1567. grid[i][j] = New Micron(1000,30000)
  1568. grid[i][j].parent.Set(140 + j * 41, 130 + i * 30 )
  1569. Endif
  1570. grid[i][j].mainv.x = grid[i][j].parent.x-cx
  1571. grid[i][j].mainv.y = grid[i][j].parent.y-cy
  1572. Next
  1573. Next
  1574. End Select
  1575. End Method
  1576. Method SetNextLevel:Void()
  1577. level += 1
  1578. angle = 0
  1579. InitLevel(level)
  1580. End method
  1581. Method CollideBullet:Void(node:List<Bullet>.Node)
  1582. For Local i:Int = 0 Until columns
  1583. For Local j:Int = 0 Until rows
  1584. If grid[i][j]
  1585. Local o:Entity = grid[i][j]
  1586. Local b := node.Value
  1587. If o.Collided(b.pos.x,b.pos.y,b.hitBox)
  1588. node.Remove()
  1589. bulletStore.ReturnItem(b)
  1590. Local e := explosionStore.GetItem()
  1591. If o.state = Entity.IN_FORMATION Or o.state = Entity.ALIGNING_OUT Or o.state = Entity.ALIGNING_IN
  1592. e.Init(o.parent.x,o.parent.y,40)
  1593. Else
  1594. e.Init(o.pos.x,o.pos.y,40)
  1595. Endif
  1596. explosionList.AddLast(e)
  1597. o.UnRegister()
  1598. If o.state = o.IN_FORMATION
  1599. score += o.value
  1600. Else
  1601. score += o.value + 200
  1602. Endif
  1603. media.ExplodeSnd2()
  1604. grid[i][j] = Null
  1605. Return
  1606. Endif
  1607. Else
  1608. Endif
  1609. Next
  1610. Next
  1611. End Method
  1612. Method KilledAll:Int()
  1613. For Local i:Int = 0 Until columns
  1614. For Local j:Int = 0 Until rows
  1615. If grid[i][j] Return False
  1616. Next
  1617. Next
  1618. Return True
  1619. End Method
  1620. Method CollidedPlayer:Int(p:Player)
  1621. For Local i:Int = 0 Until columns
  1622. For Local j:Int = 0 Until rows
  1623. If grid[i][j]
  1624. Local o:Entity = grid[i][j]
  1625. If Cast<Micron>(o) <> Null
  1626. If o.Collided(p.pos.x,p.pos.y,p.hitBox)
  1627. Local e := explosionStore.GetItem()
  1628. If o.state = Entity.IN_FORMATION Or o.state = Entity.ALIGNING_OUT Or o.state = Entity.ALIGNING_IN
  1629. e.Init(o.parent.x,o.parent.y)
  1630. Else
  1631. e.Init(o.pos.x,o.pos.y)
  1632. Endif
  1633. explosionList.AddLast(e)
  1634. o.UnRegister()
  1635. grid[i][j] = Null
  1636. media.ExplodeSnd2()
  1637. score += o.value
  1638. Return True
  1639. Endif
  1640. Elseif o.state = o.SWEEPING
  1641. Local b := Cast<Boxed>(o)
  1642. If b
  1643. If p.Collided(b.pos.x,b.pos.y,b.lazer.hitBox)
  1644. media.ExplodeSnd2()
  1645. Return True
  1646. Endif
  1647. Endif
  1648. Endif
  1649. Endif
  1650. Next
  1651. Next
  1652. Return False
  1653. End Method
  1654. Method Update:Void() Override
  1655. Local len:Float = Sin(angle/2.0)*.3 + 1.0
  1656. For Local i:Int = 0 Until columns
  1657. For Local j:Int = 0 Until rows
  1658. If grid[i][j]
  1659. If state = MOVING
  1660. grid[i][j].parent.x += Cos(angle)*speed
  1661. Else
  1662. grid[i][j].parent.Set(cx+grid[i][j].mainv.x * len,cy+grid[i][j].mainv.y * len)
  1663. Endif
  1664. grid[i][j].Update()
  1665. Endif
  1666. Next
  1667. Next
  1668. angle += 1*ATR 'speed
  1669. If angle > Float(TwoPi)
  1670. If state = MOVING
  1671. state = EXPANDING
  1672. Else
  1673. state = MOVING
  1674. Endif
  1675. angle = angle Mod TwoPi
  1676. Endif
  1677. End Method
  1678. Method Render:Void(canvas:Canvas) Override
  1679. For Local i:Int = 0 Until columns
  1680. For Local j:Int = 0 Until rows
  1681. If grid[i][j]
  1682. grid[i][j].Render(canvas)
  1683. Endif
  1684. Next
  1685. Next
  1686. End Method
  1687. End Class
  1688. Class Bullet Extends Entity
  1689. Field vx:Float
  1690. Field vy:Float
  1691. Field speed:Float
  1692. Field trailImg:Image[]
  1693. Field time:Int
  1694. Field delay:Int
  1695. Method New()
  1696. End Method
  1697. Method New(image:Image[],trail:Image[],x:Float,y:Float,dx:Float,dy:Float,speed:Float)
  1698. Init(image,trail,x,y,dx,dy,speed)
  1699. End Method
  1700. Method Init:Void(image:Image[],trail:Image[],x:Float,y:Float,dx:Float,dy:Float,speed:Float)
  1701. Self.image = image
  1702. Self.pos.Set(x,y)
  1703. Self.d.Set(dx, dy)
  1704. Self.speed = speed
  1705. Self.vx = dx * speed
  1706. Self.vy = dy * speed
  1707. Self.trailImg = trail
  1708. Self.SetHitBox(3-image[0].Handle.X,3-image[0].Handle.Y,image[0].Width - image[0].Handle.X,image[0].Height - image[0].Handle.Y)
  1709. Self.time = Millisecs()
  1710. Self.delay = 60
  1711. End Method
  1712. Method Update:Void() Override
  1713. pos.Add(vx,vy)
  1714. If delay+time < Millisecs()
  1715. Local ap:ParticleA = aparticleStore.GetItem()
  1716. ap.Set(pos.x,pos.y,speed/5.0,ATan2(d.y,d.x),trailImg,2)
  1717. aparticleList.AddLast(ap)
  1718. time = Millisecs()
  1719. Endif
  1720. End Method
  1721. Method UnRegister:Void() Override
  1722. End Method
  1723. Method Render:Void(canvas:Canvas) Override
  1724. canvas.DrawImage(image[0],pos.x,pos.y,0,1.5,1.5)
  1725. 'hitBox.Render(canvas,pos.x,pos.y)
  1726. End Method
  1727. End Class
  1728. Class BulletStore
  1729. Field list:List<Bullet>
  1730. Method New(count:Int)
  1731. list = New List<Bullet>
  1732. Fill(count)
  1733. End Method
  1734. Method Fill:Void(total:Int)
  1735. For Local i:Int = 0 Until total
  1736. list.AddLast(New Bullet())
  1737. Next
  1738. End Method
  1739. Method GetItem:Bullet()
  1740. If Not list.Empty
  1741. Return list.RemoveLast()
  1742. Endif
  1743. Return New Bullet()
  1744. End Method
  1745. Method ReturnItem:Void(bullet:Bullet)
  1746. list.AddLast(bullet)
  1747. End Method
  1748. End Class
  1749. Class Explosion Extends Entity
  1750. Field delay:Int
  1751. Field node:List<Explosion>.Node
  1752. Field frame:Int
  1753. Method New()
  1754. End method
  1755. Method New(x:Float,y:Float,frameDelay:Int=50)
  1756. Init(x,y,frameDelay)
  1757. End Method
  1758. Method Init:Void(x:Float,y:Float,frameDelay:Int=50)
  1759. Self.pos.Set(x,y)
  1760. Self.image = media.explosionImg
  1761. Self.delay = frameDelay
  1762. Self.frame = 0
  1763. Self.totalFrames = image.Length - 1
  1764. Self.startTime = currentTime
  1765. End Method
  1766. Method Update:Void() Override
  1767. If startTime+delay < currentTime
  1768. If frame < totalFrames
  1769. frame += 1
  1770. startTime = currentTime
  1771. Endif
  1772. Endif
  1773. End Method
  1774. Method Done:Int()
  1775. If frame = totalFrames
  1776. If startTime+delay < currentTime
  1777. Return True
  1778. Endif
  1779. Endif
  1780. Return False
  1781. End Method
  1782. Method UnRegister:Void() Override
  1783. End Method
  1784. Method Render:Void(canvas:Canvas) Override
  1785. canvas.DrawImage(image[frame],pos.x,pos.y,0,2.0,2.0)
  1786. End Method
  1787. End Class
  1788. Class ExplosionStore
  1789. Field list:List<Explosion>
  1790. Method New(count:Int)
  1791. list = New List<Explosion>
  1792. Fill(count)
  1793. End Method
  1794. Method Fill:Void(total:Int)
  1795. For Local i:Int = 0 Until total
  1796. list.AddLast(New Explosion())
  1797. Next
  1798. End Method
  1799. Method GetItem:Explosion()
  1800. If Not list.Empty
  1801. Return list.RemoveLast()
  1802. Endif
  1803. Return New Explosion()
  1804. End Method
  1805. Method ReturnItem:Void(explosion:Explosion)
  1806. list.AddLast(explosion)
  1807. End Method
  1808. End Class
  1809. Class AParticleStore
  1810. Field list:List<ParticleA>
  1811. Method New(count:Int)
  1812. list = New List<ParticleA>
  1813. Fill(count)
  1814. End Method
  1815. Method Fill:Void(total:Int)
  1816. For Local i:Int = 0 Until total
  1817. list.AddLast(New ParticleA())
  1818. Next
  1819. End Method
  1820. Method GetItem:ParticleA()
  1821. If Not list.Empty
  1822. Return list.RemoveLast()
  1823. Endif
  1824. Return New ParticleA()
  1825. End Method
  1826. Method ReturnItem:Void(p:ParticleA)
  1827. list.AddLast(p)
  1828. End Method
  1829. End Class
  1830. Class ParticleStore
  1831. Field list:List<Particle>
  1832. Method New(count:Int)
  1833. list = New List<Particle>
  1834. Fill(count)
  1835. End Method
  1836. Method Fill:Void(total:Int)
  1837. For Local i:Int = 0 Until total
  1838. list.AddLast(New Particle())
  1839. Next
  1840. End Method
  1841. Method GetItem:Particle()
  1842. If Not list.Empty
  1843. Return list.RemoveLast()
  1844. Endif
  1845. Return New Particle()
  1846. End Method
  1847. Method ReturnItem:Void(p:Particle)
  1848. list.AddLast(p)
  1849. End Method
  1850. End Class
  1851. Class Particle Extends Entity
  1852. Field speed:Float
  1853. Field angleRot:Float
  1854. Field alpha:Float
  1855. Field alphaDec:Float
  1856. Field frame:Int
  1857. Field node:List<Particle>.Node
  1858. Method Init:Void(image:Image[],x:Float,y:Float,rotate:Float,dx:Float,dy:Float,speed:Float,alphaDec:Float,frame:Int = 0)
  1859. Self.image = image
  1860. Self.pos.Set(x,y)
  1861. Self.d.Set(dx, dy)
  1862. Self.angleRot = rotate
  1863. Self.angle = 0
  1864. Self.speed = speed
  1865. Self.alphaDec = alphaDec
  1866. Self.alpha = 1.0
  1867. Self.frame = frame
  1868. End Method
  1869. Method Done:Int()
  1870. Return alpha <= 0
  1871. End Method
  1872. Method Update:Void() Override
  1873. angle += angleRot
  1874. alpha -= alphaDec
  1875. pos.Add(d.x * speed,d.y * speed)
  1876. End Method
  1877. Method Delet:Void()
  1878. node.Remove()
  1879. End Method
  1880. Method UnRegister:Void() Override
  1881. End Method
  1882. Method Render:Void(canvas:Canvas) Override
  1883. canvas.Alpha = alpha
  1884. canvas.DrawImage(image[frame],pos.x,pos.y,angle,1,1)
  1885. canvas.Alpha = 1.0
  1886. End Method
  1887. End Class
  1888. Function CreateShipExplosion:Void(x:Float,y:Float)
  1889. For Local py:Float = 0 Until 6
  1890. For Local px:Float = 0 Until 6
  1891. Local p:Particle = particleStore.GetItem()
  1892. Local ang:Float = Rnd(0,360)
  1893. p.Init(media.shipExplosionImg,x-12 + px*4,y-12 + py*4,ang,Cos(ang),Sin(ang),Rnd(1,5),.01,py*6+px)
  1894. shipParticleList.AddLast(p)
  1895. Next
  1896. Next
  1897. End Function
  1898. Class Media
  1899. Field atlas:Image
  1900. Field bulletImg:Image[]
  1901. Field ExplosionImg:Image[]
  1902. Field playerImg:Image[]
  1903. Field gripperImg:Image[]
  1904. Field lazerImg:Image
  1905. Field teslaImg:Image[]
  1906. Field boxedImg:Image[]
  1907. Field micronImg:Image[]
  1908. Field ufoImg:Image[]
  1909. Field specialImg:Image[]
  1910. Field starsImg:Image[]
  1911. Field alienImg:Image
  1912. ' Field backGroundImg:Image
  1913. Field trailImg:Image[]
  1914. Field shipExplosionImg:Image[]
  1915. Field explosionImg:Image[]
  1916. Field meteorImg:Image[]
  1917. Field gunbImg:Image
  1918. Field heartImg:Image
  1919. Field gunImg:Image
  1920. Field shieldImg:Image
  1921. Field woopSnd:Sound
  1922. Field shoot1:Sound
  1923. Field explode1:Sound
  1924. Field shoot2:Sound
  1925. Field explode2:Sound
  1926. Field explode3:Sound
  1927. Field shoot3:Sound
  1928. Field laser:Sound
  1929. Field music:Sound
  1930. Field channel:Channel[]
  1931. Field channelIndex:Int
  1932. Method New()
  1933. atlas = Image.Load("asset::aliens.png")
  1934. ' backGroundImg = Image.Load("asset::background.png")
  1935. LoadImages()
  1936. LoadSounds()
  1937. channelIndex = 0
  1938. End Method
  1939. Method LoadImages:Void()
  1940. alienImg = New Image(atlas,0,202,367,310)
  1941. starsImg = New Image[8]
  1942. For Local i:int = 0 Until 8
  1943. starsImg[i] = New Image(atlas,192+16*i,16,16,16)
  1944. starsImg[i].Handle = New Vec2f(.5,.5)
  1945. Next
  1946. trailImg = New Image[8]
  1947. For Local i:Int = 0 Until 8
  1948. trailImg[i] = New Image(atlas,192+16*i,16,16,16)
  1949. trailImg[i].Handle = New Vec2f(.5,.5)
  1950. next
  1951. shipExplosionImg = New Image[36]
  1952. For Local i:Int = 0 Until 36
  1953. shipExplosionImg[i] = New Image(atlas,0+4*i,64,4,4)
  1954. shipExplosionImg[i].Handle = New Vec2f(.5,.5)
  1955. next
  1956. explosionImg = New Image[8]
  1957. For Local i:Int = 0 Until 8
  1958. explosionImg[i] = New Image(atlas,0+24*i,88,24,24)
  1959. explosionImg[i].Handle = New Vec2f(.5,.5)
  1960. Next
  1961. meteorImg = New Image[16]
  1962. For Local i:int = 0 Until 16
  1963. meteorImg[i] = New Image(atlas,0+24*i,120,24,24)
  1964. meteorImg[i].Handle = New Vec2f(.5,.5)
  1965. next
  1966. ufoImg = New Image[4]
  1967. For Local i:Int = 0 Until 4
  1968. ufoImg[i] = New Image(atlas,0+40*i,144,40,20)
  1969. ufoImg[i].Handle = New Vec2f(.5,.5)
  1970. Next
  1971. gripperImg = New Image[2]
  1972. gripperImg[0] = New Image(atlas,0,0,24,24)
  1973. gripperImg[1] = New Image(atlas,24,0,24,24)
  1974. teslaImg = New Image[2]
  1975. For Local i:Int = 0 Until 2
  1976. teslaImg[i] = New Image(atlas,48+24*i,0,24,24)
  1977. teslaImg[i].Handle = New Vec2f(.5,.5)
  1978. Next
  1979. bulletImg = New Image[1]
  1980. bulletImg[0] = New Image(atlas,152,56,8,8)
  1981. bulletImg[0].Handle = New Vec2f(.5,.5)
  1982. micronImg = New Image[4]
  1983. For Local i:Int = 0 Until 4
  1984. micronImg[i] = New Image(atlas,0+16*i,48,16,16)
  1985. micronImg[i].Handle = New Vec2f(.5,.5)
  1986. Next
  1987. boxedImg = New Image[3]
  1988. For Local i:Int = 0 Until 3
  1989. boxedImg[i] = New Image(atlas,96+24*i,24,24,24)
  1990. boxedImg[i].Handle = New Vec2f(.5,.5)
  1991. Next
  1992. lazerImg = New Image(atlas,152,48,16,1)
  1993. lazerImg.Handle = New Vec2f(.5,0)
  1994. gunbImg = New Image(atlas,152,53,16,3)
  1995. gunbImg.Handle = New Vec2f(.5,1)
  1996. playerImg = New Image[2]
  1997. For Local i:Int = 0 Until 2
  1998. playerImg[i] = New Image(atlas,144+24*i,0,24,24)
  1999. playerImg[i].Handle = New Vec2f(.5,.5)
  2000. Next
  2001. specialImg = New Image[3]
  2002. specialImg[0] = New Image(atlas,195,88,18,18)
  2003. specialImg[1] = New Image(atlas,213,88,28,18)
  2004. specialImg[2] = New Image(atlas,249,88,18,18)
  2005. End Method
  2006. Method LoadSounds:Void()
  2007. shoot1 = Sound.Load("asset::shoota.ogg")
  2008. shoot2 = Sound.Load("asset::hita.ogg")
  2009. shoot3 = Sound.Load("asset::fireball.ogg")
  2010. explode1 = Sound.Load("asset::hit.ogg")
  2011. explode2 = Sound.Load("asset::explosion.ogg")
  2012. explode3 = Sound.Load("asset::bomb0.ogg")
  2013. laser = Sound.Load("asset::laser.ogg")
  2014. woopSnd = Sound.Load("asset::woop.ogg")
  2015. music = Sound.Load("asset::kickshock.ogg")
  2016. channel = New Channel[9]
  2017. For Local i:Int = 0 Until 9
  2018. channel[i] = New Channel
  2019. Next
  2020. channel[0].Volume = 0
  2021. channel[0].Play(shoot2)
  2022. channel[0].Volume = 1
  2023. End Method
  2024. Method ShootSnd1:Void()
  2025. channel[channelIndex].Play(shoot1)
  2026. channelIndex = (channelIndex+1) Mod 8
  2027. End Method
  2028. Method ShootSnd2:Void()
  2029. channel[channelIndex].Play(shoot2)
  2030. channelIndex = (channelIndex+1) Mod 8
  2031. End Method
  2032. Method ShootSnd3:Void()
  2033. channel[channelIndex].Play(shoot2)
  2034. channelIndex = (channelIndex+1) Mod 8
  2035. End Method
  2036. Method ExplodeSnd1:Void()
  2037. channel[channelIndex].Play(explode1)
  2038. channelIndex = (channelIndex+1) Mod 8
  2039. End Method
  2040. Method ExplodeSnd2:Void()
  2041. channel[channelIndex].Play(explode2)
  2042. channelIndex = (channelIndex+1) Mod 8
  2043. End Method
  2044. Method ExplodeSnd3:Void()
  2045. channel[channelIndex].Play(explode3)
  2046. channelIndex = (channelIndex+1) Mod 8
  2047. End Method
  2048. Method LaserSnd:Void()
  2049. channel[channelIndex].Play(laser)
  2050. channelIndex = (channelIndex+1) Mod 8
  2051. End Method
  2052. Method WoopSnd:Void()
  2053. channel[channelIndex].Play(woopSnd)
  2054. channelIndex = (channelIndex+1) Mod 8
  2055. End Method
  2056. Method PlayTune:Void()
  2057. channel[8].Play(music,True)
  2058. End Method
  2059. Method StopMusic()
  2060. channel[8].Stop()
  2061. End Method
  2062. End Class
  2063. Class Meteor Extends Entity
  2064. Field speed:Float
  2065. Field index:Float
  2066. Field frameCount:Int
  2067. Field frameTime:Int
  2068. Method New(x:Float,y:Float,angle:Float,speed:Float)
  2069. Self.image = media.meteorImg
  2070. Self.pos.Set(x,y)
  2071. Self.d.Set(Cos(angle),Sin(angle))
  2072. Self.speed = speed
  2073. Self.frameDelay = 100
  2074. Self.frameTime = currentTime
  2075. Self.frameCount = image.Length
  2076. End Method
  2077. Method UnRegister:Void() Override
  2078. End Method
  2079. Method Update:Void() Override
  2080. pos.Add(d.x * speed,d.y * speed)
  2081. If pos.x > 656 And d.x > 0 pos.x = -16
  2082. If pos.x < -16 And d.x < 0 pos.x = 656
  2083. If pos.y > 496 And d.y > 0 pos.y = -16
  2084. If pos.y < -16 And d.y < 0 pos.y = 496
  2085. If frameTime + frameDelay < currentTime
  2086. index = (index + 1) Mod frameCount
  2087. frameTime = currentTime
  2088. Endif
  2089. End Method
  2090. Method Render:Void(canvas:Canvas) Override
  2091. canvas.DrawImage(image[index],pos.x,pos.y,0,1.5,1.5)
  2092. End Method
  2093. End Class
  2094. Class ParticleA
  2095. Field pos:PVector2D
  2096. Field V:PVector2D
  2097. Field D:PVector2D
  2098. Field G:PVector2D
  2099. Field Speed:Float
  2100. Field image:Image[]
  2101. Field frame:Int
  2102. Field alpha:Float
  2103. Method New()
  2104. pos = New PVector2D
  2105. D = New PVector2D
  2106. V = New PVector2D
  2107. G = New PVector2D
  2108. End Method
  2109. Method New(x:Int,y:Int,speed:Float,dir:Float,image:Image[],frame:Int = 0, gx:Float = 0, gy:Float = 0)
  2110. Self.image = image
  2111. If image = Null DebugStop()
  2112. Self.frame = frame
  2113. pos = New PVector2D(x,y)
  2114. D = New PVector2D(Cos(dir),Sin(dir))
  2115. V = New PVector2D(D).Multiply(speed)
  2116. G = New PVector2D(gx,gy)
  2117. End Method
  2118. Method Set:ParticleA(x:Int,y:Int,speed:Float,dir:Float,image:Image[],frame:Int = 0, gx:Float = 0, gy:Float = 0,alpha:Float = 1)
  2119. Self.image = image
  2120. Self.frame = frame
  2121. Self.alpha = alpha
  2122. pos.Set(x,y)
  2123. D.Set(Cos(dir),Sin(dir))
  2124. V.Set(D).Multiply(speed)
  2125. G.Set(gx,gy)
  2126. Return Self
  2127. End Method
  2128. Method Update:Bool()
  2129. Local done:Bool = False
  2130. pos.Add(V.Add(G))
  2131. alpha -= .02
  2132. If alpha <= 0
  2133. done = true
  2134. Endif
  2135. Return done
  2136. End Method
  2137. Method Render:Void(canvas:Canvas)
  2138. canvas.Alpha = alpha
  2139. canvas.DrawImage(image[frame], pos.x, pos.y,0,2,2)
  2140. End Method
  2141. End Class
  2142. Class Stars
  2143. Field stars:PVector2D[]
  2144. Field starsImg:Image[]
  2145. Field starsIdx:Int[]
  2146. Field starsAlp:Float[]
  2147. Const TOTALSTARS:Int = 150
  2148. Method New()
  2149. starsImg = media.starsImg
  2150. stars = New PVector2D[TOTALSTARS]
  2151. starsIdx = New Int[TOTALSTARS]
  2152. starsAlp = New Float[TOTALSTARS]
  2153. For Local i:int = 0 Until TOTALSTARS
  2154. stars[i] = New PVector2D(Rnd(640),Rnd(480))
  2155. starsIdx[i] = Rnd(7)
  2156. starsAlp[i] = Rnd()
  2157. Next
  2158. End Method
  2159. Method Update:Void()
  2160. For Local i:Int = 0 Until TOTALSTARS
  2161. starsAlp[i] -= .005
  2162. If starsAlp[i] < 0
  2163. starsAlp[i] = 1.0
  2164. Endif
  2165. Next
  2166. End Method
  2167. Method Render:Void(canvas:Canvas)
  2168. canvas.BlendMode = BlendMode.Additive
  2169. For Local i:Int = 0 Until TOTALSTARS
  2170. canvas.Alpha = starsAlp[i]
  2171. canvas.DrawImage(starsImg[starsIdx[i]],stars[i].x,stars[i].y)
  2172. Next
  2173. canvas.BlendMode = BlendMode.Alpha
  2174. canvas.Alpha = 1.0
  2175. End Method
  2176. End Class
  2177. Class Timer
  2178. Field x:Float
  2179. Field y:Float
  2180. Field startTime:Int
  2181. Field duration:Int
  2182. Field timeRemaining:Int
  2183. Field lapsedTime:Int
  2184. Const SECOND:Int = 1000
  2185. Method New(duration:Int,x:Float,y:Float)
  2186. startTime = currentTime
  2187. Self.duration = duration
  2188. lapsedTime = currentTime - startTime
  2189. timeRemaining = ((duration - lapsedTime)/SECOND)
  2190. End Method
  2191. Method Reset:Void()
  2192. startTime = currentTime
  2193. lapsedTime = currentTime - startTime
  2194. timeRemaining = ((duration - lapsedTime)/SECOND)
  2195. End Method
  2196. Method Expire:Void()
  2197. startTime = currentTime - (duration+duration)
  2198. Update()
  2199. End Method
  2200. Method Update:Int()
  2201. lapsedTime = currentTime - startTime
  2202. timeRemaining = ((duration - lapsedTime)/SECOND)
  2203. If timeRemaining < 0
  2204. timeRemaining = 0
  2205. Return False
  2206. Endif
  2207. Return True
  2208. End Method
  2209. Method Render:Void(canvas:Canvas)
  2210. canvas.Color = New Color(0,1,0) '0,255,0
  2211. RenderText(canvas,"Seconds Left :"+timeRemaining,x,y) '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
  2212. End Method
  2213. End Class