js简单实现贪吃蛇

贪吃蛇js实现

先把整体的框架画出来

css代码

 /* 框体样式 */
        html,body{
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
​
        #Frame{
            top:50%;
            left:50%;
            width: 600px;
            height: 600px;
            background: white;
            margin-top:-300px;
            margin-left:-300px;
            position: absolute;
            text-align: center;
            border: aqua solid 1px;
        }
​
        #DisplayTab{
            background-color: #cfcfcf;
            float: left;
            width: 500px;
            margin: -1px;
            height: 600px;
            border: #00FFFF 1px solid;
        }
​
        #DisplaySelect{
            float: left;
            margin: -1px;
            width: 100px;
            height: 600px;
            border-left: lightgrey solid 1px;
            background-color: #aaffff;
        }
​
        .SnakeUnit{
            float: left;
            border-radius: 5px;
            margin: 0;
            padding: 0;
            background-color: #cfcfcf;
        }
​
        .btn {
            display: inline-block;
            font-weight: 400;
            text-align: center;
            vertical-align: middle;
            cursor: pointer;
            background-image: none;
            padding: 6px 12px;
            font-size: 14px;
            line-height: 1.42857143;
            border-radius: 4px;
            user-select: none;
            background-color: #424F63;
            border-color: #374152;
            color: #FFFFFF;
            margin: 20px;
​
        }

为了美观,可以加张好看的背景图

html代码

<body style="background-image: url(images/贪吃蛇P2.jfif);background-size: cover;">
<!-- 界面 -->
<div id="Frame" >
    <!-- 操作台 -->
    <div id="DisplayTab">
​
    </div>
    <!-- 操作选项 -->
    <div id="DisplaySelect">
        <p>分数:</p>
        <span id="grade"></span>
        <br>
        <button class="btn" id="reopen">重开</button>
        <button class="btn" id="stop">暂停</button>
        <button class="btn" id="continue">继续</button>
        <a href="index.html"><button class="btn">首页</button></a>
    </div>
</div>

具体实现

先给出所有的全局变量

 //全局变量
​
    var Unit_Row = 60;//行数
    var Unit_list = 50;//列数
    var UnitNumber = Unit_Row*Unit_list;//总单元数
    var grade = 0;//分数
​
    var vector = 1;//记录小蛇移动方向【1】左【2】上【3】下【4】右
    var speed = 120;//记录速度设置,单位毫秒
​
    var Bean = new Array(5);
    var Head_Loca = 0;//记录小蛇的头部位置
    var Snake_path = new Array();//记录小蛇身体位置
    var Snake_Add = 0;//是否允许小蛇增加
​
    var displaytab = document.getElementById("DisplayTab");
    var thread = null;//记录线程id
    var UnitList = new Array(UnitNumber); //单元列表

要实现小蛇移动吃食物,可以自己勾勒出像素,就是很多个div,可以用js代码实现,画出单元格。(单元格的样式css实现就行了,这里只需要加上类名。)

//画出单元格
    for(let i = 0; i < UnitNumber; i++){
        var unit = document.createElement("div");
        unit.className = "SnakeUnit";
        unit.style.width = 500/Unit_list + "px";
        unit.style.height = 600/Unit_Row + "px";
        displaytab.appendChild(unit);
    }

每个单元格都要存储信息,是否为食物,是小蛇身体还是头部。。。

//单元信息存储
    function unitmessage(food,Type) {
        this.food = food;//是否属于食物
        this.Type = Type;//【0】不属于【1】头部【2】身体
​
    }
​
​
    for (let i=0;i<UnitNumber;i++) {
        UnitList[i] = new unitmessage(false,0);
    }

要想开始游戏就要有游戏帧(控制按键)和渲染帧(控制画面)。

