fix: 第二阶段bug

This commit is contained in:
unanmed 2024-11-17 19:33:52 +08:00
parent 2b663da5db
commit deabd10154
3 changed files with 97 additions and 57 deletions

View File

@ -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);
} }
/** /**

View File

@ -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();
} }
} }

View File

@ -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;