前言
为了加深大家对Vue的理解以及Vue项目的实际实现,作者利用Vue生态系统对这个项目进行了重构,以方便大家的学习和探索。技术栈如下: vue-cli4 基于Vue的脚手架Xuery 作者的基于原生js* vue mvvm库二次封装的dom库
因为这个应用程序是一个 H5 游戏,所以为了清楚起见,我没有使用第三方 UI 库。 如果你想使用基于vue的第三方移动UI库,笔者推荐如下:Mint、NutUI、饿了么推出的移动UI库、一套京东风格的移动组件库muse-ui风格-基于滴滴团队开发的移动UI组件cube-ui移动UI组件库vant 有赞团队电商风格移动组件库atom-atom风格移动ui 组件库*mand-滴滴开发的基于金融场景的移动UI组件库团队
以上笔者推荐的都是社区比较完善、bug比较少的组件库。 你可以对他们有一种感觉。
回到我们的小游戏开发,我们更注重对css3的掌握。 学习完这篇文章,相信大家使用css3的编程能力将会得到很大的提高。 稍后我们也会介绍如何使用它来生成成就。 海报图功能。
文本
我们先来看看游戏的预览界面:
在线体验地址:传送门
本文的算法实现方法在之前的文章中已经讲解过。 这里主要介绍一下核心算法。 至于vue-cli的使用,笔者之前也写过相应的文章。 你可以研究它并学习它。 使用vue-cli构建项目的方式如下:
// 安装
yarn global add @vue/cli
// 创建项目
vue create pinpinle
// 进入项目并启动
cd pinpinle && yarn start
关于vue-cli3的实际配置,可以移步一张图,教你如何快速玩转vue-cli3。
H5游戏核心功能介绍
目前笔者主要整理了以下几个核心功能。 接下来我将带领大家一一实现:实现纯粹上传预览图片的功能、实现拼图分割功能、实现洗牌算法、实现生成成就海报的功能。
1.实现预览图纯上传
文件上传预览主要是通过API实现的。 原理是传递文件对象,并将其转换为data:URL格式的字符串(编码)来表示读取文件的内容。 具体代码如下:
// 2.文件上传解析
let file = $('#file');
file.on('change', function(e){
var file = this.files[0];
var fileReader = new FileReader();
// 读取完成触发的事件
fileReader.onload = function(e) {
$('.file-wrap')[0].style.backgroundImage = 'url(' + fileReader.result + ')';
imgSrc = fileReader.result;
}
file && fileReader.readAsDataURL(file);
})
2.实现拼图分割功能
一般我们处理这种拼图的时候会有以下几种解决方案: 使用n张不同的切片图片来分割图片(方法很简单,但是会造成多次请求) * 动态背景分割
经过权衡,作者提出了第三种方法,我觉得这个方法比较优雅,那就是动态背景分割。 我们只需要使用1张图片,然后用CSS友好的方式剪切图片,有点经典精灵图像的感觉,如下:
本质是我们设置了9个div,每个div使用同一张图片,图片大小等于游戏画布大小,但是我们使用(背景定位)来切割图片。 这样做的另一个好处是,它使我们更容易实现洗牌逻辑。
3. 实现洗牌算法
洗牌逻辑依赖于随机算法。 这里我们结合坐标系来实现随机生成二维坐标系的逻辑。 然后通过改变各个切片的位置,配合过渡动画,就可以实现洗牌功能和洗牌动画。
3.1 数组重排序算法
数组重排序比较简单,代码如下:
// 数组乱序
function upsetArr(arr) {
arr.sort(function(a,b){
return Math.random() > 0.5 ? -1 : 1
})
}
3.2 洗牌逻辑
混洗逻辑基于数组混洗。 具体逻辑如下:
// 洗牌方法
function shuffle(els, arr) {
upsetArr(arr);
for(var i=0, len=els.length; i< len; i++) {
var el = els[i];
el.setAttribute('index', i); // 将打乱后的数组索引缓存到元素中
el.style.transform = 'translate(' + arr[i].x + 'vw,' + arr[i].y + 'vh'+ ')';
}
}
3.3 生成n维矩阵坐标
n维矩阵主要用于洗牌和计算成功率。 具体实现如下:
// 生成n维矩阵坐标
function generateMatrix(n, dx, dy) {
var arr = [], index = 0;
for(var i = 0; i< n; i++) {
for(var j=0; j< n; j++) {
arr.push({x: j*dx, y: i*dy, index: index});
index++;
}
}
return arr
}
3.4 替换算法
位移算法主要用于切换拼图块。 例如,如果用户想要移动拼图块,可以使用位移来实现:
// 数组置换
function swap(arr, indexA, indexB) {
let cache = arr[indexA];
arr[indexA] = arr[indexB];
arr[indexB] = cache;
}
4.实现生成成果海报的功能
作者用它来生成成就海报。 如果您不熟悉该 API,可以查看 MDN 了解更多详细信息。 这里笔者简单实现了一个供大家参考:
function generateImg() {
var canvas = document.createElement("canvas");
if(canvas.getContext) {
var winW = window.innerWidth,
winH = window.innerHeight,
ctx = canvas.getContext('2d');
canvas.width = winW;
canvas.height = winH;
// 绘制背景
// ctx.fillStyle = '#06c';
var linear = ctx.createLinearGradient(0, 0, 0, winH);
linear.addColorStop(0, '#a1c4fd');
linear.addColorStop(1, '#c2e9fb');
ctx.fillStyle = linear;
ctx.fillRect(0, 0, winW, winH);
ctx.fill();
// 绘制顶部图像
var imgH = 0;
img = new Image();
img.src = imgSrc;
img.onload = function(){
// 绘制的图片宽为.7winW, 根据等比换算绘制的图片高度为 .7winW*imgH/imgW
imgH = .6*winW*this.height/this.width;
ctx.drawImage(img, .2*winW, .1*winH, .6*winW, imgH);
drawText();
drawTip();
drawCode();
}
// 绘制文字
function drawText() {
ctx.save();
ctx.fillStyle = '#fff';
ctx.font = 20 + 'px Helvetica';
ctx.textBaseline = 'hanging';
ctx.textAlign = 'center';
ctx.fillText('我只用了' + (180 -dealtime) + 's,' + '快来挑战!', winW/2, .15*winH + imgH);
ctx.restore();
}
// 绘制提示文字
function drawTip() {
ctx.save();
ctx.fillStyle = '#000';
ctx.font = 14 + 'px Helvetica';
ctx.textBaseline = 'hanging';
ctx.textAlign = 'center';
ctx.fillText('关注下方二维码开始游戏', winW/2, .25*winH + imgH);
ctx.restore();
}
// 绘制二维码
function drawCode() {
var imgCode = new Image();
imgCode.src = '/piecePlay/images/logo.png';
imgCode.onload = function(){
ctx.drawImage(imgCode, .35*winW, .3*winH + imgH, .3*winW, .3*winW);
// 生成预览图
var img = new Image();
img.src= convertCanvasToImage(canvas, 1).src;
img.className = 'previewImg';
img.onload = function(){
$('.preview-page')[0].appendChild(this);
startDx = startDx - 100;
transformX(wrap, startDx + 'vw');
}
}
}
} else {
alert('浏览器不支持canvas!')
}
}
H5益智游戏作者已经开源,有兴趣的可以学习参考。 以上逻辑部分代码可以直接集成到vue项目中。 由于实现比较简单,笔者这里就不详细介绍了。
H5可视化编辑器功能迭代说明
目前笔者实现的H5可视化编辑器H5-功能如下:实时保存功能、添加进度条组件、添加通讯实现在线代码下载功能
预览地址:基于React+Koa实现一个h5页面可视化编辑器 -
地址:基于React+Koa实现一个h5页面可视化编辑器 -
终于
如果你想了解更多H5游戏、node、gulp、css3、数据可视化等前端知识和实战操作,欢迎你在《趣谈前端》中学习讨论,探索前端的边界——一起结束。