## 스킬 시스템 개선 - skill_data.dart: 스킬 데이터 구조 전면 개편 (+1176 라인) - skill_service.dart: 스킬 발동 로직 확장 및 버프 시스템 연동 - skill.dart: 스킬 모델 개선, 쿨다운/효과 타입 추가 ## Canvas 애니메이션 리팩토링 - battle_composer.dart 삭제 (레거시 위젯 기반 렌더러) - monster_colors.dart 삭제 (AsciiCell 색상 시스템으로 통합) - canvas_battle_composer.dart: z-index 정렬 (몬스터 z=1, 캐릭터 z=2, 이펙트 z=3) - ascii_cell.dart, ascii_layer.dart: 코드 정리 ## UI/UX 개선 - hp_mp_bar.dart: l10n 적용, 몬스터 HP 바 컴팩트화 - death_overlay.dart: 사망 화면 개선 - equipment_stats_panel.dart: 장비 스탯 표시 확장 - active_buff_panel.dart: 버프 패널 개선 - notification_overlay.dart: 알림 시스템 개선 ## 다국어 지원 확장 - game_text_l10n.dart: 게임 텍스트 통합 (+758 라인) - 한국어/일본어/영어/중국어 번역 업데이트 - ARB 파일 동기화 ## 게임 로직 개선 - progress_service.dart: 진행 로직 리팩토링 - combat_calculator.dart: 전투 계산 로직 개선 - stat_calculator.dart: 스탯 계산 시스템 개선 - story_service.dart: 스토리 진행 로직 개선 ## 기타 - theme_preferences.dart 삭제 (미사용) - 테스트 파일 업데이트 - class_data.dart: 클래스 데이터 정리
114 lines
4.0 KiB
Dart
114 lines
4.0 KiB
Dart
// 캐릭터 애니메이션 프레임 (8줄 Stone Story RPG 스타일)
|
|
// 참조: Stone Story RPG - 상세하고 생동감 있는 ASCII 아트
|
|
|
|
/// 전투 페이즈
|
|
enum BattlePhase {
|
|
/// 대치 상태 (기본)
|
|
idle,
|
|
|
|
/// 공격 준비
|
|
prepare,
|
|
|
|
/// 공격 중
|
|
attack,
|
|
|
|
/// 피격 (몬스터가 맞음)
|
|
hit,
|
|
|
|
/// 복귀
|
|
recover,
|
|
}
|
|
|
|
/// 캐릭터 프레임 데이터
|
|
class CharacterFrame {
|
|
const CharacterFrame(this.lines);
|
|
|
|
/// 프레임 데이터 (3줄)
|
|
final List<String> lines;
|
|
|
|
/// 방패 오버레이 적용
|
|
/// 3줄 캐릭터: [0]=머리, [1]=몸통/팔, [2]=다리
|
|
CharacterFrame withShield() {
|
|
if (lines.length < 2) return this;
|
|
final newLines = List<String>.from(lines);
|
|
// 몸통 줄(1번줄, 팔 위치)에 방패 추가
|
|
final bodyIdx = 1;
|
|
if (newLines[bodyIdx].length >= 2) {
|
|
// 첫 두 문자를 방패로 대체
|
|
newLines[bodyIdx] = '[]${newLines[bodyIdx].substring(2)}';
|
|
} else {
|
|
newLines[bodyIdx] = '[]${newLines[bodyIdx]}';
|
|
}
|
|
return CharacterFrame(newLines);
|
|
}
|
|
}
|
|
|
|
/// 특정 페이즈와 서브프레임에 해당하는 캐릭터 프레임 반환
|
|
CharacterFrame getCharacterFrame(BattlePhase phase, int subFrame) {
|
|
final frames = switch (phase) {
|
|
BattlePhase.idle => _idleFrames,
|
|
BattlePhase.prepare => _prepareFrames,
|
|
BattlePhase.attack => _attackFrames,
|
|
BattlePhase.hit => _hitFrames,
|
|
BattlePhase.recover => _recoverFrames,
|
|
};
|
|
|
|
final index = subFrame % frames.length;
|
|
return frames[index];
|
|
}
|
|
|
|
// ============================================================================
|
|
// 대기 프레임 (숨쉬기 애니메이션) - 4프레임, 심플 3줄 스타일, 폭 6자
|
|
// 구조: [머리, 몸통+팔, 다리]
|
|
// ============================================================================
|
|
const _idleFrames = [
|
|
CharacterFrame([r' o ', r' /|\ ', r' / \ ']),
|
|
CharacterFrame([r' o ', r' /|\ ', r' | | ']),
|
|
CharacterFrame([r' o ', r' /|\ ', r' / \ ']),
|
|
CharacterFrame([r' O ', r' /|\ ', r' / \ ']),
|
|
];
|
|
|
|
// ============================================================================
|
|
// 준비 프레임 (무기 들기) - 3프레임, 심플 3줄 스타일, 폭 6자
|
|
// 구조: [머리, 몸통+팔, 다리]
|
|
// ============================================================================
|
|
const _prepareFrames = [
|
|
CharacterFrame([r' o ', r' \|\ ', r' / \ ']),
|
|
CharacterFrame([r' o_ ', r' \| ', r' / \ ']),
|
|
CharacterFrame([r' o/ ', r' \| ', r' / \ ']),
|
|
];
|
|
|
|
// ============================================================================
|
|
// 공격 프레임 (전진 + 휘두르기) - 5프레임, 심플 3줄 스타일
|
|
// 구조: [머리+공격, 몸통+팔, 다리]
|
|
// 수정: 공격 이펙트를 머리 줄로 통일 (1칸 위로)
|
|
// ============================================================================
|
|
const _attackFrames = [
|
|
CharacterFrame([r' o\ ', r' /| ', r' / \ ']),
|
|
CharacterFrame([r' o- ', r' /| ', r' / \ ']),
|
|
CharacterFrame([r' o-- ', r' /| ', r' / \ ']),
|
|
CharacterFrame([r' o-=>', r' /| ', r' / \ ']),
|
|
CharacterFrame([r' o ', r' /|\ ', r' / \ ']),
|
|
];
|
|
|
|
// ============================================================================
|
|
// 히트 프레임 (공격 명중) - 3프레임, 심플 3줄 스타일
|
|
// 구조: [머리+이펙트, 몸통+팔, 다리]
|
|
// 수정: 히트 이펙트를 머리 줄로 통일 (1칸 위로)
|
|
// ============================================================================
|
|
const _hitFrames = [
|
|
CharacterFrame([r' o-* ', r' /| ', r' / \ ']),
|
|
CharacterFrame([r' o=* ', r' /| ', r' / \ ']),
|
|
CharacterFrame([r' o~* ', r' /| ', r' / \ ']),
|
|
];
|
|
|
|
// ============================================================================
|
|
// 복귀 프레임 - 3프레임, 심플 3줄 스타일
|
|
// 구조: [머리, 몸통+팔, 다리]
|
|
// ============================================================================
|
|
const _recoverFrames = [
|
|
CharacterFrame([r' o ', r' /|\ ', r' | ']),
|
|
CharacterFrame([r' o ', r' /|\ ', r' / \ ']),
|
|
CharacterFrame([r' o ', r' /|\ ', r' / \ ']),
|
|
];
|