0

私の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);
                    });
                }
            }
4

1 に答える 1