Html飞机大战(四):状态的切换(界面加载类的编辑)
好家伙,接着写
既然我们涉及到状态了,那么我们也会涉及到状态的切换
那么我们怎样切换状态呢?
想象一下,如果我玩的游戏暂停了,那么我们肯定是通过点击或者按下某个按键来让游戏继续
这里我们选择添加点击事件来切换游戏状态
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
Html飞机大战(四):状态的切换(界面加载类的编辑)的更多相关文章
- ios单独的页面支持横竖屏的状态调整,HTML5加载下(更新2)
单独的页面支持横竖屏的状态调整,HTML5加载下 工程中设置只支持竖屏状态,在加载HTML5的界面可以是横竖屏的,在不对工程其他界面/设置做调整的同时,可以这样去 #import "View ...
- 练习PopupWindow弹出框之实现界面加载的时候显示弹出框到指定的view下面--两种延迟方法
今天在练习PopupWindow弹出框的时候,打算在界面加载的时候将弹出框展现出来并显示在指定的view下面. 初步方法是直接在OnResume方法里面直接执行showPopupWindows方法. ...
- vue 实现tab切换动态加载不同的组件
vue 实现tab切换动态加载不同的组件 使用vue中的is特性来加载不同的组件.具体看如下代码:这个功能对于vue比较复杂的页面可以使用上,可以把一个页面的功能拆分出来,使代码更简单.使用方式具体看 ...
- 因为错误关闭Selinux导致CentOS7启动失败(进度条卡死,图形界面加载卡死)
我在CentOS7上安装oracle,非常麻烦,搞半天终于安装完毕,当天我没有发现任何问题,第二天上班打开虚拟机CentOS7就进不去了. 我想起来之前关闭了Selinux,把系统名称改成了redha ...
- ionic js 加载动画 ionSpinner 提供了许多种旋转加载的动画图标。当你的界面加载时,你就可以呈现给用户相应的加载图标。 该图标采用的是SVG
ionic 加载动画 ion-spinner ionSpinner 提供了许多种旋转加载的动画图标.当你的界面加载时,你就可以呈现给用户相应的加载图标. 该图标采用的是SVG. 用法 <ion- ...
- 飞机大战(1)--添加logo和加载动画
注:以下代码都是用scratch 3.0版本编写 素材链接: 链接:https://pan.baidu.com/s/1sXqeZVuFgVTYT0OtqxXilw 提取码:1126 一.背景添加 导入 ...
- WPF 界面实现多语言支持 中英文切换 动态加载资源字典
1.使用资源字典,首先新建两个字典文件en-us.xaml.zh-cn.xaml.定义中英文的字符串在这里面[注意:添加xmlns:s="clr-namespace:System;assem ...
- eclipse启动无响应,停留在Loading workbench状态,或老是加载不了revert resources
做开发的同学们或多或少的都会遇到eclipse启动到一定程度时,就进入灰色无响应状态再也不动了.启动画面始终停留在Loading workbench状态.反复重启,状态依旧. 多数情况下,应该是非正常 ...
- iOS app应用界面加载卡顿的问题
刚发布版本,忽然发现加载界面需要3-5秒延迟,那么问题来了. 首先,发现问题: 1.看代码,基于之前版本更新都没出问题,还是比较确信不是代码中的bug,以防万一,还是仔细看了下关于界面跳转部分的代码, ...
随机推荐
- BUUCTF-菜刀666
菜刀666 这题和之前做过的流量题不同,对我还是有些难度.看了看大佬的wp才做出来的 wireshark打开流量包,一开始只是单纯过滤http,包很多,看花了眼,看了好多也没觉得有啥异常. 后面才知道 ...
- UiPath从入门到精通视频教程
匠厂出品,必属精品 Uipath中文社区qq交流群:465630324 微信小程序搜索RPA之家小店可以购买相关RPA的课程,现在联系有优惠 官网:https://rpazj.com uipath ...
- js与java encodeURI 进行编码与解码
JS escape()使用转义序列替换某些字符来对字符串进行编码 JavaScript 中国 编码后 JavaScript %u4E2D%u56FD unescape()对使用 encodeUR ...
- 【RocketMQ】消息的存储
Broker对消息的处理 BrokerController初始化的过程中,调用registerProcessor方法注册了处理器,在注册处理器的代码中可以看到创建了处理消息发送的处理器对象SendMe ...
- NC19115 选择颜色
NC19115 选择颜色 题目 题目描述 \(n\) 个人排成一个环形,每个人要从 \(c\) 种颜色中选择一个. 牛牛希望相邻的人选择的颜色是不同的 问有多少种方案. 输出方案数对 \(10007\ ...
- 打印三角形及debug用法
package www.nihao; public class demo01 { public static void main(String[] args) { //打印三角形 5行 for(int ...
- Linux shell脚本进阶使用
shell的循环控制语句 - continue:提前结束某次循环,重新开始下一次 - break:提前结束某层循环 范例: #求100以内的奇数和 #!/bin/bash sum=0 for i in ...
- SpringMVC pom
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- idea反编译jar包,jclasslib Bytecode Viewer
下载 jclasslib Bytecode Viewer https://plugins.jetbrains.com/plugin/9248-jclasslib-bytecode-viewer/ver ...
- 【一本通提高博弈论】[ZJOI2009]取石子游戏
[ZJOI2009]取石子游戏 题目描述 在研究过 Nim 游戏及各种变种之后,Orez 又发现了一种全新的取石子游戏,这个游戏是这样的: 有 n n n 堆石子,将这 n n n 堆石子摆成一排.游 ...