<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>贪吃蛇</title>
    <style type="text/css">
        *
        {
            margin: 0px;
            padding: 0px;
        }
        .food
        {
            background-color: green;
        }
        .snake
        {
            background-color: red;
        }
    </style>
    <script type="text/javascript">
        /*
        
        1.创建游戏地图
        2.创建食物的位置
        3.创建一节蛇的位置
        4.开始运行
        5.重新开始游戏
        6.键盘方向键的监听
        7.蛇的运动制作
        8.蛇前面是什么?
        
        */
        var num = 15; //地图由一个一个的15*15的方块组成
        var rows = 30; //每行30个小方块
        var cols = 20; //每列20个小方块
        var borderwidth = 5; //地图的边框宽度
        var map = []; //地图为一个二维数组
        var mainMap; //地图的id
        var sx = 0, sy = 0; //蛇的位置,即在第几个方块位置
        var alldiv; //所有蛇即地图里的所有div
        var allspan; //所有食物即地图里的所有span
        var times = 200; //定时器时间

        //创建一个地图
        function createMap() {
            var bgwidth = 2 * borderwidth + num * rows; //地图的宽度
            var bgheight = 2 * borderwidth + num * cols; //地图的高度	

            //地图的位置,处于文档中的正中央
            var left = (document.documentElement.clientWidth - bgwidth) / 2;
            var top = (document.documentElement.clientHeight - bgheight) / 2;

            document.body.innerHTML = "<div id='mainMap' style='position:absolute;left:" + left + "px;top:" + top + "px;width:" + bgwidth + "px;height:" + bgheight + "px;border-width:" + borderwidth + "px;border-color:blue;border-style:solid'></div>";

            //地图默认每个位置都是0即空白
            for (var x = 0; x < rows; x++) {
                map[x] = [];
                for (var y = 0; y < cols; y++) {
                    map[x][y] = 0;
                }
            }

            //在地图上创建一个食物
            createFood();

            //蛇只有第一次进入地图时是随机,之后其位置不能随机
            sx = parseInt(Math.random() * rows);
            sy = parseInt(Math.random() * cols);

            if (map[sx][sy] == 0) {
                //创建蛇,必须保证初始化时“蛇”与“食物”的位置不重叠
                createSnake();
            } else {
                createMap();
            }

            //获得地图下所有的div即蛇(mainMap在创建食物时已定义)
            alldiv = mainMap.getElementsByTagName("div");

            //获得地图下所有的span即食物
            allspan = mainMap.getElementsByTagName("span");
        }

        //创建食物
        function createFood() {
            //食物随机产生的位置,不能超出地图
            var fx = parseInt(Math.random() * rows);
            var fy = parseInt(Math.random() * cols);


            var left = fx * num;
            var top = fy * num;

            //食物的定位在地图中
            mainMap = document.getElementById("mainMap");

            //如果在地图上是空地时才能放食物
            if (map[fx][fy] == 0) {
                mainMap.innerHTML += "<span style='position:absolute;left:" + left + "px;top:" + top + "px;width:" + num + "px;height:" + num + "px; overflow:hidden; display:block;' class='food'></span>";
                //放有食物的位置标记为f
                map[fx][fy] = "f";
            }
            else {
                createFood(); //即遇到创建的位置不是空白时,再重新创建一下食物的位置,直到找到空白位置创建食物后此方法结束
            }
        }

        //创建蛇        
        function createSnake() {
            var left = sx * num;
            var top = sy * num;

            //蛇也必须在地图中,食物已有,这里注意内容必须是+=,否则食物将被覆盖,自定义x,y保存蛇当前的位置
            mainMap.innerHTML += "<div x='" + sx + "' y='" + sy + "' style='position:absolute;left:" + left + "px;top:" + top + "px;width:" + num + "px;height:" + num + "px; overflow:hidden;' class='snake'></div>";
            map[sx][sy] = "s"; //把蛇的位置标记为s
        }

        //键盘监听
        document.onkeydown = function () {
            var keyCode;
            if (window.navigator.appName.indexOf("Microsoft Internet Explorer") > -1) {
                keyCode = window.event.keyCode;
            }
            else {
                keyCode = arguments[0].keyCode;
            }

            switch (keyCode) {
                case 65: //左a
                    dir(-1, 0);
                    break;
                case 87: //上w
                    dir(0, -1);
                    break;
                case 68: //右d
                    dir(1, 0);
                    break;
                case 83: //下s
                    dir(0, 1);
                    break;
            }
        }

        var flag = 0; //标记位

        //蛇移动方向
        var gox, goy;
        function dir(x, y) {
            gox = x;
            goy = y;
            if (flag == 0) {
                speedUp(); //游戏开始,就开始提速
                flag = 1;
                move(); //蛇移动			
            }
        }

        //蛇移动,移动时必须判断蛇前面是什么,食物、墙、自己、空白
        function move() {
            sx += gox;
            sy += goy;


            if (sx < 0 || sy < 0 || sx >= rows || sy >= cols) {
                restartGame(); //越界
            } else {
                snakeFront = map[sx][sy]; //蛇的前方元素

                if (snakeFront == 0) {
                    moveToblank(); //蛇前面是空白
                }
                else if (snakeFront == "f") {
                    //食物
                    eatFood();
                }
                else {
                    restartGame(); //撞到自己
                }
            }
        }

        //蛇前面是空白时        
        function moveToblank() {
            map[parseInt(alldiv[0].getAttribute("x"))][parseInt(alldiv[0].getAttribute("y"))] = 0;
            //兼容IE和FF
            if (window.navigator.appName.indexOf("Microsoft Internet Explorer") > -1) {
                alldiv[0].removeNode(true);
            } else {
                alldiv[0].parentNode.removeChild(alldiv[0]);
            }
            createSnake();

            //自动走
            autoWalk();
        }

        //蛇前面是食物时
        function eatFood() {
            createSnake(); //创建一个新div,即蛇增长

            if (window.navigator.appName.indexOf("Microsoft Internet Explorer") > -1) {
                allspan[0].removeNode(true);
            } else {
                allspan[0].parentNode.removeChild(allspan[0]);
            }
            createFood(); //创建一个新食物

            autoWalk();
        }

        //自动走
        function autoWalk() {
            setTimeout("move()", times);
        }

        //蛇提速,每隔5秒提速一次
        function speedUp() {
            times -= 5;

            if (times > 5) {
                //不能减到0
                setTimeout("speedUp()", 5000);
            }
        }

        //重新开始游戏
        function restartGame() {
            if (confirm("GAME OVER,重新开始?")) {
                window.location.reload(); //重新加载一下
            }
        }

        //文档加载完成后创建地图
        window.onload = createMap;
    </script>
</head>
<body>
</body>
</html>