Kaboom-drag
创建一个let变量[1] 来存放鼠标点击拖拽的对象
// there should only be one that's currently being dragged
let curDraggin = null;
我们可以先看下面的代码部分,这部分的代码初始化了整个场景
//进行一次64次的循环,每次循环添加 obj ,并且为这个obj添加sprite,设置位置,放大,中心对齐
for (let i = 0; i < 64; i++) {
add([
sprite("mark"),
pos(rand(width()), rand(height())),
scale(5),
origin("center"),
drag(), //为每一个obj调用drag方法
i !== 0 ? color(1, 1, 1) : color(1, 0, 1),
//利用一个三元表达式来将第一个创建的图片颜色变为粉色,因为最先创建,所以在最下层,起到隐藏的作用
]);
}
然后我们再来回到上方的,这个为每一个创建的obj所创建的方法 drag(),这个方法调用的时候将
- 先看Update 每帧会判断,上面那个被创建的变量curDraggin是不是自己,如果是的话就就持续修改自己的位置 = mousePos() .sub(offset);
- 在创建这个obj的时候,把以下方法添加进点击事件
- 如果此刻有其他obj被点击(curDraggin不为null),那么直接返回
- 否则玩家就是选中的此obj,计算出与鼠标之间的offset,然后调用readd来让这个图形显示在最上方
function drag() {
let offset = vec2(0);// 创建一个误差变量,避免点击直接设置位置会带来位置变化
return {
// "add" is a special lifecycle method gets called when the obj is added to scene
add() {
// "this" in all methods refer to the obj
this.clicks(() => {
if (curDraggin) {
return;
}
curDraggin = this;
offset = mousePos().sub(this.pos);
readd(this);
});
},
// "update" is a special lifecycle method gets called every frame the obj is in scene
update() {
if (curDraggin === this) {
this.pos = mousePos().sub(offset);
}
},
};
}
然后添加方法到松开鼠标的事件:
mouseRelease(() => {
curDraggin = null;//如果鼠标松开,则把当前选中的变量重新设置回空
});
鼠标松开事件调用方法
mouseRelease(cb) // runs once when left mouse is just released
obj. clicks(()=>{}) register an onClick callback obj.clicks 是注册方法到obj,当其被点击时候调用。obj.clicks 是 area() component 带的函数,不过如果你给了一个sprite() 或者 rect() 或者 text() 这些带渲染功能的component 他们会自动计算区域并加上一个 area()
obj.clicks(() => {
// ...
});
Readd(): remove and add froggy to the scene without triggering events tied to "add" or "destroy", so it'll be drawn on the top of the layer it belongs to 方法readd是重新添加使其出现在屏幕上方,有摘出来的感觉
readd(froggy);
上方的的drag方法的使用会比较复杂一些
// a custom component handling drag 创建一个drag的方法作为component来处理拖拽
function drag() {
...
}
drag() 函数是在定义一个component,在kaboom里一个component就是一个函数,返回一个对象里面一些特殊生命周期函数,如add,update,挂在这里的add() 跟那个添加全局add()不一样,这里的是一个事件,有点类似keyDown(),当这个component的宿主obj被成功add()到场景后,这个component的add()函数会被执行(有点绕)
一个component可以看作一个单位的数据+行为,比如说sprite() component就只负责绘制图像,pos() component就只负责管理坐标,一个game object由一串component组成,所以add() 函数接受一个数组作为参数,这里的drag() 就是定义了一个新的component,只负责关于拖拽相关的行为和数据(来自@tga的帮助!)
其实这部分tga传递的是一个组件化的思想,其实在Unity的Component中就有很多的使用,而在js里面,这个component是需要把方法返回出来而不是直接贴上去写在monobehaviour里面的start()和update()就可以的
参考:
*javaScript ES6 添加了两个关键字:
let 变量是增加的块级作用域
const 声明一个只读的常量,一旦声明,常量的值就不能改变