//游戏帧
    function Game_Refresh(){
        switch(vector){
            case 1 :
                console.log("←");
                if(Head_Loca%Unit_list === 0){
                    Head_Loca += (Unit_list-1);
                }else{
                    Head_Loca -= 1;
                }
                break;
            case 2 :
                console.log("→");
                if((Head_Loca-(Unit_list-1))%Unit_list === 0){
                    Head_Loca -= (Unit_list-1);
                }else{
                    Head_Loca += 1;
                }
                break;
            case 3 :
                console.log("↑");
                if(Unit_list/Head_Loca > 1){
                    Head_Loca += Unit_list*(Unit_Row-1);
                }else{
                    Head_Loca -= Unit_list;
                }
                break;
            case 4 :
                console.log("↓");
                if (Head_Loca/Unit_list>=(Unit_Row-1)) {
                    Head_Loca -= Unit_list*(Unit_Row-1);
                } else{
                    Head_Loca += Unit_list;
                }
                break;
            default :
                console.log("无效输入");
                return;
        }
​
        //游戏失败
        if(Snake_path.indexOf(Head_Loca)!==-1){
            alert("游戏失败");
            remake();
        }
​
        for(let i = 0; i < Bean.length; i++){
            if(Head_Loca === Bean[i]){//吃到豆子,体型增长
                Snake_Add += 1;
                grade += 1; //记录分数
                speed -= 2; //速度加快
                UnitList[Head_Loca].food = false;
​
                Bean[i] = Math.floor(Math.random()*UnitNumber);
                while(Snake_path.indexOf(Bean[i])!==-1){
                    Bean[i] = Math.floor(Math.random()*UnitNumber);
                }
                //放置豆子
                UnitList[Bean[i]].food = true;
​
            }
        }
​
        // console.log("当前 :" + Snake_path + "head" + Head_Loca);
        //往最后面加一个元素(增加头部元素)
        Snake_path.push(Head_Loca);
        // console.log("当前 :" + Snake_path + "head" + Head_Loca);
        // 初始化身体属性
        for(let loca of Snake_path){
            UnitList[loca].Type = 2;
        }
​
        if(Snake_Add === 0){
            //删除尾部元素
            let Delet = Snake_path.shift();
            UnitList[Delet].Type = 0;
        }else{
            Snake_Add--;
        }
        UnitList[Head_Loca].Type = 1;
    }
​
    //渲染帧
    function Draw_Refresh(){
        //获取所有单元
        let DisplayUnit = document.querySelectorAll(".SnakeUnit");
​
        for (let i=0;i<UnitNumber;i++) {
​
            if(UnitList[i].Type === 2){
                DisplayUnit[i].style.backgroundColor = "green";
            }else if(UnitList[i].Type === 1){
                DisplayUnit[i].style.backgroundColor = "red";
            }else if(UnitList[i].food){
                DisplayUnit[i].style.backgroundColor = "yellow";
            }else{
                DisplayUnit[i].style.backgroundColor = "#cfcfcf";
            }
​
        }
    }
​
    document.onkeydown = function(event){
        var event = event || window.event;
        //键盘输入
        switch(event.keyCode){
            case 37 :
                console.log("←");
                if(vector!==2){
                    vector = 1;
                }
                break;
            case 39 :
                console.log("→");
                if(vector!==1){
                    vector = 2;
                }
                break;
            case 38 :
                console.log("↑");
                if(vector!==4){
                    vector = 3;
                }
                break;
            case 40 :
                console.log("↓");
                if(vector!==3){
                    vector = 4;
                }
                break;
            default :
                console.log("无效输入");
                return;
        }
    }

要有蛇的食物,必然不能少了食物生成函数。

//豆子产生
    function RankBean(){
        for(let i = 0; i < Bean.length; i++){
            Bean[i] = Math.floor(Math.random()*UnitNumber);
            while(Snake_path.indexOf(Bean[i])!==-1){
                Bean[i] = Math.floor(Math.random()*UnitNumber);
            }
            //放置豆子
            UnitList[Bean[i]].food = true;
​
        }
    }

最后就是游戏的重置函数了,蛇的循环移动和速度可以用定时器解决。

//游戏重置函数
    function remake(){
        window.clearInterval(thread);
​
        //初始化界面信息
        vector = 1;
        grade = 0;
        Head_Loca = 0;
        Snake_Add = 0;
        Snake_path = new Array();
        UnitList = new Array(UnitNumber);
        for (let i=0;i<UnitNumber;i++) {
            UnitList[i] = new unitmessage(false,0);
        }
​
        //设置初始位置并保存
        UnitList[0].Type = 1;
        UnitList[1].Type = 2;
        UnitList[2].Type = 2;
        UnitList[3].Type = 2;
        UnitList[4].Type = 2;
        Snake_path.push(4,3,2,1,0);
        RankBean();
        Draw_Refresh();
​
        // 启动线程
        beginThread();
​
    }
​
    function beginThread(){
        thread = setInterval(function(){
            Game_Refresh();
            var element = document.getElementById("grade");
            element.innerHTML = grade;
            Draw_Refresh();
        },speed);
    }

