canvas小游戏指南

1.布局

绘制背景及图片按照实际图片大小绘制,比如

  • 先获取图片的宽高
 this.w = game.allImg["bg_day"].width;
 this.h = game.allImg["bg_day"].height;
  • 绘制背景,每一帧都需要向左移背景,让他动起来,当向左移动的时候右侧会露底,在这里多增加几张图片,当移动的x距离等于一屏宽的时候,让x = 0
  game.draw.fillStyle = "#4ec0ca";
  game.draw.fillRect(0, 0, game.canvas.width, game.canvas.height)
  game.draw.drawImage(game.allImg["bg_day"], this.x, game.canvas.height - this.h)
  game.draw.drawImage(game.allImg["bg_day"], this.x + this.w, game.canvas.height - this.h)
  game.draw.drawImage(game.allImg["bg_day"], this.x + this.w * 2, game.canvas.height - this.h)

2.随机长度的管道

绘制随机长度管道,不仅感到高度要随机生成,绘制的时候 参数变为9个 drawImage(img,x1,y1,w1,h1,x2,y2,w2,h2)

  • 第一个参数绘制的图片
  • x1(图片裁剪的起始x坐标) y1(图片裁剪的起始y坐标) x2(图片绘制到画布的其实x坐标) y2(图片绘制到画布其实y坐标)
  • w1,h1,w2,h2(图片宽高)

3.小鸟的飞行

小鸟与管道的碰撞检,当前一屏显示的管道都会存在数组中,因为管道是长度不等的,我们检测小鸟与每一条管道的碰撞

发生碰撞的条件

  • B.x2 > = P.x1
  • B.x1 < = P.x2
  • B.y1 < = p.y1
  • B.y2 > = this.space + P.y1

4. 场景管理

使用场景管理函数管理多个场景

  • 全局中定义scene默认为 0 场景管理函数中,enter() 初始化场景属性
  • updateAndRender 更新和传染场景
  • bindEvent场景内的事件函数
enter(scene) {
        switch (scene) {
            case 0:
                game.bg = new BackGround()
                game.land = new Land()
                this.titleW = game.allImg["title"].width;
                this.titleX = game.canvas.width / 2 - this.titleW / 2;
                this.titleY = -50;
                this.btnX = game.canvas.width / 2 - game.allImg["button_play"].width / 2;
                this.btnY = game.canvas.height;
                this.birdX = game.canvas.width / 2 - game.allImg["bird0_0"].width / 2;
                this.birdY = 220;
                this.birdChangeY = 1;
                break;
            case 1:
                game.scene = 1;
                game.bg = new BackGround();
                game.land = new Land();
                this.tutorialW = game.allImg["tutorial"].width;
                this.tutorialX = game.canvas.width / 2 - this.tutorialW / 2;
                this.tutorialY = 250;
                this.alpha = 1;
                this.alphaChange = 0.03;
                break;
                ...
updateAndRender(){
    switch (game.scene){
      case 0:
        game.bg.render();
        game.land.render();
        this.titleY>=160?this.titleY=160:this.titleY+=5;
        this.btnY<=370?this.btnY=370:this.btnY-=10;
        if(this.birdY>300||this.birdY<220){
          this.birdChangeY*=-1;
        }
        this.birdY+=this.birdChangeY;
        game.draw.drawImage(game.allImg["title"],this.titleX,this.titleY);
        game.draw.drawImage(game.allImg["bird0_0"],this.birdX,this.birdY);
        game.draw.drawImage(game.allImg["button_play"],this.btnX,this.btnY);
        break;
      case 1:
        game.bg.render();
        game.land.render();
        game.draw.drawImage(game.allImg["bird0_0"],game.canvas.width/2-24,160);
        if(this.alpha>1||this.alpha<0)this.alphaChange*=-1;
        this.alpha+=this.alphaChange;
        game.draw.save();
        game.draw.globalAlpha=this.alpha;
        game.draw.drawImage(game.allImg["tutorial"],this.tutorialX,this.tutorialY);
        game.draw.restore();
        break;
        ...
 bindEvent() {
        game.canvas.onclick = (e) => {
            switch (game.scene) {
                case 0:
                    if (e.clientX >= this.btnX && e.clientX <= this.btnX + 116 && e.clientY >= this.btnY && e.clientX <= this.btnY + 70) {
                        this.enter(1)
                    }
                    break;

颁奖场景

每次用户结束游戏把分数存储localStorage中,有三个奖牌,数组中默认三个都为0,每次游戏结束后,获取当前localStorage中的值,从大到下排序,如果当前值大于数组中第一个,赋值并状态为金牌,以此类推

      let arr = JSON.parse(localStorage.getItem("FB"));
                arr.sort(function (a,b) {
                    return b-a
                })
                for (let i = 0; i < arr.length; i++) {
                    if (game.score >= arr[0]) {
                        arr[0] = game.score;
                        this.model = "medals_1";
                    } else if (game.score >= arr[1]) {
                        this.model = "medals_2";
                        arr[1] = game.score;
                    } else if (game.score >= arr[2]) {
                        this.model = "medals_3";
                        arr[2] = game.score;
                    } else {
                        this.model = "medals_0"
                    }
                }
                this.best = arr[0];
                localStorage.setItem("FB", JSON.stringify(arr));

绘制奖牌

 game.draw.drawImage(game.allImg[this.model],this.panelX+28,this.panelY+44);
                game.draw.fillStyle="#666"
                game.draw.font="20px consolas";
                game.draw.textAlign="right"
                game.draw.fillText(game.score,(game.canvas.width / 2) + 90 , this.panelY + 50);
                game.draw.fillText(this.best,(game.canvas.width / 2) + 90 , this.panelY + 96);