贪吃蛇大作战


功能
y 企业版 会员 冒泡 博客 帮助
注册 登录
项目logoliganghui/ife-17  收藏 2   关注 0  Fork 0
存放参加ife-17的代码
HTTPS  
https://git.coding.net/liganghui/ife-17.git
代码 分支 标签 版本对比 Pull Request 项目网络 项目统计 讨论
 master
寻找文件  提交历史 ife-17 / retroSnaker /src / index.html
dbe0b71346   提交于 03-07 11:19 @liganghui liganghui 修复BUG
原始数据 按行查看 提交历史
 file  14.59 KB
<!DOCTYPE html>
<html>
    <head>
         <!--
         	作者:1104070959@qq.com
         	时间:2017-03-06
         	描述:基本完成了要求,游戏测试的不多,BUG蛮多的。。。
         	原理:利用表格创建出地图,更改th的背景色,画出蛇和食物等。使用setInterval每隔一段时间更改背景色的坐标位置,产生蛇的移动效果。
         -->
        <meta charset="UTF-8">
        <title>贪吃蛇大作战</title>
    <style>
        *{margin: 0; padding: 0;}
        .wrap{position:relative;height: 500px;width: 500px; font-family: "微软雅黑"; margin: 50px auto 0; }
        .wrap .mode p,.message p,.countdown p,.mask p{font-weight: bolder;text-align: center; padding-top: 110px;font-size: 28px; color: #99CCFF;}
        .message,.mode,.countdown,.paly,.mask{position: absolute; left: 0; top: 0; bottom: 0; right: 0;}
        .countdown,.mask{background:#333333; opacity: 0.3; }
        .wrap  button{ background:rgba(230,230,230,0.5);border: 0px; outline: none; display: block; margin: 20px auto;  cursor: pointer; width: 100px;height: 30px; line-height: 30px;}
        .scoreboard p{position: absolute;left: 20px;top: 10px; font-size: 12px;}
        .play table{border-collapse:collapse;}
        .play td{border: 1px  solid #CCCCCC;}
        .food{ border-radius: 50%; box-shadow: 1px 1px 1px 1px #DDDDDD;}
    </style>
    </head>
    <body>
        <div class="wrap" >
                <div class="scoreboard"   id="scoreboard"style="display: none;">
                <p>分数:<span id="score">500</span>  速度:<span id="speed">500</span>/格    <span id="level" style="display: none;">关卡:<em id="levelNum"></em></span></p>
            </div>
            <div class="mode" id="mode" style="display: block;	">
                <p>贪吃蛇大作战</p>
                <button>自由模式</button>
                <button>闯关模式</button>
                <button>挑战模式</button>
            </div>
            <div class="message" id="message"    style="display: none;">
                <p id="gameresult">游戏结束</p>
                <button id="returnMenu">返回主菜单</button>
                <button id="restart">重新开始</button>
                <button id="next" style="display: none;">下一关</button>
            </div>
            <div class="countdown"  id="countdown" style="display: none;">
                <p id="time">5</p>
            </div>
            <div id="mask" class="mask" style="display: none;"><p>游戏暂停<br />按空格继续</p></div>
            <div id="play" class="play"></div>
        <p>按键盘方向键开始游戏,空格暂停/继续<br /></p>
        </div>
        <audio   id="audio"   src="audio/7895.wav"  preload="auto"   loop="loop" >您的浏览器不支持 audio 标签。</audio>
<script>
    var gridQuantity = 24;//游戏区域中最大网格数
     speed = 150, //蛇的移动速度
     gWidth = 20, //网格的宽度
    gHeight = 20, //网格的高度
    currentKeyValue = 0, //记录当前的移动方向
    moveTimerID = null, //记录移动计时器的ID
    speedTimerID = null, //记录速度计时器的ID
    gamePause = false, //游戏暂停
    snakeBody = [], //存放蛇身的单元格坐标的X_Y数组
    food = [], //存放食物的单元格坐标x_y
    Obstacle = [], //存放所有障碍的单元格x_y坐标数组
    foodStation = null, //存放食物的单元格坐标x_y
    level = 1, //关卡数
    score = 0, //分数
    type = null, //游戏模式(1代表闯关模式,2代表挑战模式)
    currentKeyValue = null; //移动方向
/*************扩展方法*************/
function $(x) {
    return document.getElementById(x);
}
//移出数组指定元素
Array.prototype.removeByValue = function(val) {
    for(var i = 0; i < this.length; i++) {
        if(this[i] == val) {
            this.splice(i, 1);
            break;
        }
    }
}
//游戏初始化
function init() {
    btnBind();
    drawMap();
}
//绘制表格地图
function drawMap() {
    //绘制表格
    var gameTable = "<table frame='vsides'    border='0'  > ";
    for(var i = 0; i < gridQuantity; i++) {
        gameTable += "<tr align ='center'>";
        for(var j = 0; j < gridQuantity; j++) {
            gameTable += '<td id="' + i + '_' + j + '"';
            gameTable += 'width="' + gWidth + '"height="' + gHeight + '"><div id="' + i + '_' + j + '_div" style="width:' + gWidth + 'px;height:' + gHeight + 'px;"></div></td>';
        }
        gameTable += '</tr>';
    }
    gameTable += '</table>';
    $("play").innerHTML = gameTable;
}
/*生成食物
 *  @param  Number   食物的数量
 * */
function initFood(num) {
    var i = 1;
    if(num > 0) {
        var x = parseInt(Math.random() * gridQuantity);
        var y = parseInt(Math.random() * gridQuantity);
        foodStation = x + "_" + y + "_div";
        food.push(x + "_" + y + "_div");
        snakeStation = x + "_" + y;
        //获取该位置的背景色
        backgroundColor = $(foodStation).style.background;
        snakeBgcolor = $(snakeStation).style.background;
        if(backgroundColor == "" && snakeBgcolor == "") { //如果该位置为空,则为该单元格添加颜色
            $(foodStation).style.background = "rgb(" + Math.floor(Math.random() * 254) + "," + Math.floor(Math.random() * 254) + "," + Math.floor(Math.random() * 254) + ")"; //将食物单元格背景定义为绿色
            $(foodStation).className = "food";
            num--;
            initFood(num);
        } else {
            initFood(num);
        }
    } else {
        return;
    }
}
/*初始化蛇的坐标
 *  @param  Number   蛇身的长度
 * */
function initSnake(len) {
    if(len > 0) {
        var x = parseInt(Math.random() * gridQuantity);
        var y = parseInt(Math.random() * gridQuantity);
        nowHeadStation = 0 + "_" + len; //将蛇初始化在左上角
        snakeBody.push(nowHeadStation); //向数组的首位添加蛇头
        $(nowHeadStation).style.background = "rgb(" + Math.floor(Math.random() * 254) + "," + Math.floor(Math.random() * 254) + "," + Math.floor(Math.random() * 254) + ")"; //将该单元格涂色
        len--
        initSnake(len)
    } else {
        return;
    }
}
/*  生成障碍
 *  @param  Number  障碍的数量
 */
function initObstacle(len) {
    if(len > 0) {
        var x = parseInt(Math.random() * gridQuantity);
        var y = parseInt(Math.random() * gridQuantity);
        Obstacle.push(x + "_" + y);
        if($(x + "_" + y).style.background == "") {
            $(x + "_" + y).style.background = "rgb(0,0,0)";
            len--;
            initObstacle(len);
        } else {
            initObstacle(len)
        }
    } else {
        return;
    }
}
function btnBind() {
    var btns = document.querySelectorAll(".mode button");
    /*************自由模式***********/
    btns[0].addEventListener("click", function() {
        $("mode").style.display = "none"; //主菜单隐藏
        $("countdown").style.display = "block"; //显示倒计时
        initSnake(5); //生成蛇
        initFood(10); //生成食物
        runCount("time", 5, function() { //倒计时
            $("countdown").style.display = "none"; //倒计时结束,遮罩隐藏
            $("audio").play(); //背景音乐响起来
            $("scoreboard").style.display = "block"; //信息栏 显示
            $("speed").innerText = speed; //显示速度
            $("score").innerText = 0; //显示分数
            document.onkeydown = function(e) {
                KeyDown(e); //绑定事件监听
            };
            //每隔一段时间  增加速度
            speedTimerID = setInterval(function() {
                if(speed > 10) {
                    speed -= 10;
                    $("speed").innerText = speed;
                } else {
                    window.clearInterval(speedTimerID)
                }
            }, 10000);
        });
    });
    /***************关卡模式**********/
    btns[1].addEventListener("click", function() {
        type = 1;
        $("mode").style.display = "none";
        $("countdown").style.display = "block";
        initSnake(5);
        initFood(10);
        runCount("time", 5, function() {
            $("countdown").style.display = "none";
            $("audio").play();
            $("scoreboard").style.display = "block";
            $("speed").innerText = speed;
            $("score").innerText = 0;
            document.onkeydown = function(e) {
                KeyDown(e);
            };
            $("level").style.display = "block";
            $("levelNum").innerText = level;
        });
    });
    /***************挑战模式**********/
    btns[2].addEventListener("click", function() {
        type = 2;
        $("mode").style.display = "none";
        $("countdown").style.display = "block";
        initSnake(5);
        initObstacle(5 * level);
        initFood(10);
        runCount("time", 5, function() {
            $("countdown").style.display = "none";
            $("audio").play();
            $("scoreboard").style.display = "block";
            speed = 150;
            $("speed").innerText = speed;
            $("score").innerText = 0;
            document.onkeydown = function(e) {
                KeyDown(e);
            };
            speedTimerID = setInterval(function() {
                if(speed > 10) {
                    speed -= 5;
                    $("speed").innerText = speed;
                } else {
                    window.clearInterval(speedTimerID)
                }
            }, 5000);
            $("level").style.display = "block";
            $("levelNum").innerText = level;
        });
    });
    //返回主菜单
    $("returnMenu").addEventListener("click", function(e) {
        $("mode").style.display = "block";
        $("message").style.display = "none";
        $("scoreboard").style.display="none";
        type = 0;
        drawMap();
    });
    //重新开始游戏
    $("restart").addEventListener("click", function() {
        $("message").style.display = "none";
        drawMap();
        initSnake(5);
        initFood(10);
        score=0;
        if(type == 1) {
            speed=150-level*10;
        }else{
            initObstacle(5 * level);
        }
        $("countdown").style.display = "block";
        $("score").innerText = score;
        $("speed").innerText = speed;
        runCount("time", 5, function() {
            $("countdown").style.display = "none";
            $("audio").play();
            document.onkeydown = function(e) {
                KeyDown(e);
            };
        });
    })
    //进入下一关
    $("next").addEventListener("click", function() {
        $("message").style.display = "none";
        drawMap();
        initSnake(5);
        level += 1;
        score = 0;
        $("audio").play();
        if(type == 1) {
            speed -=(level-1)*10;
            $("speed").innerText = speed;
        } else if(type == 2){
            speed =150;
            initObstacle(5 * level);
            $("speed").innerText = speed;
            speedTimerID = setInterval(function() {
                if(speed > 10) {
                    speed -= 10;
                    $("speed").innerText = speed;
                } else {
                    window.clearInterval(speedTimerID)
                }
            }, 4000);
        }
        initFood(10);
        $("level").style.display = "block";
        $("score").innerText = score;
        $("levelNum").innerText = level;
        document.onkeydown = function(e) {
            KeyDown(e);
        };
    });
}
/*  倒计时
 * 	@param   Number   设置倒计时的初始值
 * 	@param   Element   用于显示倒计时的元素
 * 	@callback  Function  倒计时结束时的回调函数
 */
function runCount(ele, t, fn) {
    if(t > 0) {
        document.getElementById(ele).innerText = t;
        t--;
        setTimeout(function() { runCount(ele, t, fn); }, 1000);
    } else {
        fn();
    }
}
function KeyDown(e) { //接受按键
    switch(e.keyCode) {
        case 37: //左
        case 38: //上
        case 39: //右
        case 40: //下
            if((e.keyCode != (currentKeyValue + 2)) && (e.keyCode != (currentKeyValue - 2))) {
                currentKeyValue = e.keyCode;
            }
            break;
        case 32:
            gamePause = !gamePause;
            break;
        default:
            return;
    }
    if(gamePause) { //如果暂停
        $("mask").style.display = "block";
        window.clearInterval(moveTimerID); //就关闭计时器
        moveTimerID = null;
    } else {
        $("mask").style.display = "none";
        window.clearInterval(moveTimerID) //否则打开计时器
        moveTimerID = window.setInterval("snakeMove()", speed);
    }
}
/*
 * 蛇移动处理
 */
function snakeMove() {
    var _x, _y;
    switch(currentKeyValue) {
        //根据用户按键,确定蛇移动的下一个坐标
        case 37: //左
            _x = coordinate("x");
            _y = coordinate("y") - 1;
            break;
        case 39: //右
            _x = coordinate("x");
            _y = coordinate("y") + 1;
            break;
        case 38: //上
            _x = coordinate("x") - 1;
            _y = coordinate("y");
            break;
        case 40: //下
            _x = coordinate("x") + 1;
            _y = coordinate("y");
            break;
    }
    collisionDetection(_x, _y);
}
/*
 * 碰撞检测
 * 
 * @param  Number   用于检测的X轴坐标
 * @param  Number   用于检测的Y轴坐标
 * 
 */
function collisionDetection(x, y) {
    //判断是否撞墙
    if((x < 0 || y < 0) || (x >= gridQuantity || y >= gridQuantity)) {
        EndState("游戏结束<br/>你撞墙了");
    } else if(rearEnd(x, y)) { //咬到自己	
        EndState("游戏结束<br/>你居然连自己都吃");
    } else if(type == 2 && detectionObstacle(x, y)) {
        EndState("游戏结束<br>你撞到了障碍");
    } else if(eatFood(x, y)) { //咬到食物
        VictoryDetection(); //检测是否过关
        initFood(1); //重新产生一个食物
        food.removeByValue(x + "_" + y + "_div"); //移出食物数组中的该项
    } else {
        //如果什么都没撞到,则通过不断改变背景色的位置,产生移动效果
        snakeBody.unshift(x + "_" + y);
        for(var i = 0; i < snakeBody.length - 1; i++) { //交替更改背景色
            $(snakeBody[i]).style.background = $(snakeBody[i + 1]).style.background;
        }
        $(snakeBody.pop()).style.background = ""; //擦出末尾的元素
    }
}
/*
 * 获取蛇头的X坐标值或Y坐标值
 */
function coordinate(i) {
    switch(i) {
        case "x": //返回蛇头单元格的X坐标值
            return parseInt($(snakeBody[0]).id.split("_")[0]);
        case "y": //返回蛇头单元格的Y坐标值
            return parseInt($(snakeBody[0]).id.split("_")[1]);
    }
}
init();
/*
 *   检测是否吃到食物
 *  *  @param  Number  需要检测的X坐标
 *  @param  Number  需要检测的Y坐标
 */
function eatFood(x, y) {
    for(var i = 0; i < food.length; i++) { //遍历食物数组
        if(food[i].split("_")[0] == x && food[i].split("_")[1] == y) {
            snakeBody.unshift(food[i].split("_")[0] + "_" + food[i].split("_")[1]); //将食物插入到蛇身数组的首位
            $(food[i].split("_")[0] + "_" + food[i].split("_")[1] + "_div").style.display = "none"; //隐藏食物
            $(snakeBody[0]).style.background = $(food[i].split("_")[0] + "_" + food[i].split("_")[1] + "_div").style.background; //蛇头的颜色等于食物的颜色
            score += 100;
            $("score").innerText = score;
            return true;
        }
    }
}
/*  
 *   检测是否撞到障碍物
 *  @param  Number  需要检测的X坐标
 *  @param  Number  需要检测的Y坐标
 * 
 */
function detectionObstacle(x, y) {
    for(var i = 0; i < Obstacle.length; i++) { //遍历障碍数组
        if(Obstacle[i].split("_")[0] == x && Obstacle[i].split("_")[1] == y) {
            return true;
        }
    }
}
/*
 *   检测是否咬到蛇身
 *  *  @param  Number  需要检测的X坐标
 *  @param  Number  需要检测的Y坐标
 */
function rearEnd(x, y) {
    var t = x + "_" + y;
    for(var i = 0; i < snakeBody.length; i++) {
        if(t == snakeBody[i]) {
            return true;
        }
    }
    return false;
}
/*
 * 判断是否满足胜利
 */
function VictoryDetection() {
    if(snakeBody.length == gridQuantity * gridQuantity - 2) {
        EndState("胜利");
        } else if((type == 1 || type == 2) && snakeBody.length == 15) {
            EndState("恭喜你,过关啦!");
            $("next").style.display = "block";
        }
    }
    /*  显示游戏结果
     *   @param    string      需要显示的结果信息
     */
    function EndState(str) {
        $("gameresult").innerHTML = str
        //重置内容
        $("next").style.display = "none";
        $("message").style.display = "block";
        window.clearInterval(moveTimerID); //停止计时
        window.clearInterval(speedTimerID);
        currentKeyValue = 0; //当前方向键设置为0;
        snakeBody = [];
        food = [];
        speed = 150;
        Obstacle = [];
        document.onkeydown = "";
        $("audio").pause();
    }
</script>
</body>
</html>
 

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值