用HTML5 Canvas实现拼图游戏

由于喜欢玩拼图游戏,因此本身开用canvas开发了一个拼图游戏,在这里分享一下开发的过程。html

生成拼图块

拼图块有直线和弯曲的两种边,要生成直线边只需知道两个点就能够生成一条线段,而生成弯曲的边则稍微复杂一些。这里用四个点来生成弯曲的线。首要用随机数决定弯曲的方向是凹仍是凸。再由是凹仍是凸计算出垂直于边的向量,即下图中的紫色与蓝色向量。首先按比例由A和B获得E和F两个点的坐标:A和B坐标记做 P A P_A P B P_B ,比例为 α \alpha ,则E点坐标 P E = α P A + ( 1 α ) P B P_E=\alpha P_A + (1-\alpha)P_B ,F点坐标 P F = α P B + ( 1 α ) P A P_F=\alpha P_B + (1-\alpha)P_A 。加上垂直的向量获得C与D两个点。git

有了中间的四个点,为了增长拼图块的随机性,须要在中间四个点加上随机的位移。

最后只需用贝塞尔曲线就获得了拼图的一个边。 (参考:stackoverflow.com/a/49371349/… )github

重复上述步骤生成拼图的四条边,就能够生成一个完整的拼图块。为了能将拼图拼在一块儿,以下图所示,每次只需生成右边与下边两条边,如图中右下角的拼图块粉色的边与上方的拼图块的下边相同,蓝色的左边与左方拼图的右边相同。
有了拼图块形状的路径,就能够用canvas的clip函数,剪出所需的拼图块的图形。但因为拼图形状不规则,因此每次移动的时候从新绘制会致使卡顿。

性能优化

缓存拼图块

为了加快拼图块的绘制速度,须要再建立一个隐藏的canvas用于缓存拼图块。以下图所示全部拼图块只需绘制一次复杂的形状,以后绘制只需从隐藏的canvas复制到用户看到的canvas中。canvas

双层Canvas

虽然在必定程度上缓存解决了卡顿问题,可是当拼图块数量达到数千张时,移动时仍是会出现卡顿。虽然每次移动的只是一小部分的拼图块,可是全部拼图块仍是须要从新绘制。更好的办法是,每次鼠标移动时只绘制移动的拼图块,而不是全部拼图块。为了实现这种效果,须要用两层canvas。以下图所示,底部灰色背景层在底部绘制静止的部分,只须要移动开始时从新绘制。图中紫色的另一层在最上面,绘制移动的拼图块,每次鼠标移动都须要绘制。缓存

最后就获得了性能还算能够的拼图游戏:

代码:e1y4r/JigsawPuzzle (github.com)性能优化