8

原生JS实现贪吃蛇游戏

 3 years ago
source link: https://blog.csdn.net/XVJINHUA954/article/details/111400052
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

原生JS实现贪吃蛇游戏

贪吃蛇游戏(原生JavaScript)

贪吃蛇游戏思路分析

游戏思想:

面向对象的思想

  • 三个js文件分别代表三个对象
  • 三个对象相互独立,在HTML中控制全局

使用面向对象思想的好处

贪吃蛇游戏采用面向对象的思想去实现,我们的食物还有蛇以及地图是相互独立的,不会对彼此产生影响,可以单独调用

贪吃蛇游戏对象分析

游戏的场景(一个大的div)

  • 场景的大小

  • 场景的边框

  • 场景在浏览器中的位置

游戏的主角(每一节是一个小的div)

  • 蛇的初始长度(四节)

  • 蛇的每一节的形状

  • 蛇的每一节的尺寸

  • 蛇的颜色(蛇头的颜色,蛇身的颜色)

  • 蛇的初始位置在哪

  • 可以自己移动,每一次移动一节的蛇身长

  • 可以通过键盘控制方向

  • 可以吃食物,并且吃完以后会长一节

食物的属性

  • 食物的大小

  • 食物的颜色(随机)

  • 食物的位置(随机)

  • 食物的形状(圆形)

食物的方法

  • 食物被蛇吃掉以后可以改变位置(随机)

游戏场景附加项

  • 游戏的障碍
  • 游戏的计分功能
  • 游戏中蛇的最长记录

游戏的主角附加项

  • 蛇可以加速
  • 游戏的关卡设置

游戏的附加项大家有兴趣的话可以自己去尝试着添加,有什么问题,可以在下方评论进行讨论!

废话少说,直接上源码!

index.HTML

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>贪吃蛇</title>
    <!-- 将三个js文件,通过外联的方式进行引入 -->
    <script src="地图.js"></script>
    <script src="蛇.js"></script>
    <script src="食物.js"></script>
</head>

<body>
    <script>
        //主界面HTML实现对游戏的全局控制
        //一,创建地图,并将地图添加到body中
        //实例化map对象
        var map = new Game_Map();
        //将map对象添加到body中
        document.body.appendChild(map);
        //三,创建食物
        //计算食物随机出现的范围是多少
        var countX = (map.offsetWidth - 40) / 20;
        var countY = (map.offsetHeight - 40) / 20;
        //实例化蛇对象,并且传参.
        var food = new Food(countX, countY, map);
        //二,创建蛇
        var snake = new Snake(3, 0, map, food)
    </script>
</body>

</html>

地图.js

