使用原生JS实现简单版的网页小游戏-贪吃蛇

今天给大家分享一个游戏,用我们所熟悉的JS实现一个贪吃蛇小游戏,自娱自乐一下

首先先整理一下思路:
点击开始游戏   startpage消失   游戏开始
随机出现食物,出现三节蛇开始运动
上下左右    改变方向运动
判断吃到食物   食物消失,蛇加一
判读游戏结束,弹出框

如下图中的一些效果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
接下我们用我们所熟悉的JS实现贪吃蛇小游戏
首先我们基本HTML页面:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>贪吃蛇</title>
    <link rel="stylesheet" href="css/demo.css">
</head>
<body>  
    <!-- 开始层 -->
    <div class="startpage" id="startPage">
        <div class="startBtn" id="startBtn">开始游戏</div>
    </div>
    <!-- 游戏层 -->
    <div class="wrapper">
        <!-- 开始按钮 -->
        <div class="left-side">
            <span id="startP">开始</span>
        </div>
        <div class="main">
            <div class="header">
                <div class="score">
                    分数:
                    <span id="score">0</span>
                </div>
            </div>
            <div class="content" id="content"></div>
        </div>
    </div>
    <!-- 游戏结束层 -->
    <div class="loser" id="lose">
        <div class="con">
            <span class="goal">当前得分</span>
            <div class="close" id="close">×</div>
            <span class="loserScore" id="loserScore"></span>
        </div>
    </div>
    <script src="js/demo.js"></script>
</body>
</html>

这里页面我们就不多说,相信大家都能看懂;
然后我们是好看的样式CSS:(这里我只是用了一些色块,大家可以用一些好看的图片)


*{
    margin: 0;
    padding: 0;
}

/* 开始层 */
.startPage{
    width: 100%;
    z-index: 999;
    height: 1000px;
    position: absolute;
    top: 0;
    left: 0;
    /* display: none; */
}

/* 开始按钮 */
.startBtn{
    width: 200px;
    height: 60px;
    z-index: 998;
    background-color: #008c8c;
    cursor: pointer;
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    margin: auto;
    text-align: center;
    line-height: 60px;
    color: #fff;
    font-size: 24px;
    border-radius: 5px;
}

/* 游戏层 */
.wrapper{
    width: 100%;
    height: 1000px;
    /* background-color: #fefefe; */
    position: relative;
}

/* 游戏左边区域 */
.left-side{
    width: 24%;
    position: absolute;
    height: 1000px;
    /* border-right: 1px solid #000;  */
}

/* 开始,暂停按钮 */
.left-side span{
    width: 100px;
    height: 100px;
    background-color: #008c8c;
    border-radius: 50%;
    text-align: center;
    line-height: 100px;
    color: #fff;
    margin-left: 100px;
    margin-top: 100px;
    display: none;
}

/* 游戏界面 */
.main {
    position: absolute;
    left: 25%;
    width: 50%;
    height: 90%;
    /* border:1px solid #000; */
}

/* 游戏界面顶部 */
.header{
    width: 100%;
    height: 80px;
    text-align: center;
}

/* 分数 */
.score{
    line-height: 80px;
    color: #999;
    font-size: 20px;
    font-weight: bolder;
}

/* 游戏区域 */
.content{
    position: absolute;
    width: 79.5%;
    height: 36.5%;
    left: 10%;
    top: 34%;
    /* border: 1px solid #f40; */
    background-color: #000;
}

/* 弹出层 */
.loser{
    display: none;
    position: 100%;
    height: 1000px;
    top: 0;
    left: 0;
}

/* 弹出框 */
.con{
    background-color: #008c8c;
    height: 300px;
    width: 400px;
    position: absolute;
    margin: auto;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    border-radius: 20px;
}

/* 弹出框说明 */
.con .goal{
    width: 400px;
    height: 50px;
    position: absolute;
    top: 10px;
    left: 0;
    text-align: center;
    line-height: 50px;
    font-size: 30px;
    color: #fff;
}

/* 游戏得分 */
.loserScore{
    display: block;
    height: 30px;
    width: 40px;
    position: absolute;
    top: 42%;
    left: 40%;
    color: #222;
    font-size: 30px;
    font-weight: bold;
}

/* 弹出框关闭按钮 */
.close{
    position: absolute;
    top: 0;
    right: 0;
    height: 40px;
    width: 40px;
    background-color: #999;
    border-radius: 50px;
    margin: 5px;
    text-align: center;
    line-height: 40px;
    font-size: 30px;
    color: #fff;
    cursor: pointer;
}

/* 食物 */
.food{
    background-color: #f40;
    border-radius: 50px;
}

/* 蛇的头部 */
.head{
    background-color: #f0f;
    border-radius: 50px;
}

/* 蛇的身体 */
.body{
    background-color: #ff0;
    border-radius: 50px;
}

接下来是我们最重要的JS部分
在这里补充一点:
如果大家使用的是VScode编辑器,大家可以装一个插件:Document This(添加注释块)

Document This
添加注释块  连续两次Ctrl+alt+d  出现如下注释
	/**
     * @class App
     * @extends {Component}
     */
注意如有热键冲突,记得将热键冲突关闭

//思路:
//点击开始游戏   startpage消失   游戏开始
//随机出现食物,出现三节蛇开始运动
//上下左右    改变方向运动
//判断吃到食物   食物消失,蛇加一
//判读游戏结束,弹出框

var content = document.getElementById('content')
var startPage = document.getElementById('startPage')
var scoreBox = document.getElementById('score')
var lose = document.getElementById('lose')
var loserScore = document.getElementById('loserScore')
var close = document.getElementById('close')
var startP = document.getElementById('startP')
var startBtn = document.getElementById("startBtn")
var snakeMove;
var speed = 200;
var startGameBool = true;
var startPaushBool = true;
init();

/**
 * 存放初始化的参数
 * 这里我们设置一个初始化函数,存放一些初始化的参数
 */
function init() {
    //地图
    this.mapW = parseInt(getComputedStyle(content).width);
    this.mapH = parseInt(getComputedStyle(content).height);
    this.mapDiv = content;

    //食物的坐标
    this.foodW = 20;
    this.foodH = 20;
    this.foodX = 0;
    this.foodY = 0;

    //蛇的坐标
    this.snakeW = 20;
    this.snakeH = 20;
    this.snakeBody = [[3, 1, 'head'], [2, 1, 'body'], [1, 1, 'body']];
    // this.snakeBody = [[4, 3, 'head'], [3,3, 'body'], [3, 2, 'body']];
    
    //游戏属性  上下左右
    this.direct = 'right';
    this.left = false;
    this.right = false;
    this.up = true;
    this.down = true;
    this.score = 0;
    bindEvent();
}

function startGame() {
    startPage.style.display = 'none'
    startP.style.display = 'block'
    food();
    snake();
}

/**
 * 随机生成食物
 * 在画布内随机位置生成一个食物(小圆点)
 */
function food() {
    var food = document.createElement('div');
    food.style.width = this.foodW + 'px';
    food.style.height = this.foodH + 'px';
    food.style.position = 'absolute';
    this.foodX = Math.floor(Math.random() * (this.mapW / 20));
    this.foodY = Math.floor(Math.random() * (this.mapH / 20));
    food.style.left = this.foodX * 20 + 'px';
    food.style.top = this.foodY * 20 + 'px';
    this.mapDiv.appendChild(food).setAttribute('class', 'food')
}

/**
 * 出现一条蛇
 */
function snake() {
    for (var i = 0; i < this.snakeBody.length; i++) {
        var snake = document.createElement('div');
        snake.style.width = this.snakeW + 'px';
        snake.style.height = this.snakeH + 'px';
        snake.style.position = 'absolute';
        snake.style.left = this.snakeBody[i][0] * 20 + 'px';
        snake.style.top = this.snakeBody[i][1] * 20 + 'px';
        snake.classList.add(this.snakeBody[i][2]);
        this.mapDiv.appendChild(snake).classList.add('snake');
        //判断蛇头自身的方向
        // 这里是判断用图片的情况下的,如果大家使用的也是色块,大家可以吧这一块去掉
        switch (this.direct) {
            case 'right':
                break;
            case 'up':
                snake.style.transform = 'rotate(270deg)'
                break;
            case 'left':
                snake.style.transform = 'rotate(180deg)'
                break;
            case 'down':
                snake.style.transform = 'rotate(90deg)'
                break;
            default:
                break;
        }
    }
}


/**
 * 默认运动轨迹
 */
function move() {
    for (var i = this.snakeBody.length - 1; i > 0; i--) {
        this.snakeBody[i][0] = this.snakeBody[i - 1][0];
        this.snakeBody[i][1] = this.snakeBody[i - 1][1];
    }
    // 假设已经运动,存放方向
    switch (this.direct) {
        case 'right':
            this.snakeBody[0][0] += 1;
            break;
        case 'up':
            this.snakeBody[0][1] -= 1;
            break;
        case 'left':
            this.snakeBody[0][0] -= 1;
            break;
        case 'down':
            this.snakeBody[0][1] += 1;
            break;
        default:
            break;
    }
    removeClass('snake');
    snake();
    if (this.snakeBody[0][0] == this.foodX && this.snakeBody[0][1] == this.foodY) {
        //吃到食物后自身数量加一
        var snakeEndX = this.snakeBody[this.snakeBody.length - 1][0];
        var snakeEndY = this.snakeBody[this.snakeBody.length - 1][1];
        switch (this.direct) {
            case 'right':
                this.snakeBody.push([snakeEndX + 1, snakeEndY, 'body']);
                break;
            case 'up':
                this.snakeBody.push([snakeEndX, snakeEndY - 1, 'body']);
                break;
            case 'left':
                this.snakeBody.push([snakeEndX - 1, snakeEndY, 'body']);
                break;
            case 'down':
                this.snakeBody.push([snakeEndX, snakeEndY + 1, 'body']);
                break;
            default:
                break;
        }
        //吃到食物
        this.score += 1;
        scoreBox.innerHTML = this.score;
        removeClass('food');
        food();
    }

    if (this.snakeBody[0][0] < 0 || this.snakeBody[0][0] >= this.mapW / 20) {
        // console.log(1)
        relodGame();
    }

    if (this.snakeBody[0][1] < 0 || this.snakeBody[0][1] >= this.mapH / 20) {
        // console.log(1)
        relodGame();
    }
    var snakeHX = this.snakeBody[0][0];
    var snakeHY = this.snakeBody[0][1];
    for (var i = 1; i < this.snakeBody.length; i++) {
        if (snakeHX == snakeBody[i][0] && snakeHY == snakeBody[i][1]) {
            // console.log(111)
            relodGame();
        }
    }
}

/**
 * 游戏结束,初始化游戏
 * 碰撞墙壁时,超出画布范围,重新开始游戏
 */
function relodGame() {
    removeClass('snake');
    removeClass('food');
    clearInterval(snakeMove);//清除定时器
    //默认坐标
    this.snakeBody = [[3, 1, 'head'], [2, 1, 'body'], [1, 1, 'body']];
    this.direct = 'right';
    this.left = false;
    this.right = false;
    this.up = true;
    this.down = true;
    lose.style.display = 'block';//弹出框
    loserScore.innerHTML = this.score;//弹出框内容更改
    this.score = 0;
    scoreBox.innerHTMl = this.score;//顶部分数
    //重新开始游戏
    startGameBool = true;
    startPaushBool = true;
    startP.innerHTML = '开始'
}


/**
 * 删除具有className 的元素
 * @param {*} className 
 */
function removeClass(className) {
    var ele = document.getElementsByClassName(className);
    while (ele.length > 0) {
        ele[0].parentNode.removeChild(ele[0]);
    }
}

/**
 * 判断上下左右方向
 * @param {*} code 
 */
function setDerict(code) {
    //判断游戏中,上下左右方向
    switch (code) {
        case 37:
            if (this.left) {
                this.direct = 'left';
                this.left = false;
                this.right = false;
                this.up = true;
                this.down = true;
            }
            break;
        case 38:
            if (this.up) {
                this.direct = 'up';
                this.left = true;
                this.right = true;
                this.up = false;
                this.down = false;
            }
            break;
        case 39:
            if (this.right) {
                this.direct = 'right';
                this.left = false;
                this.right = false;
                this.up = true;
                this.down = true;
            }
            break;
        case 40:
            if (this.down) {
                this.direct = 'down';
                this.left = true;
                this.right = true;
                this.up = false;
                this.down = false;
            }
            break;
        default:
            break;
    }
}

/**
 * 监听页面
 */
function bindEvent() {
    //弹出框关闭按钮u
    close.onclick = function () {
        lose.style.display = 'none'
    }
    //开始游戏按钮
    startBtn.onclick = function () {
        startAddPaush();
    }
    //暂停,开始按钮
    startP.onclick = function () {
        startAddPaush();
    }
}

/**
 * 执行游戏
 */
function startAddPaush() {
    if (startPaushBool) {
        if (startGameBool) {
            startGame();
            startGameBool = false;
        }
        startP.innerHTML = '暂停';
        document.onkeydown = function (e) {
            var code = e.keyCode;
            setDerict(code);
        }
        snakeMove = setInterval(function () {
            move()
        }, speed)
        startPaushBool = false;
    } else {
        startP.innerHTML = '开始';
        clearInterval(snakeMove);
        document.onkeydown = function (e) {
            e.returnValue = false;
            return false;
        }
        startPaushBool = true;
    }
}

这里给他们准备了一份源码,地址如下:
https://github.com/Janesuyue/Gluttonous-Snake

在本地下拉仓库即可;
clone https://github.com/Janesuyue/Gluttonous-Snake.git

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

竹苏

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值