Jump to content

How to stop particles from sliding over terrain after explosion?


piotr
 Share

Recommended Posts

I spawn an emitter after a tile has been destroyed to achieve a "debris" effect, but because the particles keep their velocity, they keep sliding on the terrain. I'd like the particles to explode and then just bounce of the terrain and not to move much.

 

I've tried to set the velocity to 0 in a callback function after checking for collision between particles and the layer but all it does it blocks all particles in one place and the explosion effect doesn't happen.

//in create();this.dirtBreakParticles = game.add.emitter(0,0,10);this.dirtBreakParticles.makeParticles('particles', 0);this.dirtBreakParticles.setYSpeed(-300,300);this.dirtBreakParticles.setXSpeed(-300,300);this.dirtBreakParticles.gravity = 10;//in update();game.physics.arcade.collide(this.dirtBreakParticles, this.layerDirt, function() {        this.dirtBreakParticles.setYSpeed(0,0);	this.dirtBreakParticles.setXSpeed(0,0);}, null, this);...if(tile.properties.tileHealth <= 0){  //put emitter at center of the tile  this.dirtBreakParticles.x = tile.worldX + this.tileSize * 0.5;   this.dirtBreakParticles.y = tile.worldY + this.tileSize * 0.5;  //start emitter  this.dirtBreakParticles.start(true, 5000, null, 10);   //destroy tile  this.map.removeTile(tile.x, tile.y, this.layerDirt);					}
Link to comment
Share on other sites

Hey, thanks! Didn't consider that. What's the best way to enable mass on particles? 

 

I've tried either this way

//in create();game.physics.arcade.enable(this.dirtBreakParticles);this.dirtBreakParticles.enableBody = true;this.dirtBreakParticles.setAll('body.mass', 100);
 

or this way

//in create();this.dirtBreakParticles.forEach(function(item) {   game.physics.arcade.enable(item);   item.enableBody = true;   item.body.mass = 100; 		}, this);
Link to comment
Share on other sites

body.friction is a Phaser.Point object, are you setting the x and y values respectively?

E.g.

sprite.body.friction.x = 0.5;sprite.body.friction.y = 0.5;

If it still doesn't work I will have to attempt to implement this myself when I have a spare minute. In the meantime you could try manually subtracting from the particle's velocity.x/y values every frame when colliding:
 

//in update();game.physics.arcade.collide(this.dirtBreakParticles, this.layerDirt, function(particle, dirt) {        if(particle.velocity.x > 0) particle.velocity.x -= 0.5;	if(particle.velocity.y > 0) particle.velocity.y -= 0.5;}, null, this);
Link to comment
Share on other sites

Thank you for your help, NateTheGreatt.

 

So, friction is not working, I get a "Uncaught TypeError: Cannot read property 'friction' of undefined" error on this code

this.dirtBreakParticles = game.add.emitter(0,0,10);this.dirtBreakParticles.makeParticles('particles', 0);this.dirtBreakParticles.setYSpeed(-300,300);this.dirtBreakParticles.setXSpeed(-300,300);this.dirtBreakParticles.enableBody = true;this.dirtBreakParticles.body.friction.x = 0.5;this.dirtBreakParticles.body.friction.y = 0.5;

but the second method works great (with a small correction to your code: body was missing)!

//in update();game.physics.arcade.collide(this.dirtBreakParticles, this.layerDirt, function(particle, dirt){			if(particle.body.velocity.x > 0)particle.body.velocity.x -= 0.5;if(particle.body.velocity.y > 0)particle.body.velocity.y -= 0.5;}, null, this);
Link to comment
Share on other sites

p.s. after a couple of tests: most particles slow down, but other keep moving, I guess because the code subtracts a fixed value (0.5) from a random value (-300, 300); so the higher the initial velocity the longer slow down effect will occur. 

Link to comment
Share on other sites

Be careful, your dirtBreakParticles object is an Emitter (which inherits Group), it is not a Sprite and thus it doesn't have a body. The friction variable exists only on the Body object of a Sprite. Try this (in this example I have renamed your dirtBreakParticles to dirtEmitter as to not confuse its type):

// in create()
var friction = 0.8;
this.dirtEmitter.callAll(function(particle) {    
	particle.body.friction.x = friction;    
	particle.body.friction.y = friction;
});

Adjust the friction var to your liking.

 

A third solution might be to set the body's drag variable when colliding. Drag applies constant friction.

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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