Jump to content

How to differentiate each sprite ? (By id ?)


kenshm
 Share

Recommended Posts

Hi,

 

First of all, I apologize in advance for my English (I'm from Switzerland).

For my problem, I have 4 types of asteroids (gray, red, brown and dark gray).

"var asteorid01" = gray asteroid
"var asteorid02" = red asteroid
"var asteorid03" = brown asteroid
"var asteorid04" = dark gray asteroid

I generate a multitude of asteroids from a same sprite and I do not know how to differentiate if I have + 20 asteroids on my screen (by id ?).
So as to verify when asteroid comes out of the screen :)
 

The code :

SpaceWar.Game = function (game) {	var asteorid01;	var asteorid02;	var asteorid03;	var asteorid04;};SpaceWar.Game.prototype = {	create: function(){		/*		 * Debug		 */		console.log('Start Game...');		console.log('X : ' + this.game.world.width.toString());		console.log('Y : ' + this.game.world.height.toString());		/* ------------------------------------------------------------ */		//Display background, logo, button(s), etc.    	        var background = this.game.add.sprite(0, 0, 'background');		background.width = this.game.world.width;		background.height = this.game.world.height;		this.game.physics.startSystem(Phaser.Physics.ARCADE);                //GENERATE ONE ASTEROID		var asteroidLoop = this.game.time.events.loop(Phaser.Timer.SECOND * 0.3, this.createAsteorid, this);	},	update: function(){	},		/*	 * Generates & create a random asteroid types	 */	createAsteorid: function(){		var type = Math.floor(Math.random()*(4-1+1)+1);		switch(type){			case 1:				asteorid01 = this.game.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid01');				this.game.physics.enable(asteorid01, Phaser.Physics.ARCADE);				asteorid01.body.gravity.y = this.rndGravity();			break;			case 2:				asteorid02 = this.game.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid02');				this.game.physics.enable(asteorid02, Phaser.Physics.ARCADE);				asteorid02.body.gravity.y = this.rndGravity();			break;			case 3:				asteorid03 = this.game.add.sprite(this.game.world.randomX - 230, this.rndPositionY(), 'asteorid03');				this.game.physics.enable(asteorid03, Phaser.Physics.ARCADE);				asteorid03.body.gravity.y = this.rndGravity();			break;			case 4:				asteorid04 = this.game.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid04');				this.game.physics.enable(asteorid04, Phaser.Physics.ARCADE);				asteorid04.body.gravity.y = this.rndGravity();			break;		}	},	/*	 * Generates a random position (Y) between -150 and -400 (for asteorids)	 */	rndPositionY: function(){		return Math.floor(Math.random()*((-400)-(-150)+1)+(-150));	},	/*	 * Generates a random (int) between 100 and 350 for gravity asteorid	 */	rndGravity: function(){		return Math.floor(Math.random()*(350-100+1)+100);	},	/*	 * Called when the player loose the game	 */	gameOver: function(){		this.state.start('GameOver');	}};

 

Result of my game actually (SCREENSHOT) :


51f5cc7679cd43874c2213331bd3aabb.jpg

 

 

PS : I do not know if I used the right method to generate my asteroids, I'm a beginner of phaser :P

 

Best regards,
Kenshimdev

 
Link to comment
Share on other sites

if you want to identicate each sprite, you can set a name to every sprite, like:

asteorid02.name = "red"

i'm new on Phaser too. so maybe i am wrong :P, but i solved a similar case in this way.

 

PS: Maybe you dont need identify each sprite, if you just want to check when a asteroid comes out of the screen, you can do it by using collision
 

Link to comment
Share on other sites

I advocate Ghonsha and Skeptron here, one bti from me to it, you can add them to different groups (or even just one) that way you have the control over them all.

 

Btw just wanted to point a few things from your code.

Your definition of vars:

SpaceWar.Game = function (game) {    var asteorid01;    var asteorid02;    var asteorid03;    var asteorid04;};

doesn't work in javascript. JS Interpreter goes through your function up to prototype up to global scope. You define your vars in function but your functions in prototype so you when your createAsteorid function is called it doesn't store yoru asteroid in these vars above but because (for example) asteorid01 variable doesn't exist in prototype scope it creates it automatically in global scope (that's how JS works) therefore you are polluting your global scope and if you want to reference to it in the future you won't find it the way you are doing it in the place your think it is. Simple code to check which does what you do in fiddle (uncomment that one line to see the differencet - check the comments) so define your vars localy if I can advise you - hope i didn't miss anything in your code if yes I'm sorry.

 

Also you can you use phaser random number generator instead of typing it all the time yourself, like this: rnd.integerInRange(minimum, maximum) (check the docs).

Link to comment
Share on other sites

Very well, thank you all for your help :).
 
