好家伙,

 

我们先来尝试完成一个最简单的功能

正面buff:

1.消灭全图敌机

 

我们要先找一个好看一点的素材

 

 

把背景弄成透明的(搞了好久),感谢度娘的技术支持Photoshop中如何把图片的背景变成透明的-百度经验 (baidu.com)

你问我为什么是篮球?

只因你太美

 

为了方便测试,我们先弄个测试版本出来

// 全局函数 隔一段时间就来初始化一架敌机/奖励
function createComponent() {
const currentTime = new Date().getTime();
if (currentTime - ENEMY_LASTTIME >= ENEMY_CREATE_INTERVAL) {
let ran = Math.floor(Math.random() * 100);
// if (ran < 55) {
// enemies.push(new Enemy(E1));
// } else if (ran < 85 && ran > 55) {
// enemies.push(new Enemy(E2));
// } else if (ran < 95 && ran > 85) {
// enemies.push(new Enemy(E3));
// } else if (ran > 95) {
// awards.push(new award(C1)); // }
if (ran < 30) {
enemies.push(new Enemy(E1));
} else {
awards.push(new award(C1));
}
ENEMY_LASTTIME = currentTime;
}
}

(将原本的敌机生产流程,变成只生产小敌机和奖励类)

这么做是为了方便测试

 

来吧,

1.奖励类图片素材路径

c1: "img/lanqiu.jpg"
const c1 = createImage(IMAGES.c1);

 

2.奖励类配置项

const C1 = {
type: 4,
width: 75,
height: 75,
life: 1,
score: 1,
img: c1,
minSpeed: 5,
maxSpeed: 10
};

 

3.奖励类

这个奖励类的实现逻辑其实和敌机一样(没有动画渲染,甚至比敌机类更简单一点)

//初始化奖励类
class award {
constructor(config) {
this.type = config.type;
this.width = config.width;
this.height = config.height;
this.x = Math.floor(Math.random() * (480 - config.width));
this.y = -config.height;
this.life = config.life;
this.score = config.score;
this.img = config.img;
this.live = true;
this.speed = Math.floor(Math.random() * (config.minSpeed - config.maxSpeed + 1)) + config.maxSpeed;
this.lastTime = new Date().getTime();
this.deathIndex = 0;
this.destory = false;
}
move() {
const currentTime = new Date().getTime();
if (currentTime - this.lastTime >= this.speed) {
if (this.live) {
this.y = this.y + 6;
this.lastTime = currentTime;
} else {
this.destory = true; }
}
}
paint(context) {
context.drawImage(this.img, this.x, this.y, this.width, this.height);
}
outOfBounds() {
if (this.y > 650) {
return true;
}
}
hit(o) {
let ol = o.x;
let or = o.x + o.width;
let ot = o.y;
let ob = o.y + o.height;
let el = this.x;
let er = this.x + this.width;
let et = this.y;
let eb = this.y + this.height;
if (ol > er || or < el || ot > eb || ob < et) {
return false;
} else {
return true;
}
}
// collide() {
// this.life--;
// if (this.life === 0) {
// this.live = false;
// score += this.score;
// }
// }
}

 

4.全局渲染

// 全局函数 来绘制所有的子弹/敌人组件 绘制score&life面板
function paintComponent() {
for (let i = 0; i < hero.bulletList.length; i++) {
hero.bulletList[i].paint(context);
}
for (let i = 0; i < enemies.length; i++) {
enemies[i].paint(context);
}
for (let i = 0; i < awards.length; i++) {
awards[i].paint(context);
}
context.font = "20px 微软雅黑";
context.fillStyle = "red";
context.textAlign = "left";
context.fillText("score: " + score, 10, 20);
context.textAlign = "right";
context.fillText("life: " + life, 480 - 10, 20);
//重置样式
context.fillStyle = "black";
context.textAlign = "left";
}

5.全局移动

// 全局函数 来判断所有的子弹/敌人组件 "负责移动"
function judgeComponent() {
for (let i = 0; i < hero.bulletList.length; i++) {
hero.bulletList[i].move();
}
for (let i = 0; i < enemies.length; i++) {
enemies[i].move();
}
for (let i = 0; i < awards.length; i++) {
awards[i].move();
}
}

 