在文章结尾,附上贪吃蛇的源代码(背景图可以自己换)

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
​
    <title></title>
    <style>
        /* 框体样式 */
        html,body{
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
        }
​
        #Frame{
            top:50%;
            left:50%;
            width: 600px;
            height: 600px;
            background: white;
            margin-top:-300px;
            margin-left:-300px;
            position: absolute;
            text-align: center;
            border: aqua solid 1px;
        }
​
        #DisplayTab{
            background-color: #cfcfcf;
            float: left;
            width: 500px;
            margin: -1px;
            height: 600px;
            border: #00FFFF 1px solid;
        }
​
        #DisplaySelect{
            float: left;
            margin: -1px;
            width: 100px;
            height: 600px;
            border-left: lightgrey solid 1px;
            background-color: #aaffff;
        }
​
        .SnakeUnit{
            float: left;
            border-radius: 5px;
            margin: 0;
            padding: 0;
            background-color: #cfcfcf;
        }
​
        .btn {
            display: inline-block;
            font-weight: 400;
            text-align: center;
            vertical-align: middle;
            cursor: pointer;
            background-image: none;
            padding: 6px 12px;
            font-size: 14px;
            line-height: 1.42857143;
            border-radius: 4px;
            user-select: none;
            background-color: #424F63;
            border-color: #374152;
            color: #FFFFFF;
            margin: 20px;
​
        }
​
    </style>
</head>
<body style="background-image: url(images/贪吃蛇P2.jfif);background-size: cover;">
<!-- 界面 -->
<div id="Frame" >
    <!-- 操作台 -->
    <div id="DisplayTab">
​
    </div>
    <!-- 操作选项 -->
    <div id="DisplaySelect">
        <p>分数:</p>
        <span id="grade"></span>
        <br>
        <button class="btn" id="reopen">重开</button>
        <button class="btn" id="stop">暂停</button>
        <button class="btn" id="continue">继续</button>
        <a href="index.html"><button class="btn">首页</button></a>
    </div>
</div>
</body>
​
<script type="text/javascript">
    //全局变量
​
    var Unit_Row = 60;//行数
    var Unit_list = 50;//列数
    var UnitNumber = Unit_Row*Unit_list;//总单元数
    var grade = 0;//分数
​
    var vector = 1;//记录小蛇移动方向【1】左【2】上【3】下【4】右
    var speed = 120;//记录速度设置,单位毫秒
​
    var Bean = new Array(5);
    var Head_Loca = 0;//记录小蛇的头部位置
    var Snake_path = new Array();//记录小蛇身体位置
    var Snake_Add = 0;//是否允许小蛇增加
​
    var displaytab = document.getElementById("DisplayTab");
    var thread = null;//记录线程id
    var UnitList = new Array(UnitNumber); //单元列表
​
    //画出单元格
    for(let i = 0; i < UnitNumber; i++){
        var unit = document.createElement("div");
        unit.className = "SnakeUnit";
        unit.style.width = 500/Unit_list + "px";
        unit.style.height = 600/Unit_Row + "px";
        displaytab.appendChild(unit);
    }
​
    //单元信息存储
    function unitmessage(food,Type) {
        this.food = food;//是否属于食物
        this.Type = Type;//【0】不属于【1】头部【2】身体
​
    }
​
​
    for (let i=0;i<UnitNumber;i++) {
        UnitList[i] = new unitmessage(false,0);
    }
​
    // 使用重置函数初始化游戏
    remake();
