您的位置  > 互联网

一张图教你快速玩转vue-cli3H5游戏核心功能介绍

前言

为了加深大家对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、数据可视化等前端知识和实战操作,欢迎你在《趣谈前端》中学习讨论,探索前端的边界——一起结束。