Pixi.js简单入门-动画-球体碰撞

328 阅读2分钟
  1. 创建画布和渲染器
// 创建画布
const app = new PIXI.Application({
  width: 800,
  height: 600,
  backgroundColor: 0x1099bb,
});

// 将画布添加到DOM中
document.body.appendChild(app.view);

// 创建渲染器
const renderer = app.renderer;
  1. 创建两个球体
// 创建第一个球体
const ball1 = new PIXI.Graphics();
ball1.beginFill(0xff0000);
ball1.drawCircle(0, 0, 50);
ball1.endFill();
ball1.x = 100;
ball1.y = 100;
ball1.vx = 5;
ball1.vy = 5;

// 创建第二个球体
const ball2 = new PIXI.Graphics();
ball2.beginFill(0x00ff00);
ball2.drawCircle(0, 0, 50);
ball2.endFill();
ball2.x = 500;
ball2.y = 500;
ball2.vx = -5;
ball2.vy = -5;

// 将两个球体添加到画布中
app.stage.addChild(ball1);
app.stage.addChild(ball2);

注意:这里使用了 vxvy 属性来表示球体的速度。

  1. 创建游戏循环
function gameLoop(delta) {
  // 更新球体的位置
  ball1.x += ball1.vx;
  ball1.y += ball1.vy;
  ball2.x += ball2.vx;
  ball2.y += ball2.vy;

  // 检测球体是否碰撞
  if (hitTest(ball1, ball2)) {
    // 球体碰撞后的反弹效果
    const dx = ball1.x - ball2.x;
    const dy = ball1.y - ball2.y;
    const distance = Math.sqrt(dx * dx + dy * dy);

    const normalX = dx / distance;
    const normalY = dy / distance;

    const midpointX = (ball1.x + ball2.x) / 2;
    const midpointY = (ball1.y + ball2.y) / 2;

    const dotProduct1 = ball1.vx * normalX + ball1.vy * normalY;
    const dotProduct2 = ball2.vx * normalX + ball2.vy * normalY;

    const velocity1 = dotProduct2;
    const velocity2 = dotProduct1;

    ball1.vx = normalX * velocity1;
    ball1.vy = normalY * velocity1;
    ball2.vx = normalX * velocity2;
    ball2.vy = normalY * velocity2;

    // 碰撞后将球体位置调整回来
    const overlap = 100 - distance;
    ball1.x += normalX * overlap / 2;
    ball1.y += normalY * overlap / 2;
    ball2.x -= normalX * overlap / 2;
    ball2.y -= normalY * overlap / 2;
  }

  // 边界检测
  if (ball1.x < 50 || ball1.x > 750) {
    ball1.vx *= -1;
  }
  if (ball1.y < 50 || ball1.y > 550) {
    ball1.vy *= -1;
  }
  if (ball2.x < 50 || ball2.x > 750) {
    ball2.vx *= -1;
  }
  if (ball2.y < 50 || ball2.y > 550) {
    ball2.vy *= -1;
  }
}

具体来说碰撞动画的实现:

  • 更新球体的位置:ball1和ball2对象的x和y属性值会被增加对应的vx和vy值。这个过程实际上就是简单的物理运动模拟,球体在每个循环迭代中都向它的速度方向移动。

  • 检测球体是否碰撞:使用hitTest函数检测球体是否相互碰撞。如果两个球体相撞,那么就会执行以下操作:

    • 计算碰撞后的反弹效果:使用向量运算和标量乘法计算球体的反弹方向和速度大小。
    • 调整球体的位置:在球体碰撞之后,它们有可能会重叠。为了避免这种情况,需要调整它们的位置,使它们不再重叠。在这个例子中,我们选择将两个球体移动回碰撞的中心点,并且让它们之间的距离为100。
  • 边界检测:在球体碰到边界时,将它们的速度反转,从而实现反弹的效果。这里的边界是指在画布上的左、右、上、下边缘。

  1. 创建碰撞检测函数 (这里的碰撞检测函数非常简单,只是判断两个球体之间的距离是否小于100。)
function hitTest(ball1, ball2) {
  const dx = ball1.x - ball2.x;
  const dy = ball1.y - ball2.y;
  const distance = Math.sqrt(dx * dx + dy * dy);

  return distance < 100;
}
  1. 启动游戏循环
app.ticker.add(delta => gameLoop(delta));
需要注意的是,碰撞检测函数和碰撞后的反弹效果代码都是比较简单的示例,实际应用中需要根据具体情况进行调整和优化。

希望大家点个关注和赞!!