实例:贪吃蛇游戏

第一部分:设置游戏界面,创建3个简单的函数:

  1. 游戏画板边框函数
  2. 计分函数
  3. 结束游戏函数

第二部分:制作游戏人物

  1. Block构造函数添加三个方法:drawSquaredrawCircleequal
  2. Snake构造函数添加四个方法:drawmovecheckCollisionsetDirection
  3. Apple构造函数添加2个方法:drawmove

第三部分:添加事件处理程序
添加keydown事件处理程序

<body>
    <canvas id="canvas" width="400" height="400"></canvas>
    <script src="https://code.jquery.com/jquery-2.1.0.js"></script>
    <script>
        //设置游戏界面
        var canvas = document.getElementById("canvas");    //获取到canvas的id
        var ctx = canvas.getContext("2d");    //在canvas上绘制2d图像
        
        var width = canvas.width;    //游戏界面宽为画板宽
        var height = canvas.height;    //游戏界面高为画板高
        var bolckSize = 10;    //一个格子10像素
        var widthInBlocks = width / bolckSize;    //宽分为10个格子
        var heightInBlocks = height / bolckSize;    //高分为10个格子
        
        //游戏画板边框函数,边框在画布之内
        var drawBroder = function () {
            ctx.fillStyle = "gray";    //边框颜色
            ctx.fillRect(0,0,width,bolckSize);      //上边框,坐标(0,0),宽是400像素,高10像素
            ctx.fillRect(0,height-bolckSize,width,bolckSize);   //下边框,坐标(0,390),宽是400像素,高10像素
            ctx.fillRect(0,0,bolckSize,height);     //左边框,坐标(0,0),宽是10像素,高400像素
            ctx.fillRect(height-bolckSize,0,bolckSize,height);  //右边框,减去10个像素,坐标(390,0),宽是10像素,高400像素
        };
        
        //绘制计分函数
        var score = 0;    //初始化得分为0
        var drawScore = function () {
            ctx.font = "20px courier";              //文本大小和字体
            ctx.fillStyle = "black";                //文本颜色
            ctx.textAlign = "left";                //文本基线点在左
            ctx.textBaseline = "top";              //文本基线在上
            ctx.fillText("Score: " + score,bolckSize,bolckSize);
        };
    
        //结束游戏函数
        var gameOver = function () {
            clearInterval(intervalId);    //清理画布
            ctx.font = "60 Courier";
            ctx.fillStyle = "black";
            ctx.textAlign = "center";
            ctx.textBaseline = "middle";
            ctx.fillText("GAME OVER",width/2,height/2);
        };
      
        //Block构造方法,使用Block来创建网格中的方块对象,可以用来做蛇的身体段和苹果
        var Block = function (col, row) {    //Block构造函数接收两个参数坐标点
            this.col = col;
            this.row = row;
        };
        
        //添加drawSquare方法,是用来绘制蛇的身体段,接收一个参数——颜色
        Block.prototype.drawSquare = function (color) {    //这边需要注意的是坐标所在的位置是方块的左上角顶点,不是方块的中心
            var x = this.col * bolckSize;   //x轴,因为是以blockSize 为像素单位,所以需要乘上blockSize
            var y = this.row * bolckSize;   //y轴,同上
            ctx.fillStyle = color;           //设置方块的颜色
            ctx.fillRect(x,y,bolckSize,bolckSize);  //绘制方块,大小为blockSize
        };
        
        //圆函数,绘制苹果时需要
        var circle = function (x,y,radius,boolean) {     //圆函数接受4个参数,坐标轴x、y,半径以及是填充还是画圈
            ctx.beginPath();
            ctx.arc(x,y,radius,0,Math.PI *2,false);
            if(boolean){
                ctx.fill();
            }else{
                ctx.stroke();
            }
        };
        
        //添加drawCircle方法,是用来绘制苹果的,接受一个参数——颜色
        Block.prototype.drawCircle = function (color) {    //圆圈方法为了在方块的中间,所以需要加上blockSize的一半
            var centerX = this.col * bolckSize + bolckSize/2;   //确定苹果 x 方向的位置,中心位置
            var centerY = this.row * bolckSize + bolckSize/2;   //确定苹果 y 方向的位置,中心位置
            ctx.fillStyle = color;           //确定苹果的颜色
            circle(centerX,centerY,bolckSize/2,true);  //绘制圆圈,半径为blockSize的一半
        };
        
        //添加equal方法,用来比较蛇头和苹果或蛇身任意部位是否在相同位置,接收一个参数——苹果或者蛇身的坐标
        Block.prototype.equal=function (otherBlock) {     //返回boolean,如果x,y都相同返回true,否则返回false
            return this.col === otherBlock.col && this.row === otherBlock.row;
        };
        
        //Snake构造方法,初始化三个方块,并向右移动
        var Snake = function () {
            this.segments = [    //蛇身体分割为3个格子
                new Block(7,5),
                new Block(6,5),
                new Block(5,5)
            ];
            // this.direction = "right";    //貌似可以省略
            this.nextDirection = "right";    //向右移动
        };
        
        //添加draw方法,给蛇上色
        Snake.prototype.draw = function () {
            for(var i = 0; i < this.segments.length; i++){     //遍历蛇的每一个方块,并给它上色
                this.segments[i].drawSquare("blue");     //Block的drawSquare方法用来绘制蛇的身体段的的颜色
            }
        };
        
        //添加move方法,控制蛇的方向
        Snake.prototype.move = function () {
            var head = this.segments[0];
            var newHead;
        
            this.direction = this.nextDirection;    //把下一个方向赋值给当前方向
        
            //实例化Block,作为蛇头,赋值给newHead,这里面的数字代表方格
            if(this.direction === "right"){
                newHead = new Block(head.col + 1,head.row);
            }else if(this.direction === "down"){
                newHead = new Block(head.col,head.row+1);
            }else if(this.direction === "left"){
                newHead = new Block(head.col - 1,head.row);
            }else if(this.direction === "up"){
                newHead = new Block(head.col,head.row - 1);
            }
            if(this.checkCollision(newHead)){    //检查有没有碰到头,如果碰到头游戏结束,并跳出move函数
                gameOver();
                return;
            }
        
            this.segments.unshift(newHead);    //每次移动的时候在segments数组初始位置加上新的蛇头
        
            if(newHead.equal(apple.position)) {    //如果蛇头碰到苹果的位置,得分加1,苹果移动到新的位置
                score++;
                apple.move();
            }
            else{    //否则删除蛇的尾巴,这句是对应unshift那句,移动的时前面+1,并且后面-1
                this.segments.pop();
            }
        };
        
        //添加checkCollision方法,检查蛇头有没碰到边框或者自身,接受一个参数——蛇头,就是在move方法中的newHead
        Snake.prototype.checkCollision =function (head) {
            var leftCollision = (head.col === 0);    //左边框,第0列是边框
            var topCollision = (head.row === 0);    //上边框,第0列是边框
            var rightCollision = (head.col === widthInBlocks-1);    //右边框,第39列是边框
            var bottomCollision = (head.row === heightInBlocks -1);    //下边框,第39列是边框
        
            var wallCollision = leftCollision || topCollision || rightCollision ||bottomCollision;     //判断是否是真
        
            // var selfCollision = false;
        
            for(var i = 0; i < this.segments.length; i++){    //遍历蛇的每一个方块
                if(head.equal(this.segments[i])){    //如果蛇头等于蛇身的某一个方块,那么就是蛇头碰到自身了
                   var selfCollision = true;
                }
            }
            return wallCollision || selfCollision;    //返回boolean,只要一个是真的就返回
        };
        
        //添加设置方向方法,接受一个参数——新方向
        Snake.prototype.setDirection = function(newDirection){
            if(this.direction === "up" && newDirection === "down"){    //如果当前方向是上,新方向是下,新方向无效
                return;
            }else if(this.direction === "right" && newDirection === "left"){    //同上
                return;
            }else if(this.direction === "down" && newDirection === "up"){    //同上
                return;
            }else if(this.direction === "left" && newDirection === "right"){    //同上
                return;
            }
            this.nextDirection = newDirection;     //否则把新方向赋值给下一个方向
        };
        
        //Apple构造函数,绘制苹果
        var Apple = function () {
            this.position = new Block(10,10);    //初始化苹果位置
        };
        
        //添加draw方法,绘制苹果
        Apple.prototype.draw = function () {
            this.position.drawCircle("limeGreen")     //绘制一个绿色苹果
        };
        
        //添加move方法,移动苹果
        Apple.prototype.move = function () {
            var randomCol = Math.floor(Math.random() * (widthInBlocks -2)) + 1;    //1-38随机数
            var randomRow = Math.floor(Math.random() * (heightInBlocks -2)) + 1;    //同上
            this.position = new Block(randomCol,randomRow);    //赋值给新坐标
        };
        
        var snake = new Snake();
        var apple = new Apple();
        
        //用setInterval来实现游戏动画
        var intervalId = setInterval(function () {
            ctx.clearRect(0,0,width,height);
            drawScore();
            snake.move();
            snake.draw();
            apple.draw();
            drawBroder();
        },200);
        
        //添加keydow事件处理程序
        var directions ={
            37:"left",
            38:"up",
            39:"right",
            40:"down"
        };
        $("body").keydown(function (event) {
            var newDirection = directions[event.keyCode];
            if(newDirection !== undefined){
                snake.setDirection(newDirection);
            }
        });
    </script>
</body>

这两天在学习贪吃蛇游戏,这些代码虽然已经能够看懂了,但是不看代码自己写,还是不知道怎么下手,难道这是新手普遍问题嘛?
贪吃蛇代码写到一半,没有思路了,笔记也没有整体脉络,心情很烦躁,去看了其他的学习视频,突然想到可以用思维导图来梳理程序脉络。
晚饭后花了两小时整理的程序脉络,有了这张图之后自己对程序框架了解也更显清晰了。
贪吃蛇


uccs
756 声望88 粉丝

3年 gis 开发,wx:ttxbg210604