首页 > 解决方案 > 使元素在触摸屏幕限制时反弹,例如没有画布的乒乓球游戏

问题描述

我正在尝试在此代码中实现 pong 游戏功能,但它不起作用,它只是像篮球一样反弹,我希望它像 pong 游戏一样随着方向的改变而反弹:

 <svg id="m" width="40" height="40">
        <circle cx="20" cy="20" r="20" fill="red" stroke="red" stroke-width="1"/>
    </svg>
    
    <script>
let m = document.getElementById("m");
let posX = posY = 0;

let update = function(e) {
  posX += e.movementX;
  posY += e.movementY;
  
  if(m.getBoundingClientRect().y<0){
      posY = -posY
      }
  else if(m.getBoundingClientRect().x<0){
      posX = -posX
      }
  m.style.transform = `translate(${posX}px, ${posY}px)`;
};

document.addEventListener("mousedown", () => {
  document.addEventListener("mousemove", update);
});

document.addEventListener("mouseup", () => {
  document.removeEventListener("mousemove", update);
});
    </script> 

我尝试了什么:

计算球与屏幕碰撞时当前在球中使用的矢量,并找到另一个垂直于第一个矢量并沿着它移动的矢量,但我没有找到如何继续这个想法。

编辑:我想我需要添加一个方向变量,posX += e.movementX * direction;但如何做到这一点?我在哪里可以得到那个方向并改变它?

多谢

标签: javascript

解决方案


实际上,您不需要垂直矢量:您希望球以与“墙壁”相同的角度反弹,但沿垂直于墙壁的轴对称。

您可以这样建模:当球撞到墙壁时,墙壁会产生一个反作用力,它会施加一个垂直于墙壁并指向远离墙壁的力。这是一个向量,您需要添加到球的速度向量中才能获得更新的速度向量。

在您的情况下,墙壁与您的坐标系对齐,因此非常简单:当您撞到水平墙壁时,您可以说服自己x速度矢量的分量不应受到墙壁反应的影响。至于y组件,您也可以说服自己,要弹起,您只需翻转它即可。不需要花哨的矢量数学


但是,如果您无法释放球,它永远不会正常工作。

  1. 以给定的时间间隔记录鼠标位置。不要在每个mousemove事件上都这样做,因为它触发得太频繁,这会给你带来微不足道的,有时甚至是空值。

  2. 当您释放球时,在 上mouseup,根据当前鼠标位置和最后一个鼠标位置的差异创建一个“矢量”。这就是球的初速度。您现在可以将其保存为一对xy组件,除非您想对您的球施加力,例如风或其他。

  3. 在时钟的每一个滴答声中,将此向量的分量添加到球的位置,以使其在屏幕上前进而无需鼠标的帮助。

现在球可以自由移动,您可以检测它与墙壁的碰撞并使其反弹。


推荐阅读