Sign in to follow this  
BdR

Adding custom enemy objects to a phaser.group..?

Recommended Posts

I'm trying to get familiar with the Phaser framework, and organise my project properly to expand it into a game. So far it's looking good, Phaser has a lot of useful stuff :)
 
For now, I've created a test project where several enemies should be moving around and the player has to catch them, simply by running into them. It's not really a game, just test project. It has the usual Phaser functions preload/create/update, a createSomeAnimals functino and a separate "Animal" class. I want the Animal class to contain all the logic for moving around.
 
Unfortunately there is an error in the Animal constructor class, and I don't know how to fix it. 

QuoteUncaught TypeError: Cannot set property 'frame' of undefined

It happens when trying to access the phaser.sprite of the Animal constructor class.

// animal constructorvar Animal = function(game, x, y, animaltype) {    //this.sprite = game.add.sprite((CANVAS_WIDTH / 2), (CANVAS_HEIGHT / 2), 'zookeeper');    Phaser.Sprite.call(this, game, x, y, 'zookeeper');    ..    // **ERROR OCCURS ON NEXT LINE**    //this.sprite.frame = animaltype; // animal frame 0..3    ..}Animal.prototype = Object.create(Phaser.Sprite.prototype);Animal.prototype.constructor = Animal;

I'm also not 100% familiar with how JavaScript classes and prototypes work, so I suspect I've made some errors in that area.  :huh:

 
See this example github here:
 
Or the full source code below:
// -------------------------------------// START THE GAME// -------------------------------------var CANVAS_WIDTH = 800;var CANVAS_HEIGHT = 600;var ANIMAL_COUNT = 20;var ANIMAL_SPEED = 2;var game = new Phaser.Game(CANVAS_WIDTH, CANVAS_HEIGHT, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });var player;var animalsGroup;// -------------------------------------// PHASER GAME FUNCTIONS// -------------------------------------function preload() {    game.load.spritesheet('zookeeper', 'zookeeper.png', 80, 80);}function create() {    // arcade physics    game.physics.startSystem(Phaser.Physics.ARCADE);    // blue background    game.stage.backgroundColor = 0xbada55;    //  The hero!    player = game.add.sprite((CANVAS_WIDTH / 2), (CANVAS_HEIGHT / 2), 'zookeeper');    player.frame = 4; // frame with zookeeper    player.anchor.setTo(0.5, 0.5);    game.physics.enable(player, Phaser.Physics.ARCADE);    //  The animals!    animalsGroup = game.add.group();    animalsGroup.enableBody = true;    animalsGroup.physicsBodyType = Phaser.Physics.ARCADE;    createSomeAnimals();    }function update() {    //  Run collision    game.physics.arcade.overlap(animalsGroup, player, playerHitsAnimal, null, this);}function render() {    // for (var i = 0; i < animalsGroup.length; i++)    // {    //     game.debug.body(animalsGroup.children[i]);    // }}// -------------------------------------// GAME LOGIC// -------------------------------------function createSomeAnimals () {    for (var i = 0; i < ANIMAL_COUNT; i++)    {        // which type of animal 0..3        var antype = (i % 4); // i modulo 4, will cycle through values 0..3         // random position        var x = game.rnd.integerInRange(0, CANVAS_WIDTH-80);        var y = game.rnd.integerInRange(0, CANVAS_HEIGHT-80);                // get inactive animal from animals object pool        var animal = this.animalsGroup.getFirstDead();        // if there aren't any available, create a new one        if (animal === null) {            animal = new Animal(this.game, x, y, antype);            this.animalsGroup.add(animal);        };        // else revive the animal (set it's alive property to true)        animal.revive();        animal.x = x;        animal.y = y;        animal.AnimalType = antype;    };}function playerHitsAnimal (animal, player) {    //  player hits an animal, remove the animal    animal.kill();}// -------------------------------------// ANIMAL OBJECT// -------------------------------------// animal constructorvar Animal = function(game, x, y, animaltype) {    //this.sprite = game.add.sprite((CANVAS_WIDTH / 2), (CANVAS_HEIGHT / 2), 'zookeeper');    Phaser.Sprite.call(this, game, x, y, 'zookeeper');        // set animal fields    this.xspeed = 1;    this.yspeed = 1;    this.AnimalType = animaltype;    // **ERROR ON NEXT LINE** -> Uncaught TypeError: Cannot set property 'frame' of undefined     //this.sprite.frame = animaltype; // animal frame 0..3        // enable physics for animal    //game.physics.enable(this, Phaser.Physics.ARCADE);}// Specific JavaScript object/construcor stuff going on here(?)// Animals are a type of Phaser.SpriteAnimal.prototype = Object.create(Phaser.Sprite.prototype);Animal.prototype.constructor = Animal;// animal update move aroundAnimal.prototype.update = function() {    // If this animal is disabled then don't do anything    if (this.active) {        //aads        switch (this.AnimalType) {            case 0: // not moving                break;            case 1: // move away from player                if (this.x > this.game.input.activePointer.x) {this.x = this.x + ANIMAL_SPEED;};                if (this.x < this.game.input.activePointer.x) {this.x = this.x - ANIMAL_SPEED;};                if (this.y > this.game.input.activePointer.y) {this.y = this.y + ANIMAL_SPEED;};                if (this.y < this.game.input.activePointer.y) {this.y = this.y - ANIMAL_SPEED;};                // don't move outside screen bounds                if (this.x < 0)             {this.x = 0};                if (this.x > CANVAS_WIDTH)  {this.x = CANVAS_WIDTH};                if (this.y < 0)             {this.y = 0};                if (this.y > CANVAS_HEIGHT) {this.y = CANVAS_HEIGHT};                break;            case 2: // move left-right                this.x = this.x + this.xspeed;                // move in opposite direction when on screen bounds                if ( (this.x < 0) || (this.x > CANVAS_WIDTH) ) {this.xspeed = -1 * this.xspeed;};                break;            case 3: // move all over screen                this.x = this.x + this.xspeed;                this.y = this.y + this.yspeed;                // move in opposite direction when on screen bounds                if ( (this.x < 0) || (this.x > CANVAS_WIDTH)  ) {this.xspeed = -1 * this.xspeed;};                if ( (this.y < 0) || (this.y > CANVAS_HEIGHT) ) {this.yspeed = -1 * this.yspeed;};                break;        };    };}

 

