Html飞机大战(十六): 完成"清除"敌机奖励类
好家伙,
我们先来尝试完成一个最简单的功能
正面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了)
来看看效果: