feat(animation): ASCII 애니메이션 시스템 구현
- TaskType별 애니메이션 (전투, 마을, 걷기) - 몬스터 카테고리별 전투 애니메이션 (7종) - 특수 애니메이션 (레벨업, 퀘스트 완료, Act 완료) - 색상 테마 옵션 (green, amber, white, system) - 테마 설정 SharedPreferences 저장 - 프로그레스 바를 상단으로 이동
This commit is contained in:
827
lib/src/core/animation/ascii_animation_data.dart
Normal file
827
lib/src/core/animation/ascii_animation_data.dart
Normal file
@@ -0,0 +1,827 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:askiineverdie/src/core/animation/ascii_animation_type.dart';
|
||||
|
||||
/// ASCII 애니메이션 프레임 데이터
|
||||
class AsciiAnimationData {
|
||||
const AsciiAnimationData({
|
||||
required this.frames,
|
||||
this.frameIntervalMs = 200,
|
||||
});
|
||||
|
||||
/// 각 프레임 (문자열, 최소 5줄)
|
||||
final List<String> frames;
|
||||
|
||||
/// 프레임 간격 (밀리초)
|
||||
final int frameIntervalMs;
|
||||
}
|
||||
|
||||
/// 터미널 색상 테마
|
||||
enum AsciiColorTheme {
|
||||
/// 클래식 녹색 터미널
|
||||
green,
|
||||
|
||||
/// 엠버 (호박색) 터미널
|
||||
amber,
|
||||
|
||||
/// 화이트 온 블랙
|
||||
white,
|
||||
|
||||
/// 시스템 테마 (라이트/다크 모드 따름)
|
||||
system,
|
||||
}
|
||||
|
||||
/// 테마별 색상 데이터
|
||||
class AsciiThemeColors {
|
||||
const AsciiThemeColors({
|
||||
required this.textColor,
|
||||
required this.backgroundColor,
|
||||
});
|
||||
|
||||
final Color textColor;
|
||||
final Color backgroundColor;
|
||||
}
|
||||
|
||||
/// 테마별 색상 반환
|
||||
AsciiThemeColors getThemeColors(AsciiColorTheme theme, Brightness brightness) {
|
||||
return switch (theme) {
|
||||
AsciiColorTheme.green => const AsciiThemeColors(
|
||||
textColor: Color(0xFF00FF00),
|
||||
backgroundColor: Color(0xFF0D0D0D),
|
||||
),
|
||||
AsciiColorTheme.amber => const AsciiThemeColors(
|
||||
textColor: Color(0xFFFFB000),
|
||||
backgroundColor: Color(0xFF1A1000),
|
||||
),
|
||||
AsciiColorTheme.white => const AsciiThemeColors(
|
||||
textColor: Color(0xFFE0E0E0),
|
||||
backgroundColor: Color(0xFF121212),
|
||||
),
|
||||
AsciiColorTheme.system => brightness == Brightness.dark
|
||||
? const AsciiThemeColors(
|
||||
textColor: Color(0xFFE0E0E0),
|
||||
backgroundColor: Color(0xFF1E1E1E),
|
||||
)
|
||||
: const AsciiThemeColors(
|
||||
textColor: Color(0xFF1E1E1E),
|
||||
backgroundColor: Color(0xFFF5F5F5),
|
||||
),
|
||||
};
|
||||
}
|
||||
|
||||
/// 몬스터 카테고리
|
||||
enum MonsterCategory {
|
||||
/// 기본 (고양이 모양)
|
||||
beast,
|
||||
|
||||
/// 곤충/벌레류
|
||||
insect,
|
||||
|
||||
/// 인간형 (고블린, 오크 등)
|
||||
humanoid,
|
||||
|
||||
/// 언데드 (스켈레톤, 좀비)
|
||||
undead,
|
||||
|
||||
/// 드래곤/비행 생물
|
||||
dragon,
|
||||
|
||||
/// 슬라임/젤리
|
||||
slime,
|
||||
|
||||
/// 악마/마법 생물
|
||||
demon,
|
||||
}
|
||||
|
||||
/// 몬스터 이름으로 카테고리 결정
|
||||
MonsterCategory getMonsterCategory(String? monsterBaseName) {
|
||||
if (monsterBaseName == null || monsterBaseName.isEmpty) {
|
||||
return MonsterCategory.beast;
|
||||
}
|
||||
|
||||
final name = monsterBaseName.toLowerCase();
|
||||
|
||||
// 곤충/벌레류
|
||||
if (name.contains('ant') ||
|
||||
name.contains('centipede') ||
|
||||
name.contains('spider') ||
|
||||
name.contains('beetle') ||
|
||||
name.contains('crawler') ||
|
||||
name.contains('crayfish') ||
|
||||
name.contains('anhkheg')) {
|
||||
return MonsterCategory.insect;
|
||||
}
|
||||
|
||||
// 인간형
|
||||
if (name.contains('goblin') ||
|
||||
name.contains('orc') ||
|
||||
name.contains('troll') ||
|
||||
name.contains('ogre') ||
|
||||
name.contains('giant') ||
|
||||
name.contains('scout') ||
|
||||
name.contains('bugbear') ||
|
||||
name.contains('gnoll') ||
|
||||
name.contains('kobold') ||
|
||||
name.contains('hobgoblin')) {
|
||||
return MonsterCategory.humanoid;
|
||||
}
|
||||
|
||||
// 언데드
|
||||
if (name.contains('skeleton') ||
|
||||
name.contains('zombie') ||
|
||||
name.contains('ghoul') ||
|
||||
name.contains('ghost') ||
|
||||
name.contains('wight') ||
|
||||
name.contains('wraith') ||
|
||||
name.contains('vampire') ||
|
||||
name.contains('lich') ||
|
||||
name.contains('mummy')) {
|
||||
return MonsterCategory.undead;
|
||||
}
|
||||
|
||||
// 드래곤/비행
|
||||
if (name.contains('dragon') ||
|
||||
name.contains('wyvern') ||
|
||||
name.contains('cockatrice') ||
|
||||
name.contains('griffin') ||
|
||||
name.contains('roc') ||
|
||||
name.contains('harpy') ||
|
||||
name.contains('couatl')) {
|
||||
return MonsterCategory.dragon;
|
||||
}
|
||||
|
||||
// 슬라임/젤리
|
||||
if (name.contains('slime') ||
|
||||
name.contains('pudding') ||
|
||||
name.contains('ooze') ||
|
||||
name.contains('jelly') ||
|
||||
name.contains('boogie') ||
|
||||
name.contains('blob') ||
|
||||
name.contains('jubilex')) {
|
||||
return MonsterCategory.slime;
|
||||
}
|
||||
|
||||
// 악마/마법 생물
|
||||
if (name.contains('demon') ||
|
||||
name.contains('devil') ||
|
||||
name.contains('succubus') ||
|
||||
name.contains('beholder') ||
|
||||
name.contains('demogorgon') ||
|
||||
name.contains('orcus') ||
|
||||
name.contains('vrock') ||
|
||||
name.contains('hezrou') ||
|
||||
name.contains('glabrezu')) {
|
||||
return MonsterCategory.demon;
|
||||
}
|
||||
|
||||
return MonsterCategory.beast;
|
||||
}
|
||||
|
||||
/// 기본 전투 애니메이션 (beast - 고양이 모양)
|
||||
const battleAnimationBeast = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, /\\___/\\
|
||||
/( )\\ ( o o )
|
||||
/ \\ vs ( =^= )
|
||||
_| |_ /| |\\
|
||||
| | / | | \\
|
||||
_| |_ | |_____| |
|
||||
|_________| |___| |___|''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O /\\___/\\
|
||||
/|\\----o ( o o )
|
||||
/ \\ ( =^= )
|
||||
_| |_ /| |\\
|
||||
| | / | | \\
|
||||
_| |_ | |_____| |
|
||||
|_________| |___| |___|''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o--->/\\___/\\
|
||||
/|\\-----------> ( X X )
|
||||
/ \\ ( =^= )
|
||||
_| |_ /| |\\
|
||||
| | / | | \\
|
||||
_| |_ | |_____| |
|
||||
|_________| |___| |___|''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O /\\___/\\
|
||||
/|\\ **** ( X X ) ****
|
||||
/ \\ ** ( =^= ) **
|
||||
_| |_ /| |\\
|
||||
| | / | | \\
|
||||
_| |_ | |_____| |
|
||||
|_________| |___| |___|''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ /\\___/\\
|
||||
| ( - - )
|
||||
/ \\ ( =^= )
|
||||
_| |_ /| |\\
|
||||
| | / | | \\
|
||||
_| |_ | |_____| |
|
||||
|_________| |___| |___|''',
|
||||
],
|
||||
frameIntervalMs: 220,
|
||||
);
|
||||
|
||||
/// 마을/상점 애니메이션 (7줄)
|
||||
const townAnimation = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 상점 앞에서 대기
|
||||
'''
|
||||
_______________
|
||||
/ \\ O
|
||||
| SHOP | /|\\
|
||||
| [=====] | / \\
|
||||
| | | | |
|
||||
|___|_____|______| _|_
|
||||
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~''',
|
||||
// 프레임 2: 상점으로 이동
|
||||
'''
|
||||
_______________
|
||||
/ \\ O
|
||||
| SHOP | /|\\
|
||||
| [=====] | / \\
|
||||
| | | | |
|
||||
|___|_____|______| _|_
|
||||
~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~''',
|
||||
// 프레임 3: 상점 앞 도착
|
||||
'''
|
||||
_______________
|
||||
/ \\ O
|
||||
| SHOP | /|\\
|
||||
| [=====] | / \\
|
||||
| | | | |
|
||||
|___|_____|______| _|_
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 4: 거래 중
|
||||
'''
|
||||
_______________
|
||||
/ \\ O \$
|
||||
| SHOP | /|\\ \$
|
||||
| [=====] | /\\\$
|
||||
| | @ | | |
|
||||
|___|_____|______| _|_
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 5: 거래 완료
|
||||
'''
|
||||
_______________
|
||||
/ \\ \\O/
|
||||
| SHOP | | +
|
||||
| [=====] | / \\ +
|
||||
| | @ | | | +
|
||||
|___|_____|______| _|_
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
],
|
||||
frameIntervalMs: 280,
|
||||
);
|
||||
|
||||
/// 걷는 애니메이션 (7줄, 배경 포함)
|
||||
const walkingAnimation = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 서있기
|
||||
'''
|
||||
O
|
||||
/|\\
|
||||
/ \\
|
||||
~~ | ~~
|
||||
~~~~ _|_ ~~~~
|
||||
~~~~~~ ~~~~~~~~ ~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 2: 왼발 앞
|
||||
'''
|
||||
O
|
||||
/|\\
|
||||
/|
|
||||
~~ / \\ ~~
|
||||
~~~~ _|_ ~~~~
|
||||
~~~~~~ ~~~~~~~~ ~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 3: 이동 중
|
||||
'''
|
||||
O
|
||||
/|\\
|
||||
|\\
|
||||
~~ / \\ ~~
|
||||
~~~~ _|_ ~~~~
|
||||
~~~~~~ ~~~~~~~~ ~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 4: 오른발 앞
|
||||
'''
|
||||
O
|
||||
/|\\
|
||||
|/
|
||||
~~ / \\ ~~
|
||||
~~~~ _|_ ~~~~
|
||||
~~~~~~ ~~~~~~~~ ~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
O
|
||||
/|\\
|
||||
/ \\
|
||||
~~ | ~~
|
||||
~~~~ _|_ ~~~~
|
||||
~~~~~~ ~~~~~~~~ ~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~''',
|
||||
],
|
||||
frameIntervalMs: 180,
|
||||
);
|
||||
|
||||
/// 곤충 전투 애니메이션
|
||||
const battleAnimationInsect = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, /\\_/\\
|
||||
/( )\\ ( o o )
|
||||
/ \\ vs /|=====|\\
|
||||
_| |_ < | | >
|
||||
| | \\|_____|/
|
||||
_| |_ / \\
|
||||
|_________| /_______\\''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O /\\_/\\
|
||||
/|\\----o ( o o )
|
||||
/ \\ /|=====|\\
|
||||
_| |_ < | | >
|
||||
| | \\|_____|/
|
||||
_| |_ / \\
|
||||
|_________| /_______\\''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o-->/\\_/\\
|
||||
/|\\----------> ( o o )
|
||||
/ \\ /|=====|\\
|
||||
_| |_ < | | >
|
||||
| | \\|_____|/
|
||||
_| |_ / \\
|
||||
|_________| /_______\\''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O /\\_/\\
|
||||
/|\\ **** ( X X ) ****
|
||||
/ \\ ** /|=====|\\ **
|
||||
_| |_ < | | >
|
||||
| | \\|_____|/
|
||||
_| |_ / \\
|
||||
|_________| /_______\\''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ /\\_/\\
|
||||
| ( - - )
|
||||
/ \\ /|=====|\\
|
||||
_| |_ < | | >
|
||||
| | \\|_____|/
|
||||
_| |_ / \\
|
||||
|_________| /_______\\''',
|
||||
],
|
||||
frameIntervalMs: 220,
|
||||
);
|
||||
|
||||
/// 인간형 전투 애니메이션
|
||||
const battleAnimationHumanoid = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, O
|
||||
/( )\\ /|\\
|
||||
/ \\ vs / | \\
|
||||
_| |_ ___|___
|
||||
| | | |
|
||||
_| |_ | orc |
|
||||
|_________| |_______|''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O O
|
||||
/|\\----o /|\\
|
||||
/ \\ / | \\
|
||||
_| |_ ___|___
|
||||
| | | |
|
||||
_| |_ | orc |
|
||||
|_________| |_______|''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o----> O
|
||||
/|\\-----------> /|\\
|
||||
/ \\ / | \\
|
||||
_| |_ ___|___
|
||||
| | | |
|
||||
_| |_ | orc |
|
||||
|_________| |_______|''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O O
|
||||
/|\\ **** X|X ****
|
||||
/ \\ ** / | \\ **
|
||||
_| |_ ___|___
|
||||
| | | |
|
||||
_| |_ | orc |
|
||||
|_________| |_______|''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ O
|
||||
| /|\\
|
||||
/ \\ / | \\
|
||||
_| |_ ___|___
|
||||
| | | |
|
||||
_| |_ | orc |
|
||||
|_________| |_______|''',
|
||||
],
|
||||
frameIntervalMs: 220,
|
||||
);
|
||||
|
||||
/// 언데드 전투 애니메이션
|
||||
const battleAnimationUndead = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, .-.
|
||||
/( )\\ (o.o)
|
||||
/ \\ vs |=|
|
||||
_| |_ /|X|\\
|
||||
| | / | | \\
|
||||
_| |_ \\_|_|_/
|
||||
|_________| _/ \\_''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O .-.
|
||||
/|\\----o (o.o)
|
||||
/ \\ |=|
|
||||
_| |_ /|X|\\
|
||||
| | / | | \\
|
||||
_| |_ \\_|_|_/
|
||||
|_________| _/ \\_''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o--->.-.
|
||||
/|\\-----------> (o.o)
|
||||
/ \\ |=|
|
||||
_| |_ /|X|\\
|
||||
| | / | | \\
|
||||
_| |_ \\_|_|_/
|
||||
|_________| _/ \\_''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O .-.
|
||||
/|\\ **** (X.X) ****
|
||||
/ \\ ** |=| **
|
||||
_| |_ /|X|\\
|
||||
| | / | | \\
|
||||
_| |_ \\_|_|_/
|
||||
|_________| _/ \\_''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ .-.
|
||||
| (-.-)
|
||||
/ \\ |=|
|
||||
_| |_ /|X|\\
|
||||
| | / | | \\
|
||||
_| |_ \\_|_|_/
|
||||
|_________| _/ \\_''',
|
||||
],
|
||||
frameIntervalMs: 250,
|
||||
);
|
||||
|
||||
/// 드래곤 전투 애니메이션
|
||||
const battleAnimationDragon = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, __/\\__
|
||||
/( )\\ / \\
|
||||
/ \\ vs < (O)(O) >
|
||||
_| |_ \\ \\/ /
|
||||
| | \\ /
|
||||
_| |_ /|\\~~~/|\\
|
||||
|_________| /_________\\''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O __/\\__
|
||||
/|\\----o / \\
|
||||
/ \\ < (O)(O) >
|
||||
_| |_ \\ \\/ /
|
||||
| | \\ /
|
||||
_| |_ /|\\~~~/|\\
|
||||
|_________| /_________\\''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o--->__/\\__
|
||||
/|\\---------> / \\
|
||||
/ \\ < (O)(O) >
|
||||
_| |_ \\ \\/ /
|
||||
| | \\ /
|
||||
_| |_ /|\\~~~/|\\
|
||||
|_________| /_________\\''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O __/\\__
|
||||
/|\\ **** / >< \\ ****
|
||||
/ \\ ** < (X)(X) > **
|
||||
_| |_ \\ \\/ /
|
||||
| | \\ /
|
||||
_| |_ /|\\~~~/|\\
|
||||
|_________| /_________\\''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ __/\\__
|
||||
| / \\
|
||||
/ \\ < (-)(-)>
|
||||
_| |_ \\ \\/ /
|
||||
| | \\ /
|
||||
_| |_ /|\\~~~/|\\
|
||||
|_________| /_________\\''',
|
||||
],
|
||||
frameIntervalMs: 200,
|
||||
);
|
||||
|
||||
/// 슬라임 전투 애니메이션
|
||||
const battleAnimationSlime = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, .---.
|
||||
/( )\\ / \\
|
||||
/ \\ vs ( o o )
|
||||
_| |_ \\ ~ /
|
||||
| | '---'
|
||||
_| |_ ~~~~~~~
|
||||
|_________| ~~~~~~~~~''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O .---.
|
||||
/|\\----o / \\
|
||||
/ \\ ( o o )
|
||||
_| |_ \\ ~ /
|
||||
| | '---'
|
||||
_| |_ ~~~~~~~
|
||||
|_________| ~~~~~~~~~''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o--->.---.
|
||||
/|\\---------> / \\
|
||||
/ \\ ( o o )
|
||||
_| |_ \\ ~ /
|
||||
| | '---'
|
||||
_| |_ ~~~~~~~
|
||||
|_________| ~~~~~~~~~''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O .---.
|
||||
/|\\ **** / X X \\ ****
|
||||
/ \\ ** ( ~ ) **
|
||||
_| |_ \\ /
|
||||
| | '---'
|
||||
_| |_ ~~~~~~~
|
||||
|_________| ~~~~~~~~~''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ .---.
|
||||
| / \\
|
||||
/ \\ ( - - )
|
||||
_| |_ \\ ~ /
|
||||
| | '---'
|
||||
_| |_ ~~~~~~~
|
||||
|_________| ~~~~~~~~~''',
|
||||
],
|
||||
frameIntervalMs: 280,
|
||||
);
|
||||
|
||||
/// 악마 전투 애니메이션
|
||||
const battleAnimationDemon = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 대치
|
||||
'''
|
||||
,O, /\\ /\\
|
||||
/( )\\ ( \\ / )
|
||||
/ \\ vs \\ o o /
|
||||
_| |_ | V |
|
||||
| | | ~~~ |
|
||||
_| |_ /| |\\
|
||||
|_________| /___|___|_\\''',
|
||||
// 프레임 2: 공격 준비
|
||||
'''
|
||||
O /\\ /\\
|
||||
/|\\----o ( \\ / )
|
||||
/ \\ \\ o o /
|
||||
_| |_ | V |
|
||||
| | | ~~~ |
|
||||
_| |_ /| |\\
|
||||
|_________| /___|___|_\\''',
|
||||
// 프레임 3: 공격 중
|
||||
'''
|
||||
O o--->/\\ /\\
|
||||
/|\\--------> ( \\ / )
|
||||
/ \\ \\ o o /
|
||||
_| |_ | V |
|
||||
| | | ~~~ |
|
||||
_| |_ /| |\\
|
||||
|_________| /___|___|_\\''',
|
||||
// 프레임 4: 히트
|
||||
'''
|
||||
O /\\ /\\
|
||||
/|\\ **** ( X X ) ****
|
||||
/ \\ ** \\ X X / **
|
||||
_| |_ | V |
|
||||
| | | ~~~ |
|
||||
_| |_ /| |\\
|
||||
|_________| /___|___|_\\''',
|
||||
// 프레임 5: 복귀
|
||||
'''
|
||||
\\O/ /\\ /\\
|
||||
| ( \\ / )
|
||||
/ \\ \\ - - /
|
||||
_| |_ | V |
|
||||
| | | ~~~ |
|
||||
_| |_ /| |\\
|
||||
|_________| /___|___|_\\''',
|
||||
],
|
||||
frameIntervalMs: 200,
|
||||
);
|
||||
|
||||
/// 몬스터 카테고리별 전투 애니메이션 반환
|
||||
AsciiAnimationData getBattleAnimation(MonsterCategory category) {
|
||||
return switch (category) {
|
||||
MonsterCategory.beast => battleAnimationBeast,
|
||||
MonsterCategory.insect => battleAnimationInsect,
|
||||
MonsterCategory.humanoid => battleAnimationHumanoid,
|
||||
MonsterCategory.undead => battleAnimationUndead,
|
||||
MonsterCategory.dragon => battleAnimationDragon,
|
||||
MonsterCategory.slime => battleAnimationSlime,
|
||||
MonsterCategory.demon => battleAnimationDemon,
|
||||
};
|
||||
}
|
||||
|
||||
/// 레벨업 축하 애니메이션
|
||||
const levelUpAnimation = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 시작
|
||||
'''
|
||||
* * *
|
||||
* * *
|
||||
\\O/
|
||||
* | *
|
||||
/ \\
|
||||
* *
|
||||
~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 2: 별 확산
|
||||
'''
|
||||
* * *
|
||||
* *
|
||||
* \\O/ *
|
||||
|
|
||||
* / \\ *
|
||||
* *
|
||||
~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 3: 레벨업 텍스트
|
||||
'''
|
||||
* L E V E L U P ! *
|
||||
* *
|
||||
* \\O/ *
|
||||
|
|
||||
* / \\ *
|
||||
* *
|
||||
~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 4: 빛나는 캐릭터
|
||||
'''
|
||||
* * * * *
|
||||
* *
|
||||
* \\O/ *
|
||||
* | *
|
||||
* / \\ *
|
||||
* * * *
|
||||
~~~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 5: 마무리
|
||||
'''
|
||||
+
|
||||
+++
|
||||
+++++
|
||||
\\O/
|
||||
|
|
||||
/ \\
|
||||
~~~~~~~~~~~~~~~~~~~~~''',
|
||||
],
|
||||
frameIntervalMs: 300,
|
||||
);
|
||||
|
||||
/// 퀘스트 완료 애니메이션
|
||||
const questCompleteAnimation = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 퀘스트 깃발
|
||||
'''
|
||||
[=======]
|
||||
|| ||
|
||||
|| \\O/ ||
|
||||
|| | ||
|
||||
|| / \\ ||
|
||||
||_____||
|
||||
~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 2: 승리
|
||||
'''
|
||||
[QUEST!]
|
||||
|| ||
|
||||
\\\\O//
|
||||
\\|/
|
||||
/ \\
|
||||
||_____||
|
||||
~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 3: 보상
|
||||
'''
|
||||
COMPLETE!
|
||||
|
||||
\\O/ \$\$\$
|
||||
| \$\$\$
|
||||
/ \\ \$\$\$
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 4: 축하
|
||||
'''
|
||||
* * * * *
|
||||
\\O/
|
||||
| +EXP
|
||||
/ \\ +GOLD
|
||||
* * * * *
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~''',
|
||||
// 프레임 5: 마무리
|
||||
'''
|
||||
[ VICTORY! ]
|
||||
|
||||
\\O/
|
||||
|
|
||||
/ \\
|
||||
|
||||
~~~~~~~~~~~~~~~~~~~''',
|
||||
],
|
||||
frameIntervalMs: 350,
|
||||
);
|
||||
|
||||
/// Act 완료 애니메이션 (플롯 진행)
|
||||
const actCompleteAnimation = AsciiAnimationData(
|
||||
frames: [
|
||||
// 프레임 1: 커튼
|
||||
'''
|
||||
____________________
|
||||
| |
|
||||
| A C T |
|
||||
| |
|
||||
| C O M P L E T E |
|
||||
| |
|
||||
|____________________|''',
|
||||
// 프레임 2: 캐릭터 등장
|
||||
'''
|
||||
____________________
|
||||
| * * * * * |
|
||||
| \\O/ |
|
||||
| | |
|
||||
| / \\ |
|
||||
| * * * * * |
|
||||
|____________________|''',
|
||||
// 프레임 3: 플롯 진행 표시
|
||||
'''
|
||||
____________________
|
||||
| PROLOGUE --> ACT |
|
||||
| \\O/ |
|
||||
| | --> |
|
||||
| / \\ |
|
||||
| STORY CONTINUES |
|
||||
|____________________|''',
|
||||
// 프레임 4: 축하
|
||||
'''
|
||||
____________________
|
||||
| * * * * * |
|
||||
| * \\O/ * |
|
||||
| | |
|
||||
| * / \\ * |
|
||||
| * * * * * |
|
||||
|____________________|''',
|
||||
// 프레임 5: 마무리
|
||||
'''
|
||||
____________________
|
||||
| +---------+ |
|
||||
| | NEXT | |
|
||||
| | CHAPTER | |
|
||||
| +---------+ |
|
||||
| \\O/ |
|
||||
|____________________|''',
|
||||
],
|
||||
frameIntervalMs: 400,
|
||||
);
|
||||
|
||||
/// 타입별 애니메이션 데이터 반환 (기본 전투는 beast)
|
||||
AsciiAnimationData getAnimationData(AsciiAnimationType type) {
|
||||
return switch (type) {
|
||||
AsciiAnimationType.battle => battleAnimationBeast,
|
||||
AsciiAnimationType.town => townAnimation,
|
||||
AsciiAnimationType.walking => walkingAnimation,
|
||||
AsciiAnimationType.levelUp => levelUpAnimation,
|
||||
AsciiAnimationType.questComplete => questCompleteAnimation,
|
||||
AsciiAnimationType.actComplete => actCompleteAnimation,
|
||||
};
|
||||
}
|
||||
35
lib/src/core/animation/ascii_animation_type.dart
Normal file
35
lib/src/core/animation/ascii_animation_type.dart
Normal file
@@ -0,0 +1,35 @@
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
|
||||
/// ASCII 애니메이션 타입 (TaskType과 매핑)
|
||||
enum AsciiAnimationType {
|
||||
/// 전투 장면 (캐릭터 vs 몬스터)
|
||||
battle,
|
||||
|
||||
/// 마을/상점 장면
|
||||
town,
|
||||
|
||||
/// 걷는 캐릭터
|
||||
walking,
|
||||
|
||||
/// 레벨업 축하
|
||||
levelUp,
|
||||
|
||||
/// 퀘스트 완료
|
||||
questComplete,
|
||||
|
||||
/// Act 완료 (플롯 진행)
|
||||
actComplete,
|
||||
}
|
||||
|
||||
/// TaskType을 AsciiAnimationType으로 변환
|
||||
AsciiAnimationType taskTypeToAnimation(TaskType taskType) {
|
||||
return switch (taskType) {
|
||||
TaskType.kill => AsciiAnimationType.battle,
|
||||
TaskType.market ||
|
||||
TaskType.sell ||
|
||||
TaskType.buying => AsciiAnimationType.town,
|
||||
TaskType.neutral ||
|
||||
TaskType.load ||
|
||||
TaskType.plot => AsciiAnimationType.walking,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user