Skip to content

Renderables

Trevor Williams edited this page Apr 16, 2016 · 30 revisions

Renderable

Overview - Object for simple drawing on screen. Used as a base class, no built-in image support, but you can write just about any logic on top of it.

This is the base object literal that MelonJS uses. It extends Rect, which is essentially a simple geometric rectangle, that stores various pieces of data to make it easy for working with a rectangle on screen. Basic positioning, drawing sizes, etc. The renderable does not do a whole lot, other then give you a basic object to work with for rendering to the screen.

The details for the Renderable can be found here: http://melonjs.github.io/melonJS/docs/me.Renderable.html.

A really simple implementation of a renderable can be done as follows:

    var myRenderable = me.Renderable.extend({
        init : function() {
            // position, width, height
            this._super(me.Renderable, "init", [100, 100, 50, 50]);
            this.z = 100;
        },

        draw : function(renderer) {
            renderer.setColor('#000');
            renderer.fillRect(this.pos.x, this.pos.y, this.width, this.height);
        },

        update : function() {
            return false;
        }
    });
    me.game.world.addChild(new myRenderable());

To explain the details, the extend is called. The init function is used as a constructor. The _super init is implemented by me.Rect, which accepts a me.Vector2d for the position, and integers for the width & height. The draw method simply uses the passed canvas context to draw a simple rectangle. The update returns false, as nothing needs to be processed for that object, since in this case it is not colliding with anything, nor moving.

Sprite

Overview Useful for single static image to be drawn on screen.

The me.Sprite class takes the Renderable steps further. It is an ideal object of choice when you want to work with a static image. It gives you features such as flipping the image, scaling, easier rotation, a flicker effect, and just makes it easier to draw a simple image over implementing it yourself with the me.Renderable.

It's worth checking out the docs to see what methods are available for Sprite class: http://melonjs.github.io/melonJS/docs/me.Sprite.html

And it requires very little code to get going:

    game.MySprite = me.Sprite.extend({
        init : function() {
            this._super(me.Sprite, "init", [100, 100, me.loader.getImage('workstation'), 640, 480]);
            this.z = 1;
        }
    });

    me.game.world.addChild(new game.MySprite());

As explained in the resources section, the me.loader.getImage() accepts the name specified of an image in the resources hash.

Animation Sheet

Overview - The AnimationSheet uses the image functionality that SpriteObject provides. Instead of accepting a width & height of the total image, it accepts the width & height for dimensions of a single frame. Then it parses the source image size, and keeps track of the coordinates for each frame.

Once the animation sheet is setup, you can create animations by telling it which index to use. The docs explain this fairly well, under the addAnimation method: http://melonjs.github.io/melonJS/docs/me.AnimationSheet.html

An animation object can be setup like so:

    game.Runner = me.AnimationSheet.extend({
        init: function() {
            this._super(me.AnimationSheet, "init", [0, 0, {
                image: me.loader.getImage('runner'),
                spritewidth: 64,
                spriteheight: 64
            }]);
            this.addAnimation('running', [0,1,2,3,4,3,2,1], 1);
            this.setCurrentAnimation('running');
            this.z = 1;
        }
    });
    me.game.world.addChild(new game.Runner());

It is important to note that with the animation sheet if you overwrite the update method with your own, the _super update is what processes the animation. So be sure to invoke the parent and return true if you need your own update method:

    game.Runner = me.AnimationSheet.extend({
        init: function() {
            this._super(me.AnimationSheet, "init" [0, 0, {
                image: me.loader.getImage('runner'),
                spritewidth: 64,
                spriteheight: 64
            });
            this.addAnimation('running', [0,1,2,3,4,3,2,1], 1);
            this.setCurrentAnimation('running');
            this.z = 1;
        },
        update: function() {
            if(this.vel.x !== 0) {
                this._super(me.Renderable, "update", []);
                return true;
            }
            else {
                return false;
            }
        }
    });
    me.game.world.addChild(new game.Runner());