PromptInvasion.monkey2 57 KB

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