Browse Source

Add main menu and loading screen

Thomas Dy 6 years ago
parent
commit
0bf683f1b6
4 changed files with 217 additions and 65 deletions
  1. 185 55
      scripts/game.js
  2. 2 8
      scripts/games/safari.js
  3. 30 2
      scripts/util.js
  4. BIN
      sound/cursor.mp3

+ 185 - 55
scripts/game.js

@@ -1,10 +1,60 @@
-Ticker.start();
+var fontDeferred = Q.defer();
+WebFontConfig = {
+  google: { families: [ 'Quicksand::latin' ] },
+  active: function() {
+    fontDeferred.resolve();
+  }
+};
+
+(function() {
+  var wf = document.createElement('script');
+  wf.src = ('https:' == document.location.protocol ? 'https' : 'http') +
+    '://ajax.googleapis.com/ajax/libs/webfont/1/webfont.js';
+  wf.type = 'text/javascript';
+  wf.async = 'true';
+  var s = document.getElementsByTagName('script')[0];
+  s.parentNode.insertBefore(wf, s);
+})();
+
+var soundDeferred = Q.defer();
+soundManager.setup({
+  url: 'swf/',
+  flashVersion: 9,
+  onready: function() {
+    soundDeferred.resolve(this);
+  }
+});
 
 var Game = {
   canvas: document.getElementById('game'),
+  context: document.getElementById('game').getContext('2d'),
   keysDown: {},
   start: function() {
-    Game.sceneManager.push(MainMenu);
+    addEventListener('keydown', function(e) {
+      Game.keysDown[e.keyCode] = true;
+    }, false);
+
+    addEventListener('keyup', function(e) {
+      delete Game.keysDown[e.keyCode];
+    }, false);
+
+    var fontPromise = fontDeferred.promise.timeout(5000);
+    var soundPromise = soundDeferred.promise.then(function() {
+      return [
+        createSound('confirm', 'sound/confirm.mp3'),
+        createSound('back', 'sound/back.mp3'),
+        createSound('pause', 'sound/pause.mp3'),
+        createSound('cursor', 'sound/cursor.mp3')
+      ]
+    });
+
+    Game.sceneManager.push(SplashScreen);
+    Q.allResolved([fontPromise, soundPromise]).done(function(s, f) {
+      Game.sceneManager.pop();
+      Game.sceneManager.push(MainMenu);
+    });
+
+    Ticker.start();
     Ticker.addListener(function(dt) {
       Game.sceneManager.update(dt);
       Game.sceneManager.draw();
@@ -32,44 +82,17 @@ var Game = {
     pop: function() {
       var scene = this.sceneStack.pop();
       scene.unload();
-      this.currentScene = this.sceneStack[this.sceneStack.length-1];
-      this.currentScene.resume();
+      if(this.sceneStack.length > 0) {
+        this.currentScene = this.sceneStack[this.sceneStack.length-1];
+        this.currentScene.resume();
+      }
+      else {
+        this.currentScene = null;
+      }
     }
   }
 };
 
-(function() {
-  Game.context = Game.canvas.getContext('2d');
-
-  addEventListener('keydown', function(e) {
-    Game.keysDown[e.keyCode] = true;
-  }, false);
-
-  addEventListener('keyup', function(e) {
-    delete Game.keysDown[e.keyCode];
-  }, false);
-
-  var soundDeferred = Q.defer();
-  soundManager.setup({
-    url: 'swf/',
-    flashVersion: 9,
-    onready: function() {
-      soundDeferred.resolve(this);
-    }
-  });
-  soundDeferred.promise
-    .then(function() {
-      return [
-        createSound('confirm', 'sound/confirm.mp3'),
-        createSound('back', 'sound/back.mp3'),
-        createSound('pause', 'sound/pause.mp3')
-      ]
-    })
-    .done(function() {
-      Game.start();
-    });
-})();
-
 function Scene() {}
 
 Scene.prototype._init = function() {
@@ -91,34 +114,139 @@ Scene.prototype.tween = function(from) {
   return tween;
 };
 
+Scene.prototype.load = function() {};
+Scene.prototype.unload = function() {};
+Scene.prototype.resume = function() {};
+Scene.prototype.pause = function() {};
+
+var SplashScreen = new Scene();
+(function() {
+  var ctx = Game.context;
+  var x = Game.canvas.width / 2;
+  var y = Game.canvas.height / 2;
+  var position = {x: x, y: y};
+  var RADIUS = 8;
+  var RIPPLE_SIZE = 10;
+  var RIPPLE_SPEED = 10;
+
+  var rippleCounter = 0;
+
+  SplashScreen.color = function(p) {
+    return color(255, 255, 255, p);
+  };
+
+  SplashScreen.update = function(dt) {
+    rippleCounter += RIPPLE_SPEED * dt;
+    if(rippleCounter > RIPPLE_SIZE) {
+      rippleCounter = 0;
+    }
+  };
+
+  SplashScreen.draw = function() {
+    ctx.fillStyle = 'black';
+    ctx.fillRect(0, 0, Game.canvas.width, Game.canvas.height);
+
+    ctx.fillStyle = 'white';
+    drawCircle(position, RADIUS, 3, this.color(1));
+    drawCircle(position, 2, 3, this.color(1));
+
+    // ripples
+    var p = lerp(1, 0, ease(rippleCounter/RIPPLE_SIZE));
+    drawCircle(position, RADIUS+7+rippleCounter, 1, this.color(p));
+    drawCircle(position, RADIUS+4+rippleCounter, 1, this.color(p*0.8));
+    drawCircle(position, RADIUS+1+rippleCounter, 1, this.color(p*0.5));
+  };
+})();
+
 var MainMenu = new Scene();
 (function() {
-  function onKeyUp() {
-    var beats = [
-      {url: 'sound/b1.mp3', duration: 4000},
-      {url: 'sound/b2.mp3', duration: 4000},
-      {url: 'sound/b3.mp3', duration: 4000},
-      {url: 'sound/b4.mp3', duration: 4000},
-      {url: 'sound/b5.mp3', duration: 4000}
-    ];
-
-    Game.sceneManager.push(new SoundSafari(beats));
-    soundManager.play('confirm');
+  var ctx = Game.context;
+  var canvasW = Game.canvas.width;
+  var canvasH = Game.canvas.height;
+  var selected = 0;
+  var alternate = false;
+
+  var notYetDone = {
+    name: '???',
+    alt: '???',
+    start: function() {}
+  };
+
+  var games = [
+    {
+      name: 'sound safari',
+      alt: 'sound catcher',
+      start: function() {
+        var beats = [
+          {url: 'sound/b1.mp3', duration: 4000},
+          {url: 'sound/b2.mp3', duration: 4000},
+          {url: 'sound/b3.mp3', duration: 4000},
+          {url: 'sound/b4.mp3', duration: 4000},
+          {url: 'sound/b5.mp3', duration: 4000}
+        ];
+
+        Game.sceneManager.push(new SoundSafari(beats));
+      }
+    },
+    notYetDone,
+    notYetDone,
+    notYetDone,
+    notYetDone,
+    notYetDone,
+    notYetDone
+  ];
+
+  function onKeyUp(e) {
+    switch(e.keyCode) {
+      case 66:
+        alternate = !alternate;
+        document.title = alternate ? 'SoundVoyager' : 'audventure';
+        break;
+      case 38:
+        e.preventDefault();
+        soundManager.play('cursor');
+        selected = (selected + games.length -1) % games.length;
+        break;
+      case 40:
+        e.preventDefault();
+        soundManager.play('cursor');
+        selected = (selected + 1) % games.length;
+        break;
+      case 32:
+        e.preventDefault();
+      case 13:
+        soundManager.play('confirm');
+        games[selected].start();
+    }
   }
+
   MainMenu.update = function() {};
   MainMenu.draw = function() {
-    Game.context.fillStyle = 'black';
-    Game.context.fillRect(0, 0, Game.canvas.width, Game.canvas.height);
-    Game.context.fillStyle = 'white';
-    Game.context.textAlign = 'center';
-    Game.context.fillText('Audventure', Game.canvas.width/2, Game.canvas.height/2 - 20);
-    Game.context.fillText('Press any key to start', Game.canvas.width/2, Game.canvas.height/2 + 20);
+    ctx.fillStyle = 'black';
+    ctx.fillRect(0, 0, canvasW, canvasH);
+    ctx.fillStyle = 'white';
+    ctx.textAlign = 'center';
+    var canvasWM = canvasW/2;
+    var canvasHM = canvasH/2;
+    ctx.font = font(48);
+    ctx.fillText(alternate ? 'SoundVoyager' : 'audventure', canvasWM, canvasHM - 50);
+    ctx.font = font(12);
+    games.forEach(function(game, index) {
+      var y = canvasHM + 10 + index * 20;
+      var name = alternate ? game.alt : game.name;
+      ctx.fillText(name, canvasWM, y);
+      if(index == selected) {
+        var offset = ctx.measureText(name).width / 2 + 10;
+        drawTriangle(canvasWM - offset, y - 4, 10, 7);
+        drawTriangle(canvasWM + offset, y - 4, 10, -7);
+      }
+    });
   };
   MainMenu.load = MainMenu.resume = function() {
-    addEventListener('keypress', onKeyUp);
+    addEventListener('keydown', onKeyUp);
   };
   MainMenu.unload = MainMenu.pause = function() {
-    removeEventListener('keypress', onKeyUp);
+    removeEventListener('keydown', onKeyUp);
   };
 })();
 
@@ -154,3 +282,5 @@ var PauseScreen = new Scene();
     Game.context.fillText('Q to quit', Game.canvas.width/2, Game.canvas.height/2 + 20);
   };
 })();
+
+Game.start();

+ 2 - 8
scripts/games/safari.js

@@ -56,14 +56,6 @@ function SoundSafari(beatInfo) {
 
   // Drawing functions
   {
-    function drawCircle(point, r, w, color) {
-      ctx.beginPath();
-      ctx.arc(point.x, point.y, r, 0, 2*Math.PI, false);
-      ctx.lineWidth = w;
-      ctx.strokeStyle = color;
-      ctx.stroke();
-    }
-
     function drawLeafV(point, h, w) {
       ctx.beginPath();
       ctx.moveTo(point.x, point.y);
@@ -457,7 +449,9 @@ function SoundSafari(beatInfo) {
       ctx.globalAlpha = this.textAlphaTween.value;
       ctx.fillStyle = 'white';
       ctx.textAlign = 'center';
+      ctx.font = font(48);
       ctx.fillText("sound safari", canvas.width / 2, canvas.height / 2);
+      ctx.font = font(12);
       ctx.textAlign = 'start';
       ctx.globalAlpha = 1;
     }

+ 30 - 2
scripts/util.js

@@ -11,6 +11,25 @@ function createSound(name, url) {
   return deferred.promise;
 }
 
+function drawTriangle(x, y, h, w) {
+  var ctx = Game.context;
+  ctx.beginPath();
+  ctx.moveTo(x, y);
+  ctx.lineTo(x - w, y - h/2);
+  ctx.lineTo(x - w, y + h/2);
+  ctx.closePath();
+  ctx.fill();
+}
+
+function drawCircle(point, r, w, color) {
+  var ctx = Game.context;
+  ctx.beginPath();
+  ctx.arc(point.x, point.y, r, 0, 2*Math.PI, false);
+  ctx.lineWidth = w;
+  ctx.strokeStyle = color;
+  ctx.stroke();
+}
+
 function sign(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }
 
 function lerp(from, to, p) {
@@ -31,6 +50,10 @@ function color(r,g,b,a) {
   return 'rgba('+r+','+g+','+b+','+a.toFixed(5)+')';
 }
 
+function font(size) {
+  return size+'px Quicksand, Futura, Arial, sans-serif';
+}
+
 function makeObservable(o) {
   var listeners = [];
 
@@ -67,7 +90,7 @@ var Ticker = {};
         }, 10)
       };
 
-  var then = Date.now();
+  var then = null;
   function tick(now) {
     var delta = (now - then) / 1000;
     Ticker.notify(delta);
@@ -75,9 +98,14 @@ var Ticker = {};
     nextFrame(tick);
   }
 
-  Ticker.start = function() {
+  function init(now) {
+    then = now;
     nextFrame(tick);
   }
+
+  Ticker.start = function() {
+    nextFrame(init);
+  }
 })(Ticker);
 
 // Tweens

BIN
sound/cursor.mp3