4.9 KiB
План: Game Rules & Match Logic (M5)
Цель: Реализовать систему судейства, подсчёт голов, таймер матча и управление состояниями игры (Playing, GoalPause, MatchEnded).
Архитектура: Введение MatchManager в качестве верхнего уровня управления. Он владеет World и контролирует, когда физика и ИИ мира должны обновляться, а когда игра должна быть заморожена.
Стек: Go.
Спека: docs/specs/2026-05-12-match-logic-design.md
Файловая структура
internal/game/world.go— добавление методов для проверки гола и сброса позиций.internal/game/match_manager.go— новый файл с логикой управления матчем, счетом и таймерами.cmd/game/main.go— заменаWorldнаMatchManagerв основном цикле игры.
Задачи
Задача 1: Методы управления состоянием мира
Файлы:
-
Изменить:
internal/game/world.go -
Шаг 1: Реализовать
CheckGoal()- Метод должен проверять
Puck.Position.X. - Если
X < 0\rightarrowвозвращает(entities.TeamBlue, true). - Если
X > WorldWidth\rightarrowвозвращает(entities.TeamRed, true). - Иначе
\rightarrow(entities.TeamRed, false).
- Метод должен проверять
-
Шаг 2: Реализовать
ResetPositions()- Установить
Puck.Positionв центр поля,Puck.Velocity = 0. - Для каждого игрока в
PlayersустановитьPosition = HomePositionиVelocity = 0.
- Установить
-
Шаг 3: Коммит
git add internal/game/world.go && git commit -m "feat(game): add CheckGoal and ResetPositions to World"
Задача 2: Реализация MatchManager
Файлы:
-
Создать:
internal/game/match_manager.go -
Шаг 1: Определить типы и структуру
GameState(enum:Playing,GoalPause,MatchEnded).MatchManagerструктура:World *WorldState GameStateScoreRed, ScoreBlue intMatchDuration float64(в секундах)CurrentTime float64PauseDuration float64PauseTimer float64
-
Шаг 2: Реализовать
Update(dt float64)- Логика переключения состояний:
- Если
Playing:- Проверить
World.CheckGoal(). Если гол\rightarrowState = GoalPause, обновить счет,PauseTimer = PauseDuration. - Если не гол
\rightarrowвызватьWorld.Update(dt). - Обновить
CurrentTime += dt. ЕслиCurrentTime >= MatchDuration\rightarrowState = MatchEnded.
- Проверить
- Если
GoalPause:PauseTimer -= dt.- Если
PauseTimer <= 0\rightarrowвызватьWorld.ResetPositions(),State = Playing.
- Если
MatchEnded:- Ничего не делать.
- Если
- Логика переключения состояний:
-
Шаг 3: Коммит
git add internal/game/match_manager.go && git commit -m "feat(game): implement MatchManager for game rules"
Задача 3: Интеграция в Main Loop
Файлы:
-
Изменить:
cmd/game/main.go -
Шаг 1: Обновить структуру
Game- Заменить
world *game.WorldнаmatchManager *game.MatchManager.
- Заменить
-
Шаг 2: Обновить инициализацию в
NewGame()- Создать
world := game.NewWorld(). - Создать
matchManager := game.NewMatchManager(world).
- Создать
-
Шаг 3: Обновить
Update()иDraw()- В
Update()вызыватьg.matchManager.Update(dt). - В
Draw()передаватьg.matchManager.Worldв функцию отрисовки.
- В
-
Шаг 4: Коммит
git add cmd/game/main.go && git commit -m "feat(game): integrate MatchManager into main loop"
Задача 4: Тестирование и верификация
-
Шаг 1: Проверка сценария "Гол"
- Запустить игру, забить гол.
- Ожидание: Игра замирает, через несколько секунд все возвращаются в центр.
-
Шаг 2: Проверка сценария "Конец матча"
- Установить короткий
MatchDuration(например, 10 сек). - Ожидание: Через 10 секунд игра замирает навсегда.
- Установить короткий
-
Шаг 3: Коммит
git commit -m "test(game): verify match logic flow"