//游戏场景
//我们使用构造函数来写游戏场景
function Game_Map() {
    // 用对象的属性来设置游戏场景的大小
    this.width = 1000;
    this.height = 800;
    //创建一个div来表示游戏场景
    var map = document.createElement("div");
    // 设置创建的div的长和宽
    map.style.width = this.width + "px";
    map.style.height = this.height + "px";
    //设置盒子的背景颜色
    map.style.backgroundColor = "rgba(211, 211, 211, 0.315)";
    // 设置盒子的边框
    map.style.border = "20px solid skyblue";
    //设置盒子的位置
    map.style.margin = "50px auto";
    //给地图一个相对定位(子绝父相)
    map.style.position = "relative";
    //返回值返回创建的div就是map
    return map
}
//蛇对象
//面向对象使用构造函数
function Snake(xindex, yindex, parent, food = null) {
    //使用构造函数的属性来设置蛇的长还有每一节的大小
    this.length = 4;
    this.size = 20;
    //获取传递的food
    this.food = food;
    //定义一个数组来存放蛇身
    this.list = new Array();
    // 一,创建蛇
    //蛇的的长度是4,所以我们使用for循环来创建
    for (var i = 0; i < this.length; i++) {
        //创建蛇的div
        var item = document.createElement("div");
        //设置蛇的每一节的宽和高
        item.style.width = item.style.height = this.size + "px";
        //蛇的每一节是圆形,所以我们使用圆角边框
        item.style.borderRadius = "100%";
        // 使用if判断让蛇头的的颜色和身体的颜色不一样
        if (i == 0) {
            item.style.backgroundColor = "red";
        }
        else {
            item.style.backgroundColor = "green";
        }
        //蛇是在地图里面所以蛇使用的是绝对定位
        item.style.position = "absolute";
        //定义蛇的初始位置,我们一开始给蛇的传递两个参数,来设置蛇的初始位置
        //给的csx使用for循环是0  1  2  3 所以我们给的值是从右到左一个一个放置蛇身,csx是蛇身的初始横坐标
        item.style.left = (xindex - i) * this.size + "px";
        //给的csy是她的初始纵坐标
        item.style.top = yindex * this.size + "px";
        //给蛇设置一个自定义标签,为蛇当时的方向
        item.setAttribute("dir", "right");
        //把蛇身一节一节的放入到数组中
        this.list[i] = item;
        //然后再一节一节的添加到我们的map中
        parent.appendChild(item);
    }
    // move函数
    function move(list, size, food = null) {
        //for循环遍历让蛇进行移动
        for (var i = 0; i < list.length; i++) {
            //判断蛇的移动方向
            if (list[i].getAttribute("dir") === "down") {
                //移动之前先判断一下是否碰到墙了
                if (list[0].style.top == 800 + "px") {
                    // 碰到的话,游戏结束
                    alert("游戏结束!")
                } else {
                    //没有碰到继续
                    list[i].style.top = list[i].offsetTop + size + "px";
                }

            } else if (list[i].getAttribute("dir") === "up") {
                if (list[0].style.top == -20 + "px") {
                    alert("游戏结束!")
                } else {
                    list[i].style.top = list[i].offsetTop - size + "px";
                }

            } else if (list[i].getAttribute("dir") === "left") {
                if (list[0].style.left == -20 + "px") {
                    alert("游戏结束!")
                } else {
                    list[i].style.left = list[i].offsetLeft - size + "px";
                }

            } else if (list[i].getAttribute("dir") === "right") {
                if (list[0].style.left == 1000 + "px") {
                    alert("游戏结束!")
                } else {
                    list[i].style.left = list[i].offsetLeft + size + "px";
                }

            }
        }
        //让dir属性进行传递,使得蛇身和蛇头一起向同一方向移动
        for (var i = list.length - 1; i > 0; i--) {
            list[i].setAttribute("dir", list[i - 1].getAttribute("dir"));
        }
        //判断食物是否出现
        if (food == null) {
            console.log(null);
            return;
            // 食物出现的话,判断如果蛇头和食物的位置重叠的话,那么就让食物重新定义一个新的随机位置,并且调用蛇长身体的方法
        } else if (list[0].style.left == food.food.style.left && list[0].style.top == food.food.style.top) {
            food.setPosition();
            group();
        }
    };
    //二,实现蛇的移动
    this.movetime = setInterval(move, 100, this.list, this.size, this.food,);

    // 三,控制转弯
    document.addEventListener("keydown", changeDir,);
    var list = this.list;
    function changeDir(e) {
        switch (e.keyCode) {
            // 向上
            case 38:
                list[0].setAttribute("dir", "up");
                break;
            // 向下
            case 40:
                list[0].setAttribute("dir", "down");
                break;
            // 向左
            case 37:
                list[0].setAttribute("dir", "left");
                break;
            // 向右
            case 39:
                list[0].setAttribute("dir", "right");
                break;
        }
    }
    // 【4】蛇长身体
    var group = function () {
        // 蛇头和食物重叠以后,蛇身要长长一节,所以创建一个div,设置属性,加到蛇身的最后一节上
        var item = document.createElement("div");
        item.style.width = item.style.height = "20px";
        item.style.borderRadius = "100%";
        item.style.backgroundColor = "green";
        item.style.position = "absolute";
        item.style.left = list[list.length - 1].style.left;
        item.style.top = list[list.length - 1].style.top;
        list[list.length] = item;
        parent.appendChild(item);
    }
}

食物.js

//食物对象
//构造一个食物对象函数
function Food(countX, countY, body) {
    //设置食物的大小
    this.size = 20;
    // 创建食物,设置食物的属性
    this.food = document.createElement("div");
    this.food.style.width = this.food.style.height = this.size + "px";
    this.food.style.borderRadius = "50%";
    this.food.style.position = "absolute";
    //定义食物的随机位置以及随机的颜色
    this.setPosition = function () {
        this.food.style.left = Math.floor(Math.random() * countX) * this.size + "px";
        this.food.style.top = Math.floor(Math.random() * countY) * this.size + "px";
        this.food.style.backgroundColor = `rgb(${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)},${Math.floor(Math.random() * 256)})`;
    }
    this.setPosition();
    body.appendChild(this.food);
}

注:本人小白一个,代码有什么问题的话,希望大家可以提出来,本人会及时改正!
在这里插入图片描述


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK