Added check to prevent particle starting in hazard.

master
Ben Burlingham 8 years ago
parent 143d2ec749
commit 3a350da3cc
  1. 2
      js/animation1a.js
  2. 2
      js/animation1b.js
  3. 6
      js/animation2a.js
  4. 8
      js/bundle.js
  5. 104
      js/particle.js

@ -81,7 +81,7 @@ Animation1a.prototype.updateAnimating = function(isAnimating) {
} }
Animation1a.prototype.updateCount = function(count) { Animation1a.prototype.updateCount = function(count) {
while (this.particles.length >= count) { while (this.particles.length > count) {
delete this.particles.pop().remove(); delete this.particles.pop().remove();
} }

@ -52,7 +52,7 @@ Animation1b.prototype.updateAnimating = function(isAnimating) {
} }
Animation1b.prototype.updateCount = function(count) { Animation1b.prototype.updateCount = function(count) {
while (this.particles.length >= count) { while (this.particles.length > count) {
delete this.particles.pop().remove(); delete this.particles.pop().remove();
} }

@ -9,7 +9,7 @@ function Animation2a() {
count: 1, count: 1,
maxCount: 10, maxCount: 10,
randomize: true, randomize: true,
showMovementCircle: true, showMovementCircle: false,
showVisionGrid: true, showVisionGrid: true,
speed: 4 speed: 4
}; };
@ -35,8 +35,8 @@ function Animation2a() {
// TODO perf - cache trig or perform operations // TODO perf - cache trig or perform operations
// TODO only randomize movement on 1a // TODO only randomize movement on 1a
// TODO ANIM2a Vision grid touches trig transform
// TODO ANIM2a randomize hazards // TODO ANIM2a randomize hazards
// TODO can the vision grid be relative to the particle
// TODO ANIM2 particle evade // TODO ANIM2 particle evade
// TODO ANIM2b Scale vision grid to 1000 particles // TODO ANIM2b Scale vision grid to 1000 particles
@ -68,7 +68,7 @@ Animation2a.prototype.updateAnimating = function(isAnimating) {
} }
Animation2a.prototype.updateCount = function(count) { Animation2a.prototype.updateCount = function(count) {
while (this.particles.length >= count) { while (this.particles.length > count) {
delete this.particles.pop().remove(); delete this.particles.pop().remove();
} }

File diff suppressed because one or more lines are too long

@ -27,16 +27,7 @@ function Particle(parent, bounds, config, globalGrid) {
vision: createVisionGrid(this.config) vision: createVisionGrid(this.config)
}; };
this.arc = { this.arc = createArc(bounds, globalGrid, this.config); // TODO no need to pass config after testing
centerX: random.num(0, bounds.width),
centerY: random.num(0, bounds.height),
clockwise: random.bool(),
endX: 0,
endY: 0,
length: random.num(RAD.t90, RAD.t360),
radius: random.num(100, 200),
theta: random.num(RAD.t90, RAD.t360),
};
this.nodes = { this.nodes = {
body: createBodyNode(this.config), body: createBodyNode(this.config),
@ -57,6 +48,9 @@ function Particle(parent, bounds, config, globalGrid) {
Particle.prototype.remove = function() { Particle.prototype.remove = function() {
this.nodes.parent.removeChild(this.nodes.container); this.nodes.parent.removeChild(this.nodes.container);
this.nodes.visionGrid.forEach(node => this.nodes.parent.removeChild(node));
return this; return this;
} }
@ -64,6 +58,8 @@ Particle.prototype.nextFrame = function() {
this.arc = updateArc(this.arc, this.config); this.arc = updateArc(this.arc, this.config);
this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids); this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids);
this.arc = evade(this.arc, this.grids.vision);
repaintContainer(this.nodes.container, this.arc); repaintContainer(this.nodes.container, this.arc);
repaintBody(this.nodes.body, this.arc); repaintBody(this.nodes.body, this.arc);
repaintCircle(this.nodes.circle, this.arc); repaintCircle(this.nodes.circle, this.arc);
@ -96,6 +92,34 @@ Particle.prototype.updateConfig = function(config) {
// ===== CREATION ===== // ===== CREATION =====
function createArc(bounds, globalGrid, config) {
let arc = {
centerX: random.num(0, bounds.width),
centerY: random.num(0, bounds.height),
clockwise: random.bool(),
endX: 0,
endY: 0,
length: random.num(RAD.t90, RAD.t360),
radius: random.num(100, 200),
theta: random.num(RAD.t90, RAD.t360),
};
arc.endX = arc.centerX + arc.radius * Math.cos(arc.theta);
arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta);
arc = overflowArc(arc, bounds);
const x = arc.endX - arc.endX % 5;
const y = arc.endY - arc.endY % 5;
// If starting in a hazard, recurse.
if (globalGrid[x] !== undefined && globalGrid[x][y] !== undefined) {
arc = createArc(bounds, globalGrid, config);
}
return arc;
}
function createBodyNode(config) { function createBodyNode(config) {
const node = document.createElement('div'); const node = document.createElement('div');
node.className = 'particle-body'; node.className = 'particle-body';
@ -121,10 +145,6 @@ function createContainerNode(config) {
} }
function createVisionGrid(config) { function createVisionGrid(config) {
if (config.showVisionGrid === false) {
return [];
}
const { gridSize: side, visionRadius: radius } = config; const { gridSize: side, visionRadius: radius } = config;
const r0 = radius; const r0 = radius;
const r1 = radius - side; const r1 = radius - side;
@ -133,8 +153,8 @@ function createVisionGrid(config) {
for (let x = -radius; x <= radius; x += side) { for (let x = -radius; x <= radius; x += side) {
for (let y = -radius; y <= radius; y += side) { for (let y = -radius; y <= radius; y += side) {
// Omit lower half // Omit large slices of unused circle
if (y < 0) { if (x > y || x < -y) {
continue; continue;
} }
@ -146,7 +166,7 @@ function createVisionGrid(config) {
let alpha = Math.atan(y / x); let alpha = Math.atan(y / x);
if (x < 0) { if (x < 0) {
alpha = RAD.t180 + alpha; // TODO += alpha += RAD.t180;
} }
points.push({ x, y, r, alpha, touch: false }); points.push({ x, y, r, alpha, touch: false });
@ -201,21 +221,7 @@ function updateArc(arc, { bounds, randomize, speed }) {
arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta); arc.endY = arc.centerY - arc.radius * Math.sin(arc.theta);
// Overflow. // Overflow.
if (arc.endX < 0) { arc = overflowArc(arc, bounds);
arc.endX += bounds.width;
arc.centerX += bounds.width
} else if (arc.endX > bounds.width) {
arc.endX -= bounds.width;
arc.centerX -= bounds.width
}
if (arc.endY < 0) {
arc.endY += bounds.height;
arc.centerY += bounds.height
} else if (arc.endY > bounds.height) {
arc.endY -= bounds.height;
arc.centerY -= bounds.height
}
return arc; return arc;
} }
@ -243,6 +249,26 @@ function updateVisionGrid(arc, config, grids) {
}, []); }, []);
} }
function overflowArc(arc, bounds) {
if (arc.endX < 0) {
arc.endX += bounds.width;
arc.centerX += bounds.width
} else if (arc.endX > bounds.width) {
arc.endX -= bounds.width;
arc.centerX -= bounds.width
}
if (arc.endY < 0) {
arc.endY += bounds.height;
arc.centerY += bounds.height
} else if (arc.endY > bounds.height) {
arc.endY -= bounds.height;
arc.centerY -= bounds.height
}
return arc;
}
function moveArc(arc, newRadius) { function moveArc(arc, newRadius) {
const r0 = arc.radius; const r0 = arc.radius;
const r1 = newRadius; const r1 = newRadius;
@ -263,6 +289,20 @@ function changeDirection(arc) {
return arc; return arc;
} }
// ===== ACTIONS =====
function evade(arc, visionGrid) {
const danger = visionGrid.reduce((acc, v) => acc || v.touch, false);
if (danger === false) {
return arc;
}
const evasionArc = moveArc(arc, 20);
evasionArc.length = 1;
return evasionArc;
}
// ===== RENDERING ===== // ===== RENDERING =====
function repaintContainer(node, arc) { function repaintContainer(node, arc) {
node.style.left = `${arc.endX}px`; node.style.left = `${arc.endX}px`;

Loading…
Cancel
Save