|
|
|
@ -53,9 +53,9 @@ function Particle(parent, bounds, globalGrid, observables, behavior) { |
|
|
|
|
|
|
|
|
|
this.remove$ = new Rx.Subject(); |
|
|
|
|
|
|
|
|
|
observables.fps$ |
|
|
|
|
.takeUntil(this.remove$) |
|
|
|
|
.subscribe(this.subscribeNextFrame.bind(this)); |
|
|
|
|
const frames = observables.fps$.takeUntil(this.remove$); |
|
|
|
|
frames.subscribe(this.subscribeFrameMove.bind(this)); |
|
|
|
|
frames.subscribe(this.subscribeFrameRepaint.bind(this)); |
|
|
|
|
|
|
|
|
|
observables.speed$ |
|
|
|
|
.takeUntil(this.remove$) |
|
|
|
@ -89,7 +89,7 @@ Particle.prototype.remove = function() { |
|
|
|
|
delete this.nodes; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Particle.prototype.subscribeNextFrame = function(n) { |
|
|
|
|
Particle.prototype.subscribeFrameMove = function(n) { |
|
|
|
|
this.grids.global.deletePoint({ |
|
|
|
|
x: this.arc.endX, |
|
|
|
|
y: this.arc.endY, |
|
|
|
@ -102,23 +102,25 @@ Particle.prototype.subscribeNextFrame = function(n) { |
|
|
|
|
this.arc = Arc.randomize(this.arc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.arc = Arc.step(this.arc, this.config.bounds); |
|
|
|
|
|
|
|
|
|
this.grids.vision = updateVisionGrid(this.arc, this.config, this.grids); |
|
|
|
|
const { hazards, particles } = look(this.arc, this.grids); |
|
|
|
|
|
|
|
|
|
this.updateLeader(particles); |
|
|
|
|
|
|
|
|
|
if (hazards.length > 0) { |
|
|
|
|
this.arc = Arc.evade(this.arc); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.updateLeader(particles); |
|
|
|
|
this.arc = Arc.step(this.arc, this.config.bounds); |
|
|
|
|
|
|
|
|
|
this.grids.global.setPoint({ |
|
|
|
|
x: this.arc.endX, |
|
|
|
|
y: this.arc.endY, |
|
|
|
|
type: ENTITIES.PARTICLE |
|
|
|
|
}, this); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Particle.prototype.subscribeFrameRepaint = function(n) { |
|
|
|
|
repaintContainer(this.nodes.container, this.arc, this.leaderTime); |
|
|
|
|
repaintBody(this.nodes.body, this.arc, this.leaderTime); |
|
|
|
|
repaintCircle(this.nodes.circle, this.arc); |
|
|
|
@ -166,27 +168,38 @@ Particle.prototype.updateLeader = function(particles) { |
|
|
|
|
|
|
|
|
|
if (leader !== undefined) { |
|
|
|
|
leader.leaderTime = 1; |
|
|
|
|
this.leaderTime = 0; |
|
|
|
|
this.leader = leader; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this.leader === null) { |
|
|
|
|
if (this.leaderTime > 0) { |
|
|
|
|
this.leaderTime++; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Reset leader after a bit. (320 frames is 10 seconds)
|
|
|
|
|
if (this.leaderTime > 3000) { |
|
|
|
|
this.leaderTime = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// This particle may now be leading - break execution.
|
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this.leader.nodes === undefined) { |
|
|
|
|
// if (this.leader.nodes === undefined) {
|
|
|
|
|
if (this.leader.leaderTime === 0 && this.leader.leader === null) { |
|
|
|
|
this.leader = null; |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
this.leaderTime = 0; |
|
|
|
|
|
|
|
|
|
// Visit next node to keep chains of leaders short.
|
|
|
|
|
if (this.leader.leader !== null) { |
|
|
|
|
this.leader = this.leader.leader; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (this.leaderTime > 0) { |
|
|
|
|
this.leaderTime = 0; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Beware of circular leadership, where a leader sees its tail.
|
|
|
|
|
if (this.leader.id === this.id) { |
|
|
|
|
this.leader = null; |
|
|
|
@ -207,6 +220,9 @@ function look(arc, grids) { |
|
|
|
|
|
|
|
|
|
if (global.getPoint({ x, y, type: ENTITIES.HAZARD })) { |
|
|
|
|
acc.hazards.push({ x, y }); |
|
|
|
|
point.touch = true; |
|
|
|
|
} else { |
|
|
|
|
point.touch = false; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return acc; |
|
|
|
@ -302,7 +318,7 @@ function repaintContainer(node, arc, leaderTime) { |
|
|
|
|
node.style.left = `${arc.endX}px`; |
|
|
|
|
node.style.top = `${arc.endY}px`; |
|
|
|
|
|
|
|
|
|
node.style.zIndex = (leaderTime > 0 ? 2000 : 2); |
|
|
|
|
// node.style.zIndex = (leaderTime > 0 ? 2000 : 2);
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function repaintBody(node, arc, leaderTime) { |
|
|
|
@ -312,7 +328,7 @@ function repaintBody(node, arc, leaderTime) { |
|
|
|
|
|
|
|
|
|
node.style.transform = `rotate(${rad + RAD.t45}rad)`; |
|
|
|
|
|
|
|
|
|
node.style.border = (leaderTime > 0 ? '3px dotted #fff' : ''); |
|
|
|
|
// node.style.border = (leaderTime > 0 ? '3px dotted #fff' : '');
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
function repaintCircle(node, arc) { |
|
|
|
@ -334,11 +350,11 @@ function repaintVisionGrid(nodes, arc, grids) { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
grids.vision.forEach(({ x, y }, i) => { |
|
|
|
|
grids.vision.forEach(({ x, y, touch }, i) => { |
|
|
|
|
nodes[i].style.left = `${x}px`; |
|
|
|
|
nodes[i].style.top = `${y}px`; |
|
|
|
|
|
|
|
|
|
// nodes[i].style.border = (touch ? '2px solid red' : '0');
|
|
|
|
|
nodes[i].style.border = (touch ? '1px solid red' : '0'); |
|
|
|
|
}); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|