Skip to content

Instantly share code, notes, and snippets.

@victorarias
Created March 14, 2013 19:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save victorarias/5164279 to your computer and use it in GitHub Desktop.
Save victorarias/5164279 to your computer and use it in GitHub Desktop.
Evented (cool) collision system update
function CoolCollisionSystem() {
this.currentTime = 0;
this.pq = new PriorityQueue(eventComparator);
//warmup happens only at startup (duh), to predict collisions between every particle
//this is the only n^2 loop
this.warmUp = function() {
for(var i = 0, length = this.circles.length; i < length; i++) {
this.predict(this.circles[i]);
}
this.redraw();
};
//predict future collisions and insert then inside the priority queue
this.predict = function(circle) {
if(!circle) return;
for(var i = 0, length = this.circles.length; i < length; i++) {
var circleToHit = this.circles[i];
var dt = circle.timeToHit(circleToHit);
//the if below is an optimization to avoid distant predictions that will probably never happen
if(dt > 0 && dt < this.circles.length/2)
this.pq.enqueue(new Event(this.currentTime + dt, circle, circleToHit));
}
var dtX = circle.timeToHitVerticalWall(this.canvas.width);
var dtY = circle.timeToHitHorizontalWall(this.canvas.height);
this.pq.enqueue(new Event(this.currentTime + dtX, circle, null));
this.pq.enqueue(new Event(this.currentTime + dtY, null, circle));
};
//"hack" to keep the drawing away of the main loop
//this is necessary because drawing is also an event like a collision
this.oldDraw = this.draw;
this.draw = function(){};
this.redraw = function() {
this.oldDraw();
this.pq.enqueue(new Event(this.currentTime + .1, null, null));
};
this.update = function() {
//first we must find a valid event
var e = this.pq.dequeue();
while(!e.isValid())
e = this.pq.dequeue();
var a = e.circleA;
var b = e.circleB;
//"move" every particle to the moment of the selected event
for(var i = 0, length = this.circles.length; i < length; i++) {
this.circles[i].move(e.time - this.currentTime, this.canvas.width, this.canvas.height);
}
this.currentTime = e.time;
//do the collision or just redraw
if(a && b) a.bounceOff(b);
else if(a && !b) a.bounceOffVerticalWall();
else if(!a && b) b.bounceOffHorizontalWall();
else { this.redraw(); }
//predict new collisions with the event particles (if any)
this.predict(a);
this.predict(b);
};
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment