首页 > 网站 > WEB开发 > 正文

JavaScript写一个拼图游戏

2024-04-27 14:06:42
字体:
来源:转载
供稿:网友

javaScript写一个拼图游戏

  拼图游戏的代码400行, 有点多了, 在线DEMO的地址是:打开;

  因为使用canvas,所以某些浏览器是不支持的: you know;

  为什么要用canvas(⊙o⊙)? 因为图片是一整张jpg或者png, 我们要用把图片导入到canvas画布, 然后再调用上下文context的getImageData方法, 把图片处理成小图, 这些小图就作为拼图的基本单位;

  如何判断游戏是否结束, 或者说如何判断用户拼成的大图是正确的? 我们就要在刚刚生成的小图上面添加自定义属性, 后期在小图被移动后再一个个判断,如果顺序是对的, 那么这张大图就拼接成功, 允许进入下一关;

  

  游戏一共有四个关卡, 不会有人通关的,真的....因为第四关把图片的宽高分别切成了6份, 看着都晕好吧(∩_∩);

    

  

  因为要考虑到移动端的效果, 所以主界面图片是根据屏幕适配, 拼图大图的大小是屏幕宽度和屏幕高度之间最小值的一半, 都是为了不出现滚动条。 比如:用户的手机是横屏模式, 这个横屏的宽度是1000px,高度是300px, 如果我们把主图片的宽设置为屏幕1000px的一半500, 那么垂直方向就出滚动条了;

  用户的事件只要考虑上下左右四个方向键即可, 要判断图片是否可以移动, 也要考虑到当图片移动的时候的动画效果 ,感兴趣的话考虑我的实现, 和我写的2048是一样的道理;2048的DEMO;

  如果用户觉得这些图片不好看, 甚至可以上传自己手机的图片, 浏览器要支持FileReader的API, 移动是基于webkit的内核,可以不用考虑兼容性;

  代码包含工具方法和一些基本的配置, 比如, 图片地址的配置, 图片要切成的块数 , 加载图片的工具方法等:

        //游戏关卡的图片和游戏每一个关卡要切成的图片快个数        var levels = ["lake.jpg","cat.jpg","follower.jpg","view.jpg"];        var numbers = [3,4,5,6];        //工具方法        var util = {            /**             * @desc 图片加载成功的话就执行回调函数             * @param 图片地址 || 图片的DataUrl数据;             */            loadImg : function(e, fn) {                var img = new Image;                if( typeof e !== "string" ) {                    img.src = ( e.srcElement || e.target ).result;                }else{                    img.src = e;                };                img.onload = function() {//document.body.appendChild( canvas );                    //document.getElementById("content").appendChild( canvas );                    fn&&fn();                };            }        };

  代码是基于面向对象(oop), 包含了两个类 :ClipImage 类Block 类

  ClipImage类

        /**         *  @desc 把图片通过canvas切成一块块;         */        function ClipImage(canvas , number) {        };        $.extend(ClipImage.PRototype, {            /**            * @desc 根据关卡把图片canvas切成块canvas            * 然后渲染到DOM;            * */            clip :  function () {            },            /**             * @param 把canvas块混排, 打乱排序;             * */            //使用底线库的方法shuffle打乱排序;            random : function( ) {            },            /**             * @desc 把canvas渲染到DOM;             * */            renderToDom : function () {            },            updataDom : function(cav, obj) {                this.updataMap();                $(cav).animate({top:obj.y*this.avH,left:obj.x*this.avW});            },            updataMap : function () {            },            testSuccess : function () {            }        });

  Block类

        /**         * @desc 对每一个canvas进行包装;         * @param canvas         * @param left         * @param top         * @param avW         * @param avH         * @constructor Block         */        var Block = function(canvas, left, top,avW, avH) {        };        $.extend(Block.prototype, {            /**             * @desc 对每一个canvas进行定位, 然后添加到界面中;             * */            init : function () {            },            /**             * @desc 对每一个canvas进行定位             * */            setPosition : function() {            },            /**             * @desc 向上移动会执行的函数  ,通过判断maps下有没有对应的key值判断, 界面中的固定位置是否被占用;             * */            upF : function(maps,numbers,cb) {                };            },            /**             * @desc 同上             * */            rightF : function(maps, numbers, cb) {            },            /**             * @desc 同上             * */            downF : function (maps,numbers,cb) {            },            /**             * @desc 同上             * */            leftF : function(maps,numbers,cb) {            }        });

  为了考虑移动端,我们使用了zepto封装的swipe系列事件, 默认并没有这个模块, 我们要通过script标签引用进来, github的地址为 https://github.com/madrobby/zepto/blob/master/src/touch.js#files:

            $(document).swipeLeft(function() {                run(clipImage,"leftF")            }).swipeUp(function() {                run(clipImage,"upF")            }).swipeRight(function() {                run(clipImage,"rightF")            }).swipeDown(function() {                run(clipImage,"downF")            });

  虽然是一个小游戏,都是要考虑的东西真的不少,包括动画效果, 是否可以移动, 更改数据模型, 是否成功进入下一个关卡等, 包含挺多的判断;

  全部代码, 提供思路, 代码可以作为参考:

<!DOCTYPE html><html><head lang="en">    <meta charset="UTF-8">    <title></title>    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">    <link rel="stylesheet" href="http://cdn.bootCSS.com/bootstrap/3.3.5/css/bootstrap.min.css"/>    <script src="http://cdn.bootcss.com/zepto/1.0rc1/zepto.min.js"></script>    <script src="http://cdn.bootcss.com/underscore.js/1.8.3/underscore.js"></script>    <style>        body{            margin:0;        }        #content{            position: relative;            margin:40px auto;        }        canvas{            border:1px solid #f0f0f0;            box-shadow: 2px 2px 2px #eee;        }    </style></head><body><input type="file" name="file" id="file"/><div class="container">    <div class="row">        <div class="progress">            <div class="progress-bar progress-bar-success" role="progressbar" aria-valuenow="40" aria-valuemin="0" aria-valuemax="100" style="width: 25%">                <span class>当前是第<span id="now">1</span>关,共4关</span>            </div>        </div>    </div>    <div class="row">        <div id="content" class="clearfix ">        </div>    </div></div><script>    (function(fn) {        fn($);    })(function($) {        //这个canvas是缓存图片用的;        var canvas = document.createElement("canvas");        var minScreenWidth = Math.min( document.documentElement.clientWidth/ 2, document.documentElement.clientHeight/2 );        canvas.width = minScreenWidth;        canvas.height = minScreenWidth;        document.getElementById("content").style.width =  minScreenWidth + "px";        //保存了所有的block;        var blocks = [];        //工具方法        var util = {            /**             * @desc 图片加载成功的话就执行回调函数             * @param 图片地址 || 图片的DataUrl数据;             */            loadImg : function(e, fn) {                var img = new Image;                if( typeof e !== "string" ) {                    img.src = ( e.srcElement || e.target ).result;                }else{                    img.src = e;                };                img.onload = function() {                    //canvas.width = img.width;                    //canvas.height = img.height;                    canvas.getContext("2d").drawImage( img, 0, 0 ,canvas.width, canvas.height);                    //document.body.appendChild( canvas );                    //document.getElementById("content").appendChild( canvas );                    fn&&fn();                };            }        };        //绑定事件;        function bindEvents () {            var file = $("#file");            file.bind("change", function(ev) {                var reader = new FileReader;                reader.onload = function(e) {                    util.loadImg(e, function() {                        window.clipImage = new ClipImage(canvas, numbers[window.lev]);                        window.clipImage.random();                        Controller( window.clipImage, nu
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表