This commit is contained in:
2025-12-02 11:06:23 +09:00
parent bf40c42c2c
commit 22caf64855
34 changed files with 4594 additions and 505 deletions
+59
View File
@@ -85,6 +85,65 @@ class AppGames {
icon: Icons.touch_app,
isSinglePlayerSupported: false,
),
GameInfo(
id: 'world_tour',
name: '월드 투어',
description: '주사위를 굴려 세계 여행!\n땅을 사고 통행료를 받으세요.',
icon: Icons.public,
isSinglePlayerSupported: false,
),
// [추가] 오셀로
GameInfo(
id: 'othello',
name: '오셀로',
description: '돌을 뒤집어라!\n마지막에 웃는 자가 승리',
icon: Icons.circle, // 흑백 원 아이콘
isSinglePlayerSupported: false,
),
// [추가] 알카노이드
GameInfo(
id: 'arkanoid',
name: '벽돌 깨기',
description: '추억의 아케이드!\n누가 더 높은 점수를 낼까?',
icon: Icons.view_module,
isSinglePlayerSupported: true,
),// [추가] 매스 런 (게이트 런)
GameInfo(
id: 'math_run',
name: '매스 런',
description: '좌우로 움직여 숫자를 늘리세요!\n높은 점수가 승리합니다.',
icon: Icons.calculate,
isSinglePlayerSupported: true,
),
// [추가] 점프 배틀 (횡스크롤)
GameInfo(
id: 'jump_battle',
name: '점프 배틀',
description: '장애물을 피해 끝까지 달리세요!\n타이밍 싸움!',
icon: Icons.directions_run,
isSinglePlayerSupported: true,
),
GameInfo(
id: 'iam_ground',
name: '아이엠그라운드',
description: '리듬을 타며 이름을 공격하세요!\n박자를 놓치면 탈락!',
icon: Icons.music_note, // 음표 아이콘
isSinglePlayerSupported: false, // 최소 2인 이상
),
GameInfo(
id: 'survivor',
name: '서바이버',
description: '몰려오는 몬스터를 막아내세요!\n이동만 하면 자동으로 공격합니다.',
icon: Icons.bug_report,
isSinglePlayerSupported: true,
),
GameInfo(
id: 'sequence_memory',
name: '기억의 신',
description: '반짝이는 순서를 기억하세요!\n라운드가 갈수록 종류가 다양해집니다.',
icon: Icons.apps,
isSinglePlayerSupported: true,
),
];
static GameInfo getById(String id) {
+8 -12
View File
@@ -1,44 +1,41 @@
import 'dart:convert';
/// 패킷의 종류 (라우팅 기준)
enum PacketType {
system, // 시스템 (레디, 시작, 종료, 핸드셰이크 등)
chat, // 채팅 (GlobalChatManager로 전달)
game, // 게임 로직 (GameController로 전달)
media,
unknown
system, chat, game, media, unknown
}
class PlayPacket {
final PacketType type;
final String senderId; // 보낸 사람 ID
final dynamic payload; // 실제 데이터 (Map, List, String 등)
final String senderId;
final dynamic payload;
final int timestamp;
final int? seq; // [추가] 패킷 순번
PlayPacket({
required this.type,
required this.senderId,
required this.payload,
required this.timestamp,
this.seq, // [추가]
});
// JSON -> 객체
factory PlayPacket.fromJson(Map<String, dynamic> json) {
return PlayPacket(
type: _parseType(json['type']),
senderId: json['senderId'] ?? 'unknown',
payload: json['payload'],
timestamp: json['timestamp'] ?? DateTime.now().millisecondsSinceEpoch,
seq: json['seq'], // [추가]
);
}
// 객체 -> JSON
Map<String, dynamic> toJson() {
return {
'type': type.name, // enum을 문자열로 ('chat', 'game'...)
'type': type.name,
'senderId': senderId,
'payload': payload,
'timestamp': timestamp,
if (seq != null) 'seq': seq, // [추가]
};
}
@@ -46,7 +43,6 @@ class PlayPacket {
for (var t in PacketType.values) {
if (t.name == typeStr) return t;
}
// 호환성: 기존 레거시 메시지(PING, ANSWER_SUBMIT 등)는 'unknown'이나 별도 처리
return PacketType.unknown;
}
}
@@ -0,0 +1,28 @@
class SpiderGameDto {
final int puzzleId;
final int difficulty; // 1, 2, 4 (Suits)
final List<int> cards; // 0~103 (카드 덱)
SpiderGameDto({
required this.puzzleId,
required this.difficulty,
required this.cards,
});
factory SpiderGameDto.fromJson(Map<String, dynamic> json) {
return SpiderGameDto(
puzzleId: json['puzzleId'] ?? 0,
difficulty: json['difficulty'] ?? 1,
// 카드 배열 파싱
cards: (json['cards'] as List<dynamic>?)?.map((e) => e as int).toList() ?? [],
);
}
Map<String, dynamic> toJson() {
return {
'puzzleId': puzzleId,
'difficulty': difficulty,
'cards': cards,
};
}
}