台球html游戏算法介绍

  • ​​获取本游戏代码​​
  • ​​游戏运行示例​​
  • ​​基础物理知识​​
  • ​​构建物理模型​​
  • ​​桌台及小球​​
  • ​​摩擦力​​
  • ​​小球间的碰撞检测​​
  • ​​小球间的碰撞反应​​
  • ​​小球与边界的碰撞​​
  • ​​检测落袋​​
  • ​​电脑玩家的基本思路​​
  • ​​电脑判断击目标球路径上是否有阻碍​​
  • ​​电脑计算击球角度​​
  • ​​进行下一个游戏的开发!​​
  • ​​注意事项​​

获取本游戏代码

如果需要本游戏的代码,请扫描关注我的公众号,回复“台球源码”即可。

台球html游戏算法介绍_html台球

游戏运行示例

台球html游戏算法介绍_台球游戏_02

基础物理知识

  1. 摩擦力
    ​​​f = m * af​​​ 摩擦力产生的加速度​​af​​使得台球的速度减小,最终减小为0。
  2. 动能守恒公式
    ​​​1/2 * m1 * v1^2 + 1/2 * m2 * v2^2 = 1/2 * m1 * v1’^2 + 1/2 * m2 * v2’^2​
  3. 动量守恒公式
    ​​​m1 * v1 + m2 * v2 = m1 * v1’ + m2 * v2’​

构建物理模型

桌台及小球

如下图,把桌台抽象成一个二维坐标系,每个台球的中心抽象为坐标(x,y)。
横向为向右延伸的x轴,
纵向为向下延伸的y轴。
对应到代码中,就是元素的​​​margin-left​​​ 与 ​​margin-right​​ 值。

台球html游戏算法介绍_js台球_03

摩擦力

台球html游戏算法介绍_桌球游戏_04


在小球的运动过程中,始终在其相反方向上施加一个摩擦力的加速度af。

小球间的碰撞检测

台球html游戏算法介绍_html台球_05


对于两个小球,判断是否碰撞的公式为:​​(x1 - x2) ^ 2 + (y1 - y2) ^ 2 <= (2*r) ^ 2​

小球间的碰撞反应

台球html游戏算法介绍_桌球游戏_06

首先,小球碰撞抽象为物理模型中的完全弹性碰撞,且小球的质量相等。即碰撞瞬间,二者遵循动能守恒与动量守恒。

选取两球圆心的直线为切向, 垂直于圆心直线的为法向。

于是我们可以得出结论:

​(一)在切向, 两球交换速度, 而在法向, 两球分速度不变。​

由此,我们拓展到当V1不为0,V2为0时,此时就相当于一个白球去撞一个静止不动的其他球。于是我们可以得出结论:

​(二)在切向, 球1切向速度不变, 而在法向, 球1的法向速度给了球2。​

【注】通常我们把游戏设置为1秒60帧,当小球的速度过大时,在前一帧两个小球还没相撞,但在下一帧两个球就直接重叠了。这对我们利用圆心构建法向和切向会产生很大误差。此时我们可以在小球即将重叠的前一帧,控制小球按照原有方向无限逼近,最终达到碰撞但不重叠的状态。

小球与边界的碰撞

当小球碰撞到边界时,直接把小球垂直于边界方向的速度取负数即可。

检测落袋

台球html游戏算法介绍_html台球_07


如上图边框的标红部分。我们在检测边界碰撞时,如果小球进入这些标红边界,那么小球不发生反弹。

之后,我们记录下6个球袋的坐标,利用球袋坐标与小球坐标之间的距离来判断小球是否落袋。公式:

​(x袋 - x) ^ 2 + (y袋 - y) ^ 2 <= d ^ 2​

电脑玩家的基本思路

  1. 首先明确电脑打的球是什么类别。例如:实心球,花球。此处假设电脑打的是实心球。
  2. 电脑遍历白球与每个还没入袋的实心球之间是否有其他球挡着。这关系到白球是否能击打这个球。
  3. 对于每个能击打的球,电脑再计算每个球打哪个袋子为最优选项。
  4. 现在有了白球,要击打的球,目标袋。电脑计算角度,开始击球!球进了!

电脑判断击目标球路径上是否有阻碍

台球html游戏算法介绍_桌球游戏_08


如图,判断击目标球路径上是否有阻碍,我们需要计算,“可能会阻碍的球”与白球击球路径的距离是否小于球的半径r。这里用到点与直线的距离公式。

台球html游戏算法介绍_斜率_09


我们已知三个球的球心坐标,先算出“白球”与“目标球”的​​斜率K​​​,然后代入“白球”的坐标得到​​直线方程L​​​,最后利用点到直线的距离公式算出“可能会阻碍的球”与直线L的​​距离D​​。如果D小于球的半径r,说明击球过程会被阻碍。

电脑计算击球角度

台球html游戏算法介绍_台球游戏_10

如图,我们在小球的碰撞反应中,得出过结论二:

当球1初速度不为0,球2初速度为0:

​(二)在切向, 球1切向速度不变, 而在法向, 球1的法向速度给了球2。​

根据此结论,我们不难发现,“白球”在击完“目标球”后,它的切向速度会给“目标球”,而此时切向应当是与“目标球”和“目标袋”的连线重合。若要使“目标球”入袋,我们只要反过来推导。

首先算出“目标球”与“目标袋”的​​斜率K​​​;
沿着斜率K的方向,在“目标球”的球心位置,向反方向计算出一个球的直径长度的​​​坐标(P1,P2)​​​;
使“白球”击打坐标(P1,P2),即可把“目标球”击入袋中!

进行下一个游戏的开发!

​​指尖大冒险、跳一跳​​是男人就下一百层
五子棋html游戏代码与算法介绍

注意事项

【1】 原创博客,转载本篇请与我联系,尊重版权。
【2】 关于阅读本篇博客的所有问题、代码源码、图片素材、编程技巧、编程经历都可联系我或者关注公众号"三黄工作室",交流讨论。