I made some improvements to my code, is better ? (I tried to follow your directions @AzraelTycka)
SpaceWar.Game = function (game) {};SpaceWar.Game.prototype = {	create: function(){		/*		 * Debug		 */		console.log('Start Game...');		console.log('X : ' + this.game.world.width.toString());		console.log('Y : ' + this.game.world.height.toString());		/* ------------------------------------------------------------ */		//Display background, logo, button(s), etc.    	        var background = this.game.add.sprite(0, 0, 'background');		background.width = this.game.world.width;		background.height = this.game.world.height;		this.game.physics.startSystem(Phaser.Physics.ARCADE);		asteorids = this.game.add.group();	        //asteorids.setAll('outOfBoundsKill', true);	        //asteorids.setAll('checkWorldBounds', true);		var asteroidLoop = this.game.time.events.loop(Phaser.Timer.SECOND * 0.3, this.createAsteorid, this);	},	update: function(){	},		/*	 * Generates & create a random asteroid types	 */	createAsteorid: function(){		var type = this.game.rnd.integerInRange(1, 4);		console.log('Asteorid type number : ' + type.toString());		switch(type){			case 1:				asteorids.create(this.game.world.randomX -230, this.rndPositionY(), 'asteorid01');				this.game.physics.enable(asteroids, Phaser.Physics.ARCADE);				asteroids.body.gravity.y = this.rndGravity();			break;			case 2:				asteorids.create(this.game.world.randomX -230, this.rndPositionY(), 'asteorid02');				this.game.physics.enable(asteroids, Phaser.Physics.ARCADE);				asteroids.body.gravity.y = this.rndGravity();			break;			case 3:				asteorids.create(this.game.world.randomX -230, this.rndPositionY(), 'asteorid03');				this.game.physics.enable(asteroids, Phaser.Physics.ARCADE);				asteroids.body.gravity.y = this.rndGravity();			break;			case 4:				asteorids.create(this.game.world.randomX -230, this.rndPositionY(), 'asteorid04');				this.game.physics.enable(asteroids, Phaser.Physics.ARCADE);				asteroids.body.gravity.y = this.rndGravity();			break;		}	},	/*	 * Generates a random position (Y) between -150 and -400 (for asteorids)	 */	rndPositionY: function(){		return this.game.rnd.integerInRange(-150, -400);	},	/*	 * Generates a random (int) between 100 and 350 for gravity asteorid	 */	rndGravity: function(){		return this.game.rnd.integerInRange(100, 350);	},	/*	 * Called when the player loose the game	 */	gameOver: function(){		this.state.start('GameOver');	}};
 

In particular, I created a group called "asteroids".

Despite your explanation, I can not access to my group "asteroids" in my "createAsteroid" function. How to do ? :unsure: 

PS : I commented 2 lines to check when the asteroids in my group leave the world (screen). Is this the right way ?

 
Link to comment
Share on other sites

Well I'm not entirely sure why did you commented those two lines right now they do nothing - well even uncommented they do nothing, but just for the sake of knowledge, why exactly did you do it?

 

Btw you are still polluting your global scale, just remember that anytime you create a new variable without keyword var in javascript it is automatically added to global scope (therefore right know your asteorids is on the same level as your SpaceWar. So I suggest state is as this.asteroids = this.add.group(); this way it's in your state's scope and you still keep the access to it throughout the state.

 

I think you have a typo there, your group isn't called asteroids but asteorids, perhaps you want to change it?

 

Add line console.log(this.asteroids); at the beginning of your createAsteorid function, and call it from update function. Let us know what kind of error did you get so there is something we can start with.

 

EDIT:

 

Also I suggest adding your asteroids this way:

createAsteorid: function(){        var type = this.game.rnd.integerInRange(1, 4);        console.log('Asteorid type number : ' + type.toString());        switch(type){            case 1:                var asteroid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid01', 0, this.asteroids);                asteroid.body.gravity.y = this.rndGravity();                asteroid.checkWorldBounds = true;                asteroid.outOfBoundsKill = true;                return;  // unless you have some other code to run after this part of switch, return the function            break;            // the rest according to case 1 above        }}

This way you can easily set whatever you need on your one asteroid which you are adding to the group because you keep it's reference through the createAsteorid function as you can see.

Just for the record you enabled the body on your group so you don't need to enable it in your createAsteorid function again on every asteroid as long as you add it to the group.

 

EDIT2:

Even your image references have astreoid01 as a name not asteroid, but here you are talking about asteroid, I guess another typo?

Link to comment
Share on other sites

Thanks a lot for your help. You cleared up many things in my head :P
I updated my code. All seem to work.

The code source :

SpaceWar.Game = function (game) {};SpaceWar.Game.prototype = {	create: function(){		/*		 * Debug		 */		console.log('Start Game...');		console.log('X : ' + this.game.world.width.toString());		console.log('Y : ' + this.game.world.height.toString());		/* ------------------------------------------------------------ */		//Display background, logo, button(s), etc.    	        var background = this.game.add.sprite(0, 0, 'background');		background.width = this.game.world.width;		background.height = this.game.world.height;		this.game.physics.startSystem(Phaser.Physics.ARCADE);	        this.asteroids = this.add.group();		//var asteroidLoop = this.game.time.events.loop(Phaser.Timer.SECOND * 0.3, this.createAsteorid, this);	},	update: function(){		this.createAsteorid();	},		/*	 * Generates & create a random asteroid types	 */	createAsteorid: function(){		var type = this.game.rnd.integerInRange(1, 4);		console.log('Asteorid type number : ' + type.toString());		switch(type){			case 1:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid01', 0, this.asteroids);		            this.game.physics.arcade.enable(asteorid);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = true;			break;			case 2:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid02', 0, this.asteroids);	           	    this.game.physics.arcade.enable(asteorid);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = true;			break;			case 3:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid03', 0, this.asteroids);	                    this.game.physics.arcade.enable(asteorid);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = true;			break;			case 4:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid04', 0, this.asteroids);	                    this.game.physics.arcade.enable(asteorid);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = true;			break;		}	},	/*	 * Generates a random position (Y) between -150 and -400 (for asteorids)	 */	rndPositionY: function(){		return this.game.rnd.integerInRange(-150, -400);	},	/*	 * Generates a random (int) between 100 and 350 for gravity asteorid	 */	rndGravity: function(){		return this.game.rnd.integerInRange(100, 350);	},	/*	 * Called when the player loose the game	 */	gameOver: function(){		this.state.start('GameOver');	}};

 

I had to add this line to the code works :
this.game.physics.arcade.enable(asteorid);

 

However, how can I be sure that my sprites is kill when they leaving the screen (outOfBoundsKill) ?
(((    Because I make basic spawn outside screen (see rndPositionY function)    )))

 

You see other things to change in my code ;) ?

thanks again !


PS :
I made a typo. That's "asteorid", not "asteroid".
 

Link to comment
Share on other sites

Well, if you create them outside the screen and you are checking for bounds to kill them (that's what phaser does automaticaly if you set sprite.outOfBoundsKill to true) then unless they are close to the edge (touching) phaser will most likely kill them before they get to your screen (well logically it's checking whether it's out of bounds or not and if it's you tell phaser to kill it so it's doing everything correctly).

 

Hopefully others will advise you how to solve this better, but I do it this way: I set sprite.checkWorldBounds to true but sprite.outOfBoundsKill to false (to make sure phaser doesn't kill it before it gets to screen) and I set sprite.events.onEnterBounds.add(this.killOnOutOfBounds, this); where killOnOutOfBounds looks like this:

    killOnOutOfBounds: function(sprite)    {                sprite.outOfBoundsKill = true;            }

This way my sprites are not killed even when they are spawned out of bounds but after getting in bounds they are set to get killed if they leave them. Well I tried different approaches but this was what eventually worked in my case. Others might advise you better or you can even set your own custom function to handle what you need, in my case ti was too much to make a custom function for a simple task I had in mind so adding this event to sprite was the way to go for me (well you can always set your world larger and limit camera position max and min values so it doesn't accidentaly goes in a wrong way ;-)).

 

And last advice, I didn't notice earlier. Add this line after your group creation: this.asteroids.enableBody = true;

This way when you add a sprite to the group you don't need to enable it for physics (so you can remove four lines of code: this.game.physics.arcade.enable(asteorid);

Link to comment
Share on other sites

Superb ! Thank you very much for your explanations :) !

So I adapted my code as you have advised me and we can see much more asteorid happened on screen. I think it's because "outOfBoundsKill" is set to false at spawn.

 

Here is the updated code, is it just ?
SpaceWar.Game = function (game) {};SpaceWar.Game.prototype = {	create: function(){		/*		 * Debug		 */		console.log('Start Game...');		console.log('X : ' + this.game.world.width.toString());		console.log('Y : ' + this.game.world.height.toString());		/* ------------------------------------------------------------ */		//Display background, logo, button(s), etc.    	        var background = this.game.add.sprite(0, 0, 'background');		background.width = this.game.world.width;		background.height = this.game.world.height;		this.game.physics.startSystem(Phaser.Physics.ARCADE);	        this.asteorids = this.add.group();	        this.asteorids.enableBody = true;		//var asteroidLoop = this.game.time.events.loop(Phaser.Timer.SECOND * 0.3, this.createAsteorid, this);	},	update: function(){		this.createAsteorid();		/*		this.asteorids.forEach(function(asteorid) {		  if(asteorid.outOfBoundsKill === true) {		     console.log(' asteorid is in the world, so "outOfBoundsKill" = true ');		  }		}, this);		*/			},		/*	 * Generates & create a random asteroid types	 */	createAsteorid: function(){		var type = this.game.rnd.integerInRange(1, 4);		//console.log('Asteorid type number : ' + type.toString());		switch(type){			case 1:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid01', 0, this.asteorids);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = false;	                    asteorid.events.onEnterBounds.add(this.killOnOutOfBounds, this);			break;			case 2:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid02', 0, this.asteorids);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = false;	                    asteorid.events.onEnterBounds.add(this.killOnOutOfBounds, this);			break;			case 3:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid03', 0, this.asteorids);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = false;	                    asteorid.events.onEnterBounds.add(this.killOnOutOfBounds, this);			break;			case 4:	                    var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid04', 0, this.asteorids);	                    asteorid.body.gravity.y = this.rndGravity();	                    asteorid.checkWorldBounds = true;	                    asteorid.outOfBoundsKill = false;	                    asteorid.events.onEnterBounds.add(this.killOnOutOfBounds, this);			break;		}	},	/*	 * Set the value of "outOfBoundsKill" to true on a sprite when it is called	 */	killOnOutOfBounds: function(sprite)        {                sprite.outOfBoundsKill = true;        },	/*	 * Generates a random position (Y) between -150 and -400 (for asteorids)	 */	rndPositionY: function(){		return this.game.rnd.integerInRange(-150, -400);	},	/*	 * Generates a random (int) between 100 and 350 for gravity asteorid	 */	rndGravity: function(){		return this.game.rnd.integerInRange(100, 350);	},	/*	 * Called when the player loose the game	 */	gameOver: function(){		this.state.start('GameOver');	}};

 

You can see/play the game : here
 

Additional question :

 
My function is currently in "update" function which is set to each image. Therefore, it too asteorid spawn. How to reduce the number of spawn ?
That's why I used this method:
var asteroidLoop = this.game.time.events.loop(Phaser.Timer.SECOND * 0.3, this.createAsteorid, this);

 

Thanks,
Kenshimdev

 

Link to comment
Share on other sites

Well you can actually slightly change it even more. Your switch is basically same for all the cases, only difference is the number (type), so you can leave only one part of that like this:

createAsteorid: function(){  var type = this.game.rnd.integerInRange(1, 4);  //console.log('Asteorid type number : ' + type.toString());  if (type) // make sure type is set  {     var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid0' + type, 0, this.asteorids);     asteorid.body.gravity.y = this.rndGravity();     asteorid.checkWorldBounds = true;     asteorid.outOfBoundsKill = false;     asteorid.events.onEnterBounds.add(this.killOnOutOfBounds, this);  }}

Unless you need some specific settings for asteorids ;-).

 

Good luck with your game, bye.

Link to comment
Share on other sites

 

 

Well you can actually slightly change it even more. Your switch is basically same for all the cases, only difference is the number (type), so you can leave only one part of that like this:

createAsteorid: function(){  var type = this.game.rnd.integerInRange(1, 4);  //console.log('Asteorid type number : ' + type.toString());  if (type) // make sure type is set  {     var asteorid = this.add.sprite(this.game.world.randomX -230, this.rndPositionY(), 'asteorid0' + type, 0, this.asteorids);     asteorid.body.gravity.y = this.rndGravity();     asteorid.checkWorldBounds = true;     asteorid.outOfBoundsKill = false;     asteorid.events.onEnterBounds.add(this.killOnOutOfBounds, this);  }}

 

Indeed, it makes much more sense as a method. I had not thought of at the time.
The code is now much clearer, thanks a lot :)!

 

 

Good luck with your game, bye.

 

Thanks !



 
Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...