feat(front): 프론트 화면 개선 및 설정 저장소 추가

- front_screen_animation.dart: 프론트 화면 애니메이션 추가
- settings_repository.dart: 설정 저장소 구현
- front/widgets/: 프론트 화면 위젯 분리
- mobile_carousel_layout.dart: 모바일 레이아웃 개선
- app.dart: 앱 설정 개선
- game_text_l10n.dart: 텍스트 추가
This commit is contained in:
JiWoong Sul
2025-12-23 18:52:46 +09:00
parent e6af7dd91a
commit 549851f693
10 changed files with 722 additions and 183 deletions

View File

@@ -28,6 +28,8 @@ class NewCharacterScreen extends StatefulWidget {
class _NewCharacterScreenState extends State<NewCharacterScreen> {
final TextEditingController _nameController = TextEditingController();
final ScrollController _raceScrollController = ScrollController();
final ScrollController _klassScrollController = ScrollController();
// 종족(races)과 직업(klasses) 목록 (Phase 5)
final List<RaceTraits> _races = RaceData.all;
@@ -74,14 +76,47 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
// 초기 이름 생성
_nameController.text = generateName(_nameRng);
// 선택된 종족/직업으로 스크롤
_scrollToSelectedItems();
}
@override
void dispose() {
_nameController.dispose();
_raceScrollController.dispose();
_klassScrollController.dispose();
super.dispose();
}
/// 선택된 종족/직업 위치로 스크롤
void _scrollToSelectedItems() {
// ListTile 높이 약 48px (dense 모드)
const itemHeight = 48.0;
WidgetsBinding.instance.addPostFrameCallback((_) {
if (_raceScrollController.hasClients) {
final raceOffset = _selectedRaceIndex * itemHeight;
_raceScrollController.animateTo(
raceOffset.clamp(0.0, _raceScrollController.position.maxScrollExtent),
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
if (_klassScrollController.hasClients) {
final klassOffset = _selectedKlassIndex * itemHeight;
_klassScrollController.animateTo(
klassOffset.clamp(
0.0,
_klassScrollController.position.maxScrollExtent,
),
duration: const Duration(milliseconds: 300),
curve: Curves.easeOut,
);
}
});
}
/// 스탯 굴림 (3d6 × 6)
void _rollStats() {
final rng = DeterministicRandom(_currentSeed);
@@ -108,6 +143,9 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
// 새 시드로 굴림
_currentSeed = math.Random().nextInt(0x7FFFFFFF);
_rollStats();
// 선택된 종족/직업으로 스크롤
_scrollToSelectedItems();
}
/// Unroll 버튼 클릭 (이전 롤로 복원)
@@ -415,6 +453,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
SizedBox(
height: 300,
child: ListView.builder(
controller: _raceScrollController,
itemCount: _races.length,
itemBuilder: (context, index) {
final isSelected = index == _selectedRaceIndex;
@@ -521,6 +560,7 @@ class _NewCharacterScreenState extends State<NewCharacterScreen> {
SizedBox(
height: 300,
child: ListView.builder(
controller: _klassScrollController,
itemCount: _klasses.length,
itemBuilder: (context, index) {
final isSelected = index == _selectedKlassIndex;