sea-battle/DOCUMENTATION.md
2026-01-09 08:45:22 +03:00

22 KiB
Raw Blame History

Документация игры "Морской бой"

Оглавление

  1. Обзор проекта
  2. Архитектура игры
  3. Игровые режимы
  4. Основные системы
  5. Управление и ввод
  6. Искусственный интеллект
  7. Система призов
  8. Настройки
  9. Звук и визуальные эффекты
  10. Структура проекта

Обзор проекта

Sea Battle - это аркадная игра "Морской бой" для Unity, разработанная для работы с аппаратным обеспечением через COM-порт. Игра поддерживает как одиночный режим против AI, так и многопользовательский режим (два игрока).

Ключевые особенности:

  • ? Два режима игры: против бота и против другого игрока
  • ? 6 уровней сложности AI с прогрессивной системой
  • ? Интегрированная система выдачи призов (монеты, билеты, спецпризы)
  • ? Динамическая смена окружения (день/ночь)
  • ? Уникальные голосовые профили для каждого противника
  • ? Монетная система через COM-порт
  • ?? Расширенная система настроек
  • ? Генерация QR-кодов для связи (Telegram/WhatsApp)

Архитектура игры

Основные состояния (GameState)

public enum GameState
{
    MainMenu,           // Главное меню
    ShipPlacement,      // Расстановка кораблей
    BotPlacement,       // Расстановка кораблей ботом
    Playing,            // Игровой процесс
    GameOver,           // Конец игры
    Setting,            // Настройки
    Invite,             // Приглашение игрока
    Input,              // Ввод данных
    Prize,              // Экран приза
    CharacterSetting    // Настройка персонажа
}

Режимы управления (InputMode)

public enum InputMode
{
    UI,              // Интерфейс меню
    Settings,        // Навигация в настройках
    ShipPlacement,   // Расстановка кораблей
    Battle           // Боевой режим
}

Центральный менеджер - GameManager

GameManager - главный управляющий класс игры, отвечает за:

  • Переключение состояний игры
  • Управление ходами игроков
  • Контроль победных условий
  • Инициализацию AI
  • Взаимодействие с противником
  • Управление камерой
  • Таймер бездействия (360 секунд по умолчанию)

События:

public static event Action<int, int> OnInviteSent;           // Приглашение отправлено
public static event Action<int, bool, GameMode> OnReady;     // Игрок готов
public event Action<InputMode> 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)

Ключевые функции:

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)

Компоненты:

public class Ship : MonoBehaviour
{
    public List<GameObject> decks;              // Палубы корабля
    public List<Vector2Int> deckCoords;         // Координаты на поле
    public ParticleSystem[] explosionPrefabs;   // Эффекты взрыва
    public GameObject[] debrisPrefabs;          // Обломки
    public Transform mastsContainer;            // Мачты
    
    public bool IsDestroyed();                  // Проверка уничтожения
    public void Destroy();                      // Уничтожение корабля
}

Эффекты при уничтожении:

  • Взрывы на каждой палубе
  • Отлетающие обломки с физикой
  • Падающие мачты (20% шанс)
  • Затопление корабля (ShipsMuved.Sink())

Система стрельбы

CannonBattery:

public void FireShot(GamePole targetPole, int x, int y, 
                     Action<bool, bool> onShotComplete)
{
    // Выстрел по координатам
    // Callback: (wasHit, wasShipDestroyed)
}

Механика:

  1. Выбор готового орудия из батареи
  2. Физический выстрел снаряда
  3. Попадание в цель
  4. Обработка результата (попал/промах/потопил)
  5. Визуальные и звуковые эффекты

Курсор прицеливания (TargetCursor)

Функционал:

  • Перемещение по полю (WASD/стрелки)
  • Стрельба (действие)
  • Поворот кораблей при расстановке
  • Привязка к игроку (1 или 2)
  • Автоматическая ротация камеры

Управление и ввод

Система ввода (In)

Архитектура:

In (Фасад)
  ??? InputSource (Абстракция)
  ?   ??? KeyboardInput (Для тестирования)
  ?   ??? COMinput (Работа с платой)
  ??? ButtonPinMapping (Маппинг пинов)

Источники ввода:

  1. Keyboard - клавиатура для разработки
  2. COM - физические кнопки через COM-порт

Маппинг кнопок:

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)

Основные функции:

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<int> onCoinAdded;
    public static UnityEvent<int> onCoinRemoved;
    public static UnityEvent<string> onInputRecieved;
}

Команды:

  • "302" - выключить мотор выдачи призов
  • "303" - включить мотор выдачи призов
  • "91" - запросить состояние пинов
  • "80XX" - управление подсветкой

Искусственный интеллект

Уровни сложности

Иерархия ботов:

IBotAI (Интерфейс)
  ??? EasyBotAI (Уровень 1)       - Случайные выстрелы
  ??? NormalBotAI (Уровень 2)     - Базовая стратегия
  ??? HardBotAI (Уровень 3)       - Умная стратегия
  ??? VeryHardBotAI (Уровень 4)   - Продвинутая стратегия
  ??? CrazyBotAI (Уровень 5)      - Очень сложный
  ??? UltimateBotAI (Уровень 6)   - Почти непобедимый

DifficultyManager - Система шансов

Механизм:

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)

public enum PrizeType
{
    None,       // Нет приза
    Hopper,     // Монеты через хоппер
    Ticket,     // Билеты
    Special,    // Спецприз (QR-код)
    Marbles     // Шарики
}

PrizeSystem

Функционал:

public static void GivePrize(Prize prize)
{
    // Выдача приза с проверкой настроек
    // Поддержка разных типов призов
    // Обработка ошибок выдачи
}

Процесс выдачи Hopper-приза:

  1. Проверка настроек и ошибок
  2. Отправка команды "303" (включить мотор)
  3. Ожидание подтверждения (до 10 секунд)
  4. Отправка команды "302" (выключить мотор)
  5. Обновление счетчиков

Статистика:

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

Загрузка призов:

public static Prize[] GetPrizes()
{
    // Загрузка из JSON файла
    // Возвращает массив призов для каждого уровня
}

Пример конфигурации приза:

{
    "PrizeType": "Hopper",
    "Amount": 5
}

Настройки

SettingsManager

Доступные настройки:

Настройка Опции По умолчанию
Громкость музыки 0-10 1
Громкость эффектов 0-10 8
Громкость голоса 0-10 8
Выдача призов при игре с ботом Выдавать/Не выдавать Выдавать
Бесплатная игра Вкл/Выкл Выкл
Показывать контакты администрации Вкл/Выкл Вкл
QR-код для связи Telegram/WhatsApp/Всё Telegram
Игровая тема День/Ночь День
Быстрая проверка Вкл/Выкл Выкл
Быстрая проверка наличия приза Вкл/Выкл Выкл
Выдавать приз при ошибке Вкл/Выкл Выкл
Вывод ошибки выдачи в меню Вкл/Выкл Выкл

API:

// Получение значения
string value = SettingsManager.instance.GetSettingValue("Громкость музыки");

// Изменение настройки
SettingsManager.instance.ChangeSetting("Громкость музыки", 5);

// Событие изменения
SettingsManager.instance.OnSettingsChanged.AddListener(OnSettingsChanged);

SettingsScreen

Функции:

  • Прокрутка настроек (более 5 элементов)
  • Выбор опций с визуальной обратной связью
  • Сохранение/загрузка настроек
  • Валидация и хеширование

Звук и визуальные эффекты

SoundManager

Структура:

public class SoundManager : Singleton
{
    // Источники звука для каждого игрока
    public AudioSource player1VoiceSource;
    public AudioSource player1EffectsSource;
    public AudioSource player2VoiceSource;
    public AudioSource player2EffectsSource;
    
    // Фоновая музыка
    public AudioSource musicSource;
    public AudioClip[] backgroundMusic;
    
    // Профили звуков
    public List<SoundProfile> soundProfiles;
}

Звуковые профили:

  • player / player_2 - голоса игроков
  • bot_1 - bot_5 - голоса ботов разной сложности

Основные методы:

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

Визуальные эффекты:

public class EffectManager : Singleton
{
    GameObject PlayMissText(Vector3 position);      // Текст "МИМО"
    GameObject PlayHitEffect(Vector3 position);     // Эффект попадания
    GameObject PlayExplosion(Vector3 position);     // Взрыв
}

EnvironmentManager

Управление окружением:

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/                         # Сцены

Особенности реализации

Система таймера бездействия

// В 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 - игровой процесс

Плавное перемещение:

public void MoveCameraTo(Transform target)
{
    StartCoroutine(MoveCameraSmoothly(target));
}

QR-коды для связи

QrMaker:

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)

// Система призов
"STARTS"                      - Общее количество запусков
"STARTSNUL"                   - Запуски без выдачи приза
"PRIZESGIVEN"                 - Выдано призов
"PRIZESGIVENNUL"              - Ошибок при выдаче
"PRIZES_AVAILABLE"            - Доступно призов
"PRIZING_ERROR_REGISTRED"     - Зарегистрирована ошибка
"NeedSpecialPrize"            - Нужен спецприз

// Игра
"Player_Coins"                - Монеты игрока
"SETTINGS"                    - Настройки игры
"BotChance"                   - Шанс победы над ботом
"telephone_number"            - Телефон администратора

Многопользовательская игра

Механизм приглашения:

// Отправка приглашения
OnInviteSent?.Invoke(fromPlayerId, toPlayerId);

// Обработка приглашения
GameManager.OnInviteSent += HandleInvite;

// Принятие
AcceptInvite() {
    StartPlayerGame();
    opponentManager.StartPlayerGame();
}

Синхронизация:

  • Поля копируются между игроками
  • Ходы чередуются через opponentManager
  • Победа определяется локально

Оптимизация

Пулинг объектов:

  • Эффекты уничтожаются через заданное время
  • Обломки кораблей удаляются автоматически

Ленивая загрузка:

  • Форты создаются по требованию
  • Курсор создается только при необходимости

Отладка и разработка

Быстрые клавиши (в режиме разработки)

// Player.cs
[SerializeField] private KeyCode addKey = KeyCode.F2; // Добавить кредит

Ручная настройка сложности

// GameManager
public bool useManualDifficulty = false;
public BotDifficulty manualDifficulty = BotDifficulty.Level1;

Логирование

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

{
    "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.