0%

原生js写贪吃蛇| JavaScript学习(二)

玩过的最早手机游戏——贪吃蛇🐍,满满都是回忆。快来试试吧(游戏链接在文末)

本文主要使用构造函数法

分析贪吃蛇游戏

所谓面向对象编程,对于所描述的物体,

物体的特征即为对象的属性、

物体的行为即为对象的方法。

所以可以把游戏分为两个对象,一个是食物food,一个是小蛇snake

贪吃蛇gif

food

构造food对象,food的属性有位置x,y、大小width,height、颜色color

 function Food(x,y,width,height,color){ 
         this.x = x || 0
         this.y = y || 0
         this.width = width || "15"
         this.height = height || "15"
         this.color = color || "black"
     }

food是随机出现在地图map上,所以是脱离文档流的

初始化food

//初始化食物,作为原型的方法
    Food.prototype.init = function(map){
        //创建div
        var div = document.createElement("div")
        map.appendChild(div)
        //设置div样式
        div.style.position = "absolute"
        div.style.width = this.width + 'px'
        div.style.height = this.height + 'px'
        div.style.background = this.color
        //随机出现食物位置
        this.x = parseInt(Math.random()*(map.offsetWidth/this.width-2))
        this.y = parseInt(Math.random()*(map.offsetHeight/this.height-2))
        div.style.left = this.x*this.width + "px"
        div.style.top = this.y*this.height + "px"
     }

snake

把小蛇看成多个div块并跟随第一个头移动,把多个div存在一个数组里

function Snake(width,height,direction){
        this.width = width || 15
        this.height = height || 15

        this.direction = direction || "right"
        //小蛇的身体
        this.body = [
            {x:3,y:2,color:"black"},        //头
            {x:2,y:2,color:"black"},
            {x:1,y:2,color:"black"},
        ]

    }

初始化小蛇

    Snake.prototype.init = function(map){
        //先清除以前的小蛇
        remove()
        for(var i=0 ; i<this.body.length ; i++){
            //创建div
            var div = document.createElement('div')
            map.appendChild(div)
            //设置样式
            div.style.height = this.height + 'px'
            div.style.width = this.width + 'px'
            div.style.backgroundColor = this.body[i].color
            div.style.position = "absolute"
            div.style.left = this.body[i].x * this.width + 'px'
            div.style.top = this.body[i].y * this.height + 'px'
            //存起来
            elements.push(div)
        }
    }

设置小蛇的移动

Snake.prototype.move = function(food,map){

        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 "up": {
                this.body[0].y--
                break
            }
            case "down": {
                this.body[0].y++
                break
            }
            case "right": {
                this.body[0].x++
                break
            }
            case "left": {
                this.body[0].x--
                break
            }
        }
        //小蛇当前坐标
        headX = this.body[0].x
        headY = this.body[0].y
        //食物当前坐标
        foodX = food.x
        foodY = food.y
        var last
        //设置吃食物,小蛇长度增加
        if(headX == foodX && headY == foodY){

            //更新食物
            food.init(map)
            //小蛇长度加一
            last = this.body[this.body.length-1]
            this.body.push({
                x: last.x,
                y: last.y,
                color:last.color
            })
            //设置得分

        }
        //判断小蛇吃自己
        var j = this.body.length-1

        for(j=1; j<this.body.length ; j++){
            if(headX === this.body[j].x && headY === this.body[j].y){

                clearInterval(timer)
                alert('游戏结束')
                window.toHome()
            }    
        }    
    }

Game

用geme对象初始化游戏来调用小蛇和食物

function Game(map,speed){
        this.snake = new Snake()
        this.food = new Food()
        this.map = map
        this.speed = speed || 150
        that = this
    }
Game.prototype.init = function(){
        //初始化食物
        this.food.init(this.map)
        //根据按键改变方向
        this.bindKey(this.snake,this.speed)
        //小蛇移动
        this.runSnake(this.food,this.map,this.speed)    
    }
Game.prototype.runSnake = function(food,map,speed){
        clearInterval(timer)
        //设置x轴最长距离
        var maxX = map.offsetWidth/this.snake.width-2    //减去边框
        var maxY = map.offsetHeight/this.snake.height-2
        //定义小蛇头的坐标
        var headX = this.snake.body[0].x
        var headY = this.snake.body[0].y
        //定义食物坐标
        var foodX = food.x
        var foodY = food.y

        //设置小蛇一直走
        timer = setInterval(function(){
            //小蛇当前坐标
            headX = this.snake.body[0].x
            headY = this.snake.body[0].y
            //食物当前坐标
            foodX = food.x
            foodY = food.y
            this.snake.init(map)
            this.snake.move(this.food,this.map)

            //设置撞墙,游戏结束
            if(headX >= maxX || headX <0){

                alert("游戏结束!!!")
                clearInterval(timer)
                window.toHome()
            }
            if(headY >= maxY || headY <0){
                alert("游戏结束!!!")
                clearInterval(timer)
                window.toHome()
            }
            return window.timer = timer                    
            clearInterval(timer)
        }.bind(that),speed)

    }

监听键盘的方向建

Game.prototype.bindKey = function(snake,speed){
        //获取用户按键,改变小蛇移动
        document.addEventListener("keydown",function(e){
                switch(e.keyCode){
                    case 40 :{
                        if(snake.direction !== 'up'){
                            snake.direction = "down"
                        }
                        break
                    }
                    case 38 :{
                        if(snake.direction !== "down"){
                            snake.direction = 'up'
                        }
                        break
                    }
                    case 37 :{
                        if(snake.direction !== "right"){
                            snake.direction = "left"
                        }
                        break
                    }
                    case 39 :{
                        if(snake.direction !== "left")
                        snake.direction = "right"
                        break
                    }
                }

        },false)
    }

项目源码: https://github.com/Inkwall233/snake

项目演示: https://blog.inkwall.cn/snake 快来试试吧🐍

案例学习于黑马js教程,需要学习资料的可以直接加我呦(这句话听着好熟悉的Σ(っ °Д °;)っ),一起学习,加油!