js高级面向对象之贪吃蛇

html 部分
给一张地图 蛇活动的范围就在这个地图之内

<body>
<div id="map"></div>
</body>

css部分

地图的样式

 <style>
        #map {
            width: 800px;
            height: 600px;
            background-color: grey;;
            position: relative;
        }
    </style>

js部分
我们可以先分析下有哪几个对象

  1. 食物
  2. 游戏

一.食物的对象

 ((function () {
        //保存每一个小方块,好删除小方块
        var elements = [];

        //食物的构造函数
        function Food(width, height, color, x, y) {
            this.width = width || 20;//食物的宽度  用户没有传入参数的话,默认20px
            this.height = height || 20;//食物的高度 用户没有传入参数的话,默认20px
            this.color = color || "yellow";//食物的颜色 用户没有传入参数的话,默认yellow
            //随机的横纵坐标
            this.x = x || 0;//食物的横坐标  用户没有传入参数的话,默认为0
            this.y = y || 0;//食物的纵坐标  用户没有传入参数的话,默认为0
        }

        //在原型对象上添加方法---把食物显示在地图上
        Food.prototype.init = function (map) {
            //先删除在创建
            remove();
            //1.创建一个小盒子 -- 食物
            var div = document.createElement("div");
            //2.把div添加到map中去
            map.appendChild(div);
            //3.给小盒子设置样式
            div.style.width = this.width + "px";
            div.style.height = this.height + "px";
            div.style.backgroundColor = this.color;
            div.style.position = "absolute";
            //随机数的坐标  不能超出地图的范围
            this.x = parseInt(Math.random() * (map.offsetWidth / this.width)) * this.width;//食物的随机横坐标  
            this.y = parseInt(Math.random() * (map.offsetHeight / this.height)) * this.height;//食物的随机纵坐标
            // console.log(this.x);
            // console.log(this.y);
            //设置食物随机出现的位置
            div.style.left = this.x + "px";
            div.style.top = this.y + "px";
            //把div添加到数组中去
            elements.push(div);
        }

        //封装删除食物的函数
        function remove() {
            for (var i = 0; i < elements.length; i++) {
                //获取每一个小方块
                var ele = elements[i]
                //删除map中的小方块
                ele.parentElement.removeChild(ele);
                //删除数组中的小方块
                elements.splice(i, 1)
            }
        }

        //把Food暴露给window
        window.Food = Food;
    })());

二.小蛇的对象

 ((function () {
        //用来存放小蛇的数组
        var elements = [];
        //1.小蛇的构造函数
        function Snake(width, height, direnction) {
            //小蛇每个部位的宽度
            this.width = width || 20;
            this.height = width || 20;
            //小蛇的方向
            this.direction = direnction || "right";
            //小蛇每个部位在那个坐标点-----小蛇吃食物会变长
            this.body = [
                {x: 3, y: 1, color: "white"},//小蛇的头部
                {x: 2, y: 1, color: "black"},//身体
                {x: 1, y: 1, color: "black"}
            ]
        }

        //2.在原型中添加发方法---小蛇初始化---需要地图参数
        Snake.prototype.init = function (map) {
        	//先删除小蛇
            remove();
            //遍历的创建div---小蛇的每个部位
            for (var i = 0; i < this.body.length; i++) {
                //1.创建div
                var div = document.createElement("div");
                //2.添加到地图中
                map.appendChild(div);
                var obj = this.body[i];//储存的是数组的每一个元素,也是对象
                //3.设置div的样式
                div.style.width = this.width + "px";
                div.style.height = this.height + "px";
                div.style.backgroundColor = this.body[i].color;
                div.style.position = "absolute";
                //横纵坐标
                div.style.left = obj.x * this.width + "px";
                div.style.top = obj.y * this.height + "px";              
                //把小蛇添加到数组
                elements.push(div);
            }
        }
        //暴露给window
        window.Snack = Snake;

        //3.添加一个让小蛇 移动的方法
        Snake.prototype.move = function (map, food) {
            //改变小蛇的身体坐标----》要循环小蛇的身体部位,头部要判断方向
            for (var i = this.body.length - 1; i > 0; i--) {
                //当i=2的时候,此时是第三块的坐标,把第2块的坐标给第3块的坐标
                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;
            }

            //最后:要判断小蛇是否吃到食物,----即判断蛇头的坐标
            //获取蛇头的坐标
            var headX = this.body[0].x * this.width;
            var headY = this.body[0].y * this.height;
            //食物的坐标
            var foodX = food.x;
            var foodY = food.y;

            if (headX == foodX && headY == foodY) {
                //1.重新初始化食物
                food.init(map);
                //2.获取小蛇最后的尾巴
                var last = this.body[this.body.length - 1];
                //3.添加到数组中
                this.body.push({
                    x: last.x,
                    y: last.y,
                    color: last.color
                })
            }
        };

        //4.删除小蛇的函数
        function remove() {
            for (var i = elements.length - 1; i >= 0; i--) {
                //存放每一个小蛇
                var ele = elements[i];
                //删除地图上面的
                ele.parentNode.removeChild(ele);
                //删除数组中的
                elements.splice(i, 1);
            }
        }
    })());

