推箱子小游戏

 游戏制做(推箱子):javascript

① 作地图(css+div)css

②背包+游戏公告+表格高亮+图片放大  //未实现html

③箱子的移动(动态操做标签) java

④游戏登陆页面(页面传值+正则表达式+cookie保存自动登陆)//未实现jquery

⑤游戏逻辑(js面向对象+js逻辑)ajax

⑥后端用户表通讯(jquery+ajax+json)//未实现正则表达式

1.推箱子小游戏js代码:json

逻辑思惟:后端

 1.布局:建立对象(地图、箱子、人)。缓存


 2.人的移动:

     人移动前要判断前面是否有墙壁,若是有则不能移动,不然移动。
     人移动前要判断前面是否有箱子,若是有则箱子移动、人移动。
     箱子移动前要判断前面是否有箱子,若是有则不动,不然箱子移动,人移动。
     箱子移动前要判断前面是否有墙壁,若是有则不动,不然箱子移动,人移动。
     判断箱子位置和终点位置是否相等,相等则成功。

/**
 * Created by wln on 2017/9/6.
 */
$(function () {
    Game.init($("#w_left"));//初始化容器
});

var Game = {
    gk:[
        {//关卡1
            map:[//0:移动区域,1:固定区域,2:墙壁,3:箱子最终位置
                1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 2, 0, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 2, 2, 0, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 2, 0, 0, 0, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 2, 0, 0, 0, 0, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 0, 0, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
            ],
            box:[
                {x: 4, y: 3},
                {x: 4, y: 5},
                {x: 5, y: 5}
            ],
            person:{x: 3, y: 6}
        },

        {//关卡2
            map:[
                1, 1, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 2, 0, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 2, 2, 0, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 2, 0, 0, 0, 3, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 2, 0, 0, 0, 3, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 0, 0, 2, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 0, 0, 0, 0, 0, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
                1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1
            ],
            box:[
                { x: 4, y: 3 },
                { x: 3, y: 4 },
                { x: 4, y: 5 },
                { x: 5, y: 5 }

            ],
            person: { x: 3, y: 6 }
        }
    ],

    init: function (Parent) {//构造函数模式:1.没有显式的建立对象 2.直接将属性和方法赋给了this对象 3.没有return语句
        this.Parent = Parent;
        this.Now = 0;//判断是第几关
        this.createMap(this.Now);
    },

    createMap: function(Now) {//建立地图
        this.Parent.empty();//empty() 方法从被选元素移除全部内容,包括全部文本和子节点
        document.title = "第" +(Now + 1)+"关";
        document.getElementById("up_font").innerText = "第" +(Now + 1)+"关";//第几关
        this.newJson = this.gk[Now];//关卡布局

        this.Parent.css({"width": this.newJson.map.length / 11 * 53,
            "height": this.newJson.map.length /18 * 53});//this.newJson.map.length 求的是map的面积 11*18


        var mapHtml = '';
        $.each(this.newJson.map, $.proxy(function (i, elem) {//遍历map[],建立<div>
            mapHtml += '<div class="pos' + elem + '"></div>';//为建立的div添加 class样式
        }, this));
        this.Parent.append(mapHtml);//将建立的<div>添加到 id=#w_left的<div> 里

        this.createBox();
        this.createPerson();
    },

    createBox: function () {//建立箱子布局
        $.each(this.newJson.box, $.proxy(function (i, elem) {//遍历box[],建立<div>
            var BoxHtml = $('<div class="box"></div>');//为建立的div添加 class样式
            BoxHtml.css({'left': elem.x * 53, 'top': elem.y *53});//为建立的div添加 css样式
            this.Parent.append(BoxHtml);//将建立的<div>添加到 id=#w_left的<div> 里
        }, this));
    },

    createPerson: function () {//建立人物所在的位置
        var oPerson = $('<div class="person"></div>')//为建立的div添加 class样式
        var pos = this.newJson.person;//得到父类
        oPerson.css({'left': pos.x * 53, 'top': pos.y * 53});
        oPerson.data('x', pos.x);//缓存在oPerson上的数据
        oPerson.data('y', pos.y);
        this.Parent.append(oPerson);//将建立的<div>添加到 id=#w_left的<div> 里
        this.bindPerson(oPerson);
    },

    bindPerson: function (oPerson) {//绑定对人物←↑→↓操做
        $(document).keydown($.proxy(function (e) {
            switch (e.which) {
                case 37: //
                    oPerson.css('backgroundPosition', '-159px 0');//设置人的设置背景图像的位置,以人的左上角为原点
                    this.movePerson(oPerson, {x: -1});//一次移动的距离
                    break;
                case 38: //
                    oPerson.css("backgroundPosition", "0 0");
                    this.movePerson(oPerson, { y: -1 });
                    break;
                case 39: //
                    oPerson.css("backgroundPosition", "+53px 0");
                    this.movePerson(oPerson, { x: 1 });
                    break;
                case 40: //
                    oPerson.css("backgroundPosition", "106px 0");
                    this.movePerson(oPerson, { y: 1 });
                    break;
                default:

            }
        }, this));

    },


    movePerson: function (oPerson, move) {//移动人物
        var xValue = move.x || 0;//number类型 逻辑或的做用:move有值则为move的值,不然值为0
        var yValue = move.y || 0;//获取y的值

        var length = this.newJson.map.length / 11;//map[]的宽

        // 获取人在map[]上的索引, 列数+行数*长度
        // data() 方法向被选元素附加数据,或者从被选元素获取数据。也是以一种键值对的形式存在。
        var currentMapIndex = (oPerson.data('x') + xValue) + (oPerson.data('y') + yValue) * length;

        if (this.newJson.map[currentMapIndex] != 2) {//若是不是墙壁
            //改变人的位置
            oPerson.data('x', oPerson.data('x') + xValue);
            oPerson.data('y', oPerson.data('y') + yValue);
            oPerson.css({ "left": oPerson.data("x") * 53, "top": oPerson.data("y") * 53 });

            $(".box").each($.proxy(function (i, elem) {
                //当人和箱子发生碰撞时 遇到墙的判断
                if (this.pz(oPerson, $(elem)) &&
                    this.newJson.map[(oPerson.data('x') + xValue) + (oPerson.data('y') + yValue) * length] != 2) {//若是不是墙
                    //根据人的位置,改变箱子的位置
                    $(elem).css({ 'left': (oPerson.data('x') + xValue) * 53, 'top': (oPerson.data('y') + yValue) * 53 });

                    $(".box").each($.proxy(function (j, elem2) {
                        //当遇到箱子和箱子的的碰撞时 同时前面也不是墙的判断
                        if (this.pz($(elem), $(elem2)) && elem != elem2) {
                            //箱子位置还原
                            $(elem).css({ 'left': oPerson.data('x') * 53, 'top': oPerson.data('y') * 53 });
                            //人位置还原
                            oPerson.data('x', oPerson.data('x') - xValue);
                            oPerson.data('y', oPerson.data('y') - yValue);
                            oPerson.css({ "left": oPerson.data("x") * 53, "top": oPerson.data("y") * 53 });
                        }
                    }, this));
                }
                if (this.pz(oPerson, $(elem))) {//人和墙之间的碰撞
                    //人位置还原
                    oPerson.data('x', oPerson.data('x') - xValue);
                    oPerson.data('y', oPerson.data('y') - yValue);
                    oPerson.css({ "left": oPerson.data("x") * 53, "top": oPerson.data("y") * 53 });
                }
            }, this));
        }
        this.nextShow();
    },

    nextShow: function () {//判断是否赢
        var iNum = 0;
        //绿色区域所在的位置是否所有被箱子所占据
        $(".box").each($.proxy(function (i, elem) {
            $(".pos3").each($.proxy(function (j, elem1) {
                if (this.pz($(elem), $(elem1))) {
                    iNum++;
                }
            }, this));
        }, this));
        if (iNum == this.newJson.box.length) {
            if(this.Now < 1) {
                this.Now++;
                this.createMap(this.Now);
            }else {
                setTimeout('alert("过关")', 50);
                setTimeout('document.location.reload()', 55);
            }
        }

    },

    pz: function (obj1, obj2) { //碰撞检测
        var L1 = obj1.offset().left;//获取元素距离页面左侧距离
        var R1 = obj1.offset().left + obj1.width();
        var T1 = obj1.offset().top;//获取元素距离页面顶端高度
        var B1 = obj1.offset().top + obj1.height();

        var L2 = obj2.offset().left;
        var R2 = obj2.offset().left + obj2.width();
        var T2 = obj2.offset().top;
        var B2 = obj2.offset().top + obj2.height();
        if (L1 >= R2 || T1 >= B2 || R1 <= L2 || B1 <= T2 )
        { return false; }
        else
        { return true; }
    }
};

 

