私のballs.start関数内で、requestAnimFrame内でそれをリコールできるようにしたい. 例 requestAnimFrame(this.start) (ラッパー関数内にあるため機能しません)。現時点では、私と同じようvar Balls = new balls(context);
に、つまりコンテキストの外でのみ機能します。
すべてのコード: http://jsfiddle.net/PRgTn/2/
関連する(っぽい)コード:
window.requestAnimFrame = (function () {
return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.oRequestAnimationFrame || window.msRequestAnimationFrame || function (callback) {
window.setTimeout(callback, 1000 / 60);
};
})();
var balls = function balls(context) {
this.context = context,
this.all_balls = [];
this.add = function () {
var x = new ball(this.context);
this.all_balls.push(x);
return x;
}
this.start = function () {
(function animloop() {
requestAnimFrame(animloop);
var x = new Date().getTime() - (this.time || new Date().getTime());
this.time = new Date().getTime();
Balls.update(x);
Balls.collision(x);
Balls.frames();
Balls.redraw();
})();
}
this.frames = function () {
var time = new Date().getTime();
if (!this.last_fps_time) this.last_fps_time = time;
if (!this.frames_since_last) this.frames_since_last = 0;
this.frames_since_last++;
if (time - this.last_fps_time >= 1000) {
this.frame_text = this.frames_since_last + " FPS";
this.frames_since_last = 0;
this.last_fps_time = time;
}
}
this.redraw = function () {
this.context.save();
this.context.setTransform(1, 0, 0, 1, 0, 0);
this.context.clearRect(0, 0, canvas.width, canvas.height);
this.context.restore();
this.each(function () {
this.draw();
});
this.context.fillStyle = '#000000';
this.context.font = "12px 'Open Sans'";
this.context.fillText(this.frame_text || this.frames_since_last + " FPS",5,17);
}
this.each = function (fn) {
for (var i = 0; i < this.all_balls.length; i++) {
fn.apply(this.all_balls[i]);
}
}
this.collision = function (t) {
Balls.each(function () {
var A = {}, B = {};
A = this;
Balls.each(function () {
B = this;
if ((A.y != B.y) || (A.x != B.x)) {
if (((a = Math.pow(A.x - B.x, 2)) + (b = Math.pow(A.y - B.y, 2))) <= (c = Math.pow(A.radius + B.radius, 2))) {
//http://gamedev.tutsplus.com/tutorials/implementation/when-worlds-collide-simulating-circle-circle-collisions/
var ax = (A.x_vel * (A.mass - B.mass) + (2 * B.mass * B.x_vel)) / (A.mass + B.mass);
var ay = (A.y_vel * (A.mass - B.mass) + (2 * B.mass * B.y_vel)) / (A.mass + B.mass);
B.x_vel = (B.x_vel * (B.mass - A.mass) + (2 * A.mass * A.x_vel)) / (A.mass + B.mass);
B.y_vel = (B.y_vel * (B.mass - A.mass) + (2 * A.mass * A.y_vel)) / (A.mass + B.mass);
A.x_vel = ax;
A.y_vel = ay;
A.x = A.x + (t * A.x_vel / 16);
A.y = A.y + (t * A.y_vel / 16);
B.x = B.x + (t * B.x_vel / 16);
B.y = B.y + (t * B.y_vel / 16);
//B.x = A.x+(B.x>A.x?1:-1)*Math.sqrt(c-b);
//B.y = A.y+(B.y>A.y?1:-1)*Math.sqrt(c-a);
}
}
});
});
}
this.update = function (t) {
Balls.each(function () {
this.x += (t * this.x_vel / 16);
this.y += (t * this.y_vel / 16);
var t_x_vel = this.x_vel;
var t_y_vel = this.y_vel;
if (this.x >= this.context.canvas.width - this.radius && this.x_vel > 0) this.x_vel = -this.x_vel;
if (this.x <= this.radius && this.x_vel < 0) this.x_vel = -this.x_vel;
if (this.y >= this.context.canvas.height - this.radius && this.y_vel > 0) this.y_vel = -this.y_vel;
if (this.y <= this.radius && this.y_vel < 0) this.y_vel = -this.y_vel;
if (this.x_vel != t_x_vel) this.x += (t * this.x_vel / 16);
if (this.y_vel != t_y_vel) this.y += (t * this.y_vel / 16);
});
}
}