Adding some enemies

Gamma provides a few enemy entities for you that have their own behaviour. To add an enemy object to the level, you must specify the enemy object in the entity list.

For this tutorial, we will create a gma.platformEnemy (that walks from one end a platform to the other), a gma.patrolEnemy (that walks between two points); and a few gma.jumpingEnemy (that jump on the spot repeatedly):

entities : [
    gma.platformEnemy({bottom:0, left:45, width:3, height:6}),
    gma.patrolEnemy({bottom:0, left:6, width:3, height:6, limitLeft: 3, limitRight:12}),
    gma.jumpingEnemy ({bottom:0, left:7,  width:1, height:2}),
    gma.jumpingEnemy ({bottom:3, left:8,  width:1, height:2}),
    gma.jumpingEnemy ({bottom:6, left:9,  width:1, height:2})
]

The platform and jumping enemy require only dimensions and position (like platforms), but the patrol enemy also requires limitLeft and limitRight be set.

Types

When we specify many entities with common attributes, we can move the attributes into a custom type. This type can be referenced when making the entities to avoid unnecessary repetition. We specify types using gma.manager.addCustomDefinitions. For example:

manager.addCustomDefinitions({
    types : {
        jumpingJack: ['jumpingEnemy', {
            width    : 1,
            height   : 2
        }]
    }
});

When specifying a type, you provide an array where the first element is the name of the class to instantiate (gma.jumpingEnemy) and the second element is an object containing options which will be applied to all new instances.

We can now create jumping enemies by referencing the jumpingJack type as shown below:

// Now we can reference jumping jack
entities : [
    gma.platformEnemy({bottom:0, left:45, width:3, height:6}),
    gma.patrolEnemy({bottom:0, left:6, width:3, height:6, limitLeft: 3, limitRight:12}),
    {type:'jumpingJack', bottom:0, left:21},
    {type:'jumpingJack', bottom:3, left:24},
    {type:'jumpingJack', bottom:6, left:27}
]

Note

We no longer use the gma.jumpingEnemy function explicitly nor do we specify the width/height of these enemies.

Templates

By default all entities are rendered as a blue rectangular prism. This is controlled by the template property of the entity. The default template is cube which could (redundantly) be set as follows:

manager.addCustomDefinitions({
    types : {
        jumpingJack: ['jumpingEnemy', {
            width    : 1,
            height   : 2
            template : 'cube'
        }
    }
});

If you would like to customise the appearance of an entity you must first create a template. Here, we will use the gma.meshTemplate template helper to create a green rectangular prism template:

manager.addCustomDefinitions({,
    templates : {
        greencube : ['meshTemplate', {
            mesh : gma.unitCubeInfo.mesh,
            material : {color : "#090"}   // Very Green
        }
    }
});

We can then apply this template to the jumpingJack type:

manager.addCustomDefinitions({
    types : {
        jumpingJack: ['jumpingEnemy', {
            width    : 1,
            height   : 2
            template : 'greencube'
        }
    }
});

Note

By default, cube and redcube templates already exist, which simply create a blue and red cube respectively. The Appearance section outlines types of template objects that are available and how to use them.

Also, by default, entities will have the default type, which simply creates a gma.platform and uses the cube template.

End result

require([
    'gma/base',
    'gma/manager',
    'gma/entities/character',
    'gma/events',
    'gma/entities/enemy'
], function(gma) {
        var manager = gma.manager({
            width : 600,
            height : 500
        });
        manager.character = gma.character({
            left     : 0,
            bottom   : 0,
            width    : 3,
            height   : 6,
            depth    : 3
        });
        manager.addCustomDefinitions({
            templates : {
                greencube : ['meshTemplate', {
                    mesh : gma.unitCubeInfo.mesh,
                    material : {color : "#090"}
                }]
            },

            types : {
                jumpingJack: ['jumpingEnemy', {
                    width    : 1,
                    height   : 2,
                    template : 'greencube'
                }]
            }
        });

        var myLevel = {
            spawn : {
                main : [15, 24]
            },
            entities : [
                {top:0, left:0, width:30, height:3},
                {top:0, left:39, width:30, height:3},
                gma.platformEnemy({bottom:0, left:45, width:3, height:6}),
                gma.patrolEnemy({bottom:0, left:6, width:3, height:6, limitLeft: 3, limitRight:12}),
                {type:'jumpingJack', bottom:0, left:21},
                {type:'jumpingJack', bottom:3, left:24},
                {type:'jumpingJack', bottom:6, left:27}
            ]
        };
        manager.storeLevels(myLevel);

        gma.keyHandler.register(37, manager.character.move.curry(gma.constants.LEFT));
        gma.keyHandler.register(39, manager.character.move.curry(gma.constants.RIGHT));
        gma.keyHandler.register(32, manager.character.jump);

        manager.init();
    }
);

What’s next?

In the next section we will learn how to change the camera.