0

在我的 balls.start 函数中,我希望能够在 requestAnimFrame 中调用它。例如 requestAnimFrame(this.start) (不起作用,因为它在包装函数中)。目前它只能像我一样工作:var Balls = new balls(context);在上下文之外。

所有代码:http: //jsfiddle.net/PRgTn/2/

相关(ish)代码:

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

0

您的代码没有理由属于该全局(可能是未初始化的)变量Ballsthis删除它,你可以很容易地用关键字替换它。

在您的功能中并非如此start,这是真的。animloop在全局上下文中执行,因此您需要解决此问题:

start = function() {
    var balls = this;
    (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();
    })();
};

但是,由于您不会构造 的另一个实例Balls,因此单个对象也足够了。

另外,一个大问题是Object.prototype.ball =。无论最初应该做什么,它只起作用window,因为全局范围对象继承自Object.prototype- 您创建了一种全局变量。然而,您的应用程序中的所有其他对象也将继承此可枚举属性 - 啊!

但是,您应该在适当的地方使用原型对象 - 例如用于您的Ball对象。

请参阅更新的小提琴:http: //jsfiddle.net/PRgTn/6/

于 2012-11-23T09:33:00.393 回答