Move particle stuff to a system to simplify spawning particles
This commit is contained in:
parent
ec7b01918c
commit
491f532750
BIN
src/.game.js.swp
Normal file
BIN
src/.game.js.swp
Normal file
Binary file not shown.
4
src/bootstrap.js
vendored
4
src/bootstrap.js
vendored
@ -14,7 +14,7 @@ game.bootstrap = (() => {
|
|||||||
'src/components/position.js', 'src/components/momentum.js', 'src/components/gridPosition.js',
|
'src/components/position.js', 'src/components/momentum.js', 'src/components/gridPosition.js',
|
||||||
'src/components/appearence.js', 'src/components/controllable.js', 'src/components/pushable.js',
|
'src/components/appearence.js', 'src/components/controllable.js', 'src/components/pushable.js',
|
||||||
'src/components/loadPriority.js', 'src/components/stop.js', 'src/components/alive.js',
|
'src/components/loadPriority.js', 'src/components/stop.js', 'src/components/alive.js',
|
||||||
'src/components/sprite.js'
|
'src/components/sprite.js', 'src/components/particles.js'
|
||||||
],
|
],
|
||||||
id: 'components'
|
id: 'components'
|
||||||
},
|
},
|
||||||
@ -34,7 +34,7 @@ game.bootstrap = (() => {
|
|||||||
{
|
{
|
||||||
src: [
|
src: [
|
||||||
'src/systems/render.js', 'src/systems/grid.js', 'src/systems/physics.js', 'src/systems/keyboardInput.js',
|
'src/systems/render.js', 'src/systems/grid.js', 'src/systems/physics.js', 'src/systems/keyboardInput.js',
|
||||||
'src/systems/collision.js', 'src/systems/undo.js'
|
'src/systems/collision.js', 'src/systems/undo.js', 'src/systems/particle.js'
|
||||||
],
|
],
|
||||||
id: 'systems' },
|
id: 'systems' },
|
||||||
{ src: ['src/game.js'], id: 'game' },
|
{ src: ['src/game.js'], id: 'game' },
|
||||||
|
1
src/components/particles.js
Normal file
1
src/components/particles.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
game.components.Particles = (spec) => game.Component('particles', {spec});
|
BIN
src/entities/.borderParticles.js.swp
Normal file
BIN
src/entities/.borderParticles.js.swp
Normal file
Binary file not shown.
@ -1,56 +1,40 @@
|
|||||||
game.createBorderParticles = ({colors, maxAmount, minAmount, minLife, maxLife, minRadius, maxRadius, maxSpeed}) => {
|
game.createBorderParticles = () => {
|
||||||
const particles = game.Entity();
|
const particleSpawner = game.Entity();
|
||||||
let particleSpecs = Array(randomInRange(minAmount, maxAmount)).fill(0).map(() => {
|
const spawnFunction = (particleSpec) => {
|
||||||
const particle = {
|
|
||||||
x: Math.random(),
|
|
||||||
y: Math.random(),
|
|
||||||
dx: Math.random() * maxSpeed - maxSpeed / 2,
|
|
||||||
dy: Math.random() * maxSpeed - maxSpeed / 2,
|
|
||||||
radius: randomInRange(minRadius, maxRadius),
|
|
||||||
color: colors[randomInRange(0, colors.length-1)],
|
|
||||||
lifetime: randomInRange(minLife, maxLife),
|
|
||||||
elapsed: 0,
|
|
||||||
};
|
|
||||||
switch (Math.floor(Math.random() * 4)) {
|
switch (Math.floor(Math.random() * 4)) {
|
||||||
case 0:
|
case 0:
|
||||||
particle.y = 0;
|
particleSpec.y = 0;
|
||||||
particle.dy = -Math.abs(particle.dy);
|
particleSpec.dy = -Math.abs(particleSpec.dy);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
particle.x = 1;
|
particleSpec.x = 1;
|
||||||
particle.dx = Math.abs(particle.dx);
|
particleSpec.dx = Math.abs(particleSpec.dx);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
particle.y = 1;
|
particleSpec.y = 1;
|
||||||
particle.dy = Math.abs(particle.dy);
|
particleSpec.dy = Math.abs(particleSpec.dy);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
particle.x = 0;
|
particleSpec.x = 0;
|
||||||
particle.dx = -Math.abs(particle.dx);
|
particleSpec.dx = -Math.abs(particleSpec.dx);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return particle;
|
return particleSpec;
|
||||||
});
|
};
|
||||||
game.sprites.borderParticle = game.graphics.Sprite({
|
particleSpawner.addComponent(game.components.Particles({
|
||||||
drawFunction: (elapsedTime, {x, y, width, height}, context) => {
|
spec: {
|
||||||
particleSpecs.map((spec) => spec.elapsed += elapsedTime);
|
spawnFunction,
|
||||||
particleSpecs = particleSpecs.filter((spec) => spec.lifetime > spec.elapsed);
|
colors: ["#16f7c9", "#0d6e5a", "#2fa18a", "#48cfb4", "#58877d", "#178054", "#2cdb92"],
|
||||||
if (particleSpecs.length === 0) {
|
maxSpeed: 0.20,
|
||||||
particles.removeComponent("alive");
|
minRadius: 1,
|
||||||
}
|
maxRadius: 3,
|
||||||
particleSpecs.map((spec) => {
|
minLife: 100,
|
||||||
const position = {x: (spec.x * width) + x + spec.dx * spec.elapsed, y: (spec.y * height) + y + spec.dy * spec.elapsed};
|
maxLife: 300,
|
||||||
const fill = context.fillStyle;
|
minAmount: 20,
|
||||||
context.fillStyle = spec.color;
|
maxAmount: 50,
|
||||||
context.beginPath();
|
|
||||||
context.arc(position.x, position.y, spec.radius, 0, 2 * Math.PI);
|
|
||||||
context.fill();
|
|
||||||
context.fillStyle = fill;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
}));
|
||||||
particles.addComponent(game.components.LoadPriority({priority: 1}));
|
particleSpawner.addComponent(game.components.LoadPriority({priority: 1}));
|
||||||
particles.addComponent(game.components.Alive());
|
particleSpawner.addComponent(game.components.Alive());
|
||||||
particles.addComponent(game.components.Sprite({spriteName: "borderParticle"}))
|
return particleSpawner;
|
||||||
return particles;
|
}
|
||||||
}
|
|
||||||
|
@ -26,7 +26,7 @@ game.initialize = () => {
|
|||||||
// Maintained by gridSystem as a side-effect
|
// Maintained by gridSystem as a side-effect
|
||||||
game.entitiesGrid = Array(game.config.yDim).fill(null).map(() => Array(game.config.xDim).fill(null).map(() => new Map()));
|
game.entitiesGrid = Array(game.config.yDim).fill(null).map(() => Array(game.config.xDim).fill(null).map(() => new Map()));
|
||||||
|
|
||||||
game.systemOrder = ["gridSystem", "collisionSystem", "physics", "keyboardInput", "undo", "render"];
|
game.systemOrder = ["gridSystem", "collisionSystem", "physics", "keyboardInput", "undo", "particle", "render"];
|
||||||
game.systems = { };
|
game.systems = { };
|
||||||
game.systems.physics = game.system.Physics(),
|
game.systems.physics = game.system.Physics(),
|
||||||
game.systems.gridSystem = game.system.Grid(game.entitiesGrid);
|
game.systems.gridSystem = game.system.Grid(game.entitiesGrid);
|
||||||
@ -34,6 +34,7 @@ game.initialize = () => {
|
|||||||
game.systems.render = game.system.Render(game.graphics);
|
game.systems.render = game.system.Render(game.graphics);
|
||||||
game.systems.undo = game.system.Undo(game.entitiesGrid);
|
game.systems.undo = game.system.Undo(game.entitiesGrid);
|
||||||
game.systems.keyboardInput = game.system.KeyboardInput(game.systems.undo);
|
game.systems.keyboardInput = game.system.KeyboardInput(game.systems.undo);
|
||||||
|
game.systems.particle = game.system.Particle(game.canvas.context);
|
||||||
|
|
||||||
lastTimeStamp = performance.now()
|
lastTimeStamp = performance.now()
|
||||||
requestAnimationFrame(game.loop);
|
requestAnimationFrame(game.loop);
|
||||||
|
BIN
src/systems/.collision.js.swp
Normal file
BIN
src/systems/.collision.js.swp
Normal file
Binary file not shown.
BIN
src/systems/.particle.js.swp
Normal file
BIN
src/systems/.particle.js.swp
Normal file
Binary file not shown.
BIN
src/systems/.render.js.swp
Normal file
BIN
src/systems/.render.js.swp
Normal file
Binary file not shown.
@ -39,19 +39,11 @@ game.system.Collision = (entitiesGrid) => {
|
|||||||
entity.removeComponent("momentum");
|
entity.removeComponent("momentum");
|
||||||
} else {
|
} else {
|
||||||
entitiesToPush.map((e) => {
|
entitiesToPush.map((e) => {
|
||||||
// const particles = game.createBorderParticles({
|
const pushedParticleSpawner = game.createBorderParticles();
|
||||||
// colors: ["#16f7c9", "#0d6e5a", "#2fa18a", "#48cfb4", "#58877d", "#178054", "#2cdb92"],
|
pushedParticleSpawner.addComponent(game.components.Position(e.components.position));
|
||||||
// maxSpeed: 0.20,
|
pushedParticleSpawner.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
|
||||||
// minRadius: 1,
|
game.entities[pushedParticleSpawner.id] = pushedParticleSpawner;
|
||||||
// maxRadius: 3,
|
|
||||||
// minLife: 100,
|
|
||||||
// maxLife: 300,
|
|
||||||
// minAmount: 20,
|
|
||||||
// maxAmount: 50,
|
|
||||||
// });
|
|
||||||
// particles.addComponent(game.components.Position(e.components.position));
|
|
||||||
// particles.addComponent(game.components.Appearance({width: game.canvas.width / game.config.xDim, height: game.canvas.height / game.config.yDim}));
|
|
||||||
// game.entities[particles.id] = particles;
|
|
||||||
e.addComponent(game.components.Momentum({...momentum}))
|
e.addComponent(game.components.Momentum({...momentum}))
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -33,4 +33,4 @@ game.system.KeyboardInput = (undoSystem) => {
|
|||||||
};
|
};
|
||||||
window.addEventListener("keydown", keyPress);
|
window.addEventListener("keydown", keyPress);
|
||||||
return { keys, update };
|
return { keys, update };
|
||||||
}
|
}
|
||||||
|
57
src/systems/particle.js
Normal file
57
src/systems/particle.js
Normal file
@ -0,0 +1,57 @@
|
|||||||
|
game.system.Particle = () => {
|
||||||
|
"use strict";
|
||||||
|
const particleSpawners = {};
|
||||||
|
|
||||||
|
const particleSpawner = ({colors, maxAmount, minAmount, minLife, maxLife, minRadius, maxRadius, maxSpeed, spawnFunction}) => {
|
||||||
|
return Array(randomInRange(minAmount, maxAmount)).fill(0).map(() => {
|
||||||
|
let particleSpec = {
|
||||||
|
x: Math.random(),
|
||||||
|
y: Math.random(),
|
||||||
|
dx: Math.random() * maxSpeed - maxSpeed / 2,
|
||||||
|
dy: Math.random() * maxSpeed - maxSpeed / 2,
|
||||||
|
radius: randomInRange(minRadius, maxRadius),
|
||||||
|
color: colors[randomInRange(0, colors.length-1)],
|
||||||
|
lifetime: randomInRange(minLife, maxLife),
|
||||||
|
elapsed: 0,
|
||||||
|
};
|
||||||
|
if (spawnFunction) {
|
||||||
|
particleSpec = {...particleSpec, ...spawnFunction(particleSpec)};
|
||||||
|
}
|
||||||
|
return particleSpec;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const update = (elapsedTime, entities, _changedIds) => {
|
||||||
|
for (let id in entities) {
|
||||||
|
const entity = entities[id];
|
||||||
|
if (entity.hasComponent("particles")) {
|
||||||
|
if (!particleSpawners[entity.id]) {
|
||||||
|
particleSpawners[entity.id] = particleSpawner(entity.components.particles.spec.spec);
|
||||||
|
entities[id].particleSprite = game.graphics.Sprite({
|
||||||
|
drawFunction: (elapsedTime, {x, y, width, height}, context) => {
|
||||||
|
let particleSpawner = particleSpawners[entity.id];
|
||||||
|
particleSpawner.map((particleSpec) => particleSpec.elapsed += elapsedTime);
|
||||||
|
particleSpawners[id] = particleSpawner.filter((particleSpec) => particleSpec.lifetime > particleSpec.elapsed);
|
||||||
|
particleSpawner = particleSpawners[id];
|
||||||
|
if (particleSpawner.length === 0) {
|
||||||
|
entities[id].removeComponent("alive");
|
||||||
|
}
|
||||||
|
particleSpawner.map((particleSpec) => {
|
||||||
|
const position = {x: (particleSpec.x * width) + x + particleSpec.dx * particleSpec.elapsed, y: (particleSpec.y * height) + y + particleSpec.dy * particleSpec.elapsed};
|
||||||
|
const fill = context.fillStyle;
|
||||||
|
context.fillStyle = particleSpec.color;
|
||||||
|
context.beginPath();
|
||||||
|
context.arc(position.x, position.y, particleSpec.radius, 0, 2 * Math.PI);
|
||||||
|
context.fill();
|
||||||
|
context.fillStyle = fill;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new Set();
|
||||||
|
};
|
||||||
|
|
||||||
|
return { update };
|
||||||
|
};
|
@ -10,12 +10,17 @@ game.system.Render = (graphics) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
sortedEntities.forEach((entity) => {
|
sortedEntities.forEach((entity) => {
|
||||||
if (entity.hasComponent("position") && entity.hasComponent("appearance") && entity.hasComponent("sprite")) {
|
if (entity.hasComponent("position") && entity.hasComponent("appearance")) {
|
||||||
game.sprites[entity.components.sprite.spriteName].draw(elapsedTime, {...entity.components.position, ...entity.components.appearance});
|
const drawSpec = {...entity.components.position, ...entity.components.appearance};
|
||||||
|
if (entity.hasComponent("sprite")) {
|
||||||
|
game.sprites[entity.components.sprite.spriteName].draw(elapsedTime, drawSpec);
|
||||||
|
} else if (entity.hasComponent("particles")) {
|
||||||
|
entity.particleSprite.draw(elapsedTime, drawSpec);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return new Set();
|
return new Set();
|
||||||
}
|
}
|
||||||
return { update };
|
return { update };
|
||||||
};
|
};
|
||||||
|
@ -19,7 +19,7 @@ body {
|
|||||||
border: 3px solid grey;
|
border: 3px solid grey;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
background-color: rgba(0, 0, 0, 0.95);
|
background-color: rgba(0, 0, 25, 0.9);
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-hud {
|
.game-hud {
|
||||||
@ -69,4 +69,4 @@ body {
|
|||||||
|
|
||||||
.menu-button:hover {
|
.menu-button:hover {
|
||||||
background-color: #d0d0d0;
|
background-color: #d0d0d0;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user