​
    //游戏帧
    function Game_Refresh(){
        switch(vector){
            case 1 :
                console.log("←");
                if(Head_Loca%Unit_list === 0){
                    Head_Loca += (Unit_list-1);
                }else{
                    Head_Loca -= 1;
                }
                break;
            case 2 :
                console.log("→");
                if((Head_Loca-(Unit_list-1))%Unit_list === 0){
                    Head_Loca -= (Unit_list-1);
                }else{
                    Head_Loca += 1;
                }
                break;
            case 3 :
                console.log("↑");
                if(Unit_list/Head_Loca > 1){
                    Head_Loca += Unit_list*(Unit_Row-1);
                }else{
                    Head_Loca -= Unit_list;
                }
                break;
            case 4 :
                console.log("↓");
                if (Head_Loca/Unit_list>=(Unit_Row-1)) {
                    Head_Loca -= Unit_list*(Unit_Row-1);
                } else{
                    Head_Loca += Unit_list;
                }
                break;
            default :
                console.log("无效输入");
                return;
        }
​
        //游戏失败
        if(Snake_path.indexOf(Head_Loca)!==-1){
            alert("游戏失败");
            remake();
        }
​
        for(let i = 0; i < Bean.length; i++){
            if(Head_Loca === Bean[i]){//吃到豆子,体型增长
                Snake_Add += 1;
                grade += 1; //记录分数
                speed -= 2; //速度加快
                UnitList[Head_Loca].food = false;
​
                Bean[i] = Math.floor(Math.random()*UnitNumber);
                while(Snake_path.indexOf(Bean[i])!==-1){
                    Bean[i] = Math.floor(Math.random()*UnitNumber);
                }
                //放置豆子
                UnitList[Bean[i]].food = true;
​
            }
        }
​
        // console.log("当前 :" + Snake_path + "head" + Head_Loca);
        //往最后面加一个元素(增加头部元素)
        Snake_path.push(Head_Loca);
        // console.log("当前 :" + Snake_path + "head" + Head_Loca);
        // 初始化身体属性
        for(let loca of Snake_path){
            UnitList[loca].Type = 2;
        }
​
        if(Snake_Add === 0){
            //删除尾部元素
            let Delet = Snake_path.shift();
            UnitList[Delet].Type = 0;
        }else{
            Snake_Add--;
        }
        UnitList[Head_Loca].Type = 1;
    }
​
    //渲染帧
    function Draw_Refresh(){
        //获取所有单元
        let DisplayUnit = document.querySelectorAll(".SnakeUnit");
​
        for (let i=0;i<UnitNumber;i++) {
​
            if(UnitList[i].Type === 2){
                DisplayUnit[i].style.backgroundColor = "green";
            }else if(UnitList[i].Type === 1){
                DisplayUnit[i].style.backgroundColor = "red";
            }else if(UnitList[i].food){
                DisplayUnit[i].style.backgroundColor = "yellow";
            }else{
                DisplayUnit[i].style.backgroundColor = "#cfcfcf";
            }
​
        }
    }
​
    document.onkeydown = function(event){
        var event = event || window.event;
        //键盘输入
        switch(event.keyCode){
            case 37 :
                console.log("←");
                if(vector!==2){
                    vector = 1;
                }
                break;
            case 39 :
                console.log("→");
                if(vector!==1){
                    vector = 2;
                }
                break;
            case 38 :
                console.log("↑");
                if(vector!==4){
                    vector = 3;
                }
                break;
            case 40 :
                console.log("↓");
                if(vector!==3){
                    vector = 4;
                }
                break;
            default :
                console.log("无效输入");
                return;
        }
    }
​
    //豆子产生
    function RankBean(){
        for(let i = 0; i < Bean.length; i++){
            Bean[i] = Math.floor(Math.random()*UnitNumber);
            while(Snake_path.indexOf(Bean[i])!==-1){
                Bean[i] = Math.floor(Math.random()*UnitNumber);
            }
            //放置豆子
            UnitList[Bean[i]].food = true;
​
        }
    }
​
    //游戏重置函数
    function remake(){
        window.clearInterval(thread);
​
        //初始化界面信息
        vector = 1;
        grade = 0;
        Head_Loca = 0;
        Snake_Add = 0;
        Snake_path = new Array();
        UnitList = new Array(UnitNumber);
        for (let i=0;i<UnitNumber;i++) {
            UnitList[i] = new unitmessage(false,0);
        }
​
        //设置初始位置并保存
        UnitList[0].Type = 1;
        UnitList[1].Type = 2;
        UnitList[2].Type = 2;
        UnitList[3].Type = 2;
        UnitList[4].Type = 2;
        Snake_path.push(4,3,2,1,0);
        RankBean();
        Draw_Refresh();
​
        // 启动线程
        beginThread();
​
    }
​
    function beginThread(){
        thread = setInterval(function(){
            Game_Refresh();
            var element = document.getElementById("grade");
            element.innerHTML = grade;
            Draw_Refresh();
        },speed);
    }
​
    var stopBtn = document.getElementById("stop");
    var continueBtn = document.getElementById("continue");
    var reopenBtn = document.getElementById("reopen");
    stopBtn.onclick = function(){
        clearInterval(thread);
    }
​
    continueBtn.onclick = function(){
        beginThread();
    }
​
    reopenBtn.onclick = function () {
        remake();
    }
​
</script>
</html>
​
​

配图

 

如果有想了解具体实现的,或有不清楚明白的,可以留下评论。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值