6.全局碰撞判断

// 碰撞检测函数
//此处的碰撞检测包括
//1.子弹与敌机的碰撞
//2.英雄与敌机的碰撞
//3.英雄与随机奖励的碰撞
function checkHit() {
// 遍历所有的敌机
for (let i = 0; i < awards.length; i++) {
//检测英雄是否碰到奖励类
if (awards[i].hit(hero)) {
//当然了,这个随机奖励的样式也要删了
awards.splice(i,1);
//清除所有的敌机
// for (let i = 0; i < enemies.length; i++) {
// enemies.splice(i, 1);
// }
enemies.length =0; }
}
for (let i = 0; i < enemies.length; i++) {
//检测英雄是否撞到敌机
if (enemies[i].hit(hero)) {
//将敌机和英雄的destory属性改为true
enemies[i].collide();
hero.collide();
}
for (let j = 0; j < hero.bulletList.length; j++) {
enemies[i].hit(hero.bulletList[j]);
//检测子弹是否撞到敌机
if (enemies[i].hit(hero.bulletList[j])) {
//将敌机和子弹的destory属性改为true
enemies[i].collide();
hero.bulletList[j].collide();
}
}
}
}

看这里就好

for (let i = 0; i < awards.length; i++) {
//检测英雄是否碰到奖励类
if (awards[i].hit(hero)) {
//当然了,这个随机奖励的样式也要删了
awards.splice(i,1);
//清除所有的敌机
// for (let i = 0; i < enemies.length; i++) {
// enemies.splice(i, 1);
// }
enemies.length =0; }
}

(全删了不就好了,刚开始是想着一个个删的)

来看看效果:

 (非常nice)

现在我们调回上线版本

function createComponent() {
const currentTime = new Date().getTime();
if (currentTime - ENEMY_LASTTIME >= ENEMY_CREATE_INTERVAL) {
let ran = Math.floor(Math.random() * 100);
if (ran < 55) {
enemies.push(new Enemy(E1));
} else if (ran < 85 && ran > 55) {
enemies.push(new Enemy(E2));
} else if (ran < 95 && ran > 85) {
enemies.push(new Enemy(E3));
} else if (ran > 95) {
awards.push(new award(C1)); } ENEMY_LASTTIME = currentTime;
}
}

(随机奖励给个百分之五吧,不然太bug了)

来看看效果:

 

