微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

Canvas drag 实现拖拽拼图小游戏

2016-11-04 21:41 伯乐专栏\/陈被单

(点击上方公众号,可快速关注)


作者:伯乐在线专栏作者 - 陈被单

链接:http://web.jobbole.com/88487/

点击 → 了解如何加入专栏作者


博主一直心心念念想做一个小游戏~  前段时间终于做了一个小游戏,直到现在才来总结,哈哈~ 以后要勤奋点更新博客!


实现原理


1.如何切图?


用之前的方法就是使用photoshop将图片切成相应大小的图片。这种做法不灵活,如果要更换图片的话,就得重新去切图,很麻烦。


现在是使用canvas,图片是一整张jpg或者png,把图片导入到canvas画布,然后再调用上下文context的getImageData方法,把图片处理成小图,这些小图就作为拼图的基本单位


renderImg: function (image) {

            var index = 0;

            for (var i = 0; i < 3; i++) {

                for (var j = 0; j < 3; j++) {

                    this.context.drawImage(image, 300 * j, 300 * i, 300, 600, 0, 0, 300, 300);

                    this.imgArr[index].src = this.canvas.toDataURL('image/jpeg');

                    this.imgArr[index].id = index;

                    index++;

                }

            }

        },


2.如何判断游戏是否结束?


在刚刚生成的小图上面添加自定义属性 , 后期在小图被移动后再一个个判断,如果顺序是对的,那么这张大图就拼接成功, 允许进入下一关;


isSuccess: function () {

            var imgLikeArr = document.querySelectorAll('img'),

                imgArr = Array.prototype.slice.call(imgLikeArr),

                len = imgArr.length, i,

                flag = true, self = this;

             for (i = 0; i < len; i++) {

                if (imgArr[i].id != i) {

                    flag = false;

                }

            }

 

            if (flag) {

                setTimeout(function () {

                   self.showtip();

                }, 200);

           }

       }


3.如何实现小图片随机排列?


使用math.random


randomImg: function () {

            this.imgArr.sort(function () {

                 return Math.random() - Math.random();

             });

        },


4.拖拽功能实现?


drag知识点补充站:


兼容性:IE9+,主流浏览器,移动端所有型号暂不支持


一个完整的drag and drop流程通常包含以下几个步骤:


  1. 设置可拖拽目标.设置属性draggable="true"实现元素的可拖拽.

  2. 监听dragstart设置拖拽数据

  3. 设置允许的拖放效果,如copy,move,link

  4. 设置拖放目标,默认情况下浏览器阻止所有的拖放操作,所以需要监听dragenter或者dragover取消浏览器默认行为使元素可拖放.

  5. 监听drop事件执行所需操作


拖拽事件周期中会初始化一个DataTransfer对象,用于保存拖拽数据和交互信息.

以下是它的属性和方法.


  • setData(format, data): 以键值对设置数据,format通常为数据格式,如text,text/html

  • getData(format): 获取设置的对应格式数据,format与setData()中一致


实例代码:


//监听dragstart设置拖拽数据

              on(contain, 'dragstart', function (e) {

                 var target = getTarget(e);

  

                  if (target.tagName.toLowerCase() == "img") {

                      e.dataTransfer.setData('id', e.target.id);

                  }

              });

  

             on(contain, 'drop', function (ev) {

                 var target = getTarget(ev);

        //交换图片

                 if (target.tagName.toLowerCase() == "img") {

                     var originObj = document.getElementById(ev.dataTransfer.getData('id'));

                     var cache = {

                         'src': originObj.src,

                         'id': originObj.id

                     };

                     var endObj = ev.target.querySelector('img') || ev.target;

                     originObj.src = endObj.src;

                     originObj.id = endObj.id;

                     endObj.src = cache.src;

                     endObj.id = cache.id;

                     if (originObj.id != endObj.id) {

                         self.changestep();

                     }

                     self.isSuccess();

                 }

             });

             //取消浏览器默认行为使元素可拖放.

             on(contain, 'dragover', function (ev) {

                 ev.preventDefault();

             });


核心代码和思路就是上面这些,其实整个流程走下来还是蛮简单的


有兴趣的可以上我的github (https://github.com/beidan/Puzzle),欢迎fork~star~



专栏作者简介 ( 点击 → 加入专栏作者 


陈被单:热爱前端,欢迎交流

打赏支持作者写出更多好文章,谢谢!



关注「前端大全」

看更多精选前端技术文章

↓↓↓

 
前端大全 更多文章 JavaScript 世界万物诞生记 微信小程序开放公测了 漫画:听说你是CSS高手 Web前端需要熟悉大学里[高大上]计算机专业课吗? 月薪最高 30K!15个岗位急招(含前端开发岗位)
猜您喜欢 如何处理 Swift 中的异步错误 Android CPU Frequency Interactive Governor 长夏已尽,凛冬将至,2016,QuestMobile与你携手同行 Android应用性能测试 【本周重磅】产品路上的数据分析之战