Add kill heal effect animation
This commit is contained in:
parent
1509b0c5dd
commit
be80cb17b0
Binary file not shown.
|
After Width: | Height: | Size: 933 B |
|
|
@ -33,6 +33,10 @@ export const FIGHTER_HITBOX_OFFSET_Y = 40;
|
|||
export const FIGHTER_MAX_HP = 100;
|
||||
// 적 처치 시 현재 체력 기준으로 회복되는 비율입니다.
|
||||
export const KILL_HEALTH_RECOVERY_RATIO = 0.3;
|
||||
// 처치 회복 이펙트 스프라이트시트의 프레임 수입니다.
|
||||
export const KILL_HEAL_EFFECT_FRAMES = 4;
|
||||
// 처치 회복 이펙트 애니메이션의 초당 프레임 수입니다.
|
||||
export const KILL_HEAL_EFFECT_FRAME_RATE = 12;
|
||||
// 적 처치 시 크기, 공격속도, 이동속도에 누적 적용되는 배율입니다.
|
||||
export const KILL_GROWTH_MULTIPLIER = 1.25;
|
||||
// 처치 성장 연출 tween 지속 시간(ms)입니다.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ import {
|
|||
fighterAttackEffectAnimationKey,
|
||||
fighterAttackEffectKey,
|
||||
fighterProjectileKey,
|
||||
healEffectAnimationKey,
|
||||
healEffectKey,
|
||||
} from "./fighterAssets.js";
|
||||
|
||||
export function updateFighter(scene, fighter, time, onWinner) {
|
||||
|
|
@ -357,12 +359,18 @@ function applyKillReward(winner) {
|
|||
winner.killCount = (winner.killCount ?? 0) + 1;
|
||||
|
||||
const rewardMultiplier = KILL_GROWTH_MULTIPLIER ** winner.killCount;
|
||||
const previousHp = winner.hp;
|
||||
const nextHp = recoveredHealth(winner);
|
||||
winner.killRewardMultiplier = rewardMultiplier;
|
||||
winner.hp = recoveredHealth(winner);
|
||||
winner.hp = nextHp;
|
||||
|
||||
const nextScaleX = (winner.baseScaleX ?? FIGHTER_SCALE) * rewardMultiplier;
|
||||
const nextScaleY = (winner.baseScaleY ?? FIGHTER_SCALE) * rewardMultiplier;
|
||||
|
||||
if (nextHp > previousHp) {
|
||||
spawnKillHealEffect(winner, Math.max(Math.abs(nextScaleX), Math.abs(nextScaleY)));
|
||||
}
|
||||
|
||||
winner.scene.tweens.add({
|
||||
targets: winner,
|
||||
scaleX: nextScaleX,
|
||||
|
|
@ -379,6 +387,35 @@ function recoveredHealth(fighter) {
|
|||
return Math.min(maxHp, fighter.hp + recovery);
|
||||
}
|
||||
|
||||
function spawnKillHealEffect(fighter, effectScale) {
|
||||
const scene = fighter.scene;
|
||||
const effect = scene.add
|
||||
.sprite(fighter.x, fighter.y, healEffectKey())
|
||||
.setDepth(fighter.depth + 1)
|
||||
.setScale(effectScale);
|
||||
|
||||
const syncEffectPosition = () => {
|
||||
if (!effect.active || !fighter.active) {
|
||||
return;
|
||||
}
|
||||
|
||||
effect.setPosition(fighter.x, fighter.y);
|
||||
effect.setDepth(fighter.depth + 1);
|
||||
};
|
||||
|
||||
effect.cleanup = () => {
|
||||
scene.events.off(Phaser.Scenes.Events.UPDATE, syncEffectPosition);
|
||||
};
|
||||
|
||||
scene.events.on(Phaser.Scenes.Events.UPDATE, syncEffectPosition);
|
||||
effect.play(healEffectAnimationKey());
|
||||
trackCombatObject(scene, effect);
|
||||
|
||||
effect.once(Phaser.Animations.Events.ANIMATION_COMPLETE, () => {
|
||||
disposeCombatObject(scene, effect);
|
||||
});
|
||||
}
|
||||
|
||||
function findNearestEnemy(fighters, fighter) {
|
||||
let nearestEnemy;
|
||||
let nearestDistance = Number.POSITIVE_INFINITY;
|
||||
|
|
|
|||
|
|
@ -2,6 +2,8 @@ import {
|
|||
FIGHTER_ANIMATION_OPTIONS,
|
||||
FIGHTER_FRAME_HEIGHT,
|
||||
FIGHTER_FRAME_WIDTH,
|
||||
KILL_HEAL_EFFECT_FRAME_RATE,
|
||||
KILL_HEAL_EFFECT_FRAMES,
|
||||
SELECTED_FIGHTER_OUTLINE_ALPHA,
|
||||
SELECTED_FIGHTER_OUTLINE_BLUE,
|
||||
SELECTED_FIGHTER_OUTLINE_GAP,
|
||||
|
|
@ -11,6 +13,9 @@ import {
|
|||
} from "../constants.js";
|
||||
|
||||
const SOURCE_ALPHA_THRESHOLD = 8;
|
||||
const HEAL_EFFECT_PATH = "assets/effects/heal/Heal_Effect.png";
|
||||
const HEAL_EFFECT_KEY = "kill-heal-effect";
|
||||
const HEAL_EFFECT_ANIMATION_KEY = `${HEAL_EFFECT_KEY}-anim`;
|
||||
|
||||
export function fighterSheetKey(skin, action) {
|
||||
return `${skin.key}-${action}`;
|
||||
|
|
@ -40,7 +45,20 @@ export function fighterProjectileKey(skin) {
|
|||
return `${skin.key}-projectile`;
|
||||
}
|
||||
|
||||
export function healEffectKey() {
|
||||
return HEAL_EFFECT_KEY;
|
||||
}
|
||||
|
||||
export function healEffectAnimationKey() {
|
||||
return HEAL_EFFECT_ANIMATION_KEY;
|
||||
}
|
||||
|
||||
export function preloadFighterSheets(scene, skins) {
|
||||
scene.load.spritesheet(healEffectKey(), HEAL_EFFECT_PATH, {
|
||||
frameWidth: FIGHTER_FRAME_WIDTH,
|
||||
frameHeight: FIGHTER_FRAME_HEIGHT,
|
||||
});
|
||||
|
||||
skins.forEach((skin) => {
|
||||
Object.entries(skin.animations).forEach(([action, animation]) => {
|
||||
scene.load.spritesheet(
|
||||
|
|
@ -78,6 +96,8 @@ export function createFighterAnimations(scene, skins) {
|
|||
|
||||
createAttackEffectAnimation(scene, skin);
|
||||
});
|
||||
|
||||
createHealEffectAnimation(scene);
|
||||
}
|
||||
|
||||
function preloadCombatAssets(scene, skin) {
|
||||
|
|
@ -121,6 +141,22 @@ function createAttackEffectAnimation(scene, skin) {
|
|||
});
|
||||
}
|
||||
|
||||
function createHealEffectAnimation(scene) {
|
||||
if (scene.anims.exists(healEffectAnimationKey())) {
|
||||
return;
|
||||
}
|
||||
|
||||
scene.anims.create({
|
||||
key: healEffectAnimationKey(),
|
||||
frames: scene.anims.generateFrameNumbers(healEffectKey(), {
|
||||
start: 0,
|
||||
end: KILL_HEAL_EFFECT_FRAMES - 1,
|
||||
}),
|
||||
frameRate: KILL_HEAL_EFFECT_FRAME_RATE,
|
||||
repeat: 0,
|
||||
});
|
||||
}
|
||||
|
||||
function createFighterOutlineSheet(scene, skin, action, frameCount) {
|
||||
const key = fighterOutlineSheetKey(skin, action);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue