This commit is contained in:
2025-11-24 17:53:00 +09:00
parent e992a5ca5e
commit dde81cab65
34 changed files with 3718 additions and 469 deletions
+40 -18
View File
@@ -1,31 +1,53 @@
// lib/game/base_game.dart
import 'dart:async';
import 'package:flutter/material.dart';
import '../network/network_manager.dart';
import '../model/play_packet.dart';
/// 모든 미니게임의 부모 클래스
/// 모든 게임의 부모 클래스 (자동 패킷 리스닝 기능 탑재)
abstract class BaseGame {
/// 게임 고유 ID (예: 'quiz', 'bomb') - 패킷 라우팅용
String get id;
/// 게임 이름 (로비 표시용)
String get name;
/// 게임 설명
String get description;
/// [Host] 방장이 보는 게임 화면 빌드
Widget buildHostView(BuildContext context);
// 네트워크 구독 관리자 (private)
StreamSubscription? _internalSubscription;
/// [Guest] 참가자가 보는 게임 화면 빌드
Widget buildGuestView(BuildContext context);
/// [Core] 게임 시작 시 자동 호출 (super.onStart() 필수 호출)
@mustCallSuper
void onStart() {
print("[$name] Game Engine Started");
// 네트워크 스트림 자동 구독
_internalSubscription = NetworkManager().messageStream.listen((payload) {
// 1. PlayPacket으로 변환 시도 (구조화된 데이터)
if (payload.containsKey('type') && payload.containsKey('payload')) {
try {
// 만약 패킷 타입이 'game'이라면 onGamePacketReceived 호출
// (여기서는 단순화를 위해 모든 JSON을 자식에게 넘기되, 자식이 알아서 필터링하게 하거나
// PlayPacket 구조를 강제할 수 있습니다. 현재는 하위 호환성을 위해 raw data 전달)
onMessageReceived("", payload);
} catch (e) {
print("Packet Error: $e");
}
} else {
// 레거시 데이터 처리
onMessageReceived("", payload);
}
});
}
/// 게임이 시작될 때 초기화 로직 (변수 초기화 등)
void onStart();
/// [Core] 게임 종료 시 자동 호출 (super.onDispose() 필수 호출)
@mustCallSuper
void onDispose() {
print("[$name] Game Engine Disposed");
_internalSubscription?.cancel();
}
/// 네트워크 메시지 수신 처리
/// [senderId]: 보낸 사람 ID
/// [payload]: 수신된 데이터 (JSON)
/// [Abstract] 자식 클래스가 구현해야 할 데이터 처리 메서드
/// Core가 메시지를 받으면 이 함수를 실행시켜 줍니다.
void onMessageReceived(String senderId, Map<String, dynamic> payload);
/// 게임 종료 및 메모리 정리
void onDispose();
// UI 빌더
Widget buildHostView(BuildContext context);
Widget buildGuestView(BuildContext context);
}