ladybenko Posted January 5, 2014 Share Posted January 5, 2014 Hi, I'm trying to add an existing group to a game:var dummy = new Phaser.Group(game);game.add.existing(dummy);However the addChild method that eventually gets called throws this error:Uncaught TypeError: Cannot set property '_iPrev' of undefinedWhat am I doing wrong? Thanks Link to comment Share on other sites More sharing options...
rich Posted January 5, 2014 Share Posted January 5, 2014 When you create the Group it will automatically add itself to the world. The second parameter to Group (which you're not using in the code above) specifies the parent object should you wish it to not be the World. I would still suggest you use game.add.group() rather than creating it yourself, but it won't matter if you prefer not to, just keeps it a little cleaner imho. Link to comment Share on other sites More sharing options...
ladybenko Posted January 5, 2014 Author Share Posted January 5, 2014 I would still suggest you use game.add.group() rather than creating it yourself, but it won't matter if you prefer not to, just keeps it a little cleaner imho. Hi, thanks for the reply! I'm interested in adding the group afterwards because I wanted a custom group class inheriting from Phaser.Group. The reason is that I had some sprites that were related (in this case, a HUD), and I wanted to separate the logic of creation of these sprites into the group's custom class, plus a bit of other logic related to these sprites. Is there another way of doing this? I'm new to Phaser and a bit lost Thanks! Link to comment Share on other sites More sharing options...
rich Posted January 5, 2014 Share Posted January 5, 2014 Ok that makes more sense, what I'd do in that case is have my custom class extend Group, so that when the custom object is created it gets added at the right point. Do you need an example of this? Link to comment Share on other sites More sharing options...
ladybenko Posted January 5, 2014 Author Share Posted January 5, 2014 Ok that makes more sense, what I'd do in that case is have my custom class extend Group, so that when the custom object is created it gets added at the right point. Do you need an example of this? If you would be so kind, I'd appreciate it. I tried and could not make it work Thanks a lot rich Link to comment Share on other sites More sharing options...
rich Posted January 6, 2014 Share Posted January 6, 2014 Here is how I'd do it:// Here is a custom group with a property 'key'// This isn't required, it's just an example of a custom group level property. Only 'game' is required.MonsterGroup = function (game, key) { Phaser.Group.call(this, game); this.key = key;};MonsterGroup.prototype = Object.create(Phaser.Group.prototype);MonsterGroup.prototype.constructor = MonsterGroup;/** * Generate some monsters on request, all spaced out evenly */MonsterGroup.prototype.make = function(qty, x, y) { for (var i = 0; i < qty; i++) { this.create(x, y, this.key); x += 64; }}// Boilerplate code belowvar game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });function preload() { game.load.image('bunny', 'assets/sprites/bunny.png'); game.load.image('ball', 'assets/sprites/shinyball.png');}function create() { var monsters = new MonsterGroup(game, 'bunny'); var balls = new MonsterGroup(game, 'ball'); monsters.make(6, 100, 100); balls.make(10, 64, 500);} darcys22 1 Link to comment Share on other sites More sharing options...
ladybenko Posted January 9, 2014 Author Share Posted January 9, 2014 Thanks! So what happens is that I should just not call game.add.existing because when you create a new group it gets automatically added to the game instance? Cheers Link to comment Share on other sites More sharing options...
rich Posted January 11, 2014 Share Posted January 11, 2014 Yes, Groups are automatically added into the game. You can control when and where using the parent parameter though. game.add.existing is really for adding existing Sprites (or custom objects) but I will tidy up the docs for it to make it more obvious! Link to comment Share on other sites More sharing options...
Miroku_87 Posted August 2, 2014 Share Posted August 2, 2014 Hey Rich,sorry for bringing the thread up again but I have a similar issue. I'd like to make a custom Group class that is prepared when instantiated through the "new" statement and it's added to the world afterwards.Now, if you say that a group is added immediatly when created I have a problem in editing my game structure in order to work with this behaviour.Since I come from a long experience in ActionScript3 programming I'd like to structure my Sprites classes in a similar way to AS3.Since now I've tried like below.Sprite Class Example:Alien = function (game,key){ Phaser.Sprite.call(this,game,0,0,key); this.scale.set(.5,.5); this.animations.add('move',null,5,true);};Alien.ASSETS = [ {type:'spritesheet',key:'alien1',src:'./assets/sprites/alien_1.png',sheetWidth:74,sheetHeight:64}, {type:'spritesheet',key:'alien2',src:'./assets/sprites/alien_2.png',sheetWidth:98,sheetHeight:64}, {type:'spritesheet',key:'alien3',src:'./assets/sprites/alien_3.png',sheetWidth:106,sheetHeight:64}];Alien.prototype = Object.create(Phaser.Sprite.prototype);Alien.prototype.constructor = Alien;Alien.prototype.update = function (){ this.animations.play('move');};Calling this sprite:this.alien1 = new Alien(this.game,'alien1');this.alien1.x = 0;this.alien1.y = 0;this.add.existing(this.alien1); //sort of this.addChild()this.alien2 = new Alien(this.game,'alien2');this.alien2.x = this.alien1.x + this.alien1.width;this.alien2.y = 0;this.add.existing(this.alien2);this.alien3 = new Alien(this.game,'alien3');this.alien3.x = this.alien2.x + this.alien2.width;this.alien3.y = 0;this.add.existing(this.alien3); So, when inheriting Group to create an AlienGroup class I was trying to do so:AlienGroup = function (game,formation){ Phaser.Group.call(this,game); var row = []; var alien = null; for(var r in AlienGroup.FORMATIONS[formation]) { row = AlienGroup.FORMATIONS[formation][r]; for (var f in row) { alien = new Alien(this.game,'alien'+row[f]); alien.x = parseInt(r,10) * Alien.DISTANCE_X; alien.y = parseInt(f,10) * Alien.DISTANCE_Y; this.add(alien); } }};AlienGroup.prototype = Object.create(Phaser.Group.prototype);AlienGroup.prototype.constructor = AlienGroup;AlienGroup.FORMATIONS = { 'easy' : [ [1,1,1,1,1], [1,1,1,1,1], [3,3,3,3,3], [3,3,3,3,3], [2,2,2,2,2], [2,2,2,2,2], ]};AlienGroup.DISTANCE_X = 5;AlienGroup.DISTANCE_Y = 5; After that what I'd like to do is var alienGroup = new AlienGroup(this.game,'easy')this.add.existingGroud(alienGroup); //this non-existing mighty function should add the Aliens and the AlienGroup to the world I hope I've been clear on what I'd like to achieve.Can you give me some advice? Thank you! Andrea Link to comment Share on other sites More sharing options...
mandarin Posted August 3, 2014 Share Posted August 3, 2014 If I understand what you want to achieve, the problem lies in the parameters you pass to your group's constructor. You are passing a reference to this.game, which is being set as the group's parent in the constructor. According to the documentation, you can pass null to the parent parameter to prevent the group from being added to world. When you do that, you can do this.add.existing(group).var alienGroup = new AlienGroup(null, 'easy')this.add.existing(alienGroup); Link to comment Share on other sites More sharing options...
Miroku_87 Posted August 3, 2014 Share Posted August 3, 2014 Hey Mandarin,thank you for your reply! Unfortunately doing as you say leads to an error =\Uncaught TypeError: Cannot read property 'world' of null (phaser.js:18268) Link to comment Share on other sites More sharing options...
eguneys Posted August 3, 2014 Share Posted August 3, 2014 When you add a sprite, it doesn't get added to the game world, so calling this.game.add explicitly makes sense. When you add a group, it does get added to the game world by default, so you can't call this.game.add explicitly. However If you don't want to add the group to the game.world but instead to another group you say that in the Phaser.Group constructor. In your case in the AlienGroup constructor:// AlienGroup is added to 'parent' instead of default game.worldAlienGroup = function (game, parent, formation){Phaser.Group.call(this,game, parent);and use it like this:// parent is the parent group leave it 'undefined' if you want to add to the game.worldvar alienGroup = new AlienGroup(this.game, parent, 'easy')// no need to add group explicitly// this.add.existingGroud(alienGroup);I explained this in another post here: http://www.html5gamedevs.com/topic/7655-extended-sprite-or-sprites-into-a-group/?p=45781 Link to comment Share on other sites More sharing options...
Miroku_87 Posted August 3, 2014 Share Posted August 3, 2014 Ok I get everything you said, but I know you're going to kill me now.There wasn't a Phaser problem... it was all my fault. My initial code was correct. The bug was the positioning of the objects inside the group. Alien.DISTANCE_X was NaN because I had to call AlienGroup.DISTANCE_X instead..... so the consequence was that Phaser didn't add the Aliens to the group. I'm sorry I wasted your time >_< Link to comment Share on other sites More sharing options...
Recommended Posts