feat: add pulsing animation to attack target tiles in Advance Wars
Introduce a breathing pulse effect (red fill + white border) for attack
target tiles to draw the player's eye when in "must pick a target" fire
mode. The previous static tint is preserved for the indirect-range preview
shown while a unit is merely selected.
- showAttackTiles now accepts optional { pulse: true } parameter
- Added tween-based animation with Sine.easeInOut breathing effect
- Properly clean up pulse tween in destroy() and clearOverlays()
- Updated AdvanceWarsGame to pass pulse: true when showing targets
This commit is contained in:
parent
a0b3b5f063
commit
138b078dd2
Binary file not shown.
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 36 KiB After Width: | Height: | Size: 38 KiB |
Binary file not shown.
|
|
@ -424,7 +424,7 @@ export default class AdvanceWarsGame extends Phaser.Scene {
|
|||
const run = this.run;
|
||||
run.mode = 'target';
|
||||
run.targets = targets;
|
||||
run.view.showAttackTiles(targets.map((t) => ({ x: t.x, y: t.y })));
|
||||
run.view.showAttackTiles(targets.map((t) => ({ x: t.x, y: t.y })), { pulse: true });
|
||||
}
|
||||
|
||||
onTargetClick(tile) {
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ export class AdvanceWarsMapView {
|
|||
|
||||
destroy() {
|
||||
this.flipTimer?.remove();
|
||||
this.atkPulseTween?.stop();
|
||||
this.rt?.destroy();
|
||||
this.moveG?.destroy(); this.atkG?.destroy(); this.fogG?.destroy();
|
||||
this.pathG?.destroy(); this.cursor?.destroy();
|
||||
|
|
@ -492,15 +493,42 @@ export class AdvanceWarsMapView {
|
|||
}
|
||||
}
|
||||
|
||||
showAttackTiles(tiles) {
|
||||
// pulse: true for "you must pick a target now" (entering FIRE target mode)
|
||||
// — red fill + white border breathing to draw the eye. false (default)
|
||||
// keeps the old static tint, used for the indirect-range preview shown
|
||||
// while a unit is merely selected, before a move/target is committed to.
|
||||
showAttackTiles(tiles, { pulse = false } = {}) {
|
||||
this.atkPulseTween?.stop();
|
||||
this.atkPulseTween = null;
|
||||
this.atkG.clear();
|
||||
this.atkG.fillStyle(0xff3d3d, 0.42);
|
||||
for (const { x, y } of tiles) {
|
||||
this.atkG.fillRect(this.ox + x * this.tile + 1, this.oy + y * this.tile + 1, this.tile - 2, this.tile - 2);
|
||||
if (!pulse) {
|
||||
this.atkG.fillStyle(0xff3d3d, 0.42);
|
||||
for (const { x, y } of tiles) {
|
||||
this.atkG.fillRect(this.ox + x * this.tile + 1, this.oy + y * this.tile + 1, this.tile - 2, this.tile - 2);
|
||||
}
|
||||
return;
|
||||
}
|
||||
const draw = (fillA, lineA) => {
|
||||
this.atkG.clear();
|
||||
this.atkG.fillStyle(0xff3d3d, fillA);
|
||||
this.atkG.lineStyle(Math.max(2, this.tile * 0.06), 0xffffff, lineA);
|
||||
for (const { x, y } of tiles) {
|
||||
const px = this.ox + x * this.tile + 1, py = this.oy + y * this.tile + 1, s = this.tile - 2;
|
||||
this.atkG.fillRect(px, py, s, s);
|
||||
this.atkG.strokeRect(px, py, s, s);
|
||||
}
|
||||
};
|
||||
const phase = { t: 0 };
|
||||
draw(0.30, 0.55);
|
||||
this.atkPulseTween = this.scene.tweens.add({
|
||||
targets: phase, t: 1, duration: 550, yoyo: true, repeat: -1, ease: 'Sine.easeInOut',
|
||||
onUpdate: () => draw(0.28 + phase.t * 0.34, 0.5 + phase.t * 0.5),
|
||||
});
|
||||
}
|
||||
|
||||
clearOverlays() {
|
||||
this.atkPulseTween?.stop();
|
||||
this.atkPulseTween = null;
|
||||
this.moveG.clear();
|
||||
this.atkG.clear();
|
||||
this.pathG.clear();
|
||||
|
|
|
|||
Loading…
Reference in New Issue