网页版贪吃蛇及源码

Posted MaNqo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了网页版贪吃蛇及源码相关的知识,希望对你有一定的参考价值。

之前就感觉这个网页版贪吃蛇挺有趣的,终于有时间做它啦!

效果图

由于CSDN上传图片大小的限制,截取了一小部分效果图。
在这里插入图片描述

实现思路

这个demo是通过面向对象编程实现的,首先先搭建html和css的基础架构,如下图所示。

  • 开始游戏页面
    给蛇头,蛇身,食物分别添加不同的类名(将图片都放在css对应的background-image属性里面)
// 开始按钮
.startBtn button {
    width: 180px;
    height: 60px;
    border-radius: 10px;
    font-size: 30px;
    letter-spacing: 4px;
    color: #fff;
    background-color: rgb(203, 80, 81);
    margin-left: -90px;
    margin-top: -30px;
}
// 暂停按钮
.pauseBtn button {
    opacity: 0.6;
    width: 70px;
    height: 70px;
    border-radius: 50%;

    background-image: url(../img/start.jpg);  // 这是暂停按钮
    margin-left: -35px;
    margin-top: -35px;
}
// 蛇头和蛇身
.snakeHead {
    background-image: url(../img/.png);
    background-size: cover;
}
.snakeBody {
    background-color: rgb(61, 110, 53);
    border-radius: 50%;
}

在这里插入图片描述

  • 暂停游戏页面

在这里插入图片描述
接下来就进入正题啦!

  • 先对蛇这个对象进行处理
  1. 首先,这可以看作是一个600x600的容器,每个小方格为20x20,一共有30x30个小方格
  2. 当蛇头移到下一个方格的时候,要在这里创建新的方格,而蛇尾的方格要进行删除。
  3. 对蛇这个对象进行初始化,初始时让蛇头向右移动
  4. 在开始游戏之后获取蛇头下一个位置对应的元素
Square.prototype.create = function () {
    // 创建方块
    this.viewContent.style.position = 'absolute';
    this.viewContent.style.width = squareWidth + 'px';
    this.viewContent.style.height = squareHeight + 'px';
    this.viewContent.style.left = this.x + 'px';
    this.viewContent.style.top = this.y + 'px';

    this.parent.appendChild(this.viewContent);
};

Square.prototype.remove = function () {
    this.parent.removeChild(this.viewContent);
};
  • 初始时,有一个蛇头和2个小方块蛇身,这里蛇身和蛇头形成了链表关系。
    相当于:
    body2 -> body1 -> head
    snakeHead.last = null;
    snakeHead.next = snakeBody1;

    snakeBody1.last = snakeHead;
    snakeBody1.next = snakeBody2;

    snakeBody2.last = snakeBody1;
    snakeBody2.next = null;
  • 再创建食物这个对象,当蛇头的位置和食物的位置相同时,不删除最后一个元素。
function createFood() {
    // (x, y)食物的随机坐标
    var x = null;
    var y = null;
    
    x = Math.round(Math.random() * (td - 1));  // Math.random()是0-1的随机数
    y = Math.round(Math.random() * (tr - 1));

    food = new Square(x, y, 'food');
    food.pos = [x, y];  // 存储生成食物的坐标

    var foodDom = document.querySelector('.food');
    if (foodDom) {
        // 当蛇头经过食物,此时的食物的位置替代了蛇头的位置
        foodDom.style.left = x * squareWidth + 'px';
        foodDom.style.top = y * squareHeight + 'px';
    } else {
        food.create();  // 初始时创建食物
    }

}
  • 最后创建一个game这个对象,开始设定游戏规则
  1. 初始化游戏(按下键盘位置控制蛇的运动方向)
  2. 按下开始游戏按钮时开始
  3. 点击界面暂停游戏
  4. 当蛇撞墙的时候游戏结束
// 37左 38上 39右 40下
    document.onkeydown = function (e) {
        if (e.which == 37 && snake.direction != snake.directionNum.right) {  // 往右走的是否不能按左键
            snake.direction = snake.directionNum.left;
        } else if (e.which == 38 && snake.direction != snake.directionNum.down) {
            snake.direction = snake.directionNum.up;
        } else if (e.which == 39 && snake.direction != snake.directionNum.left) {
            snake.direction = snake.directionNum.right;
        } else if (e.which == 40 && snake.direction != snake.directionNum.up) {
            snake.direction = snake.directionNum.down;
        }
    }

在这里插入图片描述

全部代码在这里

html

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="./css/index.css">
    <title>Document</title>
</head>

<body>
    <div class="content">
        <!-- 游戏按钮 -->
        <div class="btn startBtn"><button>开始游戏</button></div>
        <div class="btn pauseBtn"><button></button></div>
        <div id="snakeWrap"></div>
    </div>
    <script src="./js/index.js"></script>
</body>

</html>

css

.content {
    width: 640px;
    height: 640px;
    margin: 100px auto;
    position: relative;
}

.btn {
    width: 100%;
    height: 100%;
    position: absolute;
    left: 0;
    top: 0;
    background-color: rgba(0,0,0,.3);
    z-index: 2;
}

.btn button {
    background: none;
    border: none;
    background-size: 100% 100%;

    cursor: pointer;
    outline: none;

    position: absolute;
    left: 50%;
    top: 50%;
}

.startBtn button {
    width: 180px;
    height: 60px;
    border-radius: 10px;
    font-size: 30px;
    letter-spacing: 4px;
    color: #fff;
    background-color: rgb(203, 80, 81);
    margin-left: -90px;
    margin-top: -30px;
}

.pauseBtn {
    display: none;
}

