game.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. var fontDeferred = Q.defer();
  2. WebFontConfig = {
  3. google: { families: [ 'Quicksand::latin' ] },
  4. active: function() {
  5. fontDeferred.resolve();
  6. }
  7. };
  8. (function() {
  9. var wf = document.createElement('script');
  10. wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
  11. '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
  12. wf.type = 'text/javascript';
  13. wf.async = 'true';
  14. var s = document.getElementsByTagName('script')[0];
  15. s.parentNode.insertBefore(wf, s);
  16. })();
  17. var soundDeferred = Q.defer();
  18. soundManager.setup({
  19. url: 'swf/',
  20. flashVersion: 9,
  21. onready: function() {
  22. soundDeferred.resolve(this);
  23. }
  24. });
  25. var Game = {
  26. canvas: document.getElementById('game'),
  27. context: document.getElementById('game').getContext('2d'),
  28. keysDown: {},
  29. start: function() {
  30. addEventListener('keydown', function(e) {
  31. Game.keysDown[e.keyCode] = true;
  32. }, false);
  33. addEventListener('keyup', function(e) {
  34. delete Game.keysDown[e.keyCode];
  35. }, false);
  36. var fontPromise = fontDeferred.promise.timeout(5000);
  37. var soundPromise = soundDeferred.promise.then(function() {
  38. return [
  39. createSound('confirm', 'sound/confirm.mp3'),
  40. createSound('back', 'sound/back.mp3'),
  41. createSound('pause', 'sound/pause.mp3'),
  42. createSound('cursor', 'sound/cursor.mp3')
  43. ]
  44. });
  45. Game.sceneManager.push(SplashScreen);
  46. Q.allResolved([fontPromise, soundPromise]).done(function(s, f) {
  47. Game.sceneManager.pop();
  48. Game.sceneManager.push(MainMenu);
  49. });
  50. Ticker.start();
  51. Ticker.addListener(function(dt) {
  52. Game.sceneManager.update(dt);
  53. Game.sceneManager.draw();
  54. });
  55. },
  56. pause: function() {
  57. Game.sceneManager.push(PauseScreen);
  58. },
  59. sceneManager: {
  60. sceneStack: [],
  61. currentScene: null,
  62. update: function(delta) {
  63. if(this.currentScene) this.currentScene._update(delta);
  64. },
  65. draw: function() {
  66. if(this.currentScene) this.currentScene._draw();
  67. },
  68. push: function(scene) {
  69. if(this.currentScene) this.currentScene.pause();
  70. this.sceneStack.push(scene);
  71. if(!scene.hasTicker) scene._init();
  72. scene.load();
  73. this.currentScene = scene;
  74. },
  75. pop: function() {
  76. var scene = this.sceneStack.pop();
  77. scene.unload();
  78. if(this.sceneStack.length > 0) {
  79. this.currentScene = this.sceneStack[this.sceneStack.length-1];
  80. this.currentScene.resume();
  81. }
  82. else {
  83. this.currentScene = null;
  84. }
  85. }
  86. }
  87. };
  88. function Scene() {}
  89. Scene.prototype._init = function() {
  90. makeObservable(this);
  91. };
  92. Scene.prototype._update = function(dt) {
  93. this.notify(dt);
  94. this.update(dt);
  95. };
  96. Scene.prototype._draw = function() {
  97. this.draw();
  98. };
  99. Scene.prototype.tween = function(from) {
  100. var tween = new DeferredTween(from);
  101. tween.ticker = this.ticker;
  102. return tween;
  103. };
  104. Scene.prototype.load = function() {};
  105. Scene.prototype.unload = function() {};
  106. Scene.prototype.resume = function() {};
  107. Scene.prototype.pause = function() {};
  108. var SplashScreen = new Scene();
  109. (function() {
  110. var ctx = Game.context;
  111. var x = Game.canvas.width / 2;
  112. var y = Game.canvas.height / 2;
  113. var position = {x: x, y: y};
  114. var RADIUS = 8;
  115. var RIPPLE_SIZE = 10;
  116. var RIPPLE_SPEED = 10;
  117. var rippleCounter = 0;
  118. SplashScreen.color = function(p) {
  119. return color(255, 255, 255, p);
  120. };
  121. SplashScreen.update = function(dt) {
  122. rippleCounter += RIPPLE_SPEED * dt;
  123. if(rippleCounter > RIPPLE_SIZE) {
  124. rippleCounter = 0;
  125. }
  126. };
  127. SplashScreen.draw = function() {
  128. ctx.fillStyle = 'black';
  129. ctx.fillRect(0, 0, Game.canvas.width, Game.canvas.height);
  130. ctx.fillStyle = 'white';
  131. drawCircle(position, RADIUS, 3, this.color(1));
  132. drawCircle(position, 2, 3, this.color(1));
  133. // ripples
  134. var p = lerp(1, 0, ease(rippleCounter/RIPPLE_SIZE));
  135. drawCircle(position, RADIUS+7+rippleCounter, 1, this.color(p));
  136. drawCircle(position, RADIUS+4+rippleCounter, 1, this.color(p*0.8));
  137. drawCircle(position, RADIUS+1+rippleCounter, 1, this.color(p*0.5));
  138. };
  139. })();
  140. var MainMenu = new Scene();
  141. (function() {
  142. var ctx = Game.context;
  143. var canvasW = Game.canvas.width;
  144. var canvasH = Game.canvas.height;
  145. var selected = 0;
  146. var alternate = false;
  147. var notYetDone = {
  148. name: '???',
  149. alt: '???',
  150. start: function() {}
  151. };
  152. var games = [
  153. {
  154. name: 'sound safari',
  155. alt: 'sound catcher',
  156. start: function() {
  157. var beats = [
  158. {url: 'sound/b1.mp3', duration: 4000},
  159. {url: 'sound/b2.mp3', duration: 4000},
  160. {url: 'sound/b3.mp3', duration: 4000},
  161. {url: 'sound/b4.mp3', duration: 4000},
  162. {url: 'sound/b5.mp3', duration: 4000}
  163. ];
  164. Game.sceneManager.push(new SoundSafari(beats));
  165. }
  166. },
  167. notYetDone,
  168. notYetDone,
  169. notYetDone,
  170. notYetDone,
  171. notYetDone,
  172. notYetDone
  173. ];
  174. function onKeyUp(e) {
  175. switch(e.keyCode) {
  176. case 66:
  177. alternate = !alternate;
  178. document.title = alternate ? 'SoundVoyager' : 'audventure';
  179. break;
  180. case 38:
  181. e.preventDefault();
  182. soundManager.play('cursor');
  183. selected = (selected + games.length -1) % games.length;
  184. break;
  185. case 40:
  186. e.preventDefault();
  187. soundManager.play('cursor');
  188. selected = (selected + 1) % games.length;
  189. break;
  190. case 32:
  191. e.preventDefault();
  192. case 13:
  193. soundManager.play('confirm');
  194. games[selected].start();
  195. }
  196. }
  197. MainMenu.update = function() {};
  198. MainMenu.draw = function() {
  199. ctx.fillStyle = 'black';
  200. ctx.fillRect(0, 0, canvasW, canvasH);
  201. ctx.fillStyle = 'white';
  202. ctx.textAlign = 'center';
  203. var canvasWM = canvasW/2;
  204. var canvasHM = canvasH/2;
  205. ctx.font = font(48);
  206. ctx.fillText(alternate ? 'SoundVoyager' : 'audventure', canvasWM, canvasHM - 50);
  207. ctx.font = font(12);
  208. games.forEach(function(game, index) {
  209. var y = canvasHM + 10 + index * 20;
  210. var name = alternate ? game.alt : game.name;
  211. ctx.fillText(name, canvasWM, y);
  212. if(index == selected) {
  213. var offset = ctx.measureText(name).width / 2 + 10;
  214. drawTriangle(canvasWM - offset, y - 4, 10, 7);
  215. drawTriangle(canvasWM + offset, y - 4, 10, -7);
  216. }
  217. });
  218. };
  219. MainMenu.load = MainMenu.resume = function() {
  220. addEventListener('keydown', onKeyUp);
  221. };
  222. MainMenu.unload = MainMenu.pause = function() {
  223. removeEventListener('keydown', onKeyUp);
  224. };
  225. })();
  226. var PauseScreen = new Scene();
  227. (function() {
  228. var onKeyUp = function(e) {
  229. switch(e.charCode) {
  230. case 81:
  231. case 113:
  232. case 27:
  233. Game.sceneManager.pop();
  234. case 80:
  235. case 112:
  236. case 32:
  237. Game.sceneManager.pop();
  238. soundManager.play('back');
  239. }
  240. };
  241. PauseScreen.load = PauseScreen.resume = function() {
  242. addEventListener('keypress', onKeyUp);
  243. };
  244. PauseScreen.unload = PauseScreen.pause = function() {
  245. removeEventListener('keypress', onKeyUp);
  246. };
  247. PauseScreen.update = function() {};
  248. PauseScreen.draw = function() {
  249. Game.context.fillStyle = 'black';
  250. Game.context.fillRect(0, 0, Game.canvas.width, Game.canvas.height);
  251. Game.context.fillStyle = 'white';
  252. Game.context.textAlign = 'center';
  253. Game.context.fillText('Paused', Game.canvas.width/2, Game.canvas.height/2 - 30);
  254. Game.context.fillText('P to unpause', Game.canvas.width/2, Game.canvas.height/2);
  255. Game.context.fillText('Q to quit', Game.canvas.width/2, Game.canvas.height/2 + 20);
  256. };
  257. })();
  258. Game.start();