Skip to content

Repository files navigation

Cafe Racer

Браузерная настольная гонка для 2–12 игроков. Игроки бросают кубики и перемещают фишки по круговому треку из 36 клеток. Сочетание удачи (броски кубиков) и стратегии (решение когда ехать, а когда бросить ещё раз).

Demo | Phaser


Стек технологий

Компонент Технология
Игровой движок Phaser 3
Язык TypeScript 5
Сборщик (клиент) Vite 6
Сервер Node.js + Express 4
Шаблонизатор Pug 3
Тесты Vitest
Линтинг ESLint 9 + Prettier
Контейнеризация Docker

Архитектура

Клиент — 5 сцен Phaser 3

Boot → Game → Menu → Rules → About
  1. BootScene — инициализация, загрузка лого
  2. GameScene — основной игровой цикл: поле из 36 клеток, 3 кубика с анимацией, фишки игроков, UI статистики (тоннаж/перегревы, текущий игрок, круг), кнопки Roll/Race, анимация медалей
  3. MenuScene — управление игроками: добавление/удаление (2–12), настройка AI, просмотр статистики и медалей, настройки игры
  4. RulesScene — 11-слайдовый туториал с правилами игры
  5. AboutScene — информация об авторе

Сервер

Минимальный Express-сервер, отдаёт статику (собранный Vite-бандл, изображения, звуки) и рендерит HTML через Pug.

Структура проекта

caferacer/
├── src/
│   ├── client/
│   │   ├── index.ts                    # Точка входа, конфиг Phaser
│   │   ├── index.html                  # HTML для Vite dev server
│   │   ├── core/
│   │   │   └── GameState.ts            # Централизованное управление состоянием
│   │   ├── entities/
│   │   │   ├── Player.ts               # Класс игрока со статистикой
│   │   │   ├── Dice.ts                 # Логика бросков кубиков
│   │   │   └── Board.ts                # Расчёт позиций на поле
│   │   ├── ai/
│   │   │   └── AIPlayer.ts             # AI-логика принятия решений
│   │   ├── config/
│   │   │   ├── gameConfig.ts           # Константы игры (поле, кубики, UI)
│   │   │   └── assetManifest.ts        # Реестр всех ассетов
│   │   ├── scenes/
│   │   │   ├── BootScene.ts            # Инициализация
│   │   │   ├── GameScene.ts            # Основная игровая сцена
│   │   │   ├── MenuScene.ts            # Управление игроками и настройками
│   │   │   ├── RulesScene.ts           # Слайды с правилами
│   │   │   └── AboutScene.ts           # Информация об авторе
│   │   ├── systems/
│   │   │   ├── AudioManager.ts         # Управление звуковыми эффектами
│   │   │   └── SaveManager.ts          # Сохранение/загрузка игры
│   │   ├── types/
│   │   │   └── index.ts                # TypeScript интерфейсы
│   │   ├── utils/
│   │   │   └── helpers.ts              # Утилиты (shuffle и др.)
│   │   └── __tests__/                  # Unit-тесты
│   │       ├── AIPlayer.test.ts        # Тесты AI-логики
│   │       ├── Board.test.ts           # Тесты расчёта позиций
│   │       ├── Dice.test.ts            # Тесты бросков кубиков
│   │       ├── GameState.test.ts       # Тесты управления состоянием
│   │       ├── Player.test.ts          # Тесты механик игрока
│   │       └── helpers.test.ts         # Тесты утилит
│   └── server/
│       ├── app.ts                      # Конфигурация Express
│       ├── bin/
│       │   └── www.ts                  # Точка входа сервера (порт 4001)
│       └── routes/
│           └── index.ts                # Маршрут /
├── public/
│   ├── images/                         # 57 PNG (28 UI, 12 фишек, 11 слайдов, 5 спрайтшитов, медали)
│   ├── sounds/                         # 6 MP3-файлов
│   └── stylesheets/
│       └── style.css                   # Стили
├── views/
│   ├── layout.pug                      # Базовый шаблон
│   ├── index.pug                       # Главная страница
│   └── error.pug                       # Страница 404
├── package.json
├── tsconfig.json                       # TypeScript (общий)
├── tsconfig.server.json                # TypeScript (сервер)
├── vite.config.ts                      # Конфигурация Vite
├── vitest.config.ts                    # Конфигурация тестов
├── eslint.config.js                    # ESLint 9 flat config
├── .prettierrc                         # Prettier
├── Dockerfile                          # Multi-stage Docker build
└── docker-compose.yml                  # Docker Compose

Запуск

Требования

  • Node.js >= 18
  • npm

