topical media & game development
lib-js-animation-js-ball.js / js
author: alex
var model = {
"walls" : {"left":0, "top":0, "right": 500, "bottom": 300},
"elastity" : -0.2,
"ballRadius" : 26,
"maxSpeed" : 3.0
};
// helper
var extend = function(subClass, baseClass)
{
// Create a new class that has an empty constructor
// with the members of the baseClass
function inheritance() {};
inheritance.prototype = baseClass.prototype;
// set prototype to new instance of baseClass
// _without_ the constructor
subClass.prototype = new inheritance();
subClass.prototype.constructor = subClass;
subClass.baseConstructor = baseClass;
// enable multiple inheritance
if (baseClass.base)
{
baseClass.prototype.base = baseClass.base;
}
subClass.base = baseClass.prototype;
}
Base "platform-independent" class representing ball
parameter: {Object} x
parameter: {Object} y
parameter: {Object} vx
parameter: {Object} vy
function Ball(x, y, vx, vy) {
// default provisioning
if (x == undefined) {
x = (model.walls.right - model.walls.left - 2*model.ballRadius)*Math.random();
y = (model.walls.bottom - model.walls.top - 2*model.ballRadius)*Math.random();
vx = 2*model.maxSpeed*Math.random() - model.maxSpeed;
vy = 2*model.maxSpeed*Math.random() - model.maxSpeed;
}
this._x = x;
this._y = y;
this._vx = vx;
this._vy = vy;
this._r = model.ballRadius; // d = 52 px
this._d = 2*this._r;
this._d2 = this._d*this._d;
}
Ball.prototype.move = function() {
this._x += this._vx;
this._y += this._vy;
// walls collisons
// left
if (this._x < model.walls.left && this._vx<0) {
//this._vx += (this._x - walls.left)*elastity;
this._vx = -this._vx;
}
// top
if (this._y < model.walls.top && this._vy<0) {
//this._vy += (this._y - walls.top)*elastity;
this._vy = -this._vy;
}
// left
if (this._x > model.walls.right - this._d && this._vx>0) {
//this._vx += (this._x - walls.right + this._d)*elastity;
this._vx = -this._vx;
}
// top
if (this._y > model.walls.bottom - this._d && this._vy>0) {
//this._vy += (this._y - walls.bottom + this._d)*elastity;
this._vy = -this._vy;
}
}
Ball.prototype.doCollide = function(b) {
// calculate some vectors
var dx = this._x - b._x;
var dy = this._y - b._y;
var dvx = this._vx - b._vx;
var dvy = this._vy - b._vy;
var distance2 = dx*dx + dy*dy;
if (Math.abs(dx) > this._d || Math.abs(dy) > this._d)
return false;
if (distance2 > this._d2)
return false;
// make absolutely elastic collision
var mag = dvx*dx + dvy*dy;
// test that balls move towards each other
if (mag > 0)
return false;
mag /= distance2;
var delta_vx = dx*mag;
var delta_vy = dy*mag;
this._vx -= delta_vx;
this._vy -= delta_vy;
b._vx += delta_vx;
b._vy += delta_vy;
return true;
}
Abstract test class
parameter: {Object} N
function BallsTest(N) {
this._N = N; // number of objects
this._ballsO = new Array();
this._isRunning = false;
}
BallsTest.prototype._showFPS = null;
BallsTest.prototype.start = function(N) {
if (this._isRunning) return false;
this._isRunning = true;
if (N != undefined) {
this._N = N;
}
this._F = 0; // frames counter for FPS
this._lastF = 0;
this._lastTime = new Date();
var _this = this;
var moveBalls = function() {
if (_this._N > _this._ballsO.length)
return;
_this._F++;
// move balls
for (var i=0; i<_this._N; i++) {
_this._ballsO[i].move();
}
// process collisions
for (i=0; i<_this._N; i++) {
for (j=i+1; j<_this._N; j++) {
_this._ballsO[i].doCollide(_this._ballsO[j]);
}
}
}
var showFps = function() {
if (_this._F - _this._lastF < 10) return;
var currTime = new Date();
var delta_t = (currTime.getMinutes() - _this._lastTime.getMinutes())*60 + currTime.getSeconds() - _this._lastTime.getSeconds() + (currTime.getMilliseconds() - _this._lastTime.getMilliseconds())/1000.0;
delete currTime;
var fps = (_this._F - _this._lastF)/delta_t;
_this._lastF = _this._F;
_this._lastTime = currTime;
if (_this._showFPS)
_this._showFPS.call(_this, Math.round(fps));
}
this._int1 = setInterval(moveBalls, 5);
this._int2 = setInterval(showFps, 3000);
return true;
}
BallsTest.prototype.stop = function(){
if (!this._isRunning) return false;
this._isRunning = false;
clearInterval(this._int1);
clearInterval(this._int2);
return true;
}
(C) Æliens
18/6/2009
You may not copy or print any of this material without explicit permission of the author or the publisher.
In case of other copyright issues, contact the author.