申明
碰撞检测,用来搜检两个精灵是不是打仗。
Pixi 没有内置的碰撞检测体系, 所以这里我们运用一个名为 Bump 的库,Bump 是一个易于运用的2D碰撞要领的轻量级库,可与 Pixi 衬着引擎一同运用。它供应了制造大多数2D动作游戏所需的一切碰撞东西。
运用 Bump 库
要最先运用 Bump,起首直接用 script 标签,引入 js 文件
<script src="https://www.kkkk1000.com/js/bump.js"></script>
然后建立它的实例
let b = new Bump(PIXI);
变量 b 如今代表 Bump 实例。可以运用它来接见 Bump 的一切碰撞要领。
运用 Bump 的碰撞要领
hit
hit 要领是一种通用碰撞检测功用。它会自动检测碰撞中运用的精灵品种,并挑选恰当的碰撞要领。这意味着你没必要记着要运用 Bump 库中的很多碰撞要领的哪个,你只须要记着一个 hit 。然则为了防备 hit 要领末了发作的结果和你设想的不一样,最好照样要相识一下 Bump 库中其他的要领。
以下是 hit 要领最简朴的运用情势:
b.hit(sprite1, sprite2);
假如两个精灵碰撞到了,就返回 true,没有碰撞到,则返回 false。
在碰撞检测时,Bump 的要领默许精灵是矩形的,运用矩形碰撞检测的算法,假如你想让要领把一个精灵看成圆形,运用圆形碰撞检测的算法,须要将精灵的 circular 属性设置为 true 。
anySprite.circular = true;
假如你运用 hit 要领检测两个圆形精灵是不是碰撞,你还须要将两个精灵的 diameter 属性设置为 true 。
假如你愿望精灵对碰撞作出回响反映,使它们不堆叠,请将第三个参数设置为 true 。
b.hit(sprite1, sprite2, true);
这个防备堆叠的功用,关于制造墙壁,地板或任何其他范例的边境异常有效。
假如你想让精灵碰撞后反弹,请将第四个参数设置为 true。
b.hit(sprite1, sprite2, true, true);
注重:
假如须要精灵反弹,精灵还必须有速率属性,也就是 vx 和 vy 属性。
设置第五个参数为 true 使 hit 要领运用精灵的全局坐标。在检测不同父容器的精灵之间的碰撞时,这很有效。
b.hit(sprite1, sprite2, true, true, true);
精灵的全局坐标是相关于画布左上角的位置。
精灵的部分坐标是相关于其父容器的左上角的位置。
假如要搜检点对象是不是与精灵碰撞,将点对象作为第一个参数,以下所示:
b.hit({x: 200, y:120}, sprite);
点对象是一个具有 x 和 y 两个属性的对象,x 和 y 示意了画布中一个点的坐标。
hit 要领还许可你搜检精灵和精灵组之间的碰撞。只需将精灵组作为第二个参数即可。在此示例中,精灵组是 spriteArray。
b.hit(sprite, spriteArray, true, true, true);
你将看到 hit 要领自动遍历精灵组中的一切精灵,并依据参数中的第一个精灵检测它们。这意味着你没必要本身编写 for 轮回或 forEach 轮回。
你还可以运用回调函数作为第六个参数。这关于搜检单个精灵和精灵组之间的碰撞迥殊有效。假如发作碰撞,回调函数将运转,你可以接见碰撞返回值和碰撞中触及的精灵。下面是怎样运用这个特征来检测一个名为 sprite 的精灵和一个名为 spriteArray 的精灵组之间的碰撞。
b.hit(
sprite,
spriteArray,
true, true, true,
function (collision, platform) {
//collision 示意 sprite 的哪一边发作碰撞
//platform 示意 sprite 正在碰撞的精灵组中的精灵
console.log(collision);
console.log(platform);
}
);
这是一种实行庞杂碰撞检测的简约体式格局,可以为你供应大批信息和初级掌握,但没必要手动遍历数组中的一切精灵。
hit 要领的返回值会与你正在搜检的精灵的品种相匹配。比方,假如两个精灵都是矩形,而且 hit 要领的第三个参数是 true,碰撞后,返回值示意参数中第一个矩形发作碰撞的一侧,假如没有发作碰撞,返回值就是 undefined 。
示例:
let collision = b.hit(rectangleOne, rectangleTwo, true);
message.text = "参数中第一个矩形的碰撞侧是: " + collision;
hit 要领只是 Bump 的很多初级碰撞要领的高等包装器。假如你更喜好运用较初级别的要领,接下来会列出一切的这些要领。
hitTestPoint
最基本的碰撞检测是搜检点对象是不是与精灵碰撞。hitTestPoint 要领将协助你处理这个题目。
hitTestPoint 要领须要两个参数:
称号 | 形貌 |
---|---|
point | 具有 x 和 y 属性的点对象,x 和 y 示意了画布中一个点的坐标 |
sprite | 精灵 |
示例:
let collision = b.hitTestPoint(
{ x: 180, y: 128 }, //具有 x 和 y 属性的点对象
sprite //须要检测的精灵
)
假如点对象与精灵碰撞,hitTestPoint 要领返回 true,不然返回 false。
上面示例中的精灵被看成是矩形的,但 hitTestPoint 要领一样适用于圆形精灵。假如精灵具有 radius 属性,则 hitTestPoint 要领假定精灵是圆形的而且对它运用圆形碰撞检测算法。假如精灵没有 radius 属性,则该要领假定它是矩形。你可以给任何精灵一个 radius 属性。而一个更简朴的要领是给精灵一个 circular 属性并将其设置为 true 。
anySprite.circular = true;
如许精灵就会运用圆形碰撞检测算法,并具有一个 radius 属性,该属性的值即是精灵宽度的一半。
hitTestCircle
hitTestCircle 要领用来检测两个圆形精灵之间的碰撞。
b.hitTestCircle(sprite1,sprite2)
作为参数传入 hitTestCircle 要领的精灵须要有 radius 属性,假如精灵碰撞则返回 true,因而你可以将其与 if 语句一同运用来检测碰撞,以下所示:
if(b.hitTestCircle(sprite1,sprite2)){
message.text = "碰撞到了!";
//碰撞到后,将 vx 设置为0,住手挪动
sprite1.vx=0;
}
circleCollision
当挪动的圆形精灵遇到没有挪动的圆形精灵时,你可以运用 circleCollision 要领建立碰撞回响反映。
参数:
称号 | 默许值 | 形貌 |
---|---|---|
circle1 | 挪动的圆形精灵 | |
circle2 | 没有挪动的圆形精灵 | |
bounce | false | 用于肯定第一个精灵碰撞到第二个精灵时是不是应当反弹 |
global | false | 是不是运用精灵的全局坐标。假如要检测具有不同父容器的精灵之间的碰撞 ,这很有效 |
注重:
假如你愿望参数中第一个精灵碰撞到第二个精灵时反弹,那第一个精灵必须有速率属性,也就是 vx 和 vy 属性。
movingCircleCollision
movingCircleCollision 要领可以让两个挪动的圆形精灵在碰撞时弹开,它们会以一种异常传神的体式格局将速率传递给对方,从而使它们弹开。
参数:
称号 | 默许值 | 形貌 |
---|---|---|
circle1 | 挪动的圆形精灵 | |
circle2 | 挪动的圆形精灵 | |
global | false | 是不是运用精灵的全局坐标。假如要检测具有不同父容器的精灵之间的碰撞 , |
b.movingCircleCollision(circle1, circle2)
假如圆形精灵具有 mass 属性,则该值将用于协助肯定圆形精灵应当相互反弹的力。
假如你有一堆挪动的圆形精灵,你愿望这些精灵都在碰撞后举行反弹,这个时刻你须要把这些精灵举行两两搜检,推断它们是不是碰撞,这须要把这些精灵放在一个数组中,运用两层 for 轮回,而且内层 for 轮回的计数器比外层的 for 轮回大1,如许就可以检测一切圆形精灵的碰撞状况。
for (let i = 0; i < container.children.length; i++) {
//碰撞搜检中运用的第一个圆形精灵
var c1 = container.children[i];
for (let j = i + 1; j < container.children.length; j++) {
//碰撞搜检中运用的第二个圆形精灵
let c2 = container.children[j];
//搜检碰撞状况,假如精灵发作碰撞,将精灵弹开
b.movingCircleCollision(c1, c2);
}
}
你可以看到内层 for 轮回的计数器最先就是一个大于外层 for 轮回的数字:
let j = i + 1
这可以防备对任何一对精灵举行屡次碰撞检测。
Bump 库另有一个轻易的要领 multipleCircleCollision,运用这个要领可以替换 for 轮回的体式格局。这个要领会对每对精灵自动挪用 movingCircleCollision,使它们相互反弹。 你可以在游戏轮回中运用它来搜检数组中的一切精灵,然则要注重数组中的精灵是不能反复的。
示例:
b.multipleCircleCollision(container.children);
hitTestRectangle
要肯定两个矩形精灵是不是碰撞,请运用 hitTestRectangle 要领:
b.hitTestRectangle(rectangle1, rectangle2)
假如矩形精灵碰撞,hitTestRectangletrue 要领返回 true,没有碰撞则返回 false。
示例:
if(b.hitTestRectangle(sprite1,sprite2)){
message.text = "碰撞到了!";
}else{
message.text = "没有遇到";
}
rectangleCollision
rectangleCollision 要领使矩形精灵表现得彷佛它们有质量。它可以防备参数中的两个矩形精灵堆叠。
参数:
称号 | 默许值 | 形貌 |
---|---|---|
rectangle1 | 矩形精灵 | |
rectangle2 | 矩形精灵 | |
bounce | false | 用于肯定第一个精灵是不是应当从第二个精灵反弹 |
global | true | 是不是运用精灵的全局坐标 |
返回值:
假如精灵碰撞到了,rectangleCollision 要领返回一个字符串值,通知你第一个矩形精灵的哪一侧遇到了第二个矩形精灵。其值多是 left
,right
,top
或 bottom
。假如没有碰撞到返回值就是 undefined
。
示例:
let collision = b.rectangleCollision(sprite2, sprite1);
//碰撞发作在矩形1(第一个参数)的哪一侧
switch (collision) {
case "left":
message.text = "参数中的第一个精灵的 左边 发作碰撞";
break;
case "right":
message.text = "参数中的第一个精灵的 右边 发作碰撞";
break;
case "top":
message.text = "参数中的第一个精灵的 上方 发作碰撞";
break;
case "bottom":
message.text = "参数中的第一个精灵的 下方 发作碰撞";
break;
default:
message.text = "没有发作碰撞";
}
此示例代码将阻挠矩形堆叠,并在名为 message 的文本精灵中显现碰撞侧。
rectangleCollision 要领具有异常有效的副作用。参数中的第二个精灵可以将第一个精灵推走。假如你须要类似于推箱子游戏中的那种功用,这会很有效。
hitTestCircleRectangle
hitTestCircleRectangle 要领可以搜检圆形和矩形精灵之间的碰撞。
参数:
称号 | 默许值 | 形貌 |
---|---|---|
circle | 圆形精灵 | |
rectangle | 矩形精灵 | |
global | false | 是不是运用精灵的全局坐标 |
返回值:
假如精灵碰撞到了,hitTestCircleRectangle 要领一样返回一个字符串值,通知你圆形精灵在那里遇到了矩形精灵。其值多是 topLeft
,topMiddle
,topRight
,leftMiddle
,rightMiddle
,bottomLeft
,bottomMiddle
或 bottomRight
。假如没有碰撞到返回值就是 undefined
。
示例:
let collision = b.hitTestCircleRectangle(circle, rectangle);
if (collision) {
message.text = "圆形精灵的 " + collision + " 侧,发作碰撞";
} else {
message.text = "没有发作碰撞";
}
circleRectangleCollision
运用 circleRectangleCollision 要领让一个圆形精灵从矩形精灵的正面或角反弹。
参数:
称号 | 默许值 | 形貌 |
---|---|---|
circle | 圆形精灵 | |
rectangle | 矩形精灵 | |
bounce | false | 是不是使使精灵反弹 |
global | false | 是不是运用精灵的全局坐标 |
示例:
b.circleRectangleCollision(circle, rectangle, true);
contain
contain 要领可以将精灵限定在肯定矩形地区内。
参数:
称号 | 默许值 | 形貌 |
---|---|---|
sprite | 精灵 | |
container | 容器,这是一个对象,具有 x、y、width 和 height 属性,示意一个矩形地区。 | |
bounce | false | 肯定精灵在遇到容器边境时是不是应当反弹。 |
callbackFunction | 回调函数,当精灵碰撞到容器边境时会挪用它,而且会将 contain 要领的返回值作为参数传入这个回调函数。 |
返回值:
假如精灵碰撞到容器边境,contain 要领将返回一个 Set 对象,通知你精灵撞到了哪一侧,它的值可能有 left
,right
,top
或 bottom
,假如精灵没有碰撞到容器边境, 返回值就是 undefined
。
示例:
let collision = b.contain(sprite, { x: 0, y: 0, width: 512, height: 512 }, true, callbackFunction);
//发作碰撞时的回调函数
function callbackFunction(collision) {
console.log("collision", collision);
}
//假如发作碰撞,显现哪边的边境发作碰撞
if (collision) {
if (collision.has("left")) {
message.text = "边境 左边 发作碰撞";
};
if (collision.has("right")) {
message.text = "边境 右边 发作碰撞";
};
if (collision.has("top")) {
message.text = "边境 上方 发作碰撞";
};
if (collision.has("bottom")) {
message.text = "边境 下方 发作碰撞";
};
}
上面的代码会将精灵限定在对象定义的512 x 512像素地区内。假如精灵碰撞到容器的边境,它将会反弹, 而且显现遇到了哪边的边境,callbackFunction(第四个参数)也将运转。
contain 要领的另一个特点是,假如精灵具有 mass 属性,该值将用于以异常天然的体式格局抑止精灵的反弹。
注重:
运用 Bump 库时,最好给精灵设置上速率属性(vx,vy),由于 Bump 库中很多要领完成结果时,都须要用到这个两个属性。