Timed particle emitters in Phaser 3 - javascript

I'm adding a blood effect for when enemies are hit in my game and I want to be able to specify how long the particle emitter will emit particles for, but the lifespan property when creating a particle emitter is the lifespan of the particles, not the emitter. Is there something like this, or another way? I could set it to off after a minute but I'm not sure how a ton of inactive particle emitters would affect performance.
this.add.particles({
//particle stuff
emitterLifespan: 1000
})
Any suggestions? Thanks!

tldr; ("easy" solution simply use setTimeout(() => emiter.stop(), 1000) , to stop the emitter. In the demo below, it is the last/yellow emitter)
I don't know of any such property, and is also not mentioned in the documentation (or the unofficial more hands on documentation)
I had the same problem, since the particles work abit odd, I think.
It seems you must balance the properies carefully. For the basic scenario, (seen below), the following properties could cause a problem:
lifespan lifespan of emitted particles
maxParticles hard limit of particles
frequency milliseconds for emit cycle
I noticed if the particles "die" before it reaches maxParticles, the emitter won't "stop".
You could configer the properties, so that the emitter stop when it reaches the max ( the red particles in the example), or you could use the setTimeout function to stop it, after some time(like the yellow particles). Green and blue just show how different values won't stop the emitter. (due to the random part, and depending on the performance of the browser/pc, this might run forever or stop. On my CellPhone the blue emitter stops, but the green ones don't. And on my PC green and blue run for "ever")
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
gravity:{ y: 100 },
debug: true
}
},
scene: {
create
},
banner: false
};
function create () {
this.add.text(10,10, 'Click to Create Blood').setOrigin(0);
let g = this.make.graphics({add:false});
g.fillStyle(0xffffff)
g.fillCircle(4,4,4);
g.generateTexture('blood', 8, 8)
let particles = this.add.particles('blood');
this.input.on('pointerdown', p => {
particles.createEmitter({
tint: 0xff0000,
alpha: { start: 1, end: 0 },
scale: { start: 0.5, end: 1.5 },
speed: {random: [20, 100] },
accelerationY: {random: [-100, 200] },
rotate: { min: -180, max: 180 },
lifespan: { min: 300, max: 800 },
frequency: 20,
maxParticles: 10,
x: p.x,
y: p.y
});
particles.createEmitter({
alpha: { start: 1, end: 0 },
tint: 0x00ff00,
scale: { start: 0.5, end: 1.5 },
speed: {random: [20, 100] },
accelerationY: {random: [-100, 200] },
rotate: { min: -180, max: 180 },
lifespan: { min: 300, max: 800 },
frequency: 120,
maxParticles: 10,
x: p.x + 100,
y: p.y
});
particles.createEmitter({
alpha: { start: 1, end: 0 },
tint: 0x0000ff,
scale: { start: 0.5, end: 1.5 },
speed: {random: [20, 100] },
accelerationY: {random: [-100, 200] },
rotate: { min: -180, max: 180 },
lifespan: { min: 200, max: 300 },
frequency: 10,
maxParticles: 20,
x: p.x + 200,
y: p.y
});
let emitter = particles.createEmitter({
alpha: { start: 1, end: 0 },
tint: 0xffff00,
scale: { start: 0.5, end: 1.5 },
speed: {random: [20, 100] },
accelerationY: {random: [-100, 200] },
rotate: { min: -180, max: 180 },
lifespan: { min: 200, max: 300 },
frequency: 10,
maxParticles: 20,
x: p.x + 300,
y: p.y
});
// Stop after 1000 ms
setTimeout(()=> emitter.stop(), 1000);
});
}
new Phaser.Game(config);
<script src="https://cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>
btw.: you could also use the explode function if all particles should be emitted at once, checkout this official example, and here the link to the documenation.

Related

Phaser groups moving each child independantly

