mirror of
https://github.com/unanmed/HumanBreak.git
synced 2025-01-19 20:59:37 +08:00
fix: 第二阶段bug
This commit is contained in:
parent
2b663da5db
commit
deabd10154
@ -20,6 +20,7 @@ import {
|
|||||||
ThunderProjectile
|
ThunderProjectile
|
||||||
} from './towerBossProjectile';
|
} from './towerBossProjectile';
|
||||||
import { IStateDamageable } from '@/game/state/interface';
|
import { IStateDamageable } from '@/game/state/interface';
|
||||||
|
import { HeroRenderer } from '@/core/render/preset/hero';
|
||||||
|
|
||||||
Mota.require('var', 'loading').once('coreInit', () => {
|
Mota.require('var', 'loading').once('coreInit', () => {
|
||||||
const shader = new Shader();
|
const shader = new Shader();
|
||||||
@ -136,9 +137,13 @@ export class TowerBoss extends BarrageBoss {
|
|||||||
this.state = core.status.hero;
|
this.state = core.status.hero;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private moveTick = (x: number, y: number) => {
|
||||||
|
this.hitbox.setPosition(x * 32 + 2, y * 32 + 2);
|
||||||
|
};
|
||||||
|
|
||||||
override start() {
|
override start() {
|
||||||
super.start();
|
super.start();
|
||||||
requestAnimationFrame(() => {
|
|
||||||
this.group.remove();
|
this.group.remove();
|
||||||
this.group.append(TowerBoss.shader);
|
this.group.append(TowerBoss.shader);
|
||||||
TowerBoss.shader.append(this.mapDraw);
|
TowerBoss.shader.append(this.mapDraw);
|
||||||
@ -146,14 +151,18 @@ export class TowerBoss extends BarrageBoss {
|
|||||||
this.word.append(this.group);
|
this.word.append(this.group);
|
||||||
this.main.append(this.group);
|
this.main.append(this.group);
|
||||||
|
|
||||||
|
const event = this.group.getLayer('event');
|
||||||
|
const hero = event?.getExtends('floor-hero') as HeroRenderer;
|
||||||
|
hero?.on('moveTick', this.moveTick);
|
||||||
|
|
||||||
ArrowProjectile.init();
|
ArrowProjectile.init();
|
||||||
PortalProjectile.init();
|
PortalProjectile.init();
|
||||||
ThunderProjectile.init();
|
ThunderProjectile.init();
|
||||||
|
ThunderBallProjectile.init();
|
||||||
AttackProjectile.init();
|
AttackProjectile.init();
|
||||||
|
|
||||||
TowerBoss.effect.start();
|
TowerBoss.effect.start();
|
||||||
TowerBoss.effect.use();
|
TowerBoss.effect.use();
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override end() {
|
override end() {
|
||||||
@ -164,9 +173,14 @@ export class TowerBoss extends BarrageBoss {
|
|||||||
this.word.remove();
|
this.word.remove();
|
||||||
this.main.remove();
|
this.main.remove();
|
||||||
|
|
||||||
|
const event = this.group.getLayer('event');
|
||||||
|
const hero = event?.getExtends('floor-hero') as HeroRenderer;
|
||||||
|
hero?.off('moveTick', this.moveTick);
|
||||||
|
|
||||||
ArrowProjectile.end();
|
ArrowProjectile.end();
|
||||||
PortalProjectile.end();
|
PortalProjectile.end();
|
||||||
ThunderProjectile.end();
|
ThunderProjectile.end();
|
||||||
|
ThunderBallProjectile.end();
|
||||||
AttackProjectile.end();
|
AttackProjectile.end();
|
||||||
|
|
||||||
TowerBoss.effect.end();
|
TowerBoss.effect.end();
|
||||||
@ -211,12 +225,12 @@ export class TowerBoss extends BarrageBoss {
|
|||||||
* @param last 持续时长
|
* @param last 持续时长
|
||||||
* @param damage 造成的伤害
|
* @param damage 造成的伤害
|
||||||
*/
|
*/
|
||||||
addAttackCircle(damage: number, n: number) {
|
addAttackCircle(_: number, n: number) {
|
||||||
const s = 13 - n * 2;
|
const s = 13 - n * 2;
|
||||||
const nx = Math.floor(Math.random() * s + n + 1);
|
const nx = Math.floor(Math.random() * s + n + 1);
|
||||||
const ny = Math.floor(Math.random() * s + n + 1);
|
const ny = Math.floor(Math.random() * s + n + 1);
|
||||||
const proj = this.createProjectile(AttackProjectile, nx * 32, ny * 32);
|
const proj = this.createProjectile(AttackProjectile, nx * 32, ny * 32);
|
||||||
proj.damage = damage;
|
proj.damage = 250 + Math.floor(Math.random() * 500);
|
||||||
}
|
}
|
||||||
|
|
||||||
ai(time: number, frame: number): void {
|
ai(time: number, frame: number): void {
|
||||||
@ -277,7 +291,7 @@ export class TowerBoss extends BarrageBoss {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (time > 1500) {
|
if (time > 1500) {
|
||||||
this.changeStage(TowerBossStage.Stage1, time);
|
this.changeStage(TowerBossStage.Dialogue1, time);
|
||||||
this.attackTime = 2;
|
this.attackTime = 2;
|
||||||
this.skill1Time = 1;
|
this.skill1Time = 1;
|
||||||
this.skill2Time = 1;
|
this.skill2Time = 1;
|
||||||
@ -747,7 +761,7 @@ class HealthBar extends RenderItem {
|
|||||||
this.trans.time(2000).mode(power(3, 'out')).transition('hp', value);
|
this.trans.time(2000).mode(power(3, 'out')).transition('hp', value);
|
||||||
this.delegateTicker(() => {
|
this.delegateTicker(() => {
|
||||||
this.update();
|
this.update();
|
||||||
}, 800);
|
}, 2500);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -440,12 +440,14 @@ export class ThunderProjectile extends Projectile<TowerBoss> {
|
|||||||
private sounded: boolean = false;
|
private sounded: boolean = false;
|
||||||
|
|
||||||
private effect?: PointEffect;
|
private effect?: PointEffect;
|
||||||
private effectId?: number;
|
private effectId1?: number;
|
||||||
|
private effectId2?: number;
|
||||||
|
|
||||||
static init() {
|
static init() {
|
||||||
this.cache = new MotaOffscreenCanvas2D();
|
this.cache = new MotaOffscreenCanvas2D();
|
||||||
this.cache.setHD(true);
|
this.cache.setHD(true);
|
||||||
this.cache.withGameScale(true);
|
this.cache.withGameScale(true);
|
||||||
|
this.cache.size(480, 480);
|
||||||
}
|
}
|
||||||
|
|
||||||
static end() {
|
static end() {
|
||||||
@ -458,11 +460,20 @@ export class ThunderProjectile extends Projectile<TowerBoss> {
|
|||||||
*/
|
*/
|
||||||
createEffect(effect: PointEffect) {
|
createEffect(effect: PointEffect) {
|
||||||
this.effect = effect;
|
this.effect = effect;
|
||||||
this.effectId = effect.addEffect(
|
this.effectId1 = effect.addEffect(
|
||||||
PointEffectType.CircleBrightness,
|
PointEffectType.CircleBrightness,
|
||||||
Date.now() + 1000,
|
Date.now() + 1000,
|
||||||
400,
|
600,
|
||||||
[this.bx * 32 + 32, this.by * 32 + 32, 128, 32]
|
[this.bx * 32 + 16, this.by * 32 + 16, 128, 32],
|
||||||
|
[1, 0, 0, 0]
|
||||||
|
);
|
||||||
|
this.effectId2 = effect.addEffect(
|
||||||
|
PointEffectType.CircleWarp,
|
||||||
|
Date.now() + 1000,
|
||||||
|
600,
|
||||||
|
[this.bx * 32 + 16, this.by * 32 + 16, 240 + this.power * 32, 32],
|
||||||
|
[0.1, 6, 0.8, 0],
|
||||||
|
[0, Math.PI, 0, 0]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,7 +510,7 @@ export class ThunderProjectile extends Projectile<TowerBoss> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ai(boss: TowerBoss, time: number, frame: number): void {
|
ai(boss: TowerBoss, time: number, frame: number): void {
|
||||||
if (time > 1000) {
|
if (time > 500) {
|
||||||
if (!this.sounded) {
|
if (!this.sounded) {
|
||||||
core.playSound('thunder.mp3');
|
core.playSound('thunder.mp3');
|
||||||
this.sounded = true;
|
this.sounded = true;
|
||||||
@ -513,8 +524,8 @@ export class ThunderProjectile extends Projectile<TowerBoss> {
|
|||||||
render(canvas: MotaOffscreenCanvas2D, transform: Transform): void {
|
render(canvas: MotaOffscreenCanvas2D, transform: Transform): void {
|
||||||
const ctx = canvas.ctx;
|
const ctx = canvas.ctx;
|
||||||
if (this.time < 1000) {
|
if (this.time < 1000) {
|
||||||
const before = ctx.fillStyle;
|
|
||||||
ctx.fillStyle = '#fff';
|
ctx.fillStyle = '#fff';
|
||||||
|
ctx.globalAlpha = 0.6;
|
||||||
for (let dx = -1; dx < 2; dx++) {
|
for (let dx = -1; dx < 2; dx++) {
|
||||||
for (let dy = -1; dy < 2; dy++) {
|
for (let dy = -1; dy < 2; dy++) {
|
||||||
const x = (this.bx + dx) * 32 + 2;
|
const x = (this.bx + dx) * 32 + 2;
|
||||||
@ -522,42 +533,41 @@ export class ThunderProjectile extends Projectile<TowerBoss> {
|
|||||||
ctx.fillRect(x, y, 28, 28);
|
ctx.fillRect(x, y, 28, 28);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.fillStyle = before;
|
|
||||||
} else {
|
} else {
|
||||||
if (!this.cached) this.cacheThunder();
|
if (!this.cached) this.cacheThunder();
|
||||||
if (!ThunderProjectile.cache) return;
|
if (!ThunderProjectile.cache) return;
|
||||||
const x = this.bx * 32;
|
|
||||||
const before = ctx.globalAlpha;
|
|
||||||
const progress = (this.time - 1000) / 1000;
|
const progress = (this.time - 1000) / 1000;
|
||||||
if (progress < 0.4) {
|
|
||||||
const effect = this.effect;
|
const effect = this.effect;
|
||||||
const id = this.effectId;
|
const id = this.effectId1;
|
||||||
if (!effect || isNil(id)) return;
|
if (!effect || isNil(id)) return;
|
||||||
const effectRatio = ArrowProjectile.dangerEasing!(
|
if (progress < 0.6) {
|
||||||
progress * 2.5
|
const x = this.bx * 32 + 16;
|
||||||
|
const y = this.by * 32 + 16;
|
||||||
|
effect.setEffect(
|
||||||
|
id,
|
||||||
|
[x, y, 32 + progress * 256, 32],
|
||||||
|
[(0.6 - progress) / 0.6, 0, 0, 0]
|
||||||
);
|
);
|
||||||
effect.setEffect(id, void 0, [effectRatio, 0, 0, 0]);
|
|
||||||
}
|
}
|
||||||
if (progress < 0.5) {
|
if (progress < 0.5) {
|
||||||
ctx.globalAlpha = 1;
|
ctx.globalAlpha = 1;
|
||||||
} else {
|
} else {
|
||||||
ctx.globalAlpha = 1 - (progress - 0.5) * 2;
|
ctx.globalAlpha = 1 - (progress - 0.5) * 2;
|
||||||
}
|
}
|
||||||
ctx.drawImage(ThunderProjectile.cache.canvas, x - 60, 0);
|
ctx.drawImage(ThunderProjectile.cache.canvas, 0, 0, 480, 480);
|
||||||
ctx.globalAlpha = before;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private cacheThunder() {
|
private cacheThunder() {
|
||||||
const cache = ThunderProjectile.cache;
|
const cache = ThunderProjectile.cache;
|
||||||
if (!cache) return;
|
if (!cache) return;
|
||||||
const bottom = this.by * 32 + 32;
|
this.cached = true;
|
||||||
cache.size(120, bottom);
|
cache.clear();
|
||||||
const ctx = cache.ctx;
|
const ctx = cache.ctx;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
for (let i = 0; i < this.power; i++) {
|
for (let i = 0; i < this.power; i++) {
|
||||||
let x = this.bx * 32;
|
let x = this.bx * 32 + 16;
|
||||||
let y = this.by * 32;
|
let y = this.by * 32 + 16;
|
||||||
ctx.moveTo(x, y);
|
ctx.moveTo(x, y);
|
||||||
while (y > 0) {
|
while (y > 0) {
|
||||||
x += Math.floor(Math.random() * 30 - 15);
|
x += Math.floor(Math.random() * 30 - 15);
|
||||||
@ -565,10 +575,11 @@ export class ThunderProjectile extends Projectile<TowerBoss> {
|
|||||||
ctx.lineTo(x, y);
|
ctx.lineTo(x, y);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.shadowBlur = 3;
|
ctx.shadowBlur = 5;
|
||||||
ctx.shadowColor = '#62c8f4';
|
ctx.shadowColor = '#62c8f4';
|
||||||
ctx.lineWidth = 2;
|
ctx.lineWidth = 2;
|
||||||
ctx.globalAlpha = 0.6;
|
ctx.globalAlpha = 0.6;
|
||||||
|
ctx.strokeStyle = '#fff';
|
||||||
ctx.stroke();
|
ctx.stroke();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -596,23 +607,23 @@ export class ThunderBallProjectile extends Projectile<TowerBoss> {
|
|||||||
this.horizontal = new MotaOffscreenCanvas2D();
|
this.horizontal = new MotaOffscreenCanvas2D();
|
||||||
this.vertical = new MotaOffscreenCanvas2D();
|
this.vertical = new MotaOffscreenCanvas2D();
|
||||||
const hor = this.horizontal;
|
const hor = this.horizontal;
|
||||||
hor.size(480 - 64, 32);
|
hor.size(480, 32);
|
||||||
hor.setHD(true);
|
hor.setHD(true);
|
||||||
hor.withGameScale(true);
|
hor.withGameScale(true);
|
||||||
const ctxHor = hor.ctx;
|
const ctxHor = hor.ctx;
|
||||||
ctxHor.fillStyle = '#fff';
|
ctxHor.fillStyle = '#fff';
|
||||||
ctxHor.globalAlpha = 0.6;
|
ctxHor.globalAlpha = 0.6;
|
||||||
for (let i = 0; i < 13; i++) {
|
for (let i = 0; i < 15; i++) {
|
||||||
ctxHor.fillRect(i * 32 + 2, 2, 28, 28);
|
ctxHor.fillRect(i * 32 + 2, 2, 28, 28);
|
||||||
}
|
}
|
||||||
const ver = this.vertical;
|
const ver = this.vertical;
|
||||||
ver.size(480 - 64, 32);
|
ver.size(32, 480);
|
||||||
ver.setHD(true);
|
ver.setHD(true);
|
||||||
ver.withGameScale(true);
|
ver.withGameScale(true);
|
||||||
const ctxVer = ver.ctx;
|
const ctxVer = ver.ctx;
|
||||||
ctxVer.fillStyle = '#fff';
|
ctxVer.fillStyle = '#fff';
|
||||||
ctxVer.globalAlpha = 0.6;
|
ctxVer.globalAlpha = 0.6;
|
||||||
for (let i = 0; i < 13; i++) {
|
for (let i = 0; i < 15; i++) {
|
||||||
ctxVer.fillRect(2, i * 32 + 2, 28, 28);
|
ctxVer.fillRect(2, i * 32 + 2, 28, 28);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -732,8 +743,8 @@ export class ThunderBallProjectile extends Projectile<TowerBoss> {
|
|||||||
const height = (432 - cy) * begin;
|
const height = (432 - cy) * begin;
|
||||||
left = cx - 16;
|
left = cx - 16;
|
||||||
right = cx + 16;
|
right = cx + 16;
|
||||||
bottom = cy + 16;
|
bottom = cy + 16 + height;
|
||||||
top = cy + 16 + height;
|
top = cy + 16;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -769,27 +780,41 @@ export class ThunderBallProjectile extends Projectile<TowerBoss> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const ratio = devicePixelRatio * core.domStyle.scale;
|
||||||
const w = right - left;
|
const w = right - left;
|
||||||
const h = bottom - top;
|
const h = bottom - top;
|
||||||
|
const fw = w * ratio;
|
||||||
|
const fh = h * ratio;
|
||||||
|
const fl = left * ratio;
|
||||||
|
const ft = top * ratio;
|
||||||
|
const cell = 32 * ratio;
|
||||||
const hor = ThunderBallProjectile.horizontal!.canvas;
|
const hor = ThunderBallProjectile.horizontal!.canvas;
|
||||||
const ver = ThunderBallProjectile.vertical!.canvas;
|
const ver = ThunderBallProjectile.vertical!.canvas;
|
||||||
|
ctx.save();
|
||||||
|
ctx.globalAlpha = 1;
|
||||||
|
if (w > 0 && h > 0) {
|
||||||
switch (this.direction) {
|
switch (this.direction) {
|
||||||
case ProjectileDirection.BottomToTop:
|
case ProjectileDirection.BottomToTop:
|
||||||
case ProjectileDirection.TopToBottom: {
|
case ProjectileDirection.TopToBottom: {
|
||||||
ctx.drawImage(hor, 0, top, 32, h, left, top, w, h);
|
ctx.drawImage(ver, 0, ft, cell, fh, left, top, w, h);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ProjectileDirection.LeftToRight:
|
case ProjectileDirection.LeftToRight:
|
||||||
case ProjectileDirection.RightToLeft: {
|
case ProjectileDirection.RightToLeft: {
|
||||||
ctx.drawImage(ver, left, 0, w, 32, left, top, w, h);
|
ctx.drawImage(hor, fl, 0, fw, cell, left, top, w, h);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctx.fillStyle = '#fff';
|
ctx.fillStyle = '#fff';
|
||||||
|
ctx.shadowBlur = 8;
|
||||||
|
ctx.shadowColor = '#62c8f4';
|
||||||
ctx.globalAlpha = 0.9;
|
ctx.globalAlpha = 0.9;
|
||||||
ctx.beginPath();
|
ctx.beginPath();
|
||||||
const radius = 9 + Math.floor(Math.random() * 8 - 4);
|
const radius = 7 + Math.floor(Math.random() * 2);
|
||||||
ctx.arc(this.x, this.y, radius, 0, Math.PI * 2);
|
ctx.arc(this.x, this.y, radius, 0, Math.PI * 2);
|
||||||
ctx.fill();
|
ctx.fill();
|
||||||
|
ctx.restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -427,6 +427,7 @@ export class PointEffect {
|
|||||||
case PointEffectType.CircleContrast:
|
case PointEffectType.CircleContrast:
|
||||||
case PointEffectType.CircleSaturate:
|
case PointEffectType.CircleSaturate:
|
||||||
case PointEffectType.CircleHue:
|
case PointEffectType.CircleHue:
|
||||||
|
case PointEffectType.CircleBrightness:
|
||||||
case PointEffectType.CircleWarpTangetial: {
|
case PointEffectType.CircleWarpTangetial: {
|
||||||
transformXY(index);
|
transformXY(index);
|
||||||
transformed[index + 6] *= scale;
|
transformed[index + 6] *= scale;
|
||||||
|
Loading…
Reference in New Issue
Block a user