menus.js 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686
  1. function DiPoint(frame)
  2. {
  3. var returner =
  4. {
  5. frame: frame,
  6. x: 0,
  7. y: 0,
  8. isTouched: function(touchX, touchY)
  9. {
  10. return touchX > this.x && touchX < this.x +image[this.frame].width
  11. && touchY > this.y && touchY < this.y +image[this.frame].height
  12. },
  13. changeX: function(amount) {this.x += amount;},
  14. changeY: function(amount) {this.y += amount;},
  15. setLeft : function(amount) {this.x = amount;},
  16. setTop : function(amount) {this.y = amount;},
  17. setRight : function(amount) {this.x = amount -image[this.frame].width;},
  18. setBottom: function(amount) {this.y = amount -image[this.frame].height;},
  19. setCenterX: function(amount) {this.x = amount -image[this.frame].width /2;},
  20. setCenterY: function(amount) {this.y = amount -image[this.frame].height/2;},
  21. getLeft : function() {return this.x;},
  22. getTop : function() {return this.y;},
  23. getRight : function() {return this.x +image[this.frame].width ;},
  24. getBottom: function() {return this.y +image[this.frame].height;},
  25. getCenterX: function() {return this.x +image[this.frame].width /2;},
  26. getCenterY: function() {return this.y +image[this.frame].height/2;},
  27. draw: function()
  28. {
  29. context.drawImage(image[this.frame], this.x, this.y);
  30. },
  31. drawOffset: function(offsetX)
  32. {
  33. context.drawImage(image[this.frame], this.x +offsetX, this.y);
  34. },
  35. getSquare: function(offsetX)
  36. {
  37. return [this.x +offsetX, this.y, this.x +image[this.frame].width +offsetX, this.y +image[this.frame].height];
  38. },
  39. getSquareHalved: function()
  40. {
  41. return [this.x +image[this.frame].width/4, this.y, this.x +image[this.frame].width *3/4, this.y +image[this.frame].height];
  42. }
  43. }
  44. return returner;
  45. }
  46. function DiAnimation(max)
  47. {
  48. var returner =
  49. {
  50. counterMax: 0,
  51. counterCurrent: 0,
  52. bPositive: false,
  53. update: function()
  54. {
  55. //Positive Animation
  56. if (this.bPositive && this.counterCurrent < this.counterMax)
  57. {
  58. //Advance Animation
  59. this.counterCurrent++;
  60. //Return that animation is updated
  61. return true;
  62. }
  63. else
  64. //Negative Animation
  65. if (!this.bPositive && this.counterCurrent > 0)
  66. {
  67. //Advance Animation
  68. this.counterCurrent--;
  69. //Return that animation is updated
  70. return true;
  71. }
  72. //Return that animation is not updated
  73. return false;
  74. },
  75. //Commands
  76. startFromBeggining: function() {this.counterCurrent = 0; this.bPositive = true;},
  77. startFromEnd: function() {this.counterCurrent = this.counterMax; this.bPositive = false;},
  78. flip: function() {this.bPositive = !this.bPositive;},
  79. start: function(frameTime)
  80. {
  81. //Count Frames
  82. this.counterMax = frameTime;
  83. this.counterCurrent = 0;
  84. //Start Animation
  85. this.bPositive = true;
  86. },
  87. //Isers
  88. isPositive: function() {return this.bPositive;},
  89. isAtStart : function() {return this.counterCurrent == 0 && !this.bPositive;},
  90. isAtEnd : function() {return this.counterCurrent == this.counterMax && this.bPositive;},
  91. isRunning : function()
  92. {
  93. return this.counterCurrent > 0 && !this.bPositive
  94. || this.counterCurrent < this.counterMax && this.bPositive;
  95. },
  96. //Getters
  97. getDistance: function(amount) {return amount *this.counterCurrent /this.counterMax;},
  98. //Setters
  99. setMax : function(amount) {this.counterMax = amount;},
  100. setCounter: function(amount) {this.counterCurrent = amount;},
  101. }
  102. //Constructor
  103. //Set Max
  104. returner.counterMax = max;
  105. //Returner
  106. return returner;
  107. }
  108. function Ground()
  109. {
  110. //Create
  111. var returner =
  112. {
  113. image: DiPoint(15),
  114. width: 3,
  115. selfDestruct: false,
  116. selfDestructTimer: -1,
  117. setRight: function(amount) {this.image.x = amount -(image[15].width *this.width);},
  118. setCenterX: function(amount) {this.image.x = amount -(image[15].width *this.width)/2;},
  119. getRight: function() {return this.image.x +(this.width *image[15].width);},
  120. getCenterX: function() {return this.image.x +(this.width *image[15].width)/2;},
  121. setWidth: function(amount) {this.width = amount;},
  122. getWidth: function() {return this.width *image[15].width;},
  123. getGroundLevel: function() {return this.image.y +image[15].height/4;},
  124. update: function()
  125. {
  126. //If it's being destroyed
  127. if (this.selfDestructTimer > -1)
  128. {
  129. //Advance animation and check if it finished
  130. if (++this.selfDestructTimer >= (12 *this.width)/2)
  131. {
  132. //Make ground off-screen
  133. this.image.setBottom(height*2);
  134. //Reset SelfDestruct
  135. this.selfDestruct = false;
  136. this.selfDestructTimer = -3;
  137. }
  138. }
  139. },
  140. draw: function()
  141. {
  142. for (i = 0; i < this.width; i++)
  143. {
  144. var imageN;
  145. if (i == 0) imageN = 0; else
  146. if (i == this.width -1) imageN = 2;
  147. else imageN = 1;
  148. context.drawImage(image[this.image.frame +imageN], this.image.x +image[this.image.frame].width *i, this.image.y);
  149. }
  150. },
  151. drawOffset: function(offsetX)
  152. {
  153. for (i = 0; i < this.width; i++)
  154. {
  155. if (this.selfDestructTimer > (12 *this.width)/2/2)
  156. this.image.frame = 18;
  157. var imageN;
  158. if (i == 0) imageN = 0; else
  159. if (i == this.width -1) imageN = 2;
  160. else imageN = 1;
  161. context.drawImage(image[this.image.frame +imageN], this.image.x +image[this.image.frame].width *i +offsetX, this.image.y);
  162. }
  163. }
  164. }
  165. //Init
  166. //Return
  167. return returner;
  168. }
  169. function Character()
  170. {
  171. //Create
  172. var returner =
  173. {
  174. //Extends diPoint
  175. image: DiPoint(28),
  176. //State
  177. RUNNING: 0,
  178. FALLING: 1,
  179. JUMPING: 2,
  180. //Animation
  181. animation: DiAnimation(24),
  182. aJump: 15,
  183. //AirJump
  184. pAirJump: DiPoint(40),
  185. aAirJump: DiAnimation(15),
  186. canAirJump: true,
  187. //Character State
  188. state: 1,
  189. //Frame
  190. stateFrame: 8,
  191. currentFrame: 0,
  192. //Shield & Land
  193. isShielded: false,
  194. justLanded: false,
  195. walkingOn: 0,
  196. //Magic Circle
  197. circleSize: 0,
  198. visualCircleSize: 0,
  199. update: function(groundLevel, jumpHeight)
  200. {
  201. if (this.justLanded) this.justLanded = false;
  202. //Update state
  203. switch (this.state)
  204. {
  205. case this.RUNNING:
  206. //If running off edge, fall down
  207. if (this.image.y +image[this.image.frame].height != groundLevel)
  208. {
  209. this.state = this.FALLING;
  210. this.stateFrame = 8;
  211. this.currentFrame = 0;
  212. }
  213. break;
  214. case this.FALLING:
  215. //Apply gravity
  216. this.image.y += jumpHeight /12;
  217. //If fell on ground
  218. if (this.image.y +image[this.image.frame].height >= groundLevel
  219. && this.image.y +image[this.image.frame].height < groundLevel +jumpHeight /12)
  220. {
  221. //Set character on top of ground
  222. this.image.y = groundLevel -image[this.image.frame].height;
  223. //Start Walking
  224. this.state = this.RUNNING;
  225. this.stateFrame = 0;
  226. this.currentFrame = 0;
  227. this.justLanded = true;
  228. this.canAirJump = true;
  229. }
  230. break;
  231. case this.JUMPING:
  232. //Keep jumping
  233. this.image.y -= jumpHeight /15;
  234. //If animation reaches end
  235. if (this.aJump > 15)
  236. {
  237. //Start Falling
  238. this.state = this.FALLING;
  239. this.stateFrame = 8;
  240. this.currentFrame = 0;
  241. }
  242. //Advance animation
  243. this.aJump++;
  244. break;
  245. }
  246. //Animation
  247. if (this.animation.update())
  248. if (this.animation.counterCurrent %4 == 0)
  249. {
  250. this.currentFrame++;
  251. if (this.currentFrame >= 8
  252. || (this.stateFrame != 0 && this.currentFrame >= 1))
  253. this.currentFrame = 0;
  254. if (this.animation.isAtEnd())
  255. this.animation.startFromBeggining();
  256. //if ((this.currentFrame == 1 || this.currentFrame == 5)
  257. //&& this.stateFrame == 0)
  258. // GameSurface.playSound(0);
  259. }
  260. //Magic Circle
  261. if (this.visualCircleSize > this.circleSize) this.visualCircleSize -= 4; else
  262. if (this.visualCircleSize < this.circleSize) this.visualCircleSize += 4;
  263. //if (this.aAirJump.update())
  264. // invisJump.setAlpha(aAirJump.getDistance(255));
  265. this.pAirJump.changeX(-4);
  266. }, //end update
  267. draw: function()
  268. {
  269. var alpha = context.globalAlpha;
  270. //pAirJump
  271. if (this.aAirJump.update())
  272. {
  273. context.globalAlpha = this.aAirJump.getDistance(1);
  274. this.pAirJump.draw();
  275. }
  276. //Alpha
  277. context.globalAlpha = 0.3;
  278. //Magic Circle
  279. context.beginPath();
  280. context.arc(this.image.getCenterX(), this.image.getCenterY(),
  281. this.visualCircleSize, 0, 2 * Math.PI, false);
  282. context.fillStyle = 'black';
  283. context.fill();
  284. //Alpha
  285. context.globalAlpha = alpha;
  286. context.fillStyle = 'white';
  287. //Shield Back
  288. if (this.isShielded)
  289. context.drawImage(image[39],
  290. this.image.x, this.image.y);
  291. //Character
  292. context.drawImage(image[this.image.frame +this.stateFrame +this.currentFrame], this.image.x, this.image.y);
  293. //Shield Front
  294. if (this.isShielded)
  295. context.drawImage(image[38],
  296. this.image.x, this.image.y);
  297. },
  298. drawSimple: function()
  299. {
  300. context.drawImage(image[this.image.frame +this.currentFrame], this.image.x, this.image.y);
  301. },
  302. animate: function()
  303. {
  304. //Animation
  305. if (this.animation.update())
  306. if (this.animation.counterCurrent %4 == 0)
  307. {
  308. this.currentFrame++;
  309. if (this.currentFrame >= 8)
  310. this.currentFrame = 0;
  311. if (this.animation.isAtEnd())
  312. this.animation.startFromBeggining();
  313. //if ((this.currentFrame == 1 || this.currentFrame == 5)
  314. //&& this.stateFrame == 0)
  315. // GameSurface.playSound(0);
  316. }
  317. },
  318. jump: function()
  319. {
  320. if (true)
  321. //if (this.aJump > 5)
  322. if (this.canAirJump || this.circleSize > 0)
  323. {
  324. //Use Mana
  325. if (!this.canAirJump) this.circleSize -= 36;// *GameSurface.density;
  326. else
  327. //Waste Air Jump
  328. if (this.state == this.FALLING || this.state == this.JUMPING)
  329. {
  330. this.canAirJump = false;
  331. this.pAirJump.setCenterY(this.image.getBottom());
  332. this.pAirJump.setCenterX(this.image.getCenterX());
  333. this.aAirJump.startFromEnd();
  334. }
  335. //Jump Animation
  336. this.state = this.JUMPING;
  337. this.stateFrame = 9;
  338. this.currentFrame = 0;
  339. this.aJump = 0;
  340. //Sound
  341. //GameSurface.playSound(1);
  342. }
  343. },
  344. giveShield: function() {this.isShielded = true;},
  345. loseShield: function() {this.isShielded = fale;},
  346. addManaLevel: function()
  347. {
  348. //If circleSize smaller than max size
  349. if (this.circleSize < 108)
  350. {
  351. //Make circle bigger
  352. this.circleSize += 36;
  353. //GameSurface.playSound(3);
  354. }
  355. //circleSize greater or equal to max size
  356. else
  357. {
  358. //Remove circle
  359. this.circleSize = 0;
  360. //GameSurface.playSound(4);
  361. }
  362. },
  363. loseMana: function() {this.circleSize = 0;}
  364. }
  365. //Constructor
  366. returner.pAirJump.setRight(0);
  367. //returner.animation.startFromBeggining();
  368. returner.animation.startFromBeggining();
  369. //Return
  370. return returner;
  371. }
  372. function Background()
  373. {
  374. //Create Background
  375. var returner =
  376. {
  377. cloud1: DiPoint(3),
  378. cloud2: DiPoint(3),
  379. cloud3: DiPoint(4),
  380. mountain: [DiPoint(0), DiPoint(2), DiPoint(1)],
  381. lastMountain: 2,
  382. counter: 0,
  383. update: function(cameraX)
  384. {
  385. if (++this.counter == 5)
  386. {
  387. this.counter = 0;
  388. this.cloud1.changeX(1);
  389. if (this.cloud1.getLeft() -cameraX/12 > width)
  390. this.cloud1.setRight(cameraX/12);
  391. this.cloud2.changeX(1);
  392. if (this.cloud2.getLeft() -cameraX/12 > width)
  393. this.cloud2.setRight(cameraX/12);
  394. this.cloud3.changeX(2);
  395. if (this.cloud3.getLeft() -cameraX/6 > width)
  396. this.cloud3.setRight(cameraX/6);
  397. return true;
  398. }
  399. return false;
  400. },
  401. draw: function()
  402. {
  403. this.cloud1.draw();
  404. this.cloud2.draw();
  405. this.mountain[0].draw();
  406. this.mountain[1].draw();
  407. this.mountain[2].draw();
  408. this.cloud3.draw();
  409. },
  410. drawOffset: function(offsetX)
  411. {
  412. this.cloud1.drawOffset(offsetX/12);
  413. this.cloud2.drawOffset(offsetX/12);
  414. this.mountain[0].drawOffset(offsetX/9);
  415. this.mountain[1].drawOffset(offsetX/9);
  416. this.mountain[2].drawOffset(offsetX/9);
  417. this.cloud3.drawOffset(offsetX/6);
  418. },
  419. checkLimits: function(cameraX)
  420. {
  421. if (this.cloud1.getRight() -cameraX/12 < 0)
  422. this.cloud1.setLeft(cameraX/12 +width);
  423. if (this.cloud2.getRight() -cameraX/12 < 0)
  424. this.cloud2.setLeft(cameraX/12 +width);
  425. for (var i = 0; i < 3; i++)
  426. if (this.mountain[i].getRight() -cameraX/9 < 0)
  427. {
  428. //Set Frame
  429. this.mountain[i].frame = getRandomInt(0, 1);
  430. if (this.mountain[i].frame == this.mountain[this.lastMountain].frame)
  431. this.mountain[i].frame = 2;
  432. //Set X
  433. if (this.mountain[this.lastMountain].getRight() -cameraX/9 > width)
  434. this.mountain[i].setLeft(this.mountain[this.lastMountain].getRight());
  435. else
  436. this.mountain[i].setLeft(cameraX/9 +width);
  437. //Set Y
  438. if (this.mountain[i].frame == 2)
  439. this.mountain[i].setTop(0);
  440. else
  441. this.mountain[i].setBottom(height);
  442. //Set last mountain
  443. this.lastMountain = i;
  444. }
  445. if (this.cloud3.getRight() -cameraX/6 < 0)
  446. this.cloud3.setLeft(cameraX/6 +width);
  447. },
  448. materialize: function(cameraX)
  449. {
  450. this.cloud1.setLeft(this.cloud1.getLeft() -cameraX/12);
  451. this.cloud2.setLeft(this.cloud2.getLeft() -cameraX/12);
  452. for (i = 0; i < 3; i++)
  453. this.mountain[i].setLeft(this.mountain[i].getLeft() -cameraX/9);
  454. this.cloud3.setLeft(this.cloud3.getLeft() -cameraX/6);
  455. }
  456. }
  457. //Prepare Background
  458. returner.cloud1.setCenterX(width/4);
  459. returner.cloud2.setCenterX(width *3/4);
  460. returner.cloud2.setCenterY(height *3/4);
  461. returner.cloud3.setRight (width);
  462. returner.cloud3.setBottom(height/2);
  463. returner.mountain[0].setBottom(height);
  464. returner.mountain[0].setCenterX(0);
  465. returner.mountain[1].setLeft(width -image[returner.mountain[1].frame].width *2/3);
  466. returner.mountain[2].setLeft(returner.mountain[1].getRight());
  467. returner.mountain[2].setBottom(height);
  468. //Return Background
  469. return returner;
  470. }
  471. function MainMenu(bHardRestart)
  472. {
  473. //Create Menu
  474. var returner =
  475. {
  476. aBasic: DiAnimation(10),
  477. ground: Ground(3),
  478. tree0: DiPoint(5),
  479. tree1: DiPoint(6),
  480. title: DiPoint(7),
  481. buttonStart: DiPoint(8),
  482. buttonExtra: DiPoint(8),
  483. buttonMute: DiPoint(26),
  484. bDraw: true,
  485. nextMenu: 0,
  486. hardRestart: bHardRestart,
  487. update: function()
  488. {
  489. //Input
  490. if (input)
  491. {
  492. input = false;
  493. if (this.buttonStart.isTouched(touchX, touchY))
  494. this.destroy(2); else
  495. if (this.buttonExtra.isTouched(touchX, touchY))
  496. this.destroy(1); else
  497. if (this.buttonMute.isTouched(touchX, touchY))
  498. {
  499. if (bSound)
  500. {
  501. this.buttonMute.frame = 27;
  502. bSound = false;
  503. }
  504. else
  505. {
  506. this.buttonMute.frame = 26;
  507. bSound = true;
  508. }
  509. }
  510. sound.play();
  511. }
  512. //Update menu
  513. if (this.aBasic.update())
  514. {
  515. if (this.aBasic.isAtStart())
  516. return this.nextMenu;
  517. bDraw = true;
  518. }
  519. //Move background
  520. if (background.update(0))
  521. bDraw = true;
  522. },
  523. draw: function()
  524. {
  525. //Background
  526. background.draw();
  527. if (this.hardRestart && this.aBasic.bPositive)
  528. context.globalAlpha = this.aBasic.getDistance(10) /10;
  529. //Ground
  530. this.ground.draw();
  531. //Trees
  532. this.tree0.draw();
  533. this.tree1.draw();
  534. //Alpha
  535. context.globalAlpha = this.aBasic.getDistance(10) /10;
  536. //Title
  537. this.title.draw();
  538. //Buttons
  539. this.buttonStart.draw();
  540. this.buttonExtra.draw();
  541. //this.buttonMute.draw();
  542. //Texts
  543. //var n =
  544. context.shadowColor = "rgba(0, 0, 0, 1)";
  545. context.fillText('Start', this.buttonStart.getCenterX(), this.buttonStart.getCenterY() +fontSize/2);
  546. context.fillText('Extra', this.buttonExtra.getCenterX(), this.buttonExtra.getCenterY() +fontSize/2);
  547. context.shadowColor = "rgba(0, 0, 0, 0)";
  548. //Reset alpha
  549. context.globalAlpha = 1;
  550. },
  551. destroy: function(menu)
  552. {
  553. this.nextMenu = menu;
  554. this.aBasic.startFromEnd();
  555. }
  556. }
  557. //Prepare Menu
  558. //Animation
  559. returner.aBasic.startFromBeggining();
  560. //Ground
  561. returner.ground.setWidth(width /image[15].width +1);
  562. returner.ground.setCenterX(width/2);
  563. returner.ground.image.setBottom(height);
  564. //Trees
  565. returner.tree0.setCenterX(width /4);
  566. returner.tree0.setBottom (returner.ground.getGroundLevel());
  567. returner.tree1.setCenterX(width *5/6);
  568. returner.tree1.setBottom (returner.ground.getGroundLevel());
  569. //Title
  570. returner.title.setCenterX(width /2);
  571. returner.title.setCenterY(height/4);
  572. //Buttons
  573. returner.buttonStart.setCenterX(width /3);
  574. returner.buttonStart.setCenterY(height *2/3);
  575. returner.buttonExtra.setCenterX(width *2/3);
  576. returner.buttonExtra.setCenterY(height *2/3);
  577. returner.buttonMute.setRight (width -image[returner.buttonMute.frame].width /2);
  578. returner.buttonMute.setBottom(height -image[returner.buttonMute.frame].height /2);
  579. //Return Menu
  580. return returner;
  581. }
  582. function ExtraMenu()
  583. {
  584. //Create Menu
  585. var returner =
  586. {
  587. aBasic: DiAnimation(10),
  588. //Environment
  589. ground: Ground(3),
  590. tree0: DiPoint(5),
  591. tree1: DiPoint(6),
  592. //Dark Dimension
  593. darkDimensionLogo: DiPoint(10),
  594. //Back Buttons
  595. buttonBack: DiPoint(8),
  596. //Change Character
  597. charState: -1,
  598. aChangeChar: 0,
  599. character: Character(),
  600. buttonChangeChar: DiPoint(8),
  601. //Etc
  602. bDraw: true,
  603. nextMenu: 0,
  604. update: function()
  605. {
  606. //Input
  607. if (input)
  608. {
  609. input = false;
  610. if (this.buttonBack.isTouched(touchX, touchY))
  611. this.destroy(0); else
  612. if (this.buttonChangeChar.isTouched(touchX, touchY))
  613. this.charState = 0;
  614. }
  615. //Update menu
  616. if (this.aBasic.update())
  617. {
  618. if (this.aBasic.isAtStart())
  619. return this.nextMenu;
  620. bDraw = true;
  621. }
  622. //Move background
  623. if (background.update(0))
  624. bDraw = true;
  625. //Character
  626. this.character.animate();
  627. if(this.charState >= 0)
  628. {
  629. this.aChangeChar++;
  630. this.character.image.setLeft(width * 13/16 +(width *3/16 *Math.cos(Math.radians(90 -(this.aChangeChar*180/10)))));
  631. this.character.image.setBottom(this.ground.getGroundLevel() +image[this.character.image.frame].height +(image[this.character.image.frame].height *Math.sin(Math.radians(270+(this.aChangeChar*180/10)))));
  632. if (this.aChangeChar == 10)
  633. {
  634. if (bFirstChar)
  635. {
  636. bFirstChar = false;
  637. //change char
  638. image[28].src = 'images/diment_run_0.png';
  639. image[29].src = 'images/diment_run_1.png';
  640. image[30].src = 'images/diment_run_2.png';
  641. image[31].src = 'images/diment_run_3.png';
  642. image[32].src = 'images/diment_run_4.png';
  643. image[33].src = 'images/diment_run_5.png';
  644. image[34].src = 'images/diment_run_6.png';
  645. image[35].src = 'images/diment_run_7.png';
  646. image[36].src = 'images/diment_fall.png';
  647. image[37].src = 'images/diment_jump.png';
  648. }
  649. else
  650. {
  651. bFirstChar = true;
  652. image[28].src = 'images/darek_run_0.png';
  653. image[29].src = 'images/darek_run_1.png';
  654. image[30].src = 'images/darek_run_2.png';
  655. image[31].src = 'images/darek_run_3.png';
  656. image[32].src = 'images/darek_run_4.png';
  657. image[33].src = 'images/darek_run_5.png';
  658. image[34].src = 'images/darek_run_6.png';
  659. image[35].src = 'images/darek_run_7.png';
  660. image[36].src = 'images/darek_fall.png';
  661. image[37].src = 'images/darek_jump.png';
  662. }
  663. }else
  664. if (this.aChangeChar >= 20)
  665. {
  666. this.charState = -1;
  667. this.aChangeChar = 0;
  668. }
  669. }
  670. //If it's destroyed, return next action
  671. //...
  672. },
  673. draw: function()
  674. {
  675. //Background
  676. background.draw();
  677. //Ground
  678. this.ground.draw();
  679. //Trees
  680. this.tree0.draw();
  681. this.tree1.draw();
  682. //Alpha
  683. context.globalAlpha = this.aBasic.getDistance(10) /10;
  684. //Dark Dimension
  685. this.darkDimensionLogo.draw();
  686. //Character
  687. this.character.drawSimple();
  688. //Buttons
  689. this.buttonBack.draw();
  690. this.buttonChangeChar.draw();
  691. //Texts
  692. context.shadowColor = "rgba(0, 0, 0, 1)";
  693. context.fillText('Back', this.buttonBack.getCenterX(), this.buttonBack.getCenterY() +fontSize/2);
  694. context.fillText('Change', this.buttonChangeChar.getCenterX(), this.buttonChangeChar.getCenterY() +fontSize/2);
  695. context.fillText('Made by', this.darkDimensionLogo.getCenterX(), this.darkDimensionLogo.getTop());
  696. context.fillText('Dark Dimension', this.darkDimensionLogo.getCenterX(), this.darkDimensionLogo.getBottom() +fontSize);
  697. context.shadowColor = "rgba(0, 0, 0, 0)";
  698. //Reset alpha
  699. context.globalAlpha = 1;
  700. },
  701. destroy: function(menu)
  702. {
  703. this.nextMenu = menu;
  704. this.aBasic.startFromEnd();
  705. }
  706. }
  707. //Prepare Menu
  708. //Animation
  709. returner.aBasic.startFromBeggining();
  710. //Ground
  711. returner.ground.setWidth(width /image[15].width +1);
  712. returner.ground.setCenterX(width/2);
  713. returner.ground.image.setBottom(height);
  714. //Trees
  715. returner.tree0.setCenterX(width /4);
  716. returner.tree0.setBottom (returner.ground.getGroundLevel());
  717. returner.tree1.setCenterX(width *5/6);
  718. returner.tree1.setBottom (returner.ground.getGroundLevel());
  719. //Dark Dimension
  720. returner.darkDimensionLogo.setCenterX(width/2);
  721. returner.darkDimensionLogo.setCenterY(height/2);
  722. //Character
  723. returner.character.image.setLeft(width * 13/16);
  724. returner.character.image.setBottom(returner.ground.getGroundLevel());
  725. //Buttons
  726. returner.buttonBack.setRight(width -image[returner.buttonBack.frame].width/2);
  727. returner.buttonBack.setTop(image[returner.buttonBack.frame].height/2);
  728. //Change Character
  729. returner.buttonChangeChar.setCenterX(returner.character.image.getCenterX());
  730. returner.buttonChangeChar.setTop(returner.character.image.getBottom());
  731. //Return Menu
  732. return returner;
  733. }
  734. function GameMenu(bHardRestart)
  735. {
  736. //Create menu
  737. returner =
  738. {
  739. //Basic Animation
  740. aBasic: DiAnimation(10),
  741. bDraw: true,
  742. //Important Values
  743. //randomizer
  744. paused: false,
  745. gameRunning: -1,
  746. hardReset: false,
  747. hardRestart: bHardRestart,
  748. aStart: DiAnimation(50),
  749. //Camera
  750. cameraX: 0,
  751. speed: 16,
  752. highScore: localStorage.ritle_high_score,
  753. score: 0,
  754. //Ground
  755. groundLevel: [height*1/5, height*2/5, height*3/5, height*4/5],
  756. ground: [Ground(3), Ground(3), Ground(3), Ground(3), Ground(3)],
  757. lastGround: 4,
  758. //Trees
  759. tree: [DiPoint(5), DiPoint(6), DiPoint(6), DiPoint(6)],
  760. lastTree0: DiPoint(5),
  761. lastTree1: DiPoint(6),
  762. //Pick ups & enemies
  763. pickUp: [DiPoint(21), DiPoint(21)],
  764. enemy: [DiPoint(25), DiPoint(25)],
  765. doubleScoreTimer: DiAnimation(250),
  766. //Character
  767. character: Character(),
  768. //Crystal Show - UI
  769. diCrystal: DiPoint(21),
  770. dCrystals: 0,
  771. aCrystal: DiAnimation(16),
  772. aCrystalDelay: DiAnimation(40),
  773. tutorialDelay: DiAnimation(120),
  774. buttonPause: DiPoint(8),
  775. buttonRestart: DiPoint(8),
  776. buttonBack: DiPoint(8),
  777. buttonResume: DiPoint(8),
  778. buttonMute: DiPoint(26),
  779. //Results
  780. aResults: DiAnimation(30),
  781. dResults: 0,
  782. shownCrystals: 0,
  783. shownScore: 0,
  784. shownTotal: 0,
  785. nextMenu: 0,
  786. update: function()
  787. {
  788. //Input
  789. if (input)
  790. {
  791. //Cancel input
  792. input = false;
  793. //Skip results
  794. if (this.aResults.isRunning())
  795. {
  796. switch (this.dResults)
  797. {
  798. case 1: this.shownCrystals = this.dCrystals; break;
  799. case 2: this.shownScore = Math.floor(this.score /100) -1; break;
  800. case 3: this.shownTotal = this.shownCrystals +this.shownScore -1; break;
  801. case 4:
  802. if (this.buttonRestart.isTouched(touchX, touchY))
  803. {
  804. this.nextMenu = 2;
  805. this.aBasic.counterMax = 10;
  806. this.aBasic.startFromEnd();
  807. if (this.gameRunning > 0)
  808. this.hardReset = true;
  809. } else
  810. if (this.buttonBack.isTouched(touchX, touchY))
  811. {
  812. this.nextMenu = 0;
  813. this.aBasic.counterMax = 10;
  814. this.aBasic.startFromEnd();
  815. if (this.gameRunning > 0)
  816. this.hardReset = true;
  817. }
  818. }
  819. this.aResults.counterCurrent = this.aResults.counterMax -1;
  820. }
  821. else
  822. //Pause Menu
  823. if (this.paused)
  824. {
  825. if (this.buttonResume.isTouched(touchX, touchY))
  826. this.paused = false; else
  827. if (this.buttonRestart.isTouched(touchX, touchY))
  828. {
  829. this.nextMenu = 2;
  830. this.aBasic.counterMax = 10;
  831. this.aBasic.startFromEnd();
  832. this.hardReset = true;
  833. } else
  834. if (this.buttonBack.isTouched(touchX, touchY))
  835. {
  836. this.nextMenu = 0;
  837. this.aBasic.counterMax = 10;
  838. this.aBasic.startFromEnd();
  839. this.hardReset = true;
  840. } else
  841. if (this.buttonMute.isTouched(touchX, touchY))
  842. {
  843. if (bSound)
  844. {
  845. this.buttonMute.frame = 27;
  846. bSound = false;
  847. }
  848. else
  849. {
  850. this.buttonMute.frame = 26;
  851. bSound = true;
  852. }
  853. }
  854. } else
  855. //Pause Button
  856. if (this.buttonPause.isTouched(touchX, touchY))
  857. {
  858. this.paused = true;
  859. if (!this.aCrystal.isPositive())
  860. this.aCrystal.flip();
  861. }
  862. else
  863. this.character.jump();
  864. } //End input
  865. if (this.paused); else
  866. //Game is running
  867. if (this.gameRunning != 0)
  868. {
  869. //Advance Camera
  870. this.cameraX += this.speed;
  871. //Check background props
  872. background.checkLimits(this.cameraX);
  873. //Ground
  874. var N = 5;//ground.length
  875. for (var i = 0; i < N; i++)
  876. {
  877. //Ground has left the screen
  878. if (this.ground[i].getRight() -this.cameraX/4 <= 0
  879. && this.gameRunning == -1)
  880. {
  881. this.ground[i].image.frame = 15;
  882. //Width
  883. if (this.score < 4000) //5, 6, 7
  884. this.ground[i].setWidth(getRandomInt(5, 7)); else
  885. if (this.score < 9000) //4, 5
  886. this.ground[i].setWidth(getRandomInt(4, 5)); else
  887. if (this.score < 15000) //3, 4
  888. this.ground[i].setWidth(getRandomInt(3, 4));
  889. else //2, 3
  890. this.ground[i].setWidth(getRandomInt(2, 3));
  891. //Coordinates X
  892. if (this.score < 2000)
  893. this.ground[i].image.setLeft(this.ground[this.lastGround].getRight()); else
  894. if (this.score < 6500)
  895. this.ground[i].image.setLeft(this.ground[this.lastGround].getRight() +image[15].width); else
  896. if (this.score < 12000)
  897. this.ground[i].image.setLeft(this.ground[this.lastGround].getRight() +image[15].width +image[15].width/2); else
  898. if (this.score < 17000)
  899. this.ground[i].image.setLeft(this.ground[this.lastGround].getRight() +image[15].width *2);
  900. else
  901. this.ground[i].image.setLeft(this.ground[this.lastGround].getRight() +image[15].width *3);
  902. //Coordinates Y
  903. this.ground[i].image.setTop( this.groundLevel[ getRandomInt(0, 2) ] -image[15].height/4 );
  904. //Same ground level
  905. if (this.ground[i].image.getTop() == this.ground[this.lastGround].image.getTop())
  906. this.ground[i].image.setTop( this.groundLevel[3] -image[15].height/4 );
  907. this.lastGround = i;
  908. //Items
  909. var item = getRandomInt(0, 99);
  910. if (item < 50) item = 0; else
  911. if (item < 60) item = 1; else
  912. if (item < 64) item = 3; else
  913. if (item < 67) item = 2;
  914. else item = -1;
  915. if (item != -1)
  916. //Cycle pickups
  917. for (var j = 0; j < 2; j++)
  918. if (this.pickUp[j].getRight() -this.cameraX/4 <= 0)
  919. {
  920. //Create this pickUp
  921. this.pickUp[j].frame = 21 +item;
  922. this.pickUp[j].setLeft(this.ground[i].image.x +getRandomInt(0, this.ground[i].getWidth() -image[this.pickUp[j].frame].width));
  923. this.pickUp[j].setBottom(this.ground[i].getGroundLevel());
  924. j = 2;
  925. }
  926. //Enemies
  927. item = -1;
  928. if (getRandomInt(0, 99) < 75 && this.ground[i].width > 2)
  929. item = 0;
  930. else
  931. if (this.ground[i].width < 6 && getRandomInt(0, 99) < 60 && this.score > 3000)
  932. this.ground[i].selfDestruct = true;
  933. if (item != -1)
  934. //Cycle Enemies
  935. for (j = 0; j < 2; j++)
  936. if (this.enemy[j].getRight() -this.cameraX/4 <= 0)
  937. {
  938. //Create Enemy
  939. this.enemy[j].setCenterX(this.ground[i].image.x +this.ground[i].getWidth() /3 *getRandomInt(1, 2));
  940. this.enemy[j].setBottom(this.ground[i].getGroundLevel());
  941. j = 2;
  942. }
  943. //Chance for trees
  944. //Ground is big enough and will not selfDestruct
  945. if (this.ground[i].width >= 3 && !this.ground[i].selfDestruct)
  946. //Random chance
  947. if (getRandomInt(0, 99) < 35)
  948. //Search all trees
  949. for (var j = 0; j < 4; j++)
  950. //Find first available tree
  951. if (this.tree[j].getRight() -this.cameraX/4 <= 0)
  952. {
  953. this.tree[j].frame = getRandomInt(5, 6);
  954. this.tree[j].setBottom(this.ground[i].getGroundLevel());
  955. this.tree[j].setCenterX(this.ground[i].image.x +(this.ground[i].getWidth() *getRandomInt(1, 4)/5 ));//this.ground[i].getLeft() +(this.ground[i].getWidth() *getRandomInt(1, 4)/5 ));
  956. j = 4;
  957. }
  958. }
  959. //Update ground -Self Destruct-
  960. this.ground[i].update();
  961. }
  962. //Opening animation
  963. if (this.aStart.update())
  964. this.character.image.setRight(this.aStart.getDistance(image[this.character.image.frame].width *3));
  965. //Check if character moved to next ground
  966. if (this.character.image.getCenterX() > this.ground[this.character.walkingOn].getRight() -this.cameraX/4)
  967. if (++this.character.walkingOn >= 5) this.character.walkingOn = 0;
  968. //Character Update
  969. if ((this.character.image.getCenterX() > this.ground[this.character.walkingOn].image.getLeft()
  970. -this.cameraX/4 || this.aBasic.isRunning()) && this.gameRunning == -1)
  971. this.character.update(this.ground[this.character.walkingOn].getGroundLevel(), this.groundLevel[1]);
  972. else
  973. this.character.update(-height*2, this.groundLevel[1]);
  974. //Activate ground selfDestruct if there is
  975. if (this.character.justLanded)
  976. if (this.ground[this.character.walkingOn].selfDestruct)
  977. this.ground[this.character.walkingOn].selfDestructTimer = 0;
  978. //PickUps
  979. for (var i = 0; i < 2; i++)
  980. if (this.pickUp[i].getRight() -this.cameraX/4 > 0)
  981. //if Character picked up something
  982. if (isColliding(this.character.image.getSquareHalved(0), this.pickUp[i].getSquare(-this.cameraX/4)))//character.getSquare(), cPickUp.getSquare(-cameraX / 4, 0))
  983. //&& gameRunning == -1)
  984. {
  985. switch (this.pickUp[i].frame -21)
  986. {
  987. case 0: //Memory Crystal
  988. this.dCrystals++;
  989. if (!this.aCrystal.isPositive())
  990. this.aCrystal.flip();
  991. //GameSurface.playSound(2);
  992. break;
  993. case 1: //Magic Mana
  994. this.character.addManaLevel();
  995. break;
  996. case 2: //Shield
  997. this.character.giveShield();
  998. //GameSurface.playSound(6);
  999. break;
  1000. case 3: //Double Score
  1001. this.doubleScoreTimer.startFromBeggining();
  1002. //GameSurface.playSound(5);
  1003. break;
  1004. }
  1005. //Remove pickUp
  1006. this.pickUp[i].setRight(0);
  1007. }
  1008. //Enemies
  1009. for (i = 0; i < 2; i++)
  1010. if (this.enemy[i].getRight() -this.cameraX/4 > 0)
  1011. {
  1012. if (this.character.justLanded)
  1013. if (this.character.image.getCenterX() > this.enemy[i].x -this.cameraX/4
  1014. && this.character.image.getCenterX() < this.enemy[i].getRight() -this.cameraX/4)
  1015. {
  1016. if (this.character.isShielded)
  1017. this.character.isShielded = false; else
  1018. if (this.character.circleSize > 0)
  1019. this.character.circleSize = 0;
  1020. else
  1021. {
  1022. this.aStart.startFromEnd();
  1023. this.character.jump();
  1024. this.destroy(0);
  1025. }
  1026. //GameSurface.playSound(7);
  1027. }
  1028. }
  1029. //Game Over
  1030. if (this.character.image.y > height && this.gameRunning == -1)
  1031. {
  1032. //GameSurface.playSound(7);
  1033. this.destroy(1);
  1034. }else
  1035. //if game is ending, and it got to the final frame
  1036. if (this.gameRunning > 0)
  1037. if (this.gameRunning -this.cameraX/4 < 0)
  1038. {
  1039. //End game
  1040. this.gameRunning = 0;
  1041. //Fix camera so it has same angle as in main menu
  1042. this.cameraX = (this.ground[this.lastGround].getCenterX() -width/2) *4;
  1043. }
  1044. //Survived this frame - award score
  1045. if (!this.aBasic.isRunning() && this.gameRunning == -1)
  1046. if (this.doubleScoreTimer.update())
  1047. this.score += 2;
  1048. else
  1049. this.score++;
  1050. }//End game is running
  1051. else
  1052. //Game is not running and its not paused
  1053. background.update(this.cameraX);
  1054. //if game is ended
  1055. if (this.aResults.update())
  1056. {
  1057. //Game over updated
  1058. switch (this.dResults)
  1059. {
  1060. case 0: //Menu comes in play
  1061. break;
  1062. case 1: //Count crystals
  1063. if (this.dCrystals > 0)
  1064. this.shownCrystals++;
  1065. break;
  1066. case 2: //Count Score
  1067. if (Math.floor(this.score /100) > 0)
  1068. this.shownScore++;
  1069. break;
  1070. case 3: //Count Total
  1071. if (this.shownCrystals +this.shownScore > 0)
  1072. this.shownTotal++;
  1073. break;
  1074. case 4: //Wait for input
  1075. break;
  1076. }
  1077. //Stop updating and start next menu
  1078. if (this.aResults.isAtEnd())
  1079. {
  1080. var changed = false;
  1081. if (this.dResults < 4)
  1082. {
  1083. this.dResults++;
  1084. changed = true;
  1085. }
  1086. switch (this.dResults)
  1087. {
  1088. case 1:
  1089. if (this.dCrystals != 0)
  1090. this.aResults.start( this.dCrystals );
  1091. else
  1092. this.aResults.start( 10 );
  1093. break;
  1094. case 2:
  1095. if (Math.floor(this.score /100) != 0)
  1096. this.aResults.start( Math.floor(this.score /100) );
  1097. else
  1098. this.aResults.start( 10 );
  1099. break;
  1100. case 3:
  1101. if (this.shownCrystals +this.shownScore != 0)
  1102. this.aResults.start( this.shownCrystals +this.shownScore );
  1103. else
  1104. this.aResults.start( 10 );
  1105. break;
  1106. case 4:
  1107. this.aResults.start(50);
  1108. break;
  1109. }
  1110. if (changed && this.dResults == 4)
  1111. if (this.highScore < this.shownTotal)
  1112. localStorage.ritle_high_score = this.shownTotal;//Save High Score
  1113. }
  1114. }
  1115. //Crystal Display
  1116. if (this.aCrystalDelay.isRunning())
  1117. if (!this.paused)
  1118. {
  1119. //Advance Delay
  1120. this.aCrystalDelay.update();
  1121. //Action when it's over
  1122. if (this.aCrystalDelay.isAtEnd())
  1123. this.aCrystal.startFromEnd();
  1124. }
  1125. //else
  1126. if (this.aCrystal.update())
  1127. {
  1128. this.diCrystal.setTop( height -this.aCrystal.getDistance(image[this.diCrystal.frame].height) );//height -this.aCrystal.getDistance( image[this.diCrystal.frame].height() ));
  1129. if (this.aCrystal.isAtEnd())
  1130. this.aCrystalDelay.startFromBeggining();
  1131. }
  1132. //Redraw
  1133. this.bDraw = true;
  1134. //Menu destroyed
  1135. if (this.aBasic.update())
  1136. if (this.aBasic.isAtStart() && !this.aBasic.bPositive)
  1137. {
  1138. background.materialize(this.cameraX);
  1139. return this.nextMenu;
  1140. }
  1141. },
  1142. draw: function()
  1143. {
  1144. //Cancel draw
  1145. bDraw = false;
  1146. //Background
  1147. background.drawOffset(-this.cameraX);
  1148. //Hard reset/restart alpha
  1149. if ((this.hardRestart && this.aBasic.bPositive )
  1150. || this.hardReset)
  1151. context.globalAlpha = this.aBasic.getDistance(1);
  1152. //Ground
  1153. for (var i = 0; i < 5; i++)
  1154. this.ground[i].drawOffset(-this.cameraX/4);
  1155. //Trees
  1156. this.tree[0].drawOffset(-this.cameraX/4);
  1157. this.tree[1].drawOffset(-this.cameraX/4);
  1158. this.lastTree0.drawOffset(-this.cameraX/4);
  1159. this.lastTree1.drawOffset(-this.cameraX/4);
  1160. //Alpha
  1161. context.globalAlpha = this.aBasic.getDistance(1);
  1162. //Spikes
  1163. for (i = 0; i < 2; i++)
  1164. if (this.enemy[i].getRight() -this.cameraX/4 > 0)
  1165. this.enemy[i].drawOffset(-this.cameraX/4);
  1166. //Pick ups
  1167. for (var i = 0; i < 2; i++)
  1168. if (this.pickUp[i].getRight() > 0)
  1169. this.pickUp[i].drawOffset(-this.cameraX/4);
  1170. //Character
  1171. this.character.draw();
  1172. //Crystals
  1173. this.diCrystal.draw();
  1174. //Results
  1175. if (this.dResults == 4)
  1176. {
  1177. this.buttonBack.draw();
  1178. this.buttonRestart.draw();
  1179. } else
  1180. //Pause
  1181. if (this.paused)
  1182. {
  1183. this.buttonBack.draw();
  1184. this.buttonRestart.draw();
  1185. this.buttonResume.draw();
  1186. //this.buttonMute.draw();
  1187. }
  1188. else
  1189. if (this.gameRunning == -1)
  1190. this.buttonPause.draw();
  1191. //Texts
  1192. context.shadowColor = "rgba(0, 0, 0, 1)";
  1193. //Score
  1194. context.fillText("Score:", width/2, 5 +fontSize);
  1195. if (this.doubleScoreTimer.isRunning())
  1196. context.fillStyle = "rgb(143, 231, 134)";
  1197. context.fillText(this.score, width/2, 10 +fontSize*2);
  1198. if (this.doubleScoreTimer.isRunning)
  1199. context.fillStyle = "white";
  1200. //Crystals
  1201. if (!this.aCrystal.isAtStart())
  1202. {
  1203. context.fillText("x ", this.diCrystal.getRight(), this.diCrystal.getCenterY() +fontSize/2);
  1204. context.fillText(this.dCrystals, this.diCrystal.getCenterX() *4, this.diCrystal.getCenterY() +fontSize/2);
  1205. }
  1206. //Results
  1207. //Draw Results
  1208. if (this.aResults.isRunning())
  1209. {
  1210. context.fillText("Results:", width/2, fontSize*4);
  1211. context.fillText("Crystals:" , width/3, fontSize*5 +2);
  1212. context.fillText("Score (Points /100):" , width/3, fontSize*6 +4);
  1213. context.fillText("Total:" , width/3, fontSize*7 +6);
  1214. context.fillText("High Score:" , width/3, fontSize*8 +8);
  1215. //Crystals
  1216. if (this.dResults == 1)
  1217. context.fillStyle = "rgb(143, 231, 134)";
  1218. context.fillText(this.shownCrystals , width*2/3, fontSize*5 +2);
  1219. if (this.dResults == 1)
  1220. context.fillStyle = "white";
  1221. //Score
  1222. if (this.dResults == 2)
  1223. context.fillStyle = "rgb(143, 231, 134)";
  1224. context.fillText(this.shownScore , width*2/3, fontSize*6 +4);
  1225. if (this.dResults == 2)
  1226. context.fillStyle = "white";
  1227. //Total
  1228. if (this.dResults == 3)
  1229. context.fillStyle = "rgb(143, 231, 134)";
  1230. context.fillText(this.shownTotal , width*2/3, fontSize*7 +6);
  1231. if (this.dResults == 3)
  1232. context.fillStyle = "white";
  1233. //High Score
  1234. context.fillText(this.highScore , width*2/3, fontSize*8 +8);
  1235. if (this.shownTotal > this.highScore)
  1236. context.fillText("New High Score!" , width/2, fontSize*9 +10);
  1237. //
  1238. if (this.dResults == 4)
  1239. {
  1240. context.fillText("Restart" , this.buttonRestart.getCenterX(), this.buttonRestart.getCenterY() +fontSize/2);
  1241. context.fillText("Main Menu", this.buttonBack.getCenterX(), this.buttonBack.getCenterY() +fontSize/2);
  1242. } else
  1243. context.fillText("Click anywhere to continue",
  1244. width/2,
  1245. height *8/9 +fontSize/2);
  1246. } else
  1247. if (this.paused)
  1248. {
  1249. context.fillText("Restart" ,
  1250. this.buttonRestart.getCenterX(),
  1251. this.buttonRestart.getCenterY() +fontSize/2);
  1252. context.fillText("Resume" ,
  1253. this.buttonResume.getCenterX(),
  1254. this.buttonResume.getCenterY() +fontSize/2);
  1255. context.fillText("Main Menu",
  1256. this.buttonBack.getCenterX(),
  1257. this.buttonBack.getCenterY() +fontSize/2);
  1258. } else
  1259. if (this.gameRunning == -1)
  1260. context.fillText("Pause",
  1261. this.buttonPause.getCenterX(),
  1262. this.buttonPause.getCenterY() +fontSize/2);
  1263. context.shadowColor = "rgba(0, 0, 0, 0)";
  1264. context.globalAlpha = 1;
  1265. },
  1266. destroy: function(menu)
  1267. {
  1268. if (this.gameRunning == -1)
  1269. {
  1270. this.nextMenu = menu;
  1271. //Find first not visible ground
  1272. //Create Main Menu pattern there
  1273. //Make the rest not visible
  1274. var i = this.character.walkingOn;
  1275. var startingPoint = -1;
  1276. do
  1277. {
  1278. //if ground is right from screen
  1279. if (this.ground[i].image.x -this.cameraX/4 > width)
  1280. //First one becomes main menu pattern
  1281. if (startingPoint == -1)
  1282. {
  1283. //Create Main Menu Patter here
  1284. this.ground[i].width = width /image[15].width +1;
  1285. this.ground[i].image.setBottom(height);
  1286. this.ground[i].selfDestruct = false;
  1287. startingPoint = this.ground[i].getCenterX() -width/2;//this.ground[iii].getCenterX() -width/2;
  1288. //Last Trees
  1289. this.lastTree0.setCenterX(startingPoint +width /4);
  1290. this.lastTree0.setBottom(this.ground[i].getGroundLevel());
  1291. this.lastTree1.setCenterX(startingPoint +width *5/6);
  1292. this.lastTree1.setBottom(this.ground[i].getGroundLevel());
  1293. this.lastGround = i;
  1294. }
  1295. //The rest of them are gone
  1296. else
  1297. this.ground[i].image.y = height*2;
  1298. i++;
  1299. if (i == 5)
  1300. i = 0;
  1301. } while (i != this.character.walkingOn);
  1302. //Remove unnecessary items
  1303. for (jjj = 0; jjj < 2; jjj++)
  1304. if (this.pickUp[jjj].x -this.cameraX/4 > width)
  1305. this.pickUp[jjj].setRight(0);
  1306. //Remove unnecessary enemies(int) (startingPoint -(cameraX/4) /(4 *GameSurface.density *speed));
  1307. for (jjj = 0; jjj < 2; jjj++)
  1308. if (this.enemy[jjj].x -this.cameraX/4 > width)
  1309. this.enemy[jjj].setRight(0);
  1310. for (jjj = 0; jjj < 4; jjj++)
  1311. if (this.tree[jjj].x -this.cameraX/4 > width)
  1312. this.tree[jjj].setRight(0);
  1313. //Create game countdown
  1314. this.gameRunning = startingPoint;
  1315. //Start showing results
  1316. this.aResults.setMax(30);
  1317. this.aResults.startFromBeggining();
  1318. this.dResults = 0;
  1319. }
  1320. }
  1321. }
  1322. //Constructor
  1323. returner.aStart.startFromBeggining();
  1324. returner.aBasic.startFromBeggining();
  1325. //Ground
  1326. //First Ground
  1327. returner.ground[0].setWidth(width /image[15].width +1);
  1328. returner.ground[0].setCenterX(width/2);
  1329. returner.ground[0].image.setBottom(height);
  1330. //Rest Grounds
  1331. for (var i = 1; i < 5; i++)
  1332. {
  1333. //Init ground
  1334. returner.ground[i].setWidth(getRandomInt(3, 7));
  1335. returner.ground[i].image.setLeft(returner.ground[i-1].getRight());
  1336. //Randomize one of the ground levels except the last
  1337. returner.ground[i].image.setTop( returner.groundLevel[ getRandomInt(0, 2) ] -image[15].height/4);//randomizer.nextInt(3) ] -DiPoint.getHeight(14)/4 );
  1338. //If it matches the previous
  1339. if (returner.ground[i].image.getTop() == returner.ground[i -1].image.getTop())
  1340. //Give it the last one
  1341. returner.ground[i].image.setTop( returner.groundLevel[3] -image[15].height/4 );
  1342. }
  1343. //Constructor
  1344. if (returner.highScore == undefined)
  1345. returner.highScore = 0;
  1346. //Trees
  1347. //First two trees are fixed
  1348. returner.tree[0].setCenterX(width /4);
  1349. returner.tree[0].setBottom (returner.ground[0].getGroundLevel());
  1350. returner.tree[1].setCenterX(width *5/6);
  1351. returner.tree[1].setBottom (returner.ground[0].getGroundLevel());
  1352. //Rest are on invalid state (for reseting)
  1353. for (var i = 2; i < 4; i++)
  1354. returner.tree[i].setRight(0);
  1355. //Last two remain invalid until game stops
  1356. returner.lastTree0.setRight(0);
  1357. returner.lastTree1.setRight(0);
  1358. //Pick ups & Enemies
  1359. for (var i = 0; i < 2; i++)
  1360. {
  1361. returner.pickUp[i].setRight(0);
  1362. returner.enemy[i].setRight(0);
  1363. }
  1364. //Character
  1365. returner.character.image.setRight(0);
  1366. returner.character.image.setBottom(returner.ground[0].getGroundLevel() -1);
  1367. //Crystals - UI
  1368. returner.diCrystal.setLeft(0);
  1369. returner.diCrystal.setTop(height);
  1370. returner.buttonPause.setLeft(image[returner.buttonPause.frame].width/2);
  1371. returner.buttonPause.setTop(image[returner.buttonPause.frame].height/2);
  1372. returner.buttonRestart.setCenterX(width /4);
  1373. returner.buttonRestart.setCenterY(height *3/4);
  1374. returner.buttonResume.setCenterX(width *2/4);
  1375. returner.buttonResume.setCenterY(height *3/4);
  1376. returner.buttonBack.setCenterX(width *3/4);
  1377. returner.buttonBack.setCenterY(height *3/4);
  1378. returner.buttonMute.setRight (width -image[returner.buttonMute.frame].width /2);
  1379. returner.buttonMute.setBottom(height -image[returner.buttonMute.frame].height /2);
  1380. //Return menu
  1381. return returner;
  1382. }
  1383. // Converts from degrees to radians.
  1384. Math.radians = function(degrees) {
  1385. return degrees * Math.PI / 180;
  1386. };
  1387. //Get random integer
  1388. function getRandomInt(min, max) {
  1389. return Math.floor(Math.random() * (max - min + 1)) + min;
  1390. }
  1391. function isColliding(object1, object2)
  1392. {
  1393. return (object1[2] -object2[0] > 0)
  1394. != (object1[0] -object2[2] > 0)
  1395. && (object1[3] -object2[1] > 0)
  1396. != (object1[1] -object2[3] > 0);
  1397. }