Game
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

assets.js 4.4KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. var assetsPath = "assets/"+conf.assets;
  2. var commonPath = "assets/common";
  3. var assets = {
  4. imgs: {
  5. player: new ImageSource("theme:player"),
  6. player_flipped: new ImageSource("theme:player_flipped"),
  7. background: new ImageSource("background", null, ".jpg"),
  8. wall: new ImageSource("wall"),
  9. wall_overlap: new ImageSource("wall-overlap"),
  10. powerup: new ImageSource("powerup"),
  11. },
  12. audio: {
  13. hurt: new AudioSource("audio/hurt"),
  14. loss: new AudioSource("audio/loss"),
  15. flap: new AudioSource("audio/flap"),
  16. chomp: new AudioSource("audio/chomp"),
  17. },
  18. soundtracks: {
  19. soundtrack1: new AudioSource("soundtracks/track1"),
  20. soundtrack2: new AudioSource("soundtracks/track2"),
  21. soundtrack3: new AudioSource("soundtracks/track3"),
  22. },
  23. };
  24. /*
  25. * Audio source.
  26. */
  27. function AudioSource(src, ext) {
  28. makeEventListener(this);
  29. var ext = ext || ".mp3";
  30. this.elems = [];
  31. for (var i = 0; i < 10; ++i) {
  32. this.elems[i] = new Audio(commonPath+"/"+src+ext);
  33. this.elems[i].addEventListener("ended", function() {
  34. this.emit("ended");
  35. }.bind(this));
  36. }
  37. this.ready = false;
  38. this.index = 0;
  39. this.elems[0].addEventListener("canplaythrough", function() {
  40. if (this.ready)
  41. return;
  42. this.ready = true;
  43. this.emit("load");
  44. }.bind(this));
  45. this.elems[0].onerror = function() {
  46. console.error("Error with", src);
  47. }
  48. }
  49. AudioSource.prototype.play = function() {
  50. this.elems[this.index++].play();
  51. this.index %= this.elems.length;
  52. }
  53. AudioSource.prototype.pause = function() {
  54. for (var i in this.elems)
  55. this.elmes[i].pause();
  56. }
  57. /*
  58. * Image source.
  59. */
  60. function ImageSource(src, frameh, ext) {
  61. var ext = ext || ".png";
  62. if (src.indexOf("theme:") == 0) {
  63. src = assetsPath+"/images/"+src.split(":")[1];
  64. } else {
  65. src = commonPath+"/images/"+src;
  66. }
  67. this.img = document.createElement("img");
  68. this.ready = false;
  69. this.width = 0;
  70. this.height = 0;
  71. this.frameh = frameh == null ? -1 : frameh;
  72. this.steps = 1;
  73. this.img.onload = function() {
  74. this.ready = true;
  75. this.width = this.img.width;
  76. this.height = this.img.height;
  77. if (this.frameh === -1)
  78. this.frameh = this.height;
  79. this.steps = this.height / this.frameh;
  80. if (this.steps !== Math.round(this.steps)) {
  81. this.steps = Math.round(this.steps);
  82. console.log(
  83. "Warning: '"+src+ext+"': "+
  84. "Height isn't evenly divisible by frame height. "+
  85. "Height: "+this.height+", frame height: "+this.frameh);
  86. }
  87. }.bind(this);
  88. this.img.src = src+ext
  89. this.img.onerror = function() {
  90. console.error("error with", src);
  91. }
  92. }
  93. ImageSource.prototype.draw = function(ctx, step) {
  94. if (!step) step = 0;
  95. if (!this.ready)
  96. return;
  97. ctx.drawImage(this.img,
  98. 0, this.frameh * step,
  99. this.width, this.frameh,
  100. 0, 0,
  101. this.width, this.frameh);
  102. }
  103. function Animation(imgSrc, type, loop, fps) {
  104. this.type = type || "forward";
  105. this.loop = loop || false;
  106. this.imgSrc = imgSrc;
  107. this.fps = fps || 12;
  108. this.waitTime = 1000 / this.fps;
  109. this.doStep = false;
  110. if (type === "forward" || type === "bounce") {
  111. this.step = 0;
  112. this.direction = 1;
  113. } else if (type === "reverse" || type === "bounce-reverse") {
  114. this.step = -1;
  115. this.direction = -1;
  116. }
  117. // We don't care about the direction after setting this.direction
  118. if (this.type === "bounce-reverse")
  119. this.type = "bounce";
  120. else if (this.type === "reverse")
  121. this.type = "forward";
  122. }
  123. Animation.prototype.nextFrame = function() {
  124. if (!this.imgSrc.ready) {
  125. return;
  126. } else if (this.step === -1) {
  127. this.step = this.imgSrc.steps - 1;
  128. return;
  129. } else if (this.imgSrc.steps === 1) {
  130. return;
  131. }
  132. var next = this.step + this.direction;
  133. if (next < 0 || next > this.imgSrc.steps - 1) {
  134. if (this.loop) {
  135. if (this.type === "bounce") {
  136. this.direction = -this.direction;
  137. next = this.step + this.direction;
  138. } else if (this.type === "forward") {
  139. if (next < 0)
  140. next = this.imgSrc.steps - 1;
  141. else
  142. next = 0;
  143. }
  144. } else {
  145. this.doStep = false;
  146. return;
  147. }
  148. }
  149. this.step = next;
  150. }
  151. Animation.prototype.draw = function(ctx) {
  152. if (!this.imgSrc.ready)
  153. return;
  154. this.imgSrc.draw(ctx, this.step);
  155. if (this.doStep) {
  156. this.nextFrame();
  157. this.doStep = false;
  158. setTimeout(function() {
  159. this.doStep = true;
  160. }.bind(this), this.waitTime);
  161. }
  162. }
  163. Animation.prototype.play = function() {
  164. if (this.step !== -1)
  165. this.step = 0;
  166. this.doStep = true;
  167. }
  168. Animation.prototype.setStep = function(step) {
  169. if (step > this.imgSrc.steps - 1)
  170. this.step = this.imgSrc.steps - 1;
  171. else if (step < 0)
  172. this.step = 0;
  173. else
  174. this.step = step;
  175. }