VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 网站开发 > HTML >
  • Html飞机大战(一):绘制动态背景

好家伙,飞机大战终于开始弄了

这会有很多很多复杂的东西,但是我们总要从最简单,和最基础的部分开始,

 

我们先从背景开始弄吧!

 

1.绘制静态背景

这里我们会用到canvas

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width-devic-width,initial-scale=1.0">
<title>飞机大战</title>
<style>
    *{
        padding: 0;
        margin: 0;
    }
    canvas{
        border: 1px solid red;
        margin: auto;
    }
    #stage{
        width: 480px;
        height: 650px;
        margin: auto;
    }
</style>
</head>
<body>
    <div id="stage">
        <canvas id="canvas" width="480" height="650"></canvas>
    </div>
    <script>
        // 1.让画笔能够绘制图片
        // 1.1找到这个画布
        const canvas = document.querySelector("#canvas");
        // 1.2.利用这个画布初始换一个2D的画框
        const context = canvas.getContext("2d");

        // 2.加载这张图片
        const bg = new Image();
        bg.src="img/1.jpg";
        /* 
          image 加载的图片对象
          dX为图片开始绘制的左上角横坐标
          dY为图片开始绘制的左上角横坐标
          dWidth为图片在canvas绘制的宽度
          dHeight为图片在canvas绘制的宽度
        */
        //context.drawImage(Image,dX,dY,dWidth,dHeight)
        context.drawImage(bg,0,0,480,650)
    
    </script>
</body>
</html>
复制代码

 

然后理所当然的失败了:

于是我们来看一下代码:

会发现:

const bg = new Image();
bg.src="img/1.jpg";

这两家伙是异步代码;

我们不清楚他什么时候执行完毕

如果在绘制之前图片还没有加载还没有完毕

 

那么

context.drawImage(Image,dX,dY,dWidth,dHeight)

就只能绘制出一张空白背景了

 

所以必须等图片加载完毕后,再进行图片的绘制

 

我们的解决方案是:给它加一个”load“

 

/*

稍微提一下箭头函数:

原函数:

hello = function() {
  return "Hello World!";
}

箭头函数:

hello = () => "Hello World!";

(仅有单一返回值时可以省略return)

箭头函数好东西,ES6的新特性

 

简化函数的写法,视觉上看也更直观

 */

 

 

为其增加一个addEventListener

复制代码
bg.addEventListener("load",()=>{
            /* 
          image 加载的图片对象
          dX为图片开始绘制的左上角横坐标
          dY为图片开始绘制的左上角横坐标
          dWidth为图片在canvas绘制的宽度
          dHeight为图片在canvas绘制的宽度
        */
       
        context.drawImage(bg,0,0,480,650)
        })
       //首参为事件名
       //二参为一个回调函数,表示加载完毕后执行的代码
复制代码

 

"load"事件表示等待对象加载完毕

 

那么异步的问题就解决了

 

 

来看看效果:

 

 

 (刁图一堆)

这个时候就有人问了:

博主你是SB吗?一个<img>能搞定的为这么弄的这么麻烦,

 

诶,别急,这么弄是为了接下来的动态效果实现做铺垫

 

2.动态效果(实现向下移动)

首先确定思路:

我要让背景动起来

可以更改他渲染起点的y轴坐标(y++)

并且让它重复渲染

 

思路有了,就好办了:

我们用变量来代替参数(方便加减操作)

let x = 0;
let y = 0;

(此处为全局变量,以后会改)

 

重复渲染我们用到setInterval方法:

 

/*

    setinterval()是定时调用的函数,可按照指定的周期(以毫秒计)来调用函数或计算表达式。

 */

 

我们把绘制方法(drawImage)塞到这个里面

setInterval(()=>{context.drawImage(bg,x,y++,480,650);
              },10);

(这里有个小问题,y轴是指向下的?y++反而是让图片向下移动,没弄懂,待解决)

 

来看看效果:

 

 

但是问题又来了,在跑完一次(一次绘制完毕)之后他就没东西渲染了,又变回空白了

 

所以我们在再弄一个context.drawImage并且让他从纵坐标-650开始

     let x1 = 0;
        let y1 = 0;
        let x2 = 0;
        let y2 = -650;

方法部分:

复制代码
bg.addEventListener("load",()=>{
            /* 
               callback: Function 表示回调函数
               timeout: Number 表示每次调用函数所间隔的时间段    
            */ 
            setInterval(()=>{context.drawImage(bg,x1,y1++,480,650);
            },10);
            setInterval(()=>{context.drawImage(bg,x2,y2++,480,650);
            },10);
        })
复制代码

 

 

(犯了个错误,应该把两个context.drawImage塞到同一个setInterval中,这样写不便于变量的管理) 

 

还是那个问题,第二张图渲染完之后,再次遇到了空白的情况

 

所以,我们要想办法让他循环起来

思路如下:

尝试着让两张图循环渲染

流程如下:

第一张图开始渲染,

第一张图渲染结束,

第二张图开始渲染,

第二张图渲染结束,

第二张图渲染结束后,把第一张图的y坐标设为第二张图片渲染结束时尾部的坐标

再将第二张图片的y坐标重置到初始位置

问题就结解决了

 

 

代码如下:

我们用一个if语句去充值y坐标轴:

复制代码
setInterval(()=>{
                context.drawImage(bg,x1,y1++,480,650);
                context.drawImage(bg,x2,y2++,480,650);
                if(y2===0){
                    y1=0;
                    y2=-650;
                }
            
            },10);
复制代码

 

来看看效果:

 

 

 

搞定咯:

全部代码如下:

复制代码
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewprot" content="width-devic-width,initial-scale=1.0">
<title>飞机大战</title>
<style>
    *{
        padding: 0;
        margin: 0;
    }
    canvas{
        border: 1px solid red;
        margin: auto;
    }
    #stage{
        width: 480px;
        height: 650px;
        margin: auto;
    }
</style>
</head>
<body>
    <div id="stage">
        <canvas id="canvas" width="480" height="650"></canvas>
    </div>
    <script>
        // 1.让画笔能够绘制图片
        // 1.1找到这个画布
        const canvas = document.querySelector("#canvas");
        // 1.2.利用这个画布初始换一个2D的画框
        const context = canvas.getContext("2d");
        /* canvas画布绘制bg对象时的坐标 */
        let x1 = 0;
        let y1 = 0;
        let x2 = 0;
        let y2 = -650;
        // 2.加载这张图片
        const bg = new Image();
        bg.src="img/4.jpg";
        /* 
          image 加载的图片对象
          dX为图片开始绘制的左上角横坐标
          dY为图片开始绘制的左上角横坐标
          dWidth为图片在canvas绘制的宽度
          dHeight为图片在canvas绘制的宽度
        */
        /* 
           首参为事件名
           二参为一个回调函数,表示加载完毕后执行的代码 
        */
        bg.addEventListener("load",()=>{
            /* 
               callback: Function 表示回调函数
               timeout: Number 表示每次调用函数所间隔的时间段    
            */ 
            setInterval(()=>{
                context.drawImage(bg,x1,y1++,480,650);
                context.drawImage(bg,x2,y2++,480,650);
                if(y2===0){
                    y1=0;
                    y2=-650;
                }
            
            },10);
        })
    </script>
</body>
</html>
复制代码

 

 

3.canvas的坐标:

这玩意跟我们平时数学上用的平面直角坐标系(笛卡尔坐标系)不同;

 

 它Y轴是反着来的

 

 

That's all

 

 出处:https://www.cnblogs.com/FatTiger4399/p/16559512.html


相关教程