使用ES6写一个贪吃蛇小游戏

首先先看一个效果图

利用面向对象思想, 我把他分为了 食物类 蛇类 还有一个主文件 游戏类 此外 因为食物是随机生成的,所以,我也定义了一个生成随机数的类

下面请看代码:

生成随机数类(util.js)

export function getRandom(a,b){

    let max = Math.max(a,b);    

    let min = Math.min(a,b);    

    return parseInt(Math.random() * (max - min))+min;

}

食物类(food.js)

import { getRandom } from "./util.js";

class Food{

    constructor({ x = 1, y = 1, width = 20, height = 20, color = 'green' } = {} ){

        this.element = [];

        this.x = x;

        this.y = y;

        this.width = width;

        this.height = height;

        this.color = color;

    }

    render(map){ 

        this.remove();

        this.x = getRandom(0, map.offsetWidth / this.width - 9) * this.width;

        this.y = getRandom(0, map.offsetHeight / this.height - 1) * this.height;

        let div = document.createElement('div');

        map.appendChild(div);

        this.element.push(div);

        div.style.position = 'absolute';

        div.style.left = this.x + 'px';

        div.style.top = this.y + 'px';

        div.style.width = this.width + 'px';

        div.style.height = this.height + 'px';

        div.style.backgroundColor = this.color;

    }

    remove(){

        for(let i = this.element.length-1; i >= 0; i--){

            this.element[i].parentNode.removeChild(this.element[i]);

            this.element.splice(i, 1);

        }

    }

}

export default Food;

蛇类(snake.js)

class Snake{

    constructor({width = 20, height = 20, direction = 'right'} = {}){

          this.element = [];

          this.width = width;

          this.height = height;

          this.direction = direction;   //蛇移动的方向

          //蛇的身体(蛇节), 第一个是蛇头

        this.body = [

            {x: 3, y: 2, color: 'red'},

            {x: 2, y: 2, color: 'blue'},

            {x: 1, y: 2, color: 'blue'}

        ];

    }

    move(food,map){

        for(let i = this.body.length - 1; i > 0; i--){

            this.body[i].x = this.body[i - 1].x;

            this.body[i].y = this.body[i - 1].y;

        }

        let head = this.body[0];

        //移动的方向

        switch(this.direction){

            case 'right':

                head.x += 1;

                break;

            case 'left':

                head.x -= 1;

                break;

            case 'top':

                head.y -= 1;

                break;

            case 'bottom':

                head.y += 1;

                break;

        }

        let headX = head.x * this.width;

        let headY = head.y * this.height;

        if(headX === food.x && headY === food.y){

            let last = this.body[this.body.length - 1];

            this.body.push({

                x: last.x,

                y: last.y,

                color: last.color

            })

            food.render(map);   //  重新生成一个食物

        }

    }
 

        render(map){

            this.remove();

            for(let i = 0, len = this.body.length; i < len; i++){

                let object = this.body[i];

                let div = document.createElement('div');

                map.appendChild(div);

                this.element.push(div);

                //设置样式

                div.style.position = 'absolute';

                div.style.width = this.width + 'px';

                div.style.height = this.height + 'px';

                div.style.left = object.x * this.width + 'px';

                div.style.top = object.y * this.height + 'px';

                div.style.backgroundColor = object.color;


 

            }

        }

        remove(){   

            //从大到小

            for(let i = this.element.length-1; i >= 0; i--){

                //删除真实dom

                this.element[i].parentNode.removeChild(this.element[i]);

                //删除数组中的元素

                this.element.splice(i, 1);

            }

        }

}

export default Snake;

游戏类(game.js)

import Food from "./food.js";

import Snake from "./snake.js";

//游戏的入口文件

class Game{

    constructor(){

        this.food = new Food();

        this.snake = new Snake();

        this.map = map;

        this.timerId = null;

    }

    start(){

        this.food.render(this.map);

        this.snake.render(this.map);

        this.bindKey();

        this.runSnake();

    }

    bindKey() {

        document.addEventListener('keydown', e => {

//这里相应的键值会传到snake.js中相应的direction

            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;

            }

        })

    };

    runSnake() {

        this.timerId = setInterval( () =>{

            this.snake.move(this.food, this.map);

            let maxX = this.map.offsetWidth / this.snake.width;

            let maxY = this.map.offsetHeight / this.snake.height;

            let headX = this.snake.body[0].x;

            let headY = this.snake.body[0].y;

            if(headX <= 0 || headX >= maxX || headY <= 0 || headY >= maxY){

                alert("Game over ");

                clearInterval(this.timerId);

                return

            }

            this.snake.render(this.map);

        }, 500)

    }

}

export default Game;

最后再定义一个html文件,用于启动(注意es6启动必须以服务启动)

<!DOCTYPE html>

<html lang="en">

<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">

    <title>Document</title>

</head>

<body>

    <div id="map" style=" width:80%;height:400px;border: 1px solid orange;"> </div>

    <script type="module">

        import Game from './game.js'

        let map = document.getElementById('map');

        let game = new Game(map);

        game.start(); 

    </script>

</body>

</html>

最后在我看来es6相比es5 真的代码美观了好多,也节省了好多代码  ,最重要的是,这个面向对象的思想降低了模块之间的耦合性,总体来说,还不错

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值