自定义事件在Backbone.js中调度



我想编写一个简单的JavaScript动画,使一些球在画布内移动。我想检测到与backbone.js处理的自定义事件的碰撞,而不是为环的嵌套检查每对球之间的碰撞。

var j;
for (j = 0; j < N_BALLS; j++) {
    ball_center = new Point(..., ...);
    ball_shape = new Circle(ball_center, ball_radius);
    ball_velocity = ...;
    ball_ID = j;
    balls[j] = new Ball(ball_shape, ball_velocity, ball_ID);
    _.extend(balls[j], Backbone.Events);
    balls[j].on("imhere", balls[j].event_handler);
}
function animate() {
    if (!paused) {
        context.clearRect(0, 0, canvas.width, canvas.height);
        var j;
        for (j = 0; j < N_BALLS; j++){
            balls[j].updatePosition();
            balls[j].trigger("imhere", balls[j].shape, balls[j].ID);
        }
        for (j = 0; j < N_BALLS; j++)
           balls[j].draw(context, '#0000ff');
        window.requestNextAnimationFrame(animate);
    }
}

event_handler是每个球对象的成员方法

Ball.prototype.event_handler = function(shape, ID) {
    console.log("ball " + this.ID + " caught message from ball " + ID);
};

我希望有时候一个球会从另一个消息中抓住一个消息,但事实并非如此。

我想以某种方式安排事件处理程序可以:

  • this.ID == ID
  • 时转发事件
  • 停止事件传播如果this.ID != ID

骨干事件

this.ID可能是不确定的,因为骨干.on()需要上下文作为最后一个参数


您还在球本身上注册比赛,并在球上也触发。

事件不是主干内的全局,您需要自己创建一个全局事件频道或使用插件。寻找事件总线事件聚合器等。

一个快速的示例可能很简单:

var GlobalEvents = _.extend({}, Backbone.Events);

骨干本身是扩展Backbone.Events功能的对象,但最好为您的用例创建本地事件通道。


说到使用Backbone.Events对象,当您真的应该延长Ball原型时,您正在扩展Ball的每个实例。

_.extend(Ball.prototype, Backbone.Events);

您应该优先于listenTo,而不是on

销毁球时,您可以致电ball.stopListening(),并且可以避免内存泄漏。它还将解决event_handler回调中的上下文问题。

所以,使用全球事件聚合器:

balls[j].listenTo(GlobalEvents, "imhere", balls[j].event_handler);

骨干事件不是DOM事件,也不会上下冒泡,因此没有stopPropagationpreventDefault。在后台,它只是骨干的香草JS。


碰撞检测

现在我们已经涵盖了事件部分,让我说这不是碰撞检测的最佳解决方案。

完全相同,就像您在更新位置时是否会在其他所有球上调用isCollindingWith(ball)功能。这就是事件发生的事情,但是随着事件实施中隐藏的循环。

在此答案中处理优化的碰撞检测算法太宽了,所以我将链接到有关2D碰撞检测的精彩文章。

有趣的部分是在最后,他们谈论类似 Quad树,R-Trees或Spacial Hashmaps。

最新更新