好家伙,接着写
既然我们涉及到状态了,那么我们也会涉及到状态的切换
那么我们怎样切换状态呢?
想象一下,如果我玩的游戏暂停了,那么我们肯定是通过点击或者按下某个按键来让游戏继续
这里我们选择添加点击事件来切换游戏状态
1.我们给canvas对象添加一个点击事件用于切换状态
canvas.addEventListener("click", () => { if (state === START) { state = STARTING; } });
然后我们去弄一点飞机加载图片
(自己用PS画的,将就着用吧)
2.定义一个图片数组,用于存放图片
const loading_frame = []; loading_frame[0] = new Image() loading_frame[0].src = "img/game_loading1.jpg" loading_frame[1] = new Image() loading_frame[1].src = "img/game_loading2.jpg" loading_frame[2] = new Image() loading_frame[2].src = "img/game_loading3.jpg" loading_frame[3] = new Image() loading_frame[3].src = "img/game_loading4.jpg"
我们会用一个变量的++来选择渲染哪一张图片
3.配置加载类Loading的配置项LOADING
//飞机加载界面类的配置项 const LOADING = { //图片数组 frame: loading_frame, //图片的宽 width: 480, //图片的高 height: 100, //图片的初始绘制x,y轴 x: 0, //总高减去图片的高度 y: 650 - 100, //速度单位为毫秒 speed: 1000, };
(注释说的非常清楚了)
4.编辑Loading类:
class Loading { constructor(config) { this.frame = config.frame; //加载哪张图片的下标 this.frameIndex = 0; //图片宽度 this.width = config.width; //图片高度 this.height = config.height; this.x = config.x; this.y = config.y; this.speed = config.speed; this.lastTime = new Date().getTime(); } //一样的判断方法和绘图方法 judge() { const currentTime = new Date().getTime(); if (currentTime - this.lastTime > this.speed) { this.frameIndex++; console.log(this.frameIndex); if (this.frameIndex === 4) { //更新状态 state = RUNNING; } //更新时间 this.lastTime = currentTime; } } paint(context) { context.drawImage(this.frame[this.frameIndex], this.x, this.y, this.width, this.height) } }
方法说明:
4.1.judge方法
这里我们通过frameIndex的数字变化来对应不同的图片
和天空类相同,这里我们把(变量的控制/更新时机的判断)与绘制分开来
原理还是那条公式, 现在的时间-最后一次更新的时间 > 速度 =====>可以更新了
4.2.更新状态
if (this.frameIndex === 4) { //更新状态 state = RUNNING; }
当四张图片都加载完以后,进入到下一个状态
4.3.paint图片绘制方法
paint(context) { context.drawImage(this.frame[this.frameIndex], this.x, this.y, this.width, this.height) }
还是那几个参数(忘了就去翻前两篇博客)
5.实例化
const loading = new Loading(LOADING);
6.方法的调用
在switch结构语句里加上方法调用
case STARTING: sky.judge(); sky.paint(context); //这里需要一个飞机加载的loading loading.judge(); loading.paint(context); break;
好了,让我们来看看看效果:
(第一帧好像跳的有点快)
全部代码如下:
<!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"; //定义游戏状态 const START = 0; const STARTING = 1; const RUNNING = 2; const PAUSE = 3 const END = 4; //初始化一个加载图片logo const copyright = new Image(); copyright.src = "img/START.jpg" //初始化飞机大战的加载图片 const loading_frame = []; loading_frame[0] = new Image() loading_frame[0].src = "img/game_loading1.jpg" loading_frame[1] = new Image() loading_frame[1].src = "img/game_loading2.jpg" loading_frame[2] = new Image() loading_frame[2].src = "img/game_loading3.jpg" loading_frame[3] = new Image() loading_frame[3].src = "img/game_loading4.jpg" /* image 加载的图片对象 dX为图片开始绘制的左上角横坐标 dY为图片开始绘制的左上角横坐标 dWidth为图片在canvas绘制的宽度 dHeight为图片在canvas绘制的宽度 */ /* 首参为事件名 二参为一个回调函数,表示加载完毕后执行的代码 */ //已经是Java的形状了 class Sky { constructor(config) { //图片资源 this.bg = config.bg; this.width = config.width; this.height = config.height; this.x1 = 0; this.y1 = 0; this.x2 = 0; this.y2 = -this.height; this.speed = config.speed; //最后更新时间 this.lasttime = new Date().getTime(); } //判断方法 judge() { let currentTime = new Date().getTime(); //在此处增加一个判断 if (currentTime - this.lasttime > this.speed) { this.y1++; this.y2++; this.lasttime = currentTime; } //渲染完毕,重置y1,y2 if (this.y2 === 0) { this.y1 = 0; this.y2 = -this.height; } } //绘图方法 paint(context) { context.drawImage(this.bg, this.x1, this.y1++, this.width, this.height); context.drawImage(this.bg, this.x2, this.y2++, this.width, this.height); if (this.y2 === 0) { this.y1 = 0; this.y2 = -650; } } } //天空类的配置项 const SKY = { bg: bg, width: 480, height: 650, speed: 10, /* 速度 */ } //初始化一个飞机加载界面类 class Loading { constructor(config) { this.frame = config.frame; //加载哪张图片的下标 this.frameIndex = 0; //图片宽度 this.width = config.width; //图片高度 this.height = config.height; this.x = config.x; this.y = config.y; this.speed = config.speed; this.lastTime = new Date().getTime(); } //一样的判断方法和绘图方法 judge() { const currentTime = new Date().getTime(); if (currentTime - this.lastTime > this.speed) { this.frameIndex++; console.log(this.frameIndex); if (this.frameIndex === 4) { //更新状态 state = RUNNING; } //更新时间 this.lastTime = currentTime; } } paint(context) { context.drawImage(this.frame[this.frameIndex], this.x, this.y, this.width, this.height) } } //飞机加载界面类的配置项 const LOADING = { //图片数组 frame: loading_frame, //图片的宽 width: 480, //图片的高 height: 100, //图片的初始绘制x,y轴 x: 0, //总高减去图片的高度 y: 650 - 100, //速度单位为毫秒 speed: 1000, }; //初始化一个天空实例 const sky = new Sky(SKY); //初始化一个飞机界面加载实例 const loading = new Loading(LOADING); //state表示游戏状态 取值必须是以上的五种状态 let state = START; //为canvas绑定一个点击事件,且如果是START状态的时候需要修改成 //STARING状态 canvas.addEventListener("click", () => { if (state === START) { state = STARTING; } }); //开始加载图片了: bg.addEventListener("load", () => { /* callback: Function 表示回调函数 timeout: Number 表示每次调用函数所间隔的时间段 */ setInterval(() => { switch (state) { case START: sky.judge(); sky.paint(context); //渲染飞机大战LOGO //图片原始宽高 let logo_x = (480 - copyright.naturalWidth) / 2; let logo_y = (650 - copyright.naturalHeight) / 2; context.drawImage(copyright, logo_x, logo_y) break; case STARTING: sky.judge(); sky.paint(context); //这里需要一个飞机加载的loading loading.judge(); loading.paint(context); break; case RUNNING: sky.judge(); sky.paint(context); //加载敌机 break; case PAUSE: sky.judge(); sky.paint(context); //加载暂停页面 break; case END: sky.judge(); sky.paint(context); //加载游戏结束字样 break; } }, 10); }) </script> </body> </html>Html飞机大战Demo
标签:loading,const,frame,Html,context,new,界面,config,加载 From: https://www.cnblogs.com/FatTiger4399/p/16629003.html