教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

徐小夕 等级 637 0 0

前言

本文将带大家一步步实现一个H5拼图小游戏,考虑到H5游戏的轻量级和代码体积,我没有使用react或vue这些框架,而采用我自己写的dom库和原生javascript来实现业务功能,具体库代码可见我的文章如何用不到200行代码写一款属于自己的js类库,构建工具我采用了自己搭建的gulp4开发项目脚手架。你将学到:

  • 洗牌算法
  • 洗牌动画实现原理
  • 用FileReader API实现本地预览文件
  • 用Canvas生成海报

零零总总花了半天的时间,希望对自己后面涉及H5游戏有所帮助,也希望大家通过这篇文章有所收获。

设计思路

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

效果演示

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)

具体实现

接下来我将贴出每一步的核心代码,供大家参考学习。

1.文件上传解析

``` js
// 文件上传解析
    var 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.生成canvas海报

具体实现思路如下,canvas代码后期会封装成一个类,基本用法和思路大致如下:

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 = './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!')
        }
    }

    // 将canvas转化为图片
    function convertCanvasToImage(canvas, quality) {
        var image = new Image();
        image.src = canvas.toDataURL("image/png", quality);
        return image;
    }

3.切换元素动画和洗牌算法

我们用transform实现洗牌动画和拼图切换的动画,洗牌算法主要通过维护一个矩阵序列来实现。接下来是基本的工具方法:

// 滑动元素,用于切换页面
    function transformX(el, dx) {
        el.style.transform = 'translateX(' + dx + ')';
    }

// 生成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
    }

// 数组置换
    function swap(arr, indexA, indexB) {
        var cache = arr[indexA];
        arr[indexA] = arr[indexB];
        arr[indexB] = cache;
    }

// 数组乱序
    function upsetArr(arr) {
        arr.sort(function(a,b){
            return Math.random() > 0.5 ? -1 : 1
        })
    }

// 洗牌方法
    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'+ ')';
        }
    }

// 校验是否成功方法
    function isTestSuccess(arr) {
        return arr.every(function(item, i){ return item.index === i })
    }
// 

有了工具方法,我们可以通过如下调用实现洗牌:

//初始数组
let pool = generateMatrix(3, 28, 20);   
// 洗牌 pieces是拼图的dom集合
shuffle(pieces, pool);

该游戏的核心算法已经交给大家了,如想体验真实游戏,欢迎交流哈,如果想研究游戏源码,欢迎和我交流哈。

更多推荐

欢迎关注下方公众号,获取更多前端知识精粹学习社群教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码) 在公众号点击进群,可以加入vue学习小组,一起学习前端技术;

回复学习路径,将获取笔者多年从业经验的前端学习路径的思维导图。

收藏
评论区

相关推荐

教你用200行代码写一个爱豆拼拼乐H5小游戏(附源码)
前言 本文将带大家一步步实现一个H5拼图小游戏,考虑到H5游戏的轻量级和代码体积,我没有使用react或vue这些框架,而采用我自己写的dom库和原生javascript来实现业务功能,具体库代码可见我的文章如何用不到200行代码写一款属于自己的js类库(https://juejin.im/post/6844903880707293198),构建工具我采
Android webview 与 js(Vue) 交互
js 与原生交互分为两种情况:js 调用原生方法,原生调用 js 方法。 本文将对这两种情况分别讲解,H5 端用 vue 实现。 一、前期准备(Vue项目准备) 本文的 H5 端用Vue 实现,所以在正式开始前先把 Vue 项目环境准备好。 项目写好后,执行 npm run serve 命令启动项目,启动成功后会在命令
看了10款文档编辑器之后, 我决定...
作为一名技术工作者, 我们经常会遇到编写技术文档, 技术分享等需求, 网上也有很多现成的文档管理工具, 出于好奇心, 我拉着朋友一起实现了一个, 用来自给自足. 接下来就来介绍一下轻量级且灵活方便的文档编辑工具—— powerNice(http://h5.dooring.cn/powernice). powerNice(http://h5.door
(前端项目实战) 微信 H5音乐项目总结
![](https://oscimg.oschina.net/oscnet/b394c44d-6f96-4780-b384-388e4faf2fb1.jpg)刚刚完成了一个 H5 项目,途中使用 audio 的时候遇到不少坑,所以写篇项目总结。 项目需求 ---- 要经过微信授权才能进入。所以只能在微信打开。 流程: 1. 开场有个小的过渡效果
H5调取APP或跳转至下载
#### 来源:   最近在配合移动端做几个详情页h5分享页面,需要调取App并跳转至app详情页, 如果没有安装App,需要判断引导至下载页面。 #### 参考文档: [https://juejin.im/post/5b7efb2ee51d45388b6af96c](https://www.oschina.net/action/GoToLink?u
H5游戏开发:套圈圈
![](https://oscimg.oschina.net/oscnet/8e955a11c1b4be04937790dae3eacc4f896.jpg) 前言 虽然本文标题为介绍一个水压套圈h5游戏,但是窃以为仅仅如此对读者是没什么帮助的,毕竟读者们的工作生活很少会再写一个类似的游戏,更多的是面对需求的挑战。我更希望能举一反三,给大家在编写h
HTML5游戏开发凭什么这么火?看了你就知道了...
很多人都会问[H5游戏](https://www.oschina.net/action/GoToLink?url=http%3A%2F%2Fedu.51cto.com%2Fcourse%2Fcourse_id-1307.html)有前途吗?其实我个人是比较看好H5的前景,尤其是在这个移动互联网的时代,Web技术的触角必然会深入到各个领域. 当然H5目前仍然
h5 接入微信支付
我们公司,现在用ping++ 做h5接入,用的是 h5"壹收款" 准备: === 如果公司,现在还没有公众号的话,支付宝。 可以把这些工作,给ping++ 来做这些事情  1. 注册微信公众号,开通支付功能。 2. 注册ping++  (如果是自己 开开通的微信 支付,要填写相关信息) 3. 微信设置[网页授权获取用户基本信
Android WebView 的三种使用方式
关于原生开发好,还是混合模式开发好,还是 套壳的方式好,在这里不是重点,没有最好的,只有相对适合的。 重点是 那种方式 以最低的资源代价 适合你的业务场景,适合你的团队,根据实际情况来做技术选型。 1,使用h5替代android的view xml 前端将写好的h5 页面放在android 工程的asset目录, 打包的时候会将h5页面一起打在apk里面,
Android与H5混合开发
        Android 和 H5 在移动开发应用中非常广泛。市面上很多App都是使用Android开发的,但使用Android来开发一些比较复杂附属类,提示性的页面是得不偿失的。而H5在制作炫酷动画网页方面比较给力,且具有开发速度快,更新不用依赖于App的更新,只需要服务端更新相应的页面即可,所以App和H5页面相结合就显得尤为重要。而android
Android使用WebView加载H5页面播放视频音频,退出后还在播放问题解决
Android中经常会使用到WebView来加载H5的页面,如果H5页面中有音频或者视频的播放时,还没播放完就退出界面,这个时候会发现音频或者视频还在后台播放,这就有点一脸懵逼了,下面是解决方案: 方案一: 在webview所在的activity中的onPause()和onResume()方法中写上两句话。 public void on
ExMobi+Agile Lite开发内置浏览器APP
微信对内置浏览器的定制封装,使得H5的流量入口再次重新被定义。在原生程序中使用H5也成为非常必要的一种搭配。这也得益于H5对于简单的浏览性质的内容可以很好的进行展现和传播。 由于在实际项目中有需要在移动端使用到H5,而大部分H5页面都是来源于网络的,所以这里尝试使用[ExMobi](https://www.oschina.net/action/GoToLi
HTML 使用CSS 设置透明度Opacity
HTML/CSS标签透明度效果的实现 ------------------ 在HTML+CSS编程中,实现半透明背景,通常有3中做法,分别是使用RGBA,PNG和CSS filter。 ### 方法一. 第一种是HTML5的透明,在H5中支持透明背景颜色,但遗憾的是,H5中的办透明背景颜色只支持 rgba的写法,不支持16进制的写法如: ba
Hybrid App从概念到实战
      最近一直在准备找工作,看了很多公司的招聘介绍,有相当一部分直接写:熟悉 Hybrid App 开发加分!正好,我司开发的就有这种 Hybrid App——使用 WebViewJavascriptBridge 通信,前端封装一些常用方法调用。       现在的 app 开发,已经不在是以前一样所以页面都是有原生开发,基于应用的更新上线繁琐,由于
Taro Next H5 跨框架组件库实践
![](https://oscimg.oschina.net/oscnet/up-96f83cb51198003133bbb6dfcf26f38b6c9.png) 作者:凹凸曼 - JJ [Taro](https://www.oschina.net/action/GoToLink?url=https%3A%2F%2Fgithub.com%2FNervJS