利用Canvas实现Flappybird简陋游戏步骤

利用Canvas实现Flappybird简陋游戏步骤

Canvas是Html5中用于绘图的元素,它可以绘制各种图形,比如长方形,多边形,圆形等等。如果想要了解Canvas的使用可以参考:

http://www.w3school.com.cn/tags/html_ref_canvas.asp

  1. 创建Canvas标签、和获取绘图上下文。

     var cvs = document.getElementById('cvs');
     var ctx = cvs.getContext('2d')
    
  2. 资源加载,等所有图片资源加载完成之后,再调用main函数,真正开始游戏相关的逻辑。

    1. 把想要加载的图片的路径用数组存储起来(imgs),并新建一个空的数组(imgObjects)用于存储创建出来的img标签。
    2. 遍历imgs数组,依次用new Image()的方式创建图像标签,为它们设置src、添加加载完成事件的监听,并存储到imgObjects数组中。
    3. 书写监听器函数、创建一个计数器,该函数每次被调用时计数器+1,当计数器大于等于imgs数组长度时,所有图像加载完成,调用main函数,正式开始游戏逻辑。
  3. main函数中准备一个主循环函数loop、创建一个变量lastTime用于记录上一次调用loop时的时间,在loop中进行以下工作:

    1. 获取两帧间隔时间

      var now = Date.now();
      var dt = lastTime - now;
      lastTime = now;
      
    2. ctx.clearRect清空画布
    3. requestAnimationFrame(loop)让浏览器在自己觉得合适时,调用loop函数绘制下一帧。
      requestAnimationFrame(要循环的函数体) ,它会根据浏览器的情况,自动去优化循环的次数,正常的一个动画,每秒60帧就足够了。
  4. 封装想要绘制到屏幕上的显示对象:

    1. 小鸟精灵

      1. 小鸟会有的行为:1.以自己的速度切换要显示的图片;2.一直下落;3.在屏幕被点击时向上飞。
      2. update里要做的事情:

        1. this.waitTime记录小鸟在当前帧等待的时间,如果超过100毫秒,则切换图像

          this.waitTime += dt;
          if(this.waitTime > 100){
              this.frameIndex = (this.frameIndex + 1) % 3;
              this.waitTime -= 100;
          }
          
        2. 根据加速度和dt求得当前的速度,根据速度和dt求得当前的y轴坐标
      3. 绘制时的细节:

        1. 根据小鸟的速度获取小鸟在这一帧应该有的角度;

          var angle = this.speed / 0.3 * 45;
          
        2. 位移、旋转坐标系后,将小鸟绘制到屏幕上;

          ctx.save();  //保存上一次的坐标等状态              
          ctx.translate(this.x, this.y);
          ctx.rotate(angle / 180 * Math.PI);
          .....
          ctx.restore();  //恢复上一次的坐标等状态           
          
    2. 天空

      1. 一共有两块800*600的天空向左飘,哪块天空移出了屏幕,则将哪块天空移动到最右边(this.x = this.x + 800 * 2)。
    3. 管子
      1. 一共有5根52*420的管子,每隔200px绘制一根管子。和天空类似的,哪根管子移出了屏幕,则把哪根管子移动到最右侧,并随机生成一个上侧管子的长度pipe1H。(this.x = this.x + 200 * 5
      2. 绘制时的细节:
        1. 获取上侧的管子长度为pipe1H;把上侧的管子的图片绘制到 (this.x, pipe1H-420)点上,把下侧的管子绘制到(this.x, pipe1H + 150)的点上。(150是两根管子的间隔长度)
        2. 对两根管子分别绘制矩形路径,以便后面用isPointInPath判断小鸟是不是撞到了管子。
    4. 大地
      1. 和天空类似,但是一共有四块336*112的大地。
  5. 完成main函数,整体的架构如下:

    function main(){
    
        // TODO:创建程序所需的显示对象:鸟,天空,大地,管子
        ......
        // TODO:为canvas增加事件监听:每当鼠标点击时,给鸟一个-0.3的速度
        ......
        // TODO:主循环
        function loop(){
    
            // TODO:获取间隔时间,清空画布等
    
            // TODO:调用所有显示对象的update函数,更新各个显示对象的状态
    
    
            // TODO:根据小鸟的状态,判断小鸟是不是撞到了天花板或者地面
            if(.......){
                gameOver = true;
            }
            // TODO:用isPointInPath判断小鸟是不是撞在了柱子上。
            if(ctx.isPointInPath(bird.x, bird.y)){
                gameOver = true;
            }
            ctx.beginPath(); //记得清空路径,不要影响到下一帧的判断
    
    
            // TODO:调用所有显示对象的draw函数         
            if(!gameOver){
                requestAnimationFrame(loop)
            }
        }
        loop();
    }
    

可参看的博文:
http://www.cnblogs.com/xing901022/p/5094550.html

                                by  Turbo Beijing
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值