# Документация игры "Морской бой" ## Оглавление 1. [Обзор проекта](#обзор-проекта) 2. [Архитектура игры](#архитектура-игры) 3. [Игровые режимы](#игровые-режимы) 4. [Основные системы](#основные-системы) 5. [Управление и ввод](#управление-и-ввод) 6. [Искусственный интеллект](#искусственный-интеллект) 7. [Система призов](#система-призов) 8. [Настройки](#настройки) 9. [Звук и визуальные эффекты](#звук-и-визуальные-эффекты) 10. [Структура проекта](#структура-проекта) --- ## Обзор проекта **Sea Battle** - это аркадная игра "Морской бой" для Unity, разработанная для работы с аппаратным обеспечением через COM-порт. Игра поддерживает как одиночный режим против AI, так и многопользовательский режим (два игрока). ### Ключевые особенности: - ? Два режима игры: против бота и против другого игрока - ? 6 уровней сложности AI с прогрессивной системой - ? Интегрированная система выдачи призов (монеты, билеты, спецпризы) - ? Динамическая смена окружения (день/ночь) - ? Уникальные голосовые профили для каждого противника - ? Монетная система через COM-порт - ?? Расширенная система настроек - ? Генерация QR-кодов для связи (Telegram/WhatsApp) --- ## Архитектура игры ### Основные состояния (GameState) ```csharp public enum GameState { MainMenu, // Главное меню ShipPlacement, // Расстановка кораблей BotPlacement, // Расстановка кораблей ботом Playing, // Игровой процесс GameOver, // Конец игры Setting, // Настройки Invite, // Приглашение игрока Input, // Ввод данных Prize, // Экран приза CharacterSetting // Настройка персонажа } ``` ### Режимы управления (InputMode) ```csharp public enum InputMode { UI, // Интерфейс меню Settings, // Навигация в настройках ShipPlacement, // Расстановка кораблей Battle // Боевой режим } ``` ### Центральный менеджер - GameManager `GameManager` - главный управляющий класс игры, отвечает за: - Переключение состояний игры - Управление ходами игроков - Контроль победных условий - Инициализацию AI - Взаимодействие с противником - Управление камерой - Таймер бездействия (360 секунд по умолчанию) **События:** ```csharp public static event Action OnInviteSent; // Приглашение отправлено public static event Action OnReady; // Игрок готов public event Action OnInputModeChanged; // Режим ввода изменен ``` --- ## Игровые режимы ### 1. Режим "Игрок против Бота" (PlayerVsBot) **Процесс игры:** 1. Игрок вносит оплату (`ComWrapper.Pay()`) 2. Расстановка кораблей игроком 3. Автоматическая расстановка кораблей ботом 4. Пошаговая битва 5. Выдача приза при победе (если настройка включена) **Прогрессия сложности:** - Level 1-4: Последовательное повышение - Level 5: Активируется система шансов (DifficultyManager) - Level 6: "Непобедимый" режим ### 2. Режим "Игрок против Игрока" (PlayerVsPlayer) **Процесс игры:** 1. Первый игрок отправляет приглашение 2. Второй игрок принимает приглашение 3. Оба игрока расставляют корабли 4. Поочередная битва 5. Возврат средств при выходе в меню --- ## Основные системы ### Система игрового поля (GamePole) **Ключевые функции:** ```csharp public class GamePole : MonoBehaviour { public GameObject[,] Pole; // 10x10 сетка клеток public int[,] PoleShot; // 0-не стреляли, 1-промах, 2-попал, 3-потоплен public int[,] FreePole; // Для размещения кораблей public bool Shot(int x, int y); // Выстрел по координатам public void ArrangeShip(); // Авторасстановка кораблей public void ClearPole(); // Очистка поля public void CopyShipsFrom(GamePole source, bool hideShips); // Копирование кораблей } ``` **Размещение кораблей:** - 1x четырёхпалубный - 2x трёхпалубных - 3x двухпалубных - 4x однопалубных - **Всего: 10 кораблей** ### Система кораблей (Ship) **Компоненты:** ```csharp public class Ship : MonoBehaviour { public List decks; // Палубы корабля public List deckCoords; // Координаты на поле public ParticleSystem[] explosionPrefabs; // Эффекты взрыва public GameObject[] debrisPrefabs; // Обломки public Transform mastsContainer; // Мачты public bool IsDestroyed(); // Проверка уничтожения public void Destroy(); // Уничтожение корабля } ``` **Эффекты при уничтожении:** - Взрывы на каждой палубе - Отлетающие обломки с физикой - Падающие мачты (20% шанс) - Затопление корабля (`ShipsMuved.Sink()`) ### Система стрельбы **CannonBattery:** ```csharp public void FireShot(GamePole targetPole, int x, int y, Action onShotComplete) { // Выстрел по координатам // Callback: (wasHit, wasShipDestroyed) } ``` **Механика:** 1. Выбор готового орудия из батареи 2. Физический выстрел снаряда 3. Попадание в цель 4. Обработка результата (попал/промах/потопил) 5. Визуальные и звуковые эффекты ### Курсор прицеливания (TargetCursor) **Функционал:** - Перемещение по полю (WASD/стрелки) - Стрельба (действие) - Поворот кораблей при расстановке - Привязка к игроку (1 или 2) - Автоматическая ротация камеры --- ## Управление и ввод ### Система ввода (In) **Архитектура:** ``` In (Фасад) ??? InputSource (Абстракция) ? ??? KeyboardInput (Для тестирования) ? ??? COMinput (Работа с платой) ??? ButtonPinMapping (Маппинг пинов) ``` **Источники ввода:** 1. **Keyboard** - клавиатура для разработки 2. **COM** - физические кнопки через COM-порт **Маппинг кнопок:** ```csharp public static class ButtonPinMapping { // Игрок 1 public static int up1 = 2; public static int down1 = 3; public static int left1 = 4; public static int right1 = 5; public static int action1 = 6; public static int turn1 = 7; // Игрок 2 public static int up2 = 8; public static int down2 = 9; // ...и т.д. } ``` ### COM-система (ComWrapper) **Основные функции:** ```csharp public class ComWrapper { // Управление кредитами public static void AddCredit(int coins = 1); public static void Pay(); public static int GetPlayerCredits(); // Отправка команд public static void Send(string command); // События public static UnityEvent onCoinAdded; public static UnityEvent onCoinRemoved; public static UnityEvent onInputRecieved; } ``` **Команды:** - `"302"` - выключить мотор выдачи призов - `"303"` - включить мотор выдачи призов - `"91"` - запросить состояние пинов - `"80XX"` - управление подсветкой --- ## Искусственный интеллект ### Уровни сложности **Иерархия ботов:** ``` IBotAI (Интерфейс) ??? EasyBotAI (Уровень 1) - Случайные выстрелы ??? NormalBotAI (Уровень 2) - Базовая стратегия ??? HardBotAI (Уровень 3) - Умная стратегия ??? VeryHardBotAI (Уровень 4) - Продвинутая стратегия ??? CrazyBotAI (Уровень 5) - Очень сложный ??? UltimateBotAI (Уровень 6) - Почти непобедимый ``` ### DifficultyManager - Система шансов **Механизм:** ```csharp public static class DifficultyManager { public static int GetChance(); // Получить текущий шанс (0-100) public static void DecreaseChance(); // Уменьшить после игры public static void ResetChance(); // Сброс на 100 } ``` **Логика:** - Начальное значение: 100 - При каждой игре против Level 6: шанс уменьшается - При шансе = 0: игрок получает Level 5 (победимый) - После победы над Level 5: шанс сбрасывается ### Стратегии AI **EasyBotAI:** - Полностью случайные выстрелы **NormalBotAI и выше:** 1. Ищет раненые корабли 2. Добивает найденные цели 3. Использует умную стрельбу (шахматный порядок) --- ## Система призов ### Типы призов (PrizeType) ```csharp public enum PrizeType { None, // Нет приза Hopper, // Монеты через хоппер Ticket, // Билеты Special, // Спецприз (QR-код) Marbles // Шарики } ``` ### PrizeSystem **Функционал:** ```csharp public static void GivePrize(Prize prize) { // Выдача приза с проверкой настроек // Поддержка разных типов призов // Обработка ошибок выдачи } ``` **Процесс выдачи Hopper-приза:** 1. Проверка настроек и ошибок 2. Отправка команды `"303"` (включить мотор) 3. Ожидание подтверждения (до 10 секунд) 4. Отправка команды `"302"` (выключить мотор) 5. Обновление счетчиков **Статистика:** ```csharp public static string key_starts = "STARTS"; // Всего запусков public static string key_startsNul = "STARTSNUL"; // Запуски без приза public static string key_prizesgiven = "PRIZESGIVEN"; // Выдано призов public static string key_prizesgivenNul = "PRIZESGIVENNUL"; // Ошибок выдачи ``` ### PrizeSerializer **Загрузка призов:** ```csharp public static Prize[] GetPrizes() { // Загрузка из JSON файла // Возвращает массив призов для каждого уровня } ``` **Пример конфигурации приза:** ```json { "PrizeType": "Hopper", "Amount": 5 } ``` --- ## Настройки ### SettingsManager **Доступные настройки:** | Настройка | Опции | По умолчанию | |-----------|-------|--------------| | Громкость музыки | 0-10 | 1 | | Громкость эффектов | 0-10 | 8 | | Громкость голоса | 0-10 | 8 | | Выдача призов при игре с ботом | Выдавать/Не выдавать | Выдавать | | Бесплатная игра | Вкл/Выкл | Выкл | | Показывать контакты администрации | Вкл/Выкл | Вкл | | QR-код для связи | Telegram/WhatsApp/Всё | Telegram | | Игровая тема | День/Ночь | День | | Быстрая проверка | Вкл/Выкл | Выкл | | Быстрая проверка наличия приза | Вкл/Выкл | Выкл | | Выдавать приз при ошибке | Вкл/Выкл | Выкл | | Вывод ошибки выдачи в меню | Вкл/Выкл | Выкл | **API:** ```csharp // Получение значения string value = SettingsManager.instance.GetSettingValue("Громкость музыки"); // Изменение настройки SettingsManager.instance.ChangeSetting("Громкость музыки", 5); // Событие изменения SettingsManager.instance.OnSettingsChanged.AddListener(OnSettingsChanged); ``` ### SettingsScreen **Функции:** - Прокрутка настроек (более 5 элементов) - Выбор опций с визуальной обратной связью - Сохранение/загрузка настроек - Валидация и хеширование --- ## Звук и визуальные эффекты ### SoundManager **Структура:** ```csharp public class SoundManager : Singleton { // Источники звука для каждого игрока public AudioSource player1VoiceSource; public AudioSource player1EffectsSource; public AudioSource player2VoiceSource; public AudioSource player2EffectsSource; // Фоновая музыка public AudioSource musicSource; public AudioClip[] backgroundMusic; // Профили звуков public List soundProfiles; } ``` **Звуковые профили:** - `player` / `player_2` - голоса игроков - `bot_1` - `bot_5` - голоса ботов разной сложности **Основные методы:** ```csharp void SetActiveProfile(int playerId, string profileName); void PlayPlayerVictory(int playerId); void PlayBotVictory(int playerId); void PlayBotHit(int playerId); void PlayBotMiss(int playerId); void PlayPlayerShipDestroyed(int playerId); ``` ### EffectManager **Визуальные эффекты:** ```csharp public class EffectManager : Singleton { GameObject PlayMissText(Vector3 position); // Текст "МИМО" GameObject PlayHitEffect(Vector3 position); // Эффект попадания GameObject PlayExplosion(Vector3 position); // Взрыв } ``` ### EnvironmentManager **Управление окружением:** ```csharp public class EnvironmentManager { [Serializable] public class EnvironmentPreset { public Material skybox; // Скайбокс public Color lightColor; // Цвет света public float lightIntensity; // Интенсивность // Цвета воды (остров/океан) public Color waterShallowColor; public Color waterDeepColor; public Color waterFresnelColor; // UI public Color cursorColor; public Color cursorFrameColor; } } ``` **Пресеты:** - Preset 0: День - Preset 1: Ночь --- ## Структура проекта ``` Assets/ ??? Scripts/ ? ??? GameManager.cs # Главный менеджер игры ? ??? GamePole.cs # Игровое поле ? ??? Ship.cs # Корабль ? ??? Player.cs # Игрок ? ??? TargetCursor.cs # Курсор прицеливания ? ??? CannonBattery.cs # Батарея орудий ? ??? Cannon.cs # Орудие ? ??? Cell.cs # Клетка поля ? ??? Deck.cs # Палуба корабля ? ? ? ??? BotAI/ # Искусственный интеллект ? ? ??? IBotAI.cs # Интерфейс AI ? ? ??? EasyBotAI.cs # Легкий бот ? ? ??? NormalBotAI.cs # Средний бот ? ? ??? HardBotAI.cs # Сложный бот ? ? ??? VeryHardBotAI.cs # Очень сложный ? ? ??? CrazyBotAI.cs # Безумный ? ? ??? UltimateBotAI.cs # Непобедимый ? ? ??? DifficultyManager.cs # Управление сложностью ? ? ? ??? UI/ # Интерфейс ? ? ??? UIManager.cs # Менеджер UI ? ? ??? GameOver.cs # Экран окончания ? ? ??? AdminContactsController.cs ? ? ??? FastCheckController.cs ? ? ??? Coin.cs # Монета ? ? ??? CoinFlipUI.cs # Анимация монеты ? ? ??? EnemyCardController.cs # Карточка врага ? ? ??? EnemyManager.cs # Менеджер врагов ? ? ??? TurnTimerUI.cs # Таймер хода ? ? ? ??? Settings/ # Настройки ? ? ??? SettingsManager.cs # Менеджер настроек ? ? ??? SettingsScreen.cs # Экран настроек ? ? ??? SettingOption.cs # Опция настройки ? ? ??? GameSettings.cs # Игровые настройки ? ? ??? CharacterSettingPanel.cs ? ? ??? CountersView.cs # Отображение счетчиков ? ? ??? InitializeInput.cs # Инициализация ввода ? ? ? ??? Inputs/ # Система ввода ? ? ??? In.cs # Фасад ввода ? ? ??? InputSource.cs # Абстракция источника ? ? ??? KeyboardInput.cs # Клавиатура ? ? ??? COMinput.cs # COM-порт ? ? ??? ButtonPinMapping.cs # Маппинг кнопок ? ? ??? PlayerAction.cs # Действия игрока ? ? ??? ComSystem/ # COM-система ? ? ??? ComWrapper.cs # Обертка COM ? ? ??? ComNativeWrapper.cs # Нативные вызовы ? ? ??? PrizeSystem.cs # Система призов ? ? ??? PrizeSystem/ ? ? ??? Prize.cs ? ? ??? PrizeType.cs ? ? ??? PrizeSerializer.cs ? ? ? ??? Qr/ # QR-коды ? ? ??? QrMaker.cs # Генератор QR ? ? ??? QR_viewer.cs # Просмотр QR ? ? ? ??? Pirate/ # Пиратская команда ? ? ??? Pirate.cs ? ? ??? FortInitializer.cs # Инициализатор фортов ? ? ??? PirateCommand.cs # Команда пиратов ? ? ??? EnemyCombat.cs ? ? ??? Gun.cs ? ? ??? BoxingMachine.cs ? ? ? ??? Enum/ # Перечисления ? ? ??? GameState.cs ? ? ??? GameMode.cs ? ? ??? Direction.cs ? ? ??? KeyVault.cs # Ключи PlayerPrefs ? ? ? ??? SoundManager.cs # Менеджер звука ? ??? SoundProfile.cs # Профиль звуков ? ??? EffectManager.cs # Менеджер эффектов ? ??? EnvironmentManager.cs # Менеджер окружения ? ??? CameraShake.cs # Тряска камеры ? ??? MultiDisplaySetup.cs # Мультидисплей ? ??? Prefabs/ # Префабы ??? Materials/ # Материалы ??? Models/ # 3D модели ??? Animations/ # Анимации ??? Audio/ # Звуки ??? Images/ # Изображения ??? Scenes/ # Сцены ``` --- ## Особенности реализации ### Система таймера бездействия ```csharp // В GameManager [SerializeField] float inactionTimer = 360f; // 6 минут public float timerBackToMenu = 0; private void Update() { timerBackToMenu += Time.deltaTime; if (timerBackToMenu >= inactionTimer) { ResetGameState(true); timerBackToMenu = 0; } } ``` **Сброс таймера:** - При любом нажатии кнопки (`In.ButtonEvent`) - Автоматический возврат в меню при бездействии ### Система камеры **Позиции камеры:** - `mainMenuCameraPosition` - главное меню - `shipPlacementCameraPosition` - расстановка кораблей - `gameplayCameraPosition` - игровой процесс **Плавное перемещение:** ```csharp public void MoveCameraTo(Transform target) { StartCoroutine(MoveCameraSmoothly(target)); } ``` ### QR-коды для связи **QrMaker:** ```csharp public static Texture2D MakeTexture( string text, int pixelsPerModule = 8, bool drawQuietZones = true, Color darkColor = default, Color lightColor = default) ``` **Цветовая схема:** - Telegram: синий QR-код - WhatsApp: зеленый QR-код ### Быстрая проверка (Fast Check) **FastCheckController:** - Слушает комбинации клавиш (Fire + Turn, Up + Down) - Показывает статистику игры - Отображает ошибки выдачи призов - Работает только при включенной настройке --- ## Поток игры ### 1. Запуск приложения ``` Инициализация: ??? In.Initialize() - Система ввода ??? ComWrapper.Initialize() - COM-порт ??? PrizeSystem.Initialize() - Система призов ??? SettingsManager.Awake() - Загрузка настроек ??? GameManager.Start() - Главное меню ``` ### 2. Начало игры против бота ``` 1. ComWrapper.Pay() - Списание кредита 2. ResetGameState() - Сброс состояния 3. SetState(ShipPlacement) - Расстановка кораблей 4. SetInputMode(ShipPlacement) - Режим расстановки 5. InitTargetCursor(true) - Курсор расстановки 6. InitBot() - Инициализация AI 7. [Игрок расставляет корабли] 8. StartBattle() - Начало боя 9. PrepareForBattle() - Подготовка 10. enemyField.ArrangeShip() - Расстановка кораблей бота 11. SetState(Playing) - Игровое состояние 12. StartPlayerTurn() - Ход игрока ``` ### 3. Игровой цикл ``` Ход игрока: ??? Перемещение курсора ??? Выстрел (FireShot) ??? Обработка результата ??? Если промах ? EndPlayerTurn() Ход бота: ??? bot.MakeMove() ??? enemyBattery.FireShot() ??? Обработка результата ??? Если промах ? StartPlayerTurn() ``` ### 4. Окончание игры ``` CheckVictoryCondition(): ??? Если playerShips <= 0 ? Поражение ??? Если enemyShips <= 0 ? Победа ??? EndGame() EndGame(): ??? SetState(GameOver) ??? Если победа и бот: ? ??? Получить приз для уровня ? ??? Если Special ? показать QR ? ??? Иначе ? PrizeSystem.GivePrize() ? ??? Увеличить уровень бота ??? ShowGameOverMenu() ``` --- ## Технические детали ### PlayerPrefs ключи (KeyVault) ```csharp // Система призов "STARTS" - Общее количество запусков "STARTSNUL" - Запуски без выдачи приза "PRIZESGIVEN" - Выдано призов "PRIZESGIVENNUL" - Ошибок при выдаче "PRIZES_AVAILABLE" - Доступно призов "PRIZING_ERROR_REGISTRED" - Зарегистрирована ошибка "NeedSpecialPrize" - Нужен спецприз // Игра "Player_Coins" - Монеты игрока "SETTINGS" - Настройки игры "BotChance" - Шанс победы над ботом "telephone_number" - Телефон администратора ``` ### Многопользовательская игра **Механизм приглашения:** ```csharp // Отправка приглашения OnInviteSent?.Invoke(fromPlayerId, toPlayerId); // Обработка приглашения GameManager.OnInviteSent += HandleInvite; // Принятие AcceptInvite() { StartPlayerGame(); opponentManager.StartPlayerGame(); } ``` **Синхронизация:** - Поля копируются между игроками - Ходы чередуются через `opponentManager` - Победа определяется локально ### Оптимизация **Пулинг объектов:** - Эффекты уничтожаются через заданное время - Обломки кораблей удаляются автоматически **Ленивая загрузка:** - Форты создаются по требованию - Курсор создается только при необходимости --- ## Отладка и разработка ### Быстрые клавиши (в режиме разработки) ```csharp // Player.cs [SerializeField] private KeyCode addKey = KeyCode.F2; // Добавить кредит ``` ### Ручная настройка сложности ```csharp // GameManager public bool useManualDifficulty = false; public BotDifficulty manualDifficulty = BotDifficulty.Level1; ``` ### Логирование ```csharp Debug.Log("Игрок победил!"); Debug.LogWarning("Боту нечего стрелять"); Debug.LogError("Ошибка выдачи приза"); ``` --- ## Известные особенности 1. **Система шансов DifficultyManager** - игрок не может бесконечно проигрывать на 5 уровне 2. **Таймер бездействия** - автоматический возврат в меню через 6 минут 3. **Монетная система** - интеграция с физическим оборудованием 4. **Призы** - поддержка различных типов выдачи (хоппер, билеты, спецпризы) 5. **Мультидисплей** - поддержка нескольких экранов для двух игроков --- ## Зависимости ### NuGet пакеты - **QRCoder** - генерация QR-кодов ### Unity Assets - **TextMeshPro** - текст UI - **Particle Systems** - визуальные эффекты - **Post Processing** (возможно, для эффектов камеры) --- ## Конфигурационные файлы ### prizes.json ```json { "prizes": [ { "PrizeType": "Hopper", "Amount": 1 }, { "PrizeType": "Hopper", "Amount": 2 }, // ...до 5 уровней ] } ``` --- ## Лицензия и авторские права Проект использует сторонние ассеты: - JMO Assets (Cartoon FX) - Toony Colors Pro - ProBuilder - Skybox Cubemap Extended --- ## Контакты и поддержка Для связи с администратором: - QR-код генерируется автоматически - Номер телефона хранится в PlayerPrefs по ключу `"telephone_number"` - Отображается в UI при включенной настройке --- **Версия документации:** 1.0 **Дата:** 2025-12-10 **Язык:** Русский *Документация составлена на основе анализа исходного кода проекта Sea Battle.*