您现在知道如何制作各种图形对象,但是您可以使用它们做什么呢? 一个有趣的事情是构建一个简单的碰撞检测系统。 您可以使用一个名为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

正如你所看到的,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

因为游戏循环每秒调用play函数60次,所以这个if语句会不断检查猫和盒子之间的碰撞。如果hitTestRectangletrue,则message文本对象显示“Hit”文字。

message.text = "Hit!";
1

然后,通过将盒子的tint属性设置为十六进制红色值,盒子的颜色就从绿色更改为红色。

box.tint = 0xff3300;
1

如果没有碰撞,则message和盒子将保持其原始状态。

message.text = "No collision...";
box.tint = 0xccff99;
1
2

这段代码非常简单。 到此为止,您已经拥有了使用Pixi制作游戏所需的所有技能。

# hitTestRectangle函数

hitTestRectangle函数是什么呢? 它有什么作用,如何运作? 像这样的碰撞检测算法如何工作的细节超出了本教程的范围。如果您真的想知道,可以到这本书 (opens new window)里了解。)最最重要的是您应当知道如何使用它。 但是,以防万一,您可以参考完整的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
lastUpdate: 11/16/2021, 6:11:55 AM