前言
推箱子是一款轻松益智小游戏,在其基础上做了些更好趣的东西,推炸弹。 当然不仅仅是换成推炸弹,更有趣的部分:
- 除了默认的关卡玩单机外,玩家可以 DIY 地图并分享。
- 闯关成功后可以通过链接或生成 GIF 图分享玩法。
玩法
默认关卡
通过上下左右来控制小人移动,目标是把所有的炸弹都推入箱子内即可通关。
通关之后在胜利页面,点击链接分享玩法按钮就已复制游戏玩法链接可用于分享;分享 GIF 会自动生成动态图。
地图绘制
行和列用于控制地图的大小。地图相关的元素点击选择后,可在下面空白地图上点击或拖拽进行地图编辑。
地图编辑好之后点击游玩按钮就可试玩,底部的分享按钮可以复制游戏链接用于分享设计的地图。
新增关卡
欢迎进行地图编辑,并将数据 PR 推送至仓库 Efrice/push-mines: mini-game, welcome play. (github.com)。
代码实现
游戏数据的压缩处理
游戏所需数据量较大,直接通过链接分享时太多也不美观,通过使用 pako
库将数据进行压缩和解压处理。
js
import pako from 'pako'
export function deflate(raw: any): string {
const rawParams = JSON.stringify(raw)
const compressedData = pako.deflate(rawParams)
return btoa(String.fromCharCode.apply(null, compressedData as any))
}
export function inflate(base64Data: any): any {
const decodedData = atob(base64Data)
const uint8array = new Uint8Array(decodedData.length)
for (let i = 0; i < decodedData.length; i++)
uint8array[i] = decodedData.charCodeAt(i)
return JSON.parse(pako.inflate(uint8array, { to: 'string' }))
}
注意:
vue-router
中route.query
会将+
转换为空格,需要特殊处理该问题。
生成 gif 图
结合 html2canvas
与 gif.js
库将玩家每一步移动 dom
的结构转换为 canvas
,再使用 gif.js
把 canvas
添加至动态图之中,最后生成完整的动态图。
html2canvas
无法将svg
转换至canvas
中,游戏中元素需要使用图片来实现。
github pages 部署
在本地开发阶段正常,但是打包后的 docs
推送至 github pages 时无法展示 router-view
中的内容,在本地静态部署时也没问题。最后,将 vue-router
和 pinia
移除后部署成功。