1、碰撞原理

碰撞

碰撞,指的是窗口中两张图片是否有交集。如果有交集,则认为两张图片发生碰撞。
如下图:
碰撞判断 - 图1

假想圆

判断两张图片是否有交集,似乎不太好做,所以为了判断方便,
我们把每张图片都看做一个圆,这个圆,就是我们通常所说的假想圆。
如下图: 碰撞判断 - 图2 上图中,飞机图片和子弹图片都有个红色的圆,这个圆就是假想圆。
其实这个假想圆,非常类似于我们在数学课中所学到的三角形外接圆的概念。

碰撞原理

有了假想圆,在判断碰撞时就容易多了,我们只需要判断两个假想圆是否有交集就可以了。
如下图:
碰撞判断 - 图3
通过上图可以看出,当A、B两张图片中心点距离小于A、B两个假想圆的半径之和时
我们就认为两张图片发生了碰撞。
可问题是:两个假想圆的半径是固定的,但AB中心点的距离如何获得呢?

勾股定理

如果我们想要获得AB两个中心点距离,那么必须要用上勾股定理了。
(勾股定理:在直角三角形中,两条直角边的平方和,等于斜边的平方)
如下图:
碰撞判断 - 图4
虽然现在AB边的距离我们不知道,但BC边和AC边的距离我们是能求出来的
BC边的距离 = 子弹的x坐标 – 飞机的x坐标
AC边的距离 = 子弹的y坐标 – 飞机的y坐标
所以通过勾股定理,我们同样可以求出AB边的距离
AB AB = AC AC + BC * BC

碰撞判断

现在AB边的距离求出来了,那么接下来就是用AB边的距离与AB两假想圆半径之和做对比。
A图片假想圆半径:A图片宽高大约为80像素,那么假想圆的半径约为40像素
B图片假想圆半径:B图片宽高大约为40像素,那么假想圆的半径约为20像素
通过以上得出,碰撞条件为:AB边的距离 < 60,这时我们就认为发生碰撞

2、碰撞示例

示例

  1. //创建应用
  2. var app = new PIXI.Application(400,400);
  3. document.body.appendChild(app.view);
  4. //创建飞机图片
  5. var enemy = PIXI.Sprite.fromImage("res/plane/enemy_04.png");
  6. enemy.x = 200;
  7. enemy.y = 100;
  8. enemy.anchor.set(0.5,0.5);
  9. app.stage.addChild(enemy);
  10. //创建子弹图片
  11. var bullet = PIXI.Sprite.fromImage("res/plane/bullet_01.png");
  12. bullet.x = 234;
  13. bullet.y = 400;
  14. bullet.anchor.set(0.5,0.5);
  15. app.stage.addChild(bullet);
  16. //帧频函数
  17. app.ticker.add(animate);
  18. function animate() {
  19. moveBullet();
  20. crash();
  21. }
  22. //移动子弹
  23. function moveBullet() {
  24. bullet.y -= 10;
  25. if(bullet.y < 0) {
  26. bullet.y = 400;
  27. }
  28. }
  29. //碰撞判断
  30. function crash(){
  31. var pos = (bullet.x - enemy.x) * (bullet.x - enemy.x) + (bullet.y - enemy.y) * (bullet.y - enemy.y);
  32. if(pos < 60 * 60) {
  33. enemy.y -= 5;
  34. bullet.y = 400;
  35. }
  36. }

代码讲解

1、碰撞判断

function crash(){
var pos = (bullet.x - enemy.x) (bullet.x - enemy.x) + (bullet.y - enemy.y) (bullet.y - enemy.y);
if(pos < 60 60) {
enemy.y -= 5;
bullet.y = 400;
}
}
**var pos = (bullet.x - enemy.x)
(bullet.x - enemy.x) + (bullet.y - enemy.y) (bullet.y - enemy.y): *
通过勾股定理,求出enemy、bullet两张图片中心点距离的平方,并存储在pos变量中


if(pos < 60 * 60) {
enemy.y -= 5;
bullet.y = 400;
}
因为enemy、bullet两张图片假想圆半径之和为60,而pos是两张图片中心点距离的平方,
所以判断条件 pos < 60*60 成立时,我们就认为发生碰撞。

2.飞机与道具碰撞

var app = new PIXI.Application(500, 600);
document.body.appendChild(app.view);

var bg = new PIXI.Sprite.fromImage("res/bg_02.png");
app.stage.addChild(bg);

var plane = new PIXI.Sprite.fromImage("res/plane_blue_01.png");
plane.anchor.set(0.5,0.5);
plane.x = 250;
plane.y = 500;
app.stage.addChild(plane);

bg.interactive = true;
bg.on("mousemove",movePlane);
function movePlane(event){
    var pos = event.data.getLocalPosition(app.stage);
    plane.x = pos.x;
    plane.y = pos.y;
}


var fire = new PIXI.Sprite.fromImage("res/plane/item/img_plane_item_10.png");
fire.anchor.set(0.5,0.5);
fire.x = Math.random()*500;
fire.y = -50;
app.stage.addChild(fire);

app.ticker.add(animate);
function animate(){
    moveFire();
    crash();
}

function moveFire(){
    fire.y += 1;
}

function crash(){
    var a = plane.x - fire.x;
    var b = plane.y - fire.y;
    var c = 70;
    if(c*c > a*a+b*b){
        fire.x = Math.random()*500;
        fire.y = -50;
    }
}

代码讲解

1、添加帧频函数

app.ticker.add(animate);    <br />function animate(){    <br />moveFire();    <br />crash();    <br />}    <br />添加帧频函数,并通过帧频函数调用moveFire()、crash()两个函数    <br />    

2、定义moveFire函数

function moveFire(){
fire.y += 1;
}
定义moveFire函数,控制道具向下移动

3、定义crash函数

function crash(){
var a = plane.x - fire.x;
var b = plane.y - fire.y;
var c = 70;
if(cc > aa+bb){
fire.x = Math.random()
500;
fire.y = -50;
}
}
定义crash函数,用于实现飞机与道具的碰撞判断
if(cc > aa+b*b):通过勾股定理,判断飞机与道具是否发生碰撞