js 面向对象实现简单贪吃蛇效果

** js 面向对象实现简单贪吃蛇效果**

运行效果:
在这里插入图片描述
html代码:

<div class="map"></div>

css代码:

<style>
    .map {
        width: 800px;
        height: 600px;
        background-color: #ccc;
        position: relative;
        margin: 0 auto;
    }
</style>

js代码:

<script>
        // 自定义自调用函数,创建对象
        // 自调用函数--食物
        var map = document.querySelector(".map");
        (function () {
            // 创建数组
            var elements = [] //用来保存食物
            // 食物是一个对象,高度,宽度,颜色
            // 创建食物的构造函数
            function Food(x, y, width, height, color, borderRadius) {
                // 设置坐标
                this.x = x || 0;
                this.y = y || 0;
                // 设置宽高
                this.width = width || 20;
                this.height = height || 20;
                // 设置背景色
                this.color = color;
                this.borderRadius = borderRadius;
            }
            // 食物显示在地图上---通过原型方法进行添加
            // 因为食物显示在地图上---把地图参数传入
            Food.prototype.init = function (map) {
                var div = document.createElement("div")

                // 创建新的食物之前先删除这个食物
                remove()

                // 把div添加到map中
                map.appendChild(div)
                // 设置div样式
                div.style.width = this.width + "px";
                div.style.height = this.height + "px"
                div.style.backgroundColor = this.color || "red";
                div.style.borderRadius = this.borderRadius + "px";
                // 设置div定位,脱标
                div.style.position = "absolute"
                // 设置div的纵横坐标
                this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width
                this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height
                div.style.left = this.x + "px"
                div.style.top = this.y + "px"

                // 把食物放到数组中
                elements.push(div)
                console.log(elements)
            }

            // 删除食物 
            function remove() {
                for (var i = 0; i < elements.length; i++) {
                    var ele = elements[i]
                    // 找到这个元素和它的父元素,然后删除这个元素--页面中的元素
                    ele.parentNode.removeChild(ele)
                    // 删除数组中的元素
                    elements.splice(i, 1)
                }
            }
            // 把Food暴露给window对象
            window.Food = Food
            // window.food = new Food(0, 0, 20, 20, "red")
        })();

        // 创建蛇
        (function () {
            // 蛇的构造方法
            var elements = []; //存放蛇的身体
            // 蛇的构造函数
            function Snake(width, height, direction) {
                // 蛇的宽
                this.width = width || 20;
                this.height = height || 20;
                // 蛇的身体
                this.body = [
                    { x: 3, y: 2, color: "orange" }, //头
                    { x: 2, y: 2, color: "blue" }, //身体
                    { x: 1, y: 2, color: "blue" } //身体
                ];
                // 蛇的方向
                this.direction = direction || "right";
            }

            // 蛇的初始化
            // 为原型添加init方法--- 小蛇的初始化方法
            Snake.prototype.init = function (map) {
                // 每次先删除蛇
                remove();

                // 循环遍历创建div,创建蛇的身体
                for (var i = 0; i < this.body.length; i++) {
                    // 数组中的每个元素都是对象
                    // 蛇的每一部分都是div
                    var obj = this.body[i]
                    // 创建div
                    var div = document.createElement("div");
                    // 把div添加到map中
                    map.appendChild(div);
                    // 设置div样式
                    div.style.position = "absolute";
                    div.style.width = this.width + "px";
                    div.style.height = this.height + "px";
                    // 纵横坐标
                    div.style.left = obj.x * this.width + "px"
                    div.style.top = obj.y * this.height + "px"
                    // 背景颜色
                    div.style.backgroundColor = obj.color

                    // 把div加到数组中
                    elements.push(div);
                    // console.log(elements)
                }
            }

            // 蛇的移动--- 为原型添加方法
            Snake.prototype.move = function (map, food) {
                // 蛇的身体长度
                var i = this.body.length - 1;
                // 蛇身体移动,坐标变化
                for (; i > 0; i--) {
                    this.body[i].x = this.body[i - 1].x
                    this.body[i].y = this.body[i - 1].y
                }

                // 判断头部方向
                switch (this.direction) {
                    case "right": this.body[0].x += 1
                        break
                    case "left": this.body[0].x -= 1
                        break
                    case "top": this.body[0].y -= 1
                        break
                    case "bottom": this.body[0].y += 1
                        break
                }
                // 判断蛇有没有吃到食物
                // 当蛇头的坐标和食物的坐标一致时,吃到食物
                // 身体长度+1

                // 蛇头横纵坐标
                var headX = this.body[0].x * this.width;
                var headY = this.body[0].y * this.height;

                // 判断坐标是否一致
                if (headX == food.x && headY == food.y) {
                    // 获取蛇的尾巴---身体的最后一部分
                    var last = this.body[this.body.length - 1]
                    this.body.push({
                        x: last.x,
                        y: last.y,
                        color: last.color
                    })
                    // 删除食物,重新初始化
                    food.init(map)
                }
            }
            // 删除蛇,蛇的私有属性
            function remove() {
                //删除map中的小蛇的每个div,同时删除elements数组中的每个元素,从蛇尾向蛇头方向删除div
                var i = elements.length - 1;
                for (; i >= 0; i--) {
                    //先从当前的子元素中找到该子元素的父级元素,然后再弄死这个子元素
                    var ele = elements[i];
                    //从map地图上删除这个子元素div
                    ele.parentNode.removeChild(ele);
                    elements.splice(i, 1); // 从当前遍历到的元素删除,长度为1
                }
            }
            // 把Snake暴露给window对象
            window.Snake = Snake;
        })();

        // 自调用函数---游戏对象
        (function () {
            var that = null;  // 保存Game的实例对象
            // 游戏的构造函数
            function Game(map) {
                // 创建食物对象
                this.food = new Food()//食物对象
                this.snake = new Snake()//蛇对象
                this.map = map
                that = this
            }
            Game.prototype.init = function () {
                // 食物初始化
                this.food.init(this.map)
                // 蛇初始化
                this.snake.init(this.map)

                /* // var that = this;
                // 创建定时器,开启蛇动
                setInterval(function () {
                    that.snake.move(that.map, that.food)
                    that.snake.init(that.map)
                }, 1000)
                // 调用按键的方法,修改蛇的移动方向
                // bindKey(); */
                this.runSnake();
                // 调用按键方法,修改蛇的移动方向
                this.bindKey();
            }

            //原型中添加方法,让蛇自己动
            Game.prototype.runSnake = function () {
                // 创建定时器
                var timeId = setInterval(function () {
                    this.snake.move(this.map, this.food)
                    this.snake.init(this.map)

                    // 判断蛇不能超出地图范围
                    var maxX = map.offsetWidth / this.snake.width;
                    var maxY = map.offsetHeight / this.snake.height;
                    // 蛇头的坐标
                    var headX = this.snake.body[0].x;
                    var headY = this.snake.body[0].y;
                    // 判断横纵坐标是否超出范围
                    if (headX < 0 || headX >= maxX || headY < 0 || headY >= maxY) {
                        // 蛇超出了地图范围
                        clearInterval(timeId);
                        alert("Game Over")
                    }
                }.bind(that), 150)
            }

            // 为原型添加方法 ---按键设置,控制蛇的移动方向
            Game.prototype.bindKey = function () {
                //  获取用户按键,改变蛇运动方向
                document.addEventListener("keydown", function (e) {
                    // this指向
                    // console.log("this")
                    // 获取按键值
                    switch (e.keyCode) {
                        case 37: this.snake.direction = "left"
                            break
                        case 38: this.snake.direction = "top"
                            break
                        case 39: this.snake.direction = "right"
                            break
                        case 40: this.snake.direction = "bottom"
                            break
                    }

                }.bind(that), false)
            }
            window.Game = Game;
        })();

        var gm = new Game(map)
        gm.init();
        gm.bindKey()


        // 测试代码
        // 初始化食物
        // var fd = new Food(0, 0, 20, 20, "red", 50)
        // fd.init(map)
    </script>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值