三.游戏的对象–显示小蛇,显示食物,并自动的跑起来

 ((function () {
        //1.游戏的构造函数
        function Game() {
            this.food = new Food();//食物的对象
            this.snake = new Snack();//小蛇的对象
            this.map = document.getElementById("map");//地图对象
        };
        //2.初始化游戏对象---
        Game.prototype.init = function () {
            //显示食物和小蛇
            this.food.init(this.map);
            this.snake.init(this.map);
            //调用自动移动的小蛇
            this.runSnake(this.map, this.food);
            //调用方向的方法
            this.keyDown(this.map);
        };
        //3.添加原型的方法---是小蛇自动跑起来
        Game.prototype.runSnake = function (map, food) {
            //函数嵌套,this指向发生变化
            var that = this;
            //自动的移动
            var timeId = setInterval(function () {
                // console.log(this);//指向的window
                this.snake.move(map, food)//移动
                this.snake.init(map);//显示

                //判断横纵坐标最大值
                var maxX = map.offsetWidth / this.snake.width;
                // console.log(maxX);
                var maxY = map.offsetHeight / this.snake.height;

                //获取蛇头坐标
                var headX = this.snake.body[0].x;
                // console.log(headX);
                var headY = this.snake.body[0].y;
                //判断横纵坐标是否撞墙
                if (headX < 0 || headX >= maxX || headY < 0 || headY >= maxY) {
                    clearInterval(timeId);
                    alert("game over!");
                }
                ;


                //把这个函数的指向绑定在that的指向上面
            }.bind(that), 200);
        };

        //4.添加原型方法--设置用户的按键,改变小蛇的移动方向
        Game.prototype.keyDown = function () {
            document.addEventListener("keydown", function (e) {
                console.log(e.keyCode);//按键的值
                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(this));
        }

        //暴露给window
        window.Game = Game;
    })());

最后调用游戏的方法就可以了

 var game = new Game();
    game.init();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一个简单的C++面向对象贪吃游戏的代码示例,如下所示: ```cpp #include <iostream> #include <conio.h> #include <windows.h> using namespace std; const int width = 20; const int height = 20; class Snake { private: int x, y; public: Snake() { x = width / 2; y = height / 2; } void move(int dx, int dy) { x += dx; y += dy; if (x < 0) x = width - 1; if (x > width - 1) x = 0; if (y < 0) y = height - 1; if (y > height - 1) y = 0; } int getX() { return x; } int getY() { return y; } }; class Fruit { private: int x, y; public: Fruit() { x = rand() % width; y = rand() % height; } int getX() { return x; } int getY() { return y; } void changePosition() { x = rand() % width; y = rand() % height; } }; class Game { private: bool gameOver; Snake snake; Fruit fruit; public: Game() { gameOver = false; } void draw() { system("cls"); for (int i = 0; i < width + 2; i++) { cout << "#"; } cout << endl; for (int i = 0; i < height; i++) { for (int j = 0; j < width; j++) { if (j == 0) { cout << "#"; } if (i == snake.getY() && j == snake.getX()) { cout << "O"; } else if (i == fruit.getY() && j == fruit.getX()) { cout << "F"; } else { cout << " "; } if (j == width - 1) { cout << "#"; } } cout << endl; } for (int i = 0; i < width + 2; i++) { cout << "#"; } cout << endl; } void input() { if (_kbhit()) { switch (_getch()) { case 'a': snake.move(-1, 0); break; case 'd': snake.move(1, 0); break; case 'w': snake.move(0, -1); break; case 's': snake.move(0, 1); break; case 'x': gameOver = true; break; } } } void logic() { if (snake.getX() == fruit.getX() && snake.getY() == fruit.getY()) { fruit.changePosition(); } else { snake.move(0, 0); } } void run() { while (!gameOver) { draw(); input(); logic(); Sleep(50); } } }; int main() { Game game; game.run(); return 0; } ``` 这个程序使用了三个类:`Snake`、`Fruit`和`Game`。`Snake`类表示,`Fruit`类表示水果,`Game`类表示整个游戏。在`Game`类的`run`函数中,程序会不断地循环执行`draw`、`input`和`logic`函数,直到游戏结束。`draw`函数用于绘制游戏界面,`input`函数用于处理用户输入,`logic`函数用于处理游戏逻辑。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值