Установка

npm install

Разработка

npm run dev

Запускает параллельно:

  • Vite dev server — горячая перезагрузка клиента
  • Nodemon — автоперезапуск сервера при изменениях

Продакшн-сборка

npm run build
npm start

Приложение будет доступно на http://localhost:4001

Docker

docker compose up --build

Приложение будет доступно на http://localhost:4001


Скрипты

Команда Описание
npm run dev Запуск в режиме разработки (Vite + Nodemon)
npm run build Сборка сервера и клиента
npm start Запуск продакшн-сервера
npm test Запуск тестов (Vitest)
npm run type-check Проверка типов TypeScript
npm run lint Проверка ESLint
npm run format Форматирование Prettier

Тесты

42 unit-теста в 6 файлах:

  • AIPlayer (8 тестов) — стратегии принятия решений: финиш на последнем круге, бампинг соперников, реакция на перегревы
  • Board (10 тестов) — расчёт позиций для всех 36 клеток, смещения при движении
  • Dice (4 теста) — случайный выбор граней, валидация результатов
  • GameState (11 тестов) — управление игроками, переходы состояний, настройки игры
  • Player (4 теста) — отслеживание статистики, сброс данных
  • helpers (5 тестов) — утилитарные функции (shuffle и др.)
npm test

Игровая механика

Кубики

  • 3 кубика за ход, каждый с кастомными гранями
  • Кубик 1: [1, 0, 1, 1, 1, 0] — больше шансов на движение
  • Кубики 2 и 3: [1, 0, 1, 0, 1, 0] — 50/50
  • 1 = движение, 0 = перегрев

Ход игрока

  1. Бросок кубиков (с анимацией)
  2. Решение: Roll (бросить ещё раз для накопления тоннажа) или Race (переместить фишку, завершить ход)
  3. При повторном броске — накопление тоннажа и перегревов
  4. 5+ перегревов = штраф, ход заканчивается
  5. Фишка перемещается по круговому полю из 36 клеток
  6. Столкновение: попадание на клетку соперника отправляет его в «кафе» (старт)

Условия победы

  • Необходимо пройти заданное количество кругов (1–12)
  • Первый финишировавший побеждает, остальные ранжируются по порядку финиша

Режим Hardcore

  • Включение/выключение бампинга (столкновений) соперников
  • Добавляет тактическую глубину

AI-система (AIController)

AI использует приоритетное дерево решений:

  1. Финиш — если последний круг и хватает тоннажа до финиша → Race
  2. Бампинг — в режиме Hardcore, если можно сбить соперника → Race (пропускает игроков у старта при 5+ участниках)
  3. Защита от перегрева — если 3+ перегрева и есть тоннаж → Race
  4. По умолчанию — Roll (безопасный вариант)

Система медалей

  • 1-е / 2-е / 3-е место — финишные позиции
  • Top Speed — максимальный тоннаж за один ход
  • Breaking Player — наибольшее количество перегревов
  • Horrible Player — наихудшая удача / больше всех попаданий в кафе
  • Loser — наибольшее количество возвратов на старт

Управление

  • Клавиатура: M (меню), S (звук), H (hardcore), стрелки (навигация)
  • Сенсорные кнопки для мобильных устройств
  • Отображение статистики в реальном времени

Модель данных

interface PlayerData {
  stopz: number;          // Перегревы за ход
  goz: number;            // Тоннаж (очки движения)
  posonboard: number;     // Позиция на поле (0–36)
  lap: number;            // Текущий круг
  namesprite: string;     // Ключ спрайта фишки
  robot: boolean;         // Управляется AI
  nameplayer: string;     // Имя игрока
  sprite: Phaser.GameObjects.Sprite | null;
  posInGame: number;      // Позиция в рейтинге
  maxTon: number;         // Макс. тоннаж за ход
  sumLoser: number;       // Количество отправок в кафе
  sumStopz: number;       // Суммарные перегревы
  sumBreak: number;       // Суммарные торможения
  sumStep: number;        // Шаги за игру
  sumAllStep: number;     // Шаги за всё время
  medalsPos1: number;     // Финиши на 1-м месте
  medalsPos2: number;     // Финиши на 2-м месте
  medalsPos3: number;     // Финиши на 3-м месте
  medalsfastPlayer: number;      // Медали Top Speed
  medalsbreakingPlayer: number;  // Медали Breaking
  medalshorriblePlayer: number;  // Медали Horrible
  medalsloserPlayer: number;     // Медали Loser
}

Автор

Jirufik — jirufik@gmail.com

About

game on the PhaserJS

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages