javascript - 使元素在触摸屏幕限制时反弹,例如没有画布的乒乓球游戏
问题描述
我正在尝试在此代码中实现 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;
但如何做到这一点?我在哪里可以得到那个方向并改变它?
多谢
解决方案
实际上,您不需要垂直矢量:您希望球以与“墙壁”相同的角度反弹,但沿垂直于墙壁的轴对称。
您可以这样建模:当球撞到墙壁时,墙壁会产生一个反作用力,它会施加一个垂直于墙壁并指向远离墙壁的力。这是一个向量,您需要添加到球的速度向量中才能获得更新的速度向量。
在您的情况下,墙壁与您的坐标系对齐,因此非常简单:当您撞到水平墙壁时,您可以说服自己x
速度矢量的分量不应受到墙壁反应的影响。至于y
组件,您也可以说服自己,要弹起,您只需翻转它即可。不需要花哨的矢量数学
但是,如果您无法释放球,它永远不会正常工作。
以给定的时间间隔记录鼠标位置。不要在每个
mousemove
事件上都这样做,因为它触发得太频繁,这会给你带来微不足道的,有时甚至是空值。当您释放球时,在 上
mouseup
,根据当前鼠标位置和最后一个鼠标位置的差异创建一个“矢量”。这就是球的初速度。您现在可以将其保存为一对x
和y
组件,除非您想对您的球施加力,例如风或其他。在时钟的每一个滴答声中,将此向量的分量添加到球的位置,以使其在屏幕上前进而无需鼠标的帮助。
现在球可以自由移动,您可以检测它与墙壁的碰撞并使其反弹。
推荐阅读
- javascript - Object.assign 方法将更改源对象属性 - JS
- python - 避免 if else 实例化一个类 - python
- html - CSS图像位置
- java - org.netezza.error.NzSQLException:驱动程序可以在 org.netezza.internal.QueryExecutor.sendQuery(QueryExecutor.java:444) 一次处理一个查询
- java - 我想使用 selenium java 通过带有字体大小的标签分别获取所有文本
- php - 如何在php中将对象数组转换为键值对
- reactjs - 我如何在 reactJS 的确切路线上将 className 更改为在 li 上处于活动状态
- php - PHP:改进扩展机制以遵循规则?
- php - 如何在 HTML 和代码片段之间交换数据?(WordPress)
- ffmpeg - 当我将视频转换为图像时,ffmpeg 停止