Html飞机大战(十六): 完成"清除"敌机奖励类的更多相关文章

  1. Html飞机大战(十八): 模块化+项目开源

    好家伙,好久好久没有更新这个系列了   为了使文档更方便阅读,使代码更容易维护,来把这个飞机大战模块化 项目已开源: https://gitee.com/tang-and-han-dynasties/ ...

  2. 章节十六、3-TestNG方法和类注解

    一.Test Suite(测试套件) 我们通常认为一个testcase就是一个测试方法,但是会有很多的testcase,所以我们不可能把所有的testcase放到同一个测试类中,假如需要测试的页面有1 ...

  3. HTML5学习笔记(十六):原型、类和继承【JS核心知识点】

    理解原型 在JavaScript中,只要声明了一个函数,就会为该函数创建一个名为prototype的属性,该属性指向当前函数的原型对象. 而函数的原型对象有一个constructor属性,该属性指向刚 ...

  4. Java并发(十六):并发工具类——Exchanger

    Exchanger(交换者)是一个用于线程间协作的工具类.Exchanger用于进行线程间的数据交换.它提供一个同步点,在这个同步点两个线程可以交换彼此的数据.这两个线程通过exchange方法交换数 ...

  5. JAVASE(十六) IO流 :File类、节点流、缓冲流、转换流、编码集、对象流

    个人博客网:https://wushaopei.github.io/    (你想要这里多有) 1.File类型 1.1.File类的理解 File类是在java.io包下 File可以理解成一个文件 ...

  6. python版飞机大战代码简易版

    # -*- coding:utf-8 -*- import pygame import sys from pygame.locals import * from pygame.font import ...

  7. 【cocos2d-x 3.7 飞机大战】 决战南海I (四) 敌机管理

    敌方飞机应该不定时的出现,有自己的生命周期.运动轨迹.这个类用来管理敌机的产生.移动.爆炸.销毁等. 敌机管理类主要函数例如以下 //绑定控制器(更新分数) void bindController(C ...

  8. web版canvas做飞机大战游戏 总结

    唠唠:两天的时间跟着做了个飞机大战的游戏,感觉做游戏挺好的.说是用html5做,发现全都是js.说js里一切皆为对象,写的最多的还是函数,都是函数调用.对这两天的代码做个总结,希望路过的大神指点一下, ...

  9. Cocos2d-x 3.0final 终结者系列教程16-《微信飞机大战》实现

    看到cocos2d-x推出了3.1版本号,真是每月一次新版本号,速度. 另一个好消息就是http://cn.cocos2d-x.org/上线了,祝贺!啥时候把我的视频和教程放上去呢?!! . 视频下载 ...

  10. 我的第一个NPM包:panghu-planebattle-esm(胖虎飞机大战)使用说明

    好家伙,我的包终于开发完啦 欢迎使用胖虎的飞机大战包!! 为你的主页添加色彩 这是一个有趣的网页小游戏包,使用canvas和js开发 使用ES6模块化开发 效果图如下:  (觉得图片太sb的可以自己改 ...

随机推荐

  1. [转帖]【k8s】5、资源管理命令-声明式

    文章目录 一. yaml和json介绍 1.yuml语言介绍 2.k8s支持的文件格式 3.yaml和json的主要区别 二.声明式对象管理 1.命令式对象配置 2.声明式对象配置 3.声明式对象管理 ...

  2. [转帖]多CPU && 多核CPU | 多进程 && 多线程 | 并行 && 并发

    https://cloud.tencent.com/developer/article/1886157?areaSource=&traceId=   文章目录 区分 多CPU &&am ...

  3. 服务器Raid配置的一些思考

    背景 随着公司软件的发展.客户越来越多. 测试环境和兼容环境也越来越多. 不管是虚拟化,还是裸金属做数据库 存储都是绕不开的一道门槛. 最近又上架了几台服务器, 所以想趁着周末总结一下 最近服务器上架 ...

  4. docker上部署启动RabbitMQ

    在docker上部署启动RabbitMQ及使用 一.docker上部署启动RabbitMQ 1.查询rabbitmq镜像 docker search rabbitmq:management 2.拉取r ...

  5. Gin 应用多实例部署session问题、session参数与刷新

    目录 一.Gin Session 存储的实现方案 二.memstore:基于内存的实现 2.1 基本使用 2.2 关键参数 三.使用redis:多实例部署 3.1 使用redis优势 3.2 基本使用 ...

  6. 小白学k8s(1)二进制部署k8s

    二进制部署k8s 前言 准备工作 关闭防火墙 关闭 swap 分区 关闭 SELinux 更新系统时间 秘钥免密码 设置主机名称 服务器角色 安装etcd 创建证书 生成证书 部署Etcd 在Node ...

  7. MiniRBT中文小型预训练模型:结合了全词掩码技术和两段式知识蒸馏技术,加快推理速度

    MiniRBT中文小型预训练模型:结合了全词掩码(Whole Word Masking)技术和两段式知识蒸馏(Knowledge Distillation)技术,加快推理速度 在自然语言处理领域中,预 ...

  8. 关于飞桨UIE等模型预测推理时间很久的问题分析以及解决,蒸馏剪枝部署问题解决

    1.关于飞桨UIE等模型预测推理时间很久的问题分析以及解决 1.1.原因分析 用uie做实体识别,Taskflow预测的时间与schema内的实体类别数量成正比,schema里面有多少个实体类别 实体 ...

  9. 纪念JDBC

    技术总是在不断更新变化的,尤其是在IT编程领域. 有时候我们理所当然的用着现成的框架,以至于用的太过于顺手,更要时不时的骂一句: 什么垃圾框架?我家狗都不会用! 如果那些被拍死在沙滩的"前浪 ...

  10. python截取字符串(字符串切片)

    python中使用[]来截取字符串,语法: 字符串[起始位置:结束位置] 一.起始位置:结束位置 先看几个例子: s = 'python' print(s) #输出 python 直接输出字符串 #从 ...