so i have a phaser group
this.cows = this.physics.add.group({
key: "cow",
repeat: 2,
setXY: { x: 160, y: 1500, stepX: 32 },
});
this.cows.children.iterate(function (child) {
child.setSize(20, 10, true);
child.setBounceY(Phaser.Math.FloatBetween(0.2, 0.4));
});
I plan to update the movement of every child in the update function, so how would i make sure every child has a different amount of movement in a different direction?
Depending on your use case you could simply use, a property destination which the child wants to reach, and when it is reached, just set a new destination.
Here a short demo showcaing this:
(it uses Vector's, not everybody likes/understtands them, but they are concise)
document.body.style = 'margin:0;';
var config = {
type: Phaser.AUTO,
width: 536,
height: 183,
physics: {
default: 'arcade',
arcade: {
debug: true
}
},
scene: {
create,
update
},
banner: false
};
function create () {
this.add.text(10,10, 'Random Movment')
.setOrigin(0)
.setStyle({fontStyle: 'bold', fontFamily: 'Arial'});
let graphics = this.make.graphics();
graphics.fillStyle(0xffffff);
graphics.fillRect(0, 0, 10, 10);
graphics.generateTexture('cow', 10, 10);
this.cows = this.physics.add.group({
key: "cow",
repeat: 2,
setXY: { x: 50, y: 50, stepX: 32 },
});
this.cows.children.iterate(function (child) {
child.setSize(10, 10, true);
child.setBounceY(Phaser.Math.FloatBetween(0.2, 0.4));
child.speed = Phaser.Math.Between(30, 50);
child.destination = { x: child.x , y: child.y};
});
}
function update(){
this.cows.children.iterate(function (child) {
if(Phaser.Math.Distance.BetweenPoints(child.body.position, child.destination) <= 20){
//new destination
child.destination = { x:Phaser.Math.Between(50, 200), y:Phaser.Math.Between(50, 150)};
// Setup velocity
let vector = new Phaser.Math.Vector2(child.destination);
vector.subtract(child.body.position)
.setLength(child.speed);
child.setVelocity(vector.x, vector.y);
}
});
}
new Phaser.Game(config);
<script src="//cdn.jsdelivr.net/npm/phaser#3.55.2/dist/phaser.js"></script>

Particles spawn too fast - Phaser 3

I am trying to make a snow effect behind the main menu of my game using the particle emitter but particles spawn way too fast.
I have this code:
var particles = this.add.particles('snow');
var emitter = particles.createEmitter({
speedY: { min: 15, max: 40 },
gravityY: 0,
scale: 0.2,
quantity: 1,
lifespan: { min: 28000, max: 30000 },
emitZone: { source: new Phaser.Geom.Line(-20, -100, 820, -100 )}
});
And quantity is only one, so I do not know how to fix this. Is it possible to change the spawn speed of the particles?
I am using Phaser 3 and the arcade physics.
I think what you're looking for is the frequency setting.
It doesn't exactly change the spawn speed, but it changes the time between flow cycles. If you add a frequency: 1000 to the emitter you currently have, it gives you about 8-10 particles on the screen at a time. You can play with that number until you get the flow you want.
I achieved for my snow effect this way, maybe it helps you. It has a random wind blow and rotation for the snowflakes.
this.emitter = snowParticles.createEmitter({
frame: [0, 1, 2, 3, 4, 5],
x: {min: 0, max: this.sys.game.canvas.width},
y: 0 ,
lifespan: {min: 20000, max: 60000},
speedY: 50,
gravityX: Math.ceil((Math.random() - 0.5) * 2) < 1 ? -10 : 10,
gravityY: 10,
minVelocityY: 10,
maxVelocityY: 30,
minVelocityX: 10,
maxVelocityX: 30,
quantity: 1,
scale: 0.4,
frequency: 1000,
blendMode: 'ADD',
rotate: { start: 0, end: 180 }
});
Here is the uploaded live example: https://vajda.co.uk/demo/react/winter-landscape/

Change zoom level 3d scatterPlot (Plotly)

I have a 3d scatterplot of which i want to change its zoom level and pan around it programmatically. I have tried setting the range in the layout from the beggining but it does not change the actual zoom level, just the points in the range:
"layout":
{
margin: {
l: 0,
r: 0,
b: 0,
t: 0,
pad: 1
},
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
}
},
Also i've tried invoking it with the relayout function, but it is also not working
var update = {
scene:{
xaxis: {range:[-13,13.5]},
yaxis: {range:[-15.5,13.5]},
zaxis: {range:[-14.5,13.5]},
},
};
Plotly.relayout(gd, update);
Finally i found the property to change the camera position:
var update = {
scene:{
camera: {
center: { x: 0, y: 0, z: 0 },
eye: { x: 2, y: 2, z: 0.1 },
up: { x: 0, y: 0, z: 1 }
}
},
};
Plotly.relayout(gd, update);

Matter JS - option list - Am I blind?

New to MatterJS.
In the example, theres is options to draw circle, rectangle, etc.
Those options are like using Sprite, FillStyle...
I see no where in the documentation the list of options and values related to that.
Anyone can help?
Thanks.
From reading the source code of matter.js I found the defaults for options. Doesn't explain what each does but at least here's a list of them:
var defaults = {
id: Common.nextId(),
type: 'body',
label: 'Body',
parts: [],
plugin: {},
angle: 0,
vertices: Vertices.fromPath('L 0 0 L 40 0 L 40 40 L 0 40'),
position: { x: 0, y: 0 },
force: { x: 0, y: 0 },
torque: 0,
positionImpulse: { x: 0, y: 0 },
constraintImpulse: { x: 0, y: 0, angle: 0 },
totalContacts: 0,
speed: 0,
angularSpeed: 0,
velocity: { x: 0, y: 0 },
angularVelocity: 0,
isSensor: false,
isStatic: false,
isSleeping: false,
motion: 0,
sleepThreshold: 60,
density: 0.001,
restitution: 0,
friction: 0.1,
frictionStatic: 0.5,
frictionAir: 0.01,
collisionFilter: {
category: 0x0001,
mask: 0xFFFFFFFF,
group: 0
},
slop: 0.05,
timeScale: 1,
render: {
visible: true,
opacity: 1,
sprite: {
xScale: 1,
yScale: 1,
xOffset: 0,
yOffset: 0
},
lineWidth: 0
}
};
As taras pointed out the object's properties are initialized from these options.
These options are body's properties, described in Matter.Body module: http://brm.io/matter-js/docs/classes/Body.html#properties
I think that in those examples, matter.js is handling the drawing of the shapes of the bodies itself through Render.bodies (inside matter.js file) and related functions.
In case anyone want to draw lines, circles or rectangles, they can access the canvas that matter.js uses, and draw them via lineTo, arc functions of canvas, I guess.

custom point to point path with bezier curve animation

I wanna create a moving car object that animates from point-A to point-B, point-B to point-C, and point-C to point-D. I'm using the "jQuery.Path.js" with bezier curve function but it only has 2 points to setup (start & end). How can I add 2 more points in between?? please help!
here's the original js page: JQUERY PATH BEZIER CURVE GENERATOR
<script type="text/javascript" src="js/jquery.path.js"></script>
<script type="text/javascript">
function animate(){
var path = {
start: {
x: 1200,
y: 445,
},
second: {
x: 890,
y: 520,
},
third: {
x: 650,
y: 600,
angle: 20,
length: 0.2
},
end: {
x: -100,
y: 470,
}
};
$('.car').animate(
{
path : new $.path.bezier(path)
},
20000,
animate
);
}
animate();
</script>

Categories