.pauseBtn button {
    opacity: 0.6;
    width: 70px;
    height: 70px;
    border-radius: 50%;

    background-image: url(../img/start.jpg);
    margin-left: -35px;
    margin-top: -35px;
}

#snakeWrap {
    position: relative;
    width: 600px;
    height: 600px;
    background: linear-gradient(45deg, #a3abd6 0%,rgb(142, 161, 214) 25%,rgb(173, 194, 255) 50%, rgb(90, 130, 248) 100%);
    border: 20px solid rgb(230, 116, 116);
}
#snakeWrap div{
    position: absolute;
    width: 20px;
    height: 20px;
}
.snakeHead {
    background-image: url(../img/.png);
    background-size: cover;
}
.snakeBody {
    background-color: rgb(61, 110, 53);
    border-radius: 50%;
}
.food {
    background-image: url(../img/苹果.png);
    background-size: cover;
}

JS

// 30 x 30
var squareWidth = 20, // 方块的宽高
    squareHeight = 20,
    tr = 30,  // 行
    td = 30   // 列
var snake = null,  // snake的实例
    food = null,  // 食物的实例
    game = null;  // 

function Square(x, y, classname) {
    this.x = x * squareWidth;
    this.y = y * squareHeight;
    this.class = classname;

    this.viewContent = document.createElement('div');  // 方块对应的dom元素
    this.viewContent.className = this.class;
    this.parent = document.getElementById('snakeWrap');  // 方块的父级
}

Square.prototype.create = function () {
    // 创建方块
    this.viewContent.style.position = 'absolute';
    this.viewContent.style.width = squareWidth + 'px';
    this.viewContent.style.height = squareHeight + 'px';
    this.viewContent.style.left = this.x + 'px';
    this.viewContent.style.top = this.y + 'px';

    this.parent.appendChild(this.viewContent);
};

Square.prototype.remove = function () {
    this.parent.removeChild(this.viewContent);
};

// 蛇
function Snake() {
    this.head = null;  // 存一下蛇头
    this.tail = null;  // 存一下蛇尾
    this.pos = [];     // 存储蛇身上的每一个位置
    this.directionNum = {
        left: {
            x: -1,
            y: 0,
            rotate: 270
        },
        right: {
            x: 1,
            y: 0,
            rotate: 90
        },
        up: {
            x: 0,
            y: -1,
            rotate: 180
        },
        down: {
            x: 0,
            y: 1,
            rotate: 0
        },
    };  // 蛇运动的方向
}
Snake.prototype.init = function () {
    // 创建蛇头+2个蛇身
    var snakeHead = new Square(2, 0, 'snakeHead');
    snakeHead.create();  // 创建蛇头
    this.head = snakeHead;   // 存储蛇头信息
    this.pos.push([2, 0]);   // 把蛇头的位置存起来

    // 创建蛇身
    var snakeBody1 = new Square(1, 0, 'snakeBody');
    snakeBody1.create();
    this.pos.push([1, 0]);

    var snakeBody2 = new Square(0, 0, 'snakeBody');
    snakeBody2.create();
    this.tail = snakeBody2;  // 把蛇尾的信息存起来
    this.pos.push([0, 0]);
    console.log(Snake.pos);

    // 形成链表关系
    snakeHead.last = null;
    snakeHead.next = snakeBody1;

    snakeBody1.last = snakeHead;
    snakeBody1.next = snakeBody2;

    snakeBody2.last = snakeBody1;
    snakeBody2.next = null;

    // 给蛇添加属性,表示蛇走的方向
    this.direction = this.directionNum.right;
}

// 这个方法用来获取蛇头下一个位置对应的元素
Snake.prototype.getNextPos = function () {
    var nextPos = [  // 蛇头下一个点坐标
        this.head.x / squareWidth + this.direction.x,
        this.head.y / squareHeight + this.direction.y,
    ]
    // console.log(nextPos);
    // console.log(nextPos);
    // 下一个点是自己,代表撞到了自己,游戏结束
    var selfCollied = false;  // 是否撞到了自己
    this.pos.forEach(function (value) {
        if (value[0] == nextPos[0] && value[1] == nextPos[1]) {
            selfCollied = true;
        }
    });
    if (selfCollied) {
        this.strategies.die.call(this);
        return;
    }
    // 下一个点是墙,游戏结束
    if (nextPos[0] < 0 || nextPos[1] < 0 || nextPos[0] > td - 1 || nextPos[1] > tr - 1) {
        this.strategies.die.call(this);
        return;
    }
    // 下一个点是食物,吃
    if (food && food.pos[0] == nextPos[0] && food.pos[1] == nextPos[1]) {
        // 说明蛇头要走的下个点是食物
        this.strategies.eat.call(this);
        return;
    }


    // 下一个点,继续走

    // 改变this的指向
    this.strategies.move.call(this);
};

Snake.prototype.strategies = {
    move: function (format) {  // 这个参数决定了要不要删除最后一个节点
        // console.log(this);
        // 创建一个新身体
        var newBody = new Square(this.head.x / squareWidth, this.head.y / squareHeight, 'snakeBody');
        以上是关于网页版贪吃蛇及源码的主要内容,如果未能解决你的问题,请参考以下文章

HTML5+CSS+JS 贪吃蛇demo

HTML5+CSS+JS 贪吃蛇demo

Pygame实战这游戏有毒,刷爆朋友圈:小编已与病毒版贪吃蛇大战了三百回合,最高分339?

c语言版贪吃蛇小游戏

JS学习——贪吃蛇代码(简易版)

JS学习——贪吃蛇代码(简易版)