Search code examples
javascriptbrowserifycreatejseaseljs

Extending a "class" and exporting it via modules


I was following tutorial on tuts+ about game development using easeljs (browserify, bower, grunt). I'm in over my head, nonetheless I was hoping to finish, but part of the tutorials workflow (class model) is now deprecated. This is what createjs team had to say about it: http://blog.createjs.com/new-createjs-class-model/

I don't understand enough, since I didn't know the previous model and TBH trying to get JS to behave OO-like can be a pain.

I have main.js and Button.js based of online demos of easeljs. I would like to extend easeljs Container and export the Button prototype (prototype is JS way of defining a class, is this correct?) and use (create instance of?) it in main.js.

  1. Should I use anonymous function to wrap the Button.js file to avoid using global scope or is that not necessary since I am exporting it via its constructor?

  2. Is exporting the constructor the preferred way of exporting JS classes?

  3. var p in Button.js stands for prototype?

  4. If I were to create new methods for this class I would do so using p.newMethod = function() {}; function expression? And when I would create Button instance (var myButton = new Button("Best button", "green")) in main.js I could call them like so - myButton.newMethod;?

  5. Any other corrections and useful light to medium weight content links would be greatly appreciated.

main.js

'use strict';

var utils = require('./util/index')
    , domReady = utils.domReady
    , Button = require('./Button');

var c = createjs;

console.log('Game started: EaselJS version: ' + c.EaselJS.version);

domReady(function () {
    var stage = new c.Stage('main');

    stage.addChild(new Button("Best button", "green"));

    stage.update();
});

Button.js

 'use strict';

    module.exports = Button;

    function Button(label, color) {
        this.Container_constructor();
        this.color = color;
        this.label = label;

        this.setup();
    }

    var p = createjs.extend(Button, createjs.Container);

    p.setup = function() {
        var text = new createjs.Text(this.label, "20px Arial", "#000");
        text.textBaseline = "top";
        text.textAlign = "center";

        var width = text.getMeasuredWidth()+30;
        var height = text.getMeasuredHeight()+20;

        text.x = width/2;
        text.y = 10;

        var background = new createjs.Shape();
        background.graphics.beginFill(this.color).drawRoundRect(0,0,width,height,10);

        this.addChild(background, text);
        this.cursor = "pointer";

        this.mouseChildren = false;

        this.offset = Math.random()*10;
        this.count = 0;
    };

    window.Button = createjs.promote(Button, "Container");
  1. Please, don't get all "this question is too broad" on me - it is as straight forward as possible and I would really appreciate help.

Solution

  • Here are answers to some of your questions. I don't know anything about using CreateJS content with require.js, so I can't answer your first 2 questions.

    1. Yes, the p is just a reference to the object prototype, returned by the createjs.extend method.

    2. Your summary of creating methods on the prototype and calling them is correct.

    I wouldn't personally take an inheritance approach with something like this. As you mentioned, inheritance in JavaScript is sort of a mess, so only use it when it makes sense. In your case, I might compose a Container instance, which includes the background and text, and just use stage.addChild(new Button().container). I used the name "container" for the composed content to show the context, but I would probably find something more agnostic, like "instance" or "sprite".