Share this post


Link to post
Share on other sites

I see that you're trying to extend the Sprite class.

 

I think you can use this:

this.frame = animaltype;

instead of 

this.sprite.frame = animaltype;

since 'this' is already point at itself (Sprite object).

Share this post


Link to post
Share on other sites
I've put the player in a separate Player class, but now the player is not displaying at all. :huh: Anyone know what has gone wrong here?

 

I've update the github https://github.com/BdR76/phaseranimals and here is the code:



function create() {
    ..
    player = new Player(game);
    ..
}

// -------------------------------------
// PLAYER OBJECT
// -------------------------------------
// player constructor
var Player = function(game) {
    Phaser.Sprite.call(this, game, (CANVAS_WIDTH / 2), (CANVAS_HEIGHT / 2), 'zookeeper');
    this.frame = 4; // frame with zookeeper
    this.anchor.setTo(0.5, 0.5);

    // enable physics for player
    game.physics.enable(this, Phaser.Physics.ARCADE);
}

// Specific JavaScript object/construcor stuff going on here(?)
// Player is a type of Phaser.Sprite
Player.prototype = Object.create(Phaser.Sprite.prototype);
Player.prototype.constructor = Player;

Share this post


Link to post
Share on other sites

You need to add the newly created player object to the world, or a group/display object already in the world, as instantiating a sprite doesn't take care of this part. You're adding animals to this.animalsGroup but not adding player anywhere in the scene.

Share this post


Link to post
Share on other sites

You need to add the newly created player object to the world, or a group/display object already in the world, as instantiating a sprite doesn't take care of this part. You're adding animals to this.animalsGroup but not adding player anywhere in the scene.

 

Okay, but how do I add the my custom player to the game? These javascript objects and classes are tricky. I've tried this

player = new Player(game);game.add(player);// gives error -> object is not a function

And I've also tried this, but that also gives an error

var Player = function(pgame) {    ..    this = game.add.sprite(x, y, 'zookeeper');    ..}// gives error -> Invalid left-hand side in assignment

Share this post


Link to post
Share on other sites
It wasn't immediately obvious, but I think I found it. :)
player = new Player(game);game.world.add(player); // <- this does the trick

I've updated the github project which can serve as an example for newcomers to Phaser. So if anyone has comments or improvements please let me know.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.