refactor(ui): 기타 화면 정리
- FrontScreen, HallOfFameScreen 개선 - NewCharacterScreen, SettingsScreen 정리 - App 초기화 로직 정리
This commit is contained in:
@@ -469,7 +469,8 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
}
|
||||
|
||||
void _navigateToNewCharacter(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
Navigator.of(context)
|
||||
.push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => NewCharacterScreen(
|
||||
onCharacterCreated: (initialState, {bool testMode = false}) {
|
||||
@@ -477,7 +478,8 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
},
|
||||
),
|
||||
),
|
||||
).then((_) {
|
||||
)
|
||||
.then((_) {
|
||||
// 새 게임 후 돌아오면 세이브 정보 갱신 (BGM은 _checkForExistingSave에서 재생)
|
||||
_checkForExistingSave();
|
||||
});
|
||||
@@ -544,7 +546,8 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
}
|
||||
|
||||
void _navigateToGame(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
Navigator.of(context)
|
||||
.push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => GamePlayScreen(
|
||||
controller: _controller,
|
||||
@@ -555,7 +558,8 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
onThemeModeChange: _changeThemeMode,
|
||||
),
|
||||
),
|
||||
).then((_) {
|
||||
)
|
||||
.then((_) {
|
||||
// 게임에서 돌아오면 세이브 정보 갱신 (BGM은 _checkForExistingSave에서 재생)
|
||||
_checkForExistingSave();
|
||||
});
|
||||
@@ -563,9 +567,13 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
|
||||
/// Phase 10: 명예의 전당 화면으로 이동
|
||||
void _navigateToHallOfFame(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(builder: (context) => const HallOfFameScreen()),
|
||||
).then((_) {
|
||||
Navigator.of(context)
|
||||
.push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => const HallOfFameScreen(),
|
||||
),
|
||||
)
|
||||
.then((_) {
|
||||
// 명예의 전당에서 돌아오면 타이틀 BGM 재생
|
||||
_audioService.playBgm('title');
|
||||
});
|
||||
@@ -573,11 +581,11 @@ class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
|
||||
/// 로컬 아레나 화면으로 이동
|
||||
void _navigateToArena(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => const ArenaScreen(),
|
||||
),
|
||||
).then((_) {
|
||||
Navigator.of(context)
|
||||
.push(
|
||||
MaterialPageRoute<void>(builder: (context) => const ArenaScreen()),
|
||||
)
|
||||
.then((_) {
|
||||
// 아레나에서 돌아오면 명예의 전당 다시 로드 및 타이틀 BGM 재생
|
||||
_loadHallOfFame();
|
||||
_audioService.playBgm('title');
|
||||
@@ -636,10 +644,7 @@ class _SplashScreen extends StatelessWidget {
|
||||
fontSize: 14,
|
||||
color: RetroColors.cream,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: RetroColors.brown,
|
||||
offset: Offset(1, 1),
|
||||
),
|
||||
Shadow(color: RetroColors.brown, offset: Offset(1, 1)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -648,10 +653,7 @@ class _SplashScreen extends StatelessWidget {
|
||||
),
|
||||
const SizedBox(height: 32),
|
||||
// 레트로 로딩 바
|
||||
SizedBox(
|
||||
width: 160,
|
||||
child: _RetroLoadingBar(),
|
||||
),
|
||||
SizedBox(width: 160, child: _RetroLoadingBar()),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
@@ -107,8 +107,8 @@ class FrontScreen extends StatelessWidget {
|
||||
onHallOfFame: onHallOfFame != null
|
||||
? () => onHallOfFame!(context)
|
||||
: null,
|
||||
onLocalArena: onLocalArena != null &&
|
||||
hallOfFameCount >= 2
|
||||
onLocalArena:
|
||||
onLocalArena != null && hallOfFameCount >= 2
|
||||
? () => onLocalArena!(context)
|
||||
: null,
|
||||
savedGamePreview: savedGamePreview,
|
||||
@@ -153,10 +153,7 @@ class _RetroHeader extends StatelessWidget {
|
||||
fontSize: 14,
|
||||
color: RetroColors.gold,
|
||||
shadows: [
|
||||
Shadow(
|
||||
color: RetroColors.goldDark,
|
||||
offset: Offset(2, 2),
|
||||
),
|
||||
Shadow(color: RetroColors.goldDark, offset: Offset(2, 2)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -169,7 +166,10 @@ class _RetroHeader extends StatelessWidget {
|
||||
spacing: 8,
|
||||
runSpacing: 8,
|
||||
children: [
|
||||
_RetroTag(icon: Icons.cloud_off_outlined, label: l10n.tagNoNetwork),
|
||||
_RetroTag(
|
||||
icon: Icons.cloud_off_outlined,
|
||||
label: l10n.tagNoNetwork,
|
||||
),
|
||||
_RetroTag(icon: Icons.timer_outlined, label: l10n.tagIdleRpg),
|
||||
_RetroTag(icon: Icons.storage_rounded, label: l10n.tagLocalSaves),
|
||||
],
|
||||
|
||||
@@ -159,9 +159,7 @@ class _HeroVsBossAnimationState extends State<HeroVsBossAnimation> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final frame = _applyGlitchEffect(
|
||||
frontScreenAnimationFrames[_currentFrame],
|
||||
);
|
||||
final frame = _applyGlitchEffect(frontScreenAnimationFrames[_currentFrame]);
|
||||
|
||||
// 현재 종족 이름 (UI 표시용)
|
||||
final raceName = RaceData.findById(_currentRaceId)?.name ?? 'Hero';
|
||||
@@ -172,10 +170,7 @@ class _HeroVsBossAnimationState extends State<HeroVsBossAnimation> {
|
||||
// 항상 검은 배경
|
||||
color: Colors.black,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
border: Border.all(
|
||||
color: Colors.white24,
|
||||
width: 1,
|
||||
),
|
||||
border: Border.all(color: Colors.white24, width: 1),
|
||||
// 은은한 글로우 효과
|
||||
boxShadow: [
|
||||
BoxShadow(
|
||||
@@ -192,9 +187,7 @@ class _HeroVsBossAnimationState extends State<HeroVsBossAnimation> {
|
||||
Flexible(
|
||||
child: FittedBox(
|
||||
fit: BoxFit.scaleDown,
|
||||
child: RichText(
|
||||
text: _buildColoredTextSpan(frame),
|
||||
),
|
||||
child: RichText(text: _buildColoredTextSpan(frame)),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 8),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:asciineverdie/data/game_text_l10n.dart' as l10n;
|
||||
@@ -136,9 +137,7 @@ class _HallOfFameScreenState extends State<HallOfFameScreen> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 10),
|
||||
decoration: BoxDecoration(
|
||||
color: goldColor.withValues(alpha: 0.2),
|
||||
border: Border(
|
||||
bottom: BorderSide(color: goldColor, width: 2),
|
||||
),
|
||||
border: Border(bottom: BorderSide(color: goldColor, width: 2)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -166,7 +165,11 @@ class _HallOfFameScreenState extends State<HallOfFameScreen> {
|
||||
itemCount: hallOfFame.entries.length,
|
||||
itemBuilder: (context, index) {
|
||||
final entry = hallOfFame.entries[index];
|
||||
return _HallOfFameEntryCard(entry: entry, rank: index + 1);
|
||||
return _HallOfFameEntryCard(
|
||||
entry: entry,
|
||||
rank: index + 1,
|
||||
onDeleteRequest: () => _confirmDelete(entry),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
@@ -174,14 +177,103 @@ class _HallOfFameScreenState extends State<HallOfFameScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// 삭제 확인 다이얼로그 (디버그 모드 전용)
|
||||
Future<void> _confirmDelete(HallOfFameEntry entry) async {
|
||||
final confirmed = await showDialog<bool>(
|
||||
context: context,
|
||||
builder: (context) => RetroDialog(
|
||||
title: l10n.uiConfirm.toUpperCase(),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(16),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
'${entry.characterName} (Lv.${entry.level})\n'
|
||||
'${l10n.uiConfirmDelete}',
|
||||
style: const TextStyle(fontFamily: 'PressStart2P', fontSize: 7),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () => Navigator.pop(context, false),
|
||||
child: Text(l10n.uiCancel),
|
||||
),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: RetroColors.hpOf(context),
|
||||
),
|
||||
onPressed: () => Navigator.pop(context, true),
|
||||
child: Text(l10n.uiDelete),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
if (confirmed == true && mounted) {
|
||||
await _deleteEntry(entry.id);
|
||||
}
|
||||
}
|
||||
|
||||
/// 엔트리 삭제 실행
|
||||
Future<void> _deleteEntry(String id) async {
|
||||
final success = await _storage.deleteEntry(id);
|
||||
|
||||
if (!mounted) return;
|
||||
|
||||
if (success) {
|
||||
// 성공 시 목록 새로고침
|
||||
await _loadHallOfFame();
|
||||
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
l10n.uiDeleted,
|
||||
style: const TextStyle(fontFamily: 'PressStart2P', fontSize: 6),
|
||||
),
|
||||
backgroundColor: RetroColors.mpOf(context),
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
// 실패 시 에러 메시지
|
||||
if (mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
l10n.uiError,
|
||||
style: const TextStyle(fontFamily: 'PressStart2P', fontSize: 6),
|
||||
),
|
||||
backgroundColor: RetroColors.hpOf(context),
|
||||
duration: const Duration(seconds: 2),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// 명예의 전당 엔트리 카드
|
||||
class _HallOfFameEntryCard extends StatelessWidget {
|
||||
const _HallOfFameEntryCard({required this.entry, required this.rank});
|
||||
const _HallOfFameEntryCard({
|
||||
required this.entry,
|
||||
required this.rank,
|
||||
required this.onDeleteRequest,
|
||||
});
|
||||
|
||||
final HallOfFameEntry entry;
|
||||
final int rank;
|
||||
final VoidCallback onDeleteRequest;
|
||||
|
||||
void _showDetailDialog(BuildContext context) {
|
||||
showDialog<void>(
|
||||
@@ -259,8 +351,9 @@ class _HallOfFameEntryCard extends StatelessWidget {
|
||||
vertical: 2,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
color: RetroColors.mpOf(context)
|
||||
.withValues(alpha: 0.2),
|
||||
color: RetroColors.mpOf(
|
||||
context,
|
||||
).withValues(alpha: 0.2),
|
||||
border: Border.all(
|
||||
color: RetroColors.mpOf(context),
|
||||
width: 1,
|
||||
@@ -337,6 +430,36 @@ class _HallOfFameEntryCard extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
// 삭제 버튼 (디버그 모드 전용)
|
||||
if (kDebugMode) ...[
|
||||
const SizedBox(width: 8),
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
// 이벤트 전파 중지 (카드 클릭 방지)
|
||||
onDeleteRequest();
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(4),
|
||||
decoration: BoxDecoration(
|
||||
color: RetroColors.hpOf(
|
||||
context,
|
||||
).withValues(alpha: 0.2),
|
||||
border: Border.all(
|
||||
color: RetroColors.hpOf(context),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Icon(
|
||||
Icons.delete_outline,
|
||||
size: 16,
|
||||
color: RetroColors.hpOf(context),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
@@ -459,9 +582,7 @@ class _GameClearDialog extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(vertical: 12),
|
||||
decoration: BoxDecoration(
|
||||
color: goldColor.withValues(alpha: 0.2),
|
||||
border: Border(
|
||||
bottom: BorderSide(color: goldColor, width: 2),
|
||||
),
|
||||
border: Border(bottom: BorderSide(color: goldColor, width: 2)),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
@@ -496,10 +617,7 @@ class _GameClearDialog extends StatelessWidget {
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Container(
|
||||
height: 2,
|
||||
color: borderColor,
|
||||
),
|
||||
Container(height: 2, color: borderColor),
|
||||
const SizedBox(height: 16),
|
||||
// 캐릭터 정보
|
||||
Text(
|
||||
@@ -528,9 +646,21 @@ class _GameClearDialog extends StatelessWidget {
|
||||
alignment: WrapAlignment.center,
|
||||
children: [
|
||||
_buildStat(context, l10n.hofLevel, '${entry.level}'),
|
||||
_buildStat(context, l10n.hofTime, entry.formattedPlayTime),
|
||||
_buildStat(context, l10n.hofDeaths, '${entry.totalDeaths}'),
|
||||
_buildStat(context, l10n.hofQuests, '${entry.questsCompleted}'),
|
||||
_buildStat(
|
||||
context,
|
||||
l10n.hofTime,
|
||||
entry.formattedPlayTime,
|
||||
),
|
||||
_buildStat(
|
||||
context,
|
||||
l10n.hofDeaths,
|
||||
'${entry.totalDeaths}',
|
||||
),
|
||||
_buildStat(
|
||||
context,
|
||||
l10n.hofQuests,
|
||||
'${entry.questsCompleted}',
|
||||
),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
@@ -817,7 +947,12 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
spacing: 8,
|
||||
runSpacing: 6,
|
||||
children: [
|
||||
_buildStatItem(context, Icons.timer, l10n.hofTime, entry.formattedPlayTime),
|
||||
_buildStatItem(
|
||||
context,
|
||||
Icons.timer,
|
||||
l10n.hofTime,
|
||||
entry.formattedPlayTime,
|
||||
),
|
||||
_buildStatItem(
|
||||
context,
|
||||
Icons.pest_control,
|
||||
@@ -860,7 +995,11 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
_buildCombatStatChip(l10n.statStr, '${stats.str}', Colors.red),
|
||||
_buildCombatStatChip(l10n.statCon, '${stats.con}', Colors.orange),
|
||||
_buildCombatStatChip(l10n.statDex, '${stats.dex}', Colors.green),
|
||||
_buildCombatStatChip(l10n.statInt, '${stats.intelligence}', Colors.blue),
|
||||
_buildCombatStatChip(
|
||||
l10n.statInt,
|
||||
'${stats.intelligence}',
|
||||
Colors.blue,
|
||||
),
|
||||
_buildCombatStatChip(l10n.statWis, '${stats.wis}', Colors.purple),
|
||||
_buildCombatStatChip(l10n.statCha, '${stats.cha}', Colors.pink),
|
||||
],
|
||||
@@ -873,8 +1012,16 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
_buildCombatStatChip(l10n.statAtk, '${stats.atk}', Colors.red.shade700),
|
||||
_buildCombatStatChip(l10n.statMAtk, '${stats.magAtk}', Colors.blue.shade700),
|
||||
_buildCombatStatChip(
|
||||
l10n.statAtk,
|
||||
'${stats.atk}',
|
||||
Colors.red.shade700,
|
||||
),
|
||||
_buildCombatStatChip(
|
||||
l10n.statMAtk,
|
||||
'${stats.magAtk}',
|
||||
Colors.blue.shade700,
|
||||
),
|
||||
_buildCombatStatChip(
|
||||
l10n.statCri,
|
||||
'${(stats.criRate * 100).toStringAsFixed(1)}%',
|
||||
@@ -889,7 +1036,11 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
_buildCombatStatChip(l10n.statDef, '${stats.def}', Colors.brown),
|
||||
_buildCombatStatChip(l10n.statMDef, '${stats.magDef}', Colors.indigo),
|
||||
_buildCombatStatChip(
|
||||
l10n.statMDef,
|
||||
'${stats.magDef}',
|
||||
Colors.indigo,
|
||||
),
|
||||
_buildCombatStatChip(
|
||||
l10n.statEva,
|
||||
'${(stats.evasion * 100).toStringAsFixed(1)}%',
|
||||
@@ -908,8 +1059,16 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
spacing: 6,
|
||||
runSpacing: 4,
|
||||
children: [
|
||||
_buildCombatStatChip(l10n.statHp, '${stats.hpMax}', Colors.red.shade400),
|
||||
_buildCombatStatChip(l10n.statMp, '${stats.mpMax}', Colors.blue.shade400),
|
||||
_buildCombatStatChip(
|
||||
l10n.statHp,
|
||||
'${stats.hpMax}',
|
||||
Colors.red.shade400,
|
||||
),
|
||||
_buildCombatStatChip(
|
||||
l10n.statMp,
|
||||
'${stats.mpMax}',
|
||||
Colors.blue.shade400,
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
@@ -1021,7 +1180,10 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(6),
|
||||
decoration: BoxDecoration(
|
||||
color: rarityColor.withValues(alpha: 0.1),
|
||||
border: Border.all(color: rarityColor.withValues(alpha: 0.3), width: 1),
|
||||
border: Border.all(
|
||||
color: rarityColor.withValues(alpha: 0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
@@ -1076,11 +1238,7 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
// 스탯 요약
|
||||
if (statSummary.isNotEmpty) ...[
|
||||
const SizedBox(height: 4),
|
||||
Wrap(
|
||||
spacing: 6,
|
||||
runSpacing: 2,
|
||||
children: statSummary,
|
||||
),
|
||||
Wrap(spacing: 6, runSpacing: 2, children: statSummary),
|
||||
],
|
||||
],
|
||||
),
|
||||
@@ -1180,16 +1338,32 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
|
||||
// 확률 스탯
|
||||
if (stats.criRate > 0) {
|
||||
addStat(l10n.statCri, '+${(stats.criRate * 100).toStringAsFixed(0)}%', Colors.amber);
|
||||
addStat(
|
||||
l10n.statCri,
|
||||
'+${(stats.criRate * 100).toStringAsFixed(0)}%',
|
||||
Colors.amber,
|
||||
);
|
||||
}
|
||||
if (stats.blockRate > 0) {
|
||||
addStat(l10n.statBlock, '+${(stats.blockRate * 100).toStringAsFixed(0)}%', Colors.blueGrey);
|
||||
addStat(
|
||||
l10n.statBlock,
|
||||
'+${(stats.blockRate * 100).toStringAsFixed(0)}%',
|
||||
Colors.blueGrey,
|
||||
);
|
||||
}
|
||||
if (stats.evasion > 0) {
|
||||
addStat(l10n.statEva, '+${(stats.evasion * 100).toStringAsFixed(0)}%', Colors.teal);
|
||||
addStat(
|
||||
l10n.statEva,
|
||||
'+${(stats.evasion * 100).toStringAsFixed(0)}%',
|
||||
Colors.teal,
|
||||
);
|
||||
}
|
||||
if (stats.parryRate > 0) {
|
||||
addStat(l10n.statParry, '+${(stats.parryRate * 100).toStringAsFixed(0)}%', Colors.cyan);
|
||||
addStat(
|
||||
l10n.statParry,
|
||||
'+${(stats.parryRate * 100).toStringAsFixed(0)}%',
|
||||
Colors.cyan,
|
||||
);
|
||||
}
|
||||
|
||||
// 보너스 스탯
|
||||
@@ -1227,10 +1401,7 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
padding: const EdgeInsets.all(8),
|
||||
decoration: BoxDecoration(
|
||||
color: RetroColors.backgroundOf(context),
|
||||
border: Border.all(
|
||||
color: RetroColors.borderOf(context),
|
||||
width: 1,
|
||||
),
|
||||
border: Border.all(color: RetroColors.borderOf(context), width: 1),
|
||||
),
|
||||
child: Text(
|
||||
l10n.hofNoSkills.toUpperCase(),
|
||||
@@ -1255,7 +1426,10 @@ class _HallOfFameDetailDialog extends StatelessWidget {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
color: skillColor.withValues(alpha: 0.1),
|
||||
border: Border.all(color: skillColor.withValues(alpha: 0.3), width: 1),
|
||||
border: Border.all(
|
||||
color: skillColor.withValues(alpha: 0.3),
|
||||
width: 1,
|
||||
),
|
||||
),
|
||||
child: Text(
|
||||
'$translatedName $rank',
|
||||
|
||||
@@ -784,5 +784,4 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
|
||||
ClassPassiveType.firstStrikeBonus => passive.description,
|
||||
};
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,10 +11,7 @@ import 'package:asciineverdie/src/core/animation/race_character_frames.dart';
|
||||
/// 새 캐릭터 생성 화면에서 선택한 종족의 idle 애니메이션을 보여줌.
|
||||
/// RichText 기반 색상 적용.
|
||||
class RacePreview extends StatefulWidget {
|
||||
const RacePreview({
|
||||
super.key,
|
||||
required this.raceId,
|
||||
});
|
||||
const RacePreview({super.key, required this.raceId});
|
||||
|
||||
/// 종족 ID (예: "byte_human", "kernel_giant")
|
||||
final String raceId;
|
||||
@@ -121,9 +118,7 @@ class _RacePreviewState extends State<RacePreview> {
|
||||
);
|
||||
}
|
||||
|
||||
return RichText(
|
||||
text: TextSpan(children: spans),
|
||||
);
|
||||
return RichText(text: TextSpan(children: spans));
|
||||
}
|
||||
|
||||
/// 문자별 색상 매핑
|
||||
|
||||
@@ -122,10 +122,7 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
children: [
|
||||
Icon(Icons.settings, color: theme.colorScheme.primary),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
game_l10n.uiSettings,
|
||||
style: theme.textTheme.titleLarge,
|
||||
),
|
||||
Text(game_l10n.uiSettings, style: theme.textTheme.titleLarge),
|
||||
const Spacer(),
|
||||
IconButton(
|
||||
icon: const Icon(Icons.close),
|
||||
@@ -196,9 +193,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
padding: const EdgeInsets.only(bottom: 8),
|
||||
child: Text(
|
||||
title,
|
||||
style: Theme.of(context).textTheme.titleMedium?.copyWith(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
style: Theme.of(
|
||||
context,
|
||||
).textTheme.titleMedium?.copyWith(fontWeight: FontWeight.bold),
|
||||
),
|
||||
);
|
||||
}
|
||||
@@ -292,7 +289,10 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
leading: Text(lang.$3, style: const TextStyle(fontSize: 24)),
|
||||
title: Text(lang.$2),
|
||||
trailing: isSelected
|
||||
? Icon(Icons.check, color: Theme.of(context).colorScheme.primary)
|
||||
? Icon(
|
||||
Icons.check,
|
||||
color: Theme.of(context).colorScheme.primary,
|
||||
)
|
||||
: null,
|
||||
onTap: () {
|
||||
game_l10n.setGameLocale(lang.$1);
|
||||
@@ -331,16 +331,9 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
||||
children: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(label),
|
||||
Text('$percentage%'),
|
||||
],
|
||||
),
|
||||
Slider(
|
||||
value: value,
|
||||
onChanged: onChanged,
|
||||
divisions: 10,
|
||||
children: [Text(label), Text('$percentage%')],
|
||||
),
|
||||
Slider(value: value, onChanged: onChanged, divisions: 10),
|
||||
],
|
||||
),
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user