fix(animation): 전투 애니메이션 위치 및 이펙트 개선
- 캐릭터/몬스터 hit/attack 페이즈 위치 버그 수정 - 이펙트 위치를 캐릭터/몬스터 위치에 따라 동적 계산 - 이벤트 기반 페이즈 리셋을 idle 진입 시에만 수행
This commit is contained in:
@@ -137,11 +137,12 @@ class CanvasBattleComposer {
|
|||||||
|
|
||||||
// 페이즈별 X 위치 (Phase 7: 공격자별 위치 분리)
|
// 페이즈별 X 위치 (Phase 7: 공격자별 위치 분리)
|
||||||
// 플레이어가 공격자일 때만 이동, 아니면 제자리(12)
|
// 플레이어가 공격자일 때만 이동, 아니면 제자리(12)
|
||||||
|
// hit 페이즈에서도 플레이어 공격 중이면 위치 유지 (Bug fix)
|
||||||
final charX = switch (phase) {
|
final charX = switch (phase) {
|
||||||
BattlePhase.idle => 12,
|
BattlePhase.idle => 12,
|
||||||
BattlePhase.prepare => isPlayerAttacking ? 15 : 12,
|
BattlePhase.prepare => isPlayerAttacking ? 15 : 12,
|
||||||
BattlePhase.attack => isPlayerAttacking ? 18 : 12,
|
BattlePhase.attack => isPlayerAttacking ? 18 : 12,
|
||||||
BattlePhase.hit => attacker == AttackerType.both ? 18 : 12,
|
BattlePhase.hit => isPlayerAttacking ? 18 : 12,
|
||||||
BattlePhase.recover => isPlayerAttacking ? 15 : 12,
|
BattlePhase.recover => isPlayerAttacking ? 15 : 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -181,10 +182,11 @@ class CanvasBattleComposer {
|
|||||||
|
|
||||||
// 페이즈별 X 위치 (Phase 7: 공격자별 위치 분리)
|
// 페이즈별 X 위치 (Phase 7: 공격자별 위치 분리)
|
||||||
// 몬스터가 공격자일 때만 이동, 아니면 제자리(48)
|
// 몬스터가 공격자일 때만 이동, 아니면 제자리(48)
|
||||||
|
// attack 페이즈에서도 몬스터 공격 중이면 위치 유지 (Bug fix)
|
||||||
final monsterRightEdge = switch (phase) {
|
final monsterRightEdge = switch (phase) {
|
||||||
BattlePhase.idle => 48,
|
BattlePhase.idle => 48,
|
||||||
BattlePhase.prepare => isMonsterAttacking ? 45 : 48,
|
BattlePhase.prepare => isMonsterAttacking ? 45 : 48,
|
||||||
BattlePhase.attack => attacker == AttackerType.both ? 42 : 48,
|
BattlePhase.attack => isMonsterAttacking ? 42 : 48,
|
||||||
BattlePhase.hit => isMonsterAttacking ? 42 : 48,
|
BattlePhase.hit => isMonsterAttacking ? 42 : 48,
|
||||||
BattlePhase.recover => isMonsterAttacking ? 45 : 48,
|
BattlePhase.recover => isMonsterAttacking ? 45 : 48,
|
||||||
};
|
};
|
||||||
@@ -211,24 +213,50 @@ class CanvasBattleComposer {
|
|||||||
int subFrame,
|
int subFrame,
|
||||||
AttackerType attacker,
|
AttackerType attacker,
|
||||||
) {
|
) {
|
||||||
|
// 공격자별 위치 계산을 위한 플래그 (동일 로직 재사용)
|
||||||
|
final isPlayerAttacking =
|
||||||
|
attacker == AttackerType.player || attacker == AttackerType.both;
|
||||||
|
final isMonsterAttacking =
|
||||||
|
attacker == AttackerType.monster || attacker == AttackerType.both;
|
||||||
|
|
||||||
|
// 캐릭터 위치 계산 (characterLayer와 동일 로직)
|
||||||
|
const charWidth = 6;
|
||||||
|
final charX = switch (phase) {
|
||||||
|
BattlePhase.idle => 12,
|
||||||
|
BattlePhase.prepare => isPlayerAttacking ? 15 : 12,
|
||||||
|
BattlePhase.attack => isPlayerAttacking ? 18 : 12,
|
||||||
|
BattlePhase.hit => isPlayerAttacking ? 18 : 12,
|
||||||
|
BattlePhase.recover => isPlayerAttacking ? 15 : 12,
|
||||||
|
};
|
||||||
|
|
||||||
|
// 몬스터 위치 계산 (monsterLayer와 동일 로직)
|
||||||
|
final monsterRightEdge = switch (phase) {
|
||||||
|
BattlePhase.idle => 48,
|
||||||
|
BattlePhase.prepare => isMonsterAttacking ? 45 : 48,
|
||||||
|
BattlePhase.attack => isMonsterAttacking ? 42 : 48,
|
||||||
|
BattlePhase.hit => isMonsterAttacking ? 42 : 48,
|
||||||
|
BattlePhase.recover => isMonsterAttacking ? 45 : 48,
|
||||||
|
};
|
||||||
|
final monsterX = monsterRightEdge - monsterWidth;
|
||||||
|
|
||||||
// 공격자에 따라 다른 이펙트 사용
|
// 공격자에 따라 다른 이펙트 사용
|
||||||
final List<String> effectLines;
|
final List<String> effectLines;
|
||||||
final int effectX;
|
final int effectX;
|
||||||
|
|
||||||
if (attacker == AttackerType.player) {
|
if (attacker == AttackerType.player) {
|
||||||
// 플레이어 공격: 무기 이펙트 → 몬스터 왼쪽
|
// 플레이어 공격: 무기 이펙트 → 몬스터 왼쪽 바로 옆
|
||||||
final effect = getWeaponEffect(weaponCategory);
|
final effect = getWeaponEffect(weaponCategory);
|
||||||
effectLines = _getEffectLines(effect, phase, subFrame);
|
effectLines = _getEffectLines(effect, phase, subFrame);
|
||||||
effectX = 28;
|
effectX = monsterX - 2;
|
||||||
} else if (attacker == AttackerType.monster) {
|
} else if (attacker == AttackerType.monster) {
|
||||||
// 몬스터 공격: 왼쪽 방향 이펙트 → 캐릭터 오른쪽
|
// 몬스터 공격: 왼쪽 방향 이펙트 → 캐릭터 오른쪽 바로 옆
|
||||||
effectLines = _getMonsterAttackEffect(phase, subFrame);
|
effectLines = _getMonsterAttackEffect(phase, subFrame);
|
||||||
effectX = 18;
|
effectX = charX + charWidth;
|
||||||
} else {
|
} else {
|
||||||
// 동시 공격(both): 무기 이펙트 중앙 표시
|
// 동시 공격(both): 무기 이펙트 두 캐릭터 중앙
|
||||||
final effect = getWeaponEffect(weaponCategory);
|
final effect = getWeaponEffect(weaponCategory);
|
||||||
effectLines = _getEffectLines(effect, phase, subFrame);
|
effectLines = _getEffectLines(effect, phase, subFrame);
|
||||||
effectX = 23;
|
effectX = (charX + charWidth + monsterX) ~/ 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (effectLines.isEmpty) return null;
|
if (effectLines.isEmpty) return null;
|
||||||
|
|||||||
@@ -474,12 +474,11 @@ class _AsciiAnimationCardState extends State<AsciiAnimationCard> {
|
|||||||
_showBlockEffect = false;
|
_showBlockEffect = false;
|
||||||
_showParryEffect = false;
|
_showParryEffect = false;
|
||||||
_showSkillEffect = false;
|
_showSkillEffect = false;
|
||||||
// 이벤트 기반 페이즈 종료
|
// 공격자 타입 및 이벤트 기반 페이즈 리셋 (idle 페이즈 진입 시에만)
|
||||||
_isEventDrivenPhase = false;
|
// 공격 사이클(prepare→attack→hit→recover) 동안 유지 (Bug fix)
|
||||||
// 공격자 타입 리셋 (idle 페이즈 진입 시에만)
|
|
||||||
// 공격 사이클(prepare→attack→hit→recover) 동안 유지
|
|
||||||
if (_battlePhaseSequence[_phaseIndex].$1 == BattlePhase.idle) {
|
if (_battlePhaseSequence[_phaseIndex].$1 == BattlePhase.idle) {
|
||||||
_currentAttacker = AttackerType.none;
|
_currentAttacker = AttackerType.none;
|
||||||
|
_isEventDrivenPhase = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_battleSubFrame++;
|
_battleSubFrame++;
|
||||||
|
|||||||
Reference in New Issue
Block a user