Leader reset. Hazard update. Animation 3c.

master
Ben Burlingham 8 years ago
parent 16bb851024
commit 85208e9063
  1. 8
      index.html
  2. 3
      js/animation.js
  3. 2
      js/animation2a.js
  4. 2
      js/animation2b.js
  5. 2
      js/animation3a.js
  6. 15
      js/animation3c.js
  7. 12
      js/arc.js
  8. 28
      js/bundle.js
  9. 12
      js/index.js
  10. 48
      js/particle.js

@ -84,12 +84,18 @@
<div class='outerContainer' id='3a'></div>
<p>
On a larger scale, the particles are starting to take on a personality.
</p>
<div class='outerContainer' id='3b'></div>
<p>
The exploration is now complete: arc-based movement, independent AIs, grid-based vision,
hazards, and cohesive flocking behavior, on a large scale:
</p>
<div class='outerContainer' id='3b'></div>
<div class='outerContainer' id='3c'></div>
<script src='js/bundle.js'></script>
<script src='/core/js/ui.js'></script>

@ -44,10 +44,9 @@ Animation.prototype.subscribeCount = function(count) {
}
}
Animation.prototype.addHazards = function() {
Animation.prototype.addHazards = function(n) {
const bounds = this.container.getBoundingClientRect();
const n = Random.num(1, 3);
for (let i = 0; i < n; i++) {
const w = Random.num(50, 200);
const h = Random.num(50, 200);

@ -10,5 +10,5 @@ export default function(destroy$) {
};
const observables = Controls(destroy$, config);
(new Animation(observables, id, true)).addHazards();
(new Animation(observables, id, true)).addHazards(2);
}

@ -10,5 +10,5 @@ export default function(destroy$) {
};
const observables = Controls(destroy$, config);
new Animation(observables, id).addHazards();
new Animation(observables, id).addHazards(2);
}

@ -11,5 +11,5 @@ export default function(destroy$) {
};
const observables = Controls(destroy$, config);
new Animation(observables, id, BEHAVIOR.COHESION);
new Animation(observables, id, BEHAVIOR.COHESION).addHazards();
}

@ -0,0 +1,15 @@
import Animation from './animation';
import Controls from './controls';
import { BEHAVIOR } from './enums';
export default function(destroy$) {
const id = '3c';
const config = {
id,
count: 200,
maxCount: 1000
};
const observables = Controls(destroy$, config);
new Animation(observables, id, BEHAVIOR.COHESION).addHazards(1);
}

@ -137,20 +137,22 @@ const Arc = {
if (arc.speed > arcToFollow.speed) {
arc = Arc.changeSpeed(arc, arc.speed - 1);
} if (arc.speed < arcToFollow.speed) {
}
if (arc.speed < arcToFollow.speed) {
arc = Arc.changeSpeed(arc, arc.speed + 1);
}
} else if (rigidityCoeff < rigidity) {
arc = Arc.changeRadius(arc, 20);
if (arc.speed > arcToFollow.speed - 1) {
if (arc.speed > arcToFollow.speed) {
arc = Arc.changeSpeed(arc, arc.speed - 1);
}
} else {
arc = Arc.changeRadius(arc, 4000);
if (arc.speed < (arcToFollow.speed + 2)) {
if (arc.speed < arcToFollow.speed + 2) {
arc = Arc.changeSpeed(arc, arc.speed + 1);
}
}
@ -159,8 +161,8 @@ const Arc = {
},
evade: function(arc) {
arc = Arc.changeRadius(arc, 20);
arc.length = 1;
arc = Arc.changeRadius(arc, 15);
arc.length = 0.3;
return arc;
}

File diff suppressed because one or more lines are too long

@ -5,6 +5,7 @@ import Animation2a from './animation2a';
import Animation2b from './animation2b';
import Animation3a from './animation3a';
import Animation3b from './animation3b';
import Animation3c from './animation3c';
require('../css/reset.scss');
require('../css/index.scss');
@ -14,9 +15,9 @@ require('../css/controls.scss');
window.addEventListener('load', () => {
const destroy$ = new Rx.BehaviorSubject(null);
window.addEventListener('blur', () => {
destroy$.next('all');
});
// window.addEventListener('blur', () => {
// destroy$.next('all');
// });
Animation1a(destroy$);
Animation1b(destroy$);
@ -24,14 +25,11 @@ window.addEventListener('load', () => {
Animation2b(destroy$);
Animation3a(destroy$);
Animation3b(destroy$);
Animation3c(destroy$);
});
// TODO remove bottom padding from Disqus
// TODO sort out particle nextframe
// TODO abs positioning on controls elements so order doesn't matter
// TODO grid touches
// TODO leader not quite right, if 2 particles, sometimes ignored
// TODO Randomize leaders every 30 sec
// INTERESTING CONTROLS:
// sensitivity

@ -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');
});
}

Loading…
Cancel
Save