事件系统
Crafty 使用组件进行通信。
基本思想是将函数绑定到命名事件。当事件被触发时,函数会被直接调用。这里有一个简单的例子:
// Create a red square
var square = Crafty.e("2D, Canvas, Color")
.attr({x:10,y:10, w:30, h:30})
.color("blue");
// When a "Blush" event is triggered, turn pink
square.bind("Blush", function() {
// the function will be called in the context of the entity
this.color("pink")
});
// Trigger the event, causing the square to turn pink
square.trigger("Blush");
在上边,我们为实体绑定了一个事件,然后立刻触发它。更典型的情况是,我们在游戏逻辑的其他地方来触发它。您可以将多个函数绑定到同一事件,但一般不应依赖它们按特定顺序执行。
每个实体都有一些与事件有关的方法,这在文档 Crafty Core. 有详细的介绍。
传递数据
很多事件都会传递数据给绑定的函数。让我们修改上边的代码来定义一个更通用的 "ChangeColor" 事件:
square.bind("ChangeColor", function(color) {
this.color(color);
});
square.trigger("ChangeColor", "pink"); // Turn pink
当你触发事件时,第二个参数可以传递一个值。这不会对你造成限制,因为你也可以传递一个对象 —— 例如,你想 "ChangeColor"
使用 RGB 值来代替颜色名称:
// Assume that color is an object
square.bind("ChangeColor", function(color) {
this.color(color.r, color,g, color.b);
})
// Specify the RGB values corresponding to pink
square.trigger("ChangeColor", {r:255, g:192, b:203});
解绑事件
要解绑一个事件,你需要绑定函数的引用,所以它不能是匿名的。修改我们之前的例子:
var turnPink = function() {
this.color("pink");
}
// Bind the function to an event
square.bind("Blush", turnPink);
// Immediately unbind it!
square.unbind("Blush", turnPink);
有时候你希望函数只被触发一次,这时,你可以使用 .one()
来代替 .bind()
进行绑定:
// Use the .one() method instead of .bind()
square.one("JumpRight", function() {
// Move 10 px to the right
this.x += 100;
});
// If we trigger the event twice, the bound function will be called only the first time
square.trigger("JumpRight");
square.trigger("JumpRight");
内置事件
很多 Crafty 内置的组件都会触发事件,大部分有用的事件都可以在 API 文档中找到。例如, 2D
组件 在位置改变的时候会触发 "Move" 事件 , 并且该事件会传递一个表示旧位置的对象。
// Bind a function to the "Move" event
// It will log the initial and new x position anytime the entity moves
square.bind("Move", function(oldPosition) {
console.log(oldPosition._x, this.x);
});
square.x = 100; // Will print "10, 100"
在 Crafty 的 API 文档中,内置事件都是高亮的绿色。
全局事件
到目前为止,我们讨论的所有事件都是针对某个特定实体的。但事件也可以在全局触发 —— 将在所有实体上触发。
// Define two entities at x=5 and x=10
var varrick = Crafty.e("2D").attr({x:5});
var xhuli = Crafty.e("2D").attr({x:10});
// Bind to an event called "Thing"
varrick.bind("Thing", function() { this.x += 20; });
xhuli.bind("Thing", function() { this.x += 10; });
// Do the thing!
// varrick and xhuli will *both* move to the right
Crafty.trigger("Thing");
// You can still trigger the same events directly on an entity
xhuli.trigger("Thing");
你也可以直接在 Crafty 对象上绑定事件:
Crafty.bind("Thing", function() {
console.log("Crafty does the thing.")
});
在全局绑定的函数中,上下文 this 为全局的 Crafty 对象(this === Crafty
)。
和你想的一样,Crafty.unbind()
和 Crafty.one()
也是这样!
你将在 游戏循环 章节中,了解到一个非常重要的事件 "EnterFrame"。