Files
asciinevrdie/lib/src/core/animation/weapon_effects.dart
JiWoong Sul a404c82f35 refactor(animation): 애니메이션 시스템 정리
- AsciiCanvasPainter, CanvasBattleComposer 개선
- WeaponEffects 정리
2026-01-12 16:17:11 +09:00

191 lines
7.1 KiB
Dart

import 'package:asciineverdie/src/core/animation/weapon_category.dart';
/// 무기 카테고리별 공격 이펙트 ASCII 프레임
///
/// 각 이펙트는 멀티라인 (최대 5줄, 24자 폭).
/// 캐릭터와 몬스터 사이에 표시됨.
class WeaponEffect {
const WeaponEffect({
required this.prepareFrames,
required this.attackFrames,
required this.hitFrames,
this.hitSound = '*HIT!*',
this.effectHeight = 3,
this.effectYStart = 2,
});
/// 준비 프레임 (멀티라인)
final List<List<String>> prepareFrames;
/// 공격 프레임 (멀티라인)
final List<List<String>> attackFrames;
/// 히트 프레임 (멀티라인)
final List<List<String>> hitFrames;
/// 히트 효과음 텍스트
final String hitSound;
/// 이펙트 높이 (줄 수)
final int effectHeight;
/// 이펙트 시작 Y 위치 (0~7)
final int effectYStart;
}
/// 카테고리별 무기 이펙트 반환
WeaponEffect getWeaponEffect(WeaponCategory category) {
return switch (category) {
WeaponCategory.blunt => _bluntEffect,
WeaponCategory.cable => _cableEffect,
WeaponCategory.projectile => _projectileEffect,
WeaponCategory.energy => _energyEffect,
WeaponCategory.cosmic => _cosmicEffect,
WeaponCategory.unarmed => _unarmedEffect,
};
}
// ============================================================================
// 둔기류 - 휘두르기 (5줄)
// ============================================================================
const _bluntEffect = WeaponEffect(
prepareFrames: [
[r' ', r' _ ', r' / ', r' / ', r' / '],
[r' ', r' _/ ', r' / ', r' / ', r' / '],
],
attackFrames: [
[r' ', r' _/ ', r' / ', r' / ', r' / '],
[r' ', r' _/ ', r' / ', r' /________', r'/ '],
[r' ', r' _/ ', r' /________', r'/ ', r' '],
[r' ', r' _/____=> ', r'/ ', r' ', r' '],
],
hitFrames: [
[r' *BASH* ', r' _/____=> ', r'/ ** ', r' ** ', r' '],
[r' *SMASH!* ', r' _/____ ', r' / ** ', r' ** ', r' '],
],
hitSound: '*BASH*',
effectHeight: 5,
effectYStart: 1,
);
// ============================================================================
// 케이블류 - 채찍질 (5줄)
// ============================================================================
const _cableEffect = WeaponEffect(
prepareFrames: [
[r' ', r'~ ', r' ~ ', r' ~ ', r' ~ '],
[r' ', r'~~ ', r' ~~ ', r' ~ ', r' ~ '],
],
attackFrames: [
[r' ', r'~~~ ', r' ~~~ ', r' ~~ ', r' ~ '],
[r' ', r'~~~~ ', r' ~~~~ ', r' ~~', r' '],
[r' ', r'~~~~~> ', r' ~~~~~', r' ', r' '],
[r' ', r'~~~~~~> ', r' ~~~~', r' ', r' '],
],
hitFrames: [
[r' *WHIP* ', r'~~~~~~> ', r' ~~~~', r' **', r' '],
[r' *CRACK!* ', r'~~~~~> ', r' ~~~~~', r' **', r' '],
],
hitSound: '*WHIP*',
effectHeight: 5,
effectYStart: 1,
);
// ============================================================================
// 투척류 - 발사 (5줄)
// ============================================================================
const _projectileEffect = WeaponEffect(
prepareFrames: [
[r' ', r' ', r' [=] ', r' ', r' '],
[r' ', r' _ ', r' [==] ', r' - ', r' '],
],
attackFrames: [
[r' ', r' . ', r' [> ', r" ' ", r' '],
[r' ', r' . ', r' [> ', r" ' ", r' '],
[r' ', r' . ', r' [>', r" ' ", r' '],
[
r' ',
r' ',
r' [>',
r' ',
r' ',
],
],
hitFrames: [
[r' *CLANG!* ', r' ***', r' [>', r' ***', r' '],
[r' *CRASH!* ', r' *** ', r' [> ', r' *** ', r' '],
],
hitSound: '*CLANG*',
effectHeight: 5,
effectYStart: 1,
);
// ============================================================================
// 에너지류 - 빔 발사 (5줄)
// ============================================================================
const _energyEffect = WeaponEffect(
prepareFrames: [
[r' ', r' == ', r' <**> ', r' == ', r' '],
[r' ==== ', r' ====== ', r' <****> ', r' ====== ', r' ==== '],
],
attackFrames: [
[r' ====== ', r' ======== ', r'===<**>===', r' ======== ', r' ====== '],
[r' ======== ', r'==========', r'===<**>===', r'==========', r' ======== '],
[r'==========', r'==========', r'====<**>==', r'==========', r'=========='],
[r'==========', r'==========', r'=====<**>=', r'==========', r'=========='],
],
hitFrames: [
[r'===*ZAP*==', r'==========', r'====<**>==', r'==========', r'===*ZAP*=='],
[r'==*BZZT!*=', r'==========', r'=====<**>=', r'==========', r'==*BZZT!*='],
],
hitSound: '*ZAP*',
effectHeight: 5,
effectYStart: 1,
);
// ============================================================================
// 우주급 - 초월적 공격 (5줄)
// ============================================================================
const _cosmicEffect = WeaponEffect(
prepareFrames: [
[r' * ', r' @ @ ', r' @ @ ', r' @ @ ', r' * '],
[r' * * ', r' @ @ ', r' @ @', r' @ @ ', r' * * '],
],
attackFrames: [
[r' * ', r' * * * ', r' * * * *', r' * * * ', r' * '],
[r' *** ', r' * * * *', r'* * * * ', r' * * * *', r' *** '],
[r' ***** ', r' ******* ', r'*********', r' ******* ', r' ***** '],
[r' **VOID**', r'*********', r'*********', r'*********', r' **VOID**'],
],
hitFrames: [
[r'*SINGULAR', r'*********', r'***!!!***', r'*********', r'*DESTROY*'],
[r'!!!VOID!!', r'*********', r'*********', r'*********', r'!!!VOID!!'],
],
hitSound: '***VOID***',
effectHeight: 5,
effectYStart: 1,
);
// ============================================================================
// 맨손 - 기본 펀치 (5줄)
// ============================================================================
const _unarmedEffect = WeaponEffect(
prepareFrames: [
[r' ', r' ', r' > ', r' ', r' '],
[r' ', r' _ ', r' -> ', r' - ', r' '],
],
attackFrames: [
[r' ', r' __ ', r' ---> ', r' -- ', r' '],
[r' ', r' ___ ', r' -----> ', r' --- ', r' '],
[r' ', r' ____', r' ======>', r' ----', r' '],
],
hitFrames: [
[r' *POW!* ', r' ****', r' ======>', r' ****', r' '],
[r' *PUNCH!* ', r' **** ', r' =====> ', r' **** ', r' '],
],
hitSound: '*POW*',
effectHeight: 5,
effectYStart: 1,
);