2.推箱子的index.css代码:

/*总体 B*/
.whole {
    width: 1150px;
    height: 600px;
    background-color: #999999;
    margin:5px auto;
}
/*总体 E*/
/*左边 B*/
.w_left {
    margin-top: 7px;
    margin-left: 10px;
    border-top: 3px solid black;
    border-left: 3px solid black;
    border-right: 1px solid black;
    border-bottom: 1px solid black;
    position: relative;
}

.pos0 {
    width: 51px;
    height: 51px;
    float: left;
    background: #39ffff;
    border-bottom: 2px solid black;
    border-right: 2px solid black;
}

.pos1 {
    width: 51px;
    height: 51px;
    float: left;
    background: #39ffff;
    border-bottom: 2px solid black;
    border-right: 2px solid black;
}

.pos2 {
    width: 51px;
    height: 51px;
    float: left;
    background: white;
    border-bottom: 2px solid black;
    border-right: 2px solid black;
}

.pos3 {
    width: 51px;
    height: 51px;
    float: left;
    background: #67b168;
    border-bottom: 2px solid black;
    border-right: 2px solid black;
}

.box {
    width: 51px;
    height: 51px;
    position: absolute;
    background-color: yellow;
}

.person {
    width: 51px;
    height: 51px;
    position: absolute;
    background-color: red;
}
/*左边 E*/
/*右边 B*/
.w_right {
    width: 150px;
    height: 581px;
    background-color: #a67300;
    margin-top: 7px;
    margin-right: 10px;
    border: 2px solid black;
}
.w_right_up {
    width: 100%;
    height: 60px;
    background-color: white;
}
.w_right_up .up_font {
    font:normal normal 26px "微软雅黑";
    text-align: center;
    padding-top: 15px;
}
/*右边 E*/

 

3.推箱子的common.css代码:

@charset "utf-8";
/* 存放CSS初始化代码 */
/* 去掉标签的默认margin和padding: */
html, body, ul, li, ol, p, h1, h2, h3, form,img {
    margin:0; 
    padding:0;
}
/* 去掉图片的边框: */
img {
    border:0;
}
/* 去掉ul前面的小点 */
ul {
    list-style:none;
}
/* 去掉input标签默认的padding-top,padding-bottom,border */
input {
    padding-top:0; padding-bottom:0; border:none;
}
/* 去掉a标签的下划线 */
a {
    text-decoration:none;
}
/* 给body设置一个统一的字体样式和背景颜色 */
body {
    font:normal normal 12px "宋体"; 
    color:#4c4c4c; 
    background-color:#fae8c8;
}
/* 左右浮动,清除浮动 */
.fl {float:left;} 
.fr {float:right;} 
.clearfix:after {
    content:"."; 
    height:0;
    line-height:0; 
    display:block; 
    visibility:hidden; 
    clear: both;
} 
.clearfix {
    zoom:1;
}

 

4.推箱子的index.html代码:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>推箱子</title>
    <script src="https://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script>
    <script type="text/javascript" src="js/index.js"></script>
    <link rel="stylesheet" type="text/css" href="css/common.css">
    <link rel="stylesheet" type="text/css" href="css/index.css">
</head>
<body>


<!-- 总体 B-->
<div class="whole">
    <!-- 左边 B-->
    <div class="w_left fl" id="w_left">

    </div>
    <!-- 左边 E-->
    <!-- 右边 B-->
    <div class="w_right fr">
        <!-- 上边 B-->
        <div class="w_right_up">
            <p class="up_font" id="up_font"></p>
        </div>
        <!-- 上边 E-->
    </div>
    <!-- 右边 E-->
</div>
<!-- 总体 E-->
</body>
</html>
相关文章
相关标签/搜索