Director and Scene

If you have multiple ‘scenes’ in your game, for example a start screen, the actual game screen and an option screen then you will probably want to employ the Director and Scene concepts.

There’s different names for those concepts. Some call the scenes “stages” or “screens” and obviously the name ‘director’ is also debatable

A central director makes it easier to switch between different scenes where each scene has his own independent logic drawing the whole screen and consuming all input event hands. A director could also keep track of a stack of scenes which would allow you to push() and pop() but this useful extension is not covered in the tutorial.

The director is created:

    var director = new Director();

Our director will manage the screen, i.e., create the screen and let the active scene draw on it. Let’s think about the scene API for a moment:

This is how a start screen could look like:

    var StartScene = function(director) {

      this.handleEvent = function(event) {
         if (event.type === gamejs.event.MOUSE_UP) {
            director.replaceScene(new GameScene(director));
         }
      };

      this.draw = function(display) {
         display.blit(startPicture);
      };

      var startPicture = gamejs.image.load('images/start.png');
      return this;
   };

This scene doesn’t have a update(msDuration) function because the start screen never changes. It waits for a gamejs.event.MOUSE_UP event to switch to the next scene by calling director.replaceScene(nextScene).

Initially, our director is paused and has no scene active. We start the game by calling director.start(firstScene):

    var firstScene = new StartScene(director);
    director.start(firstScene);

The Director class, which provides the above functionality, needs to keep track of the active scene and forwards the draw, update and handleEvent calls to it:

    function Director () {
       var onAir = false;
       var activeScene = null;

       this.update = function(msDuration) {
          if (!onAir) return;

          if (activeScene.update) {
             activeScene.update(msDuration);
          }
       }

       this.draw = function(display) {
          if (activeScene.draw) {
              activeScene.draw(display);
          }
       };

       this.handleEvent = function(event) {
          if (activeScene.handleEvent) {
             activeScene.handleEvent(event);
          }
       }


       this.start = function(scene) {
          onAir = true;
          this.replaceScene(scene);
          return;
       };

       this.replaceScene = function(scene) {
          activeScene = scene;
       };

       this.getScene = function() {
          return activeScene;
       };
       return this;
    };

End of Tutorial