feat: 초기 커밋
- Progress Quest 6.4 Flutter 포팅 프로젝트 - 게임 루프, 상태 관리, UI 구현 - 캐릭터 생성, 인벤토리, 장비, 주문 시스템 - 시장/판매/구매 메커니즘
This commit is contained in:
145
lib/src/app.dart
Normal file
145
lib/src/app.dart
Normal file
@@ -0,0 +1,145 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import 'package:askiineverdie/src/core/engine/game_mutations.dart';
|
||||
import 'package:askiineverdie/src/core/engine/progress_service.dart';
|
||||
import 'package:askiineverdie/src/core/engine/reward_service.dart';
|
||||
import 'package:askiineverdie/src/core/model/game_state.dart';
|
||||
import 'package:askiineverdie/src/core/model/pq_config.dart';
|
||||
import 'package:askiineverdie/src/core/storage/save_manager.dart';
|
||||
import 'package:askiineverdie/src/core/storage/save_repository.dart';
|
||||
import 'package:askiineverdie/src/features/front/front_screen.dart';
|
||||
import 'package:askiineverdie/src/features/front/save_picker_dialog.dart';
|
||||
import 'package:askiineverdie/src/features/game/game_play_screen.dart';
|
||||
import 'package:askiineverdie/src/features/game/game_session_controller.dart';
|
||||
import 'package:askiineverdie/src/features/new_character/new_character_screen.dart';
|
||||
|
||||
class AskiiNeverDieApp extends StatefulWidget {
|
||||
const AskiiNeverDieApp({super.key});
|
||||
|
||||
@override
|
||||
State<AskiiNeverDieApp> createState() => _AskiiNeverDieAppState();
|
||||
}
|
||||
|
||||
class _AskiiNeverDieAppState extends State<AskiiNeverDieApp> {
|
||||
late final GameSessionController _controller;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
const config = PqConfig();
|
||||
final mutations = GameMutations(config);
|
||||
final rewards = RewardService(mutations);
|
||||
|
||||
_controller = GameSessionController(
|
||||
progressService: ProgressService(
|
||||
config: config,
|
||||
mutations: mutations,
|
||||
rewards: rewards,
|
||||
),
|
||||
saveManager: SaveManager(SaveRepository()),
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_controller.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'Ascii Never Die',
|
||||
debugShowCheckedModeBanner: false,
|
||||
theme: ThemeData(
|
||||
colorScheme: ColorScheme.fromSeed(seedColor: const Color(0xFF234361)),
|
||||
scaffoldBackgroundColor: const Color(0xFFF4F5F7),
|
||||
useMaterial3: true,
|
||||
),
|
||||
home: FrontScreen(
|
||||
onNewCharacter: _navigateToNewCharacter,
|
||||
onLoadSave: _loadSave,
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
void _navigateToNewCharacter(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => NewCharacterScreen(
|
||||
onCharacterCreated: (initialState) {
|
||||
_startGame(context, initialState);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _loadSave(BuildContext context) async {
|
||||
// 저장 파일 목록 조회
|
||||
final saves = await _controller.saveManager.listSaves();
|
||||
|
||||
if (!context.mounted) return;
|
||||
|
||||
String? selectedFileName;
|
||||
|
||||
if (saves.isEmpty) {
|
||||
// 저장 파일이 없으면 안내 메시지
|
||||
ScaffoldMessenger.of(
|
||||
context,
|
||||
).showSnackBar(const SnackBar(content: Text('저장된 게임이 없습니다.')));
|
||||
return;
|
||||
} else if (saves.length == 1) {
|
||||
// 파일이 하나면 바로 선택
|
||||
selectedFileName = saves.first.fileName;
|
||||
} else {
|
||||
// 여러 개면 다이얼로그 표시
|
||||
selectedFileName = await SavePickerDialog.show(context, saves);
|
||||
}
|
||||
|
||||
if (selectedFileName == null || !context.mounted) return;
|
||||
|
||||
// 선택된 파일 로드
|
||||
await _controller.loadAndStart(
|
||||
fileName: selectedFileName,
|
||||
cheatsEnabled: false,
|
||||
);
|
||||
|
||||
if (_controller.status == GameSessionStatus.running) {
|
||||
if (context.mounted) {
|
||||
_navigateToGame(context);
|
||||
}
|
||||
} else if (_controller.status == GameSessionStatus.error) {
|
||||
if (context.mounted) {
|
||||
ScaffoldMessenger.of(context).showSnackBar(
|
||||
SnackBar(
|
||||
content: Text(
|
||||
'저장 파일을 불러올 수 없습니다: ${_controller.error ?? "알 수 없는 오류"}',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _startGame(BuildContext context, GameState initialState) async {
|
||||
await _controller.startNew(initialState, cheatsEnabled: false);
|
||||
|
||||
if (context.mounted) {
|
||||
// NewCharacterScreen을 pop하고 GamePlayScreen으로 이동
|
||||
Navigator.of(context).pushReplacement(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => GamePlayScreen(controller: _controller),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _navigateToGame(BuildContext context) {
|
||||
Navigator.of(context).push(
|
||||
MaterialPageRoute<void>(
|
||||
builder: (context) => GamePlayScreen(controller: _controller),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user