您现在知道如何制作各种图形对象,但是您可以使用它们做什么呢? 一个有趣的事情是构建一个简单的碰撞检测
系统。 您可以使用一个名为hitTestRectangle
的自定义函数,该函数检查是否有两个矩形的Pixi精灵正在接触。
hitTestRectangle(spriteOne, spriteTwo)
1
如果它们重叠,hitTestRectangle
将返回true
。你可以if
语句来判断两个精灵是否碰撞:
if (hitTestRectangle(cat, box)) {
//There's a collision
} else {
//There's no collision
}
1
2
3
4
5
2
3
4
5
正如你所看到的,hitTestRectangle
是通往游戏设计世界的大门。
运行examples
目录下的collisionDetection.html
文件,查看如何使用hitTestRectangle
。使用箭头键移动猫。如果猫碰到了盒子,盒子就会变成红色,文本对象就会显示“Hit!”
您已经看到了创建这些元素的所有代码,以及使猫移动的键盘控制系统。唯一的新变化是play
函数内部使用hitTestRectangle
来检查碰撞。
function play(delta) {
//use the cat's velocity to make it move
cat.x += cat.vx;
cat.y += cat.vy;
//check for a collision between the cat and the box
if (hitTestRectangle(cat, box)) {
//if there's a collision, change the message text
//and tint the box red
message.text = "hit!";
box.tint = 0xff3300;
} else {
//if there's no collision, reset the message
//text and the box's color
message.text = "No collision...";
box.tint = 0xccff99;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
因为游戏循环每秒调用play
函数60次,所以这个if
语句会不断检查猫和盒子之间的碰撞。如果hitTestRectangle
为true
,则message
文本对象显示“Hit”文字。
message.text = "Hit!";
1
然后,通过将盒子的tint
属性设置为十六进制红色值,盒子的颜色就从绿色更改为红色。
box.tint = 0xff3300;
1
如果没有碰撞,则message
和盒子将保持其原始状态。
message.text = "No collision...";
box.tint = 0xccff99;
1
2
2
这段代码非常简单。 到此为止,您已经拥有了使用Pixi制作游戏所需的所有技能。
# hitTestRectangle函数
hitTestRectangle
函数是什么呢? 它有什么作用,如何运作? 像这样的碰撞检测算法如何工作的细节超出了本教程的范围。如果您真的想知道,可以到这本书里了解。)最最重要的是您应当知道如何使用它。 但是,以防万一,您可以参考完整的hitTestRectangle
函数定义。 您能从注释中找出这些问题的答案吗?
function hitTestRectangle(r1, r2) {
//Define the variables we'll need to calculate
let hit, combinedHalfWidths, combinedHalfHeights, vx, vy;
//hit will determine whether there's a collision
hit = false;
//Find the center points of each sprite
r1.centerX = r1.x + r1.width / 2;
r1.centerY = r1.y + r1.height / 2;
r2.centerX = r2.x + r2.width / 2;
r2.centerY = r2.y + r2.height / 2;
//Find the half-widths and half-heights of each sprite
r1.halfWidth = r1.width / 2;
r1.halfHeight = r1.height / 2;
r2.halfWidth = r2.width / 2;
r2.halfHeight = r2.height / 2;
//Calculate the distance vector between the sprites
vx = r1.centerX - r2.centerX;
vy = r1.centerY - r2.centerY;
//Figure out the combined half-widths and half-heights
combinedHalfWidths = r1.halfWidth + r2.halfWidth;
combinedHalfHeights = r1.halfHeight + r2.halfHeight;
//Check for a collision on the x axis
if (Math.abs(vx) < combinedHalfWidths) {
//A collision might be occurring. Check for a collision on the y axis
if (Math.abs(vy) < combinedHalfHeights) {
//There's definitely a collision happening
hit = true;
} else {
//There's no collision on the y axis
hit = false;
}
} else {
//There's no collision on the x axis
hit = false;
}
//`hit` will be either `true` or `false`
return hit;
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50