Skip to content

Crossover League começou como uma brincadeira: um jogo de futebol hipotético entre minha turma atual do ensino médio e a do fundamental. O “crossover” veio daí. O que era piada virou um jogo arcade de futebol no navegador, com física própria, IA agressiva demais e zero motivos racionais para existir — mas existe.

License

Notifications You must be signed in to change notification settings

pedronicolasg/crossoverleague

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

⚽ Crossover League

O Crossover League nasceu de um cenário hipotético meio duvidoso: um jogo de futebol entre minha turma atual do ensino médio e minha antiga turma do ensino fundamental. O “crossover” no nome veio daí. O problema é que eu tive um hiperfoco, a brincadeira escalou e agora isso é um jogo de futebol arcade rodando no navegador, com uma IA desnecessariamente agressiva, física própria e absolutamente nenhuma justificativa racional para existir — mas existe.


📋 Visão Geral

O projeto consiste em uma engine de jogo personalizada construída sobre HTML5 Canvas, gerenciada por um loop de jogo modular. A interface do usuário (HUDs, Menus, Placar) é reativa e controlada via Alpine.js, enquanto a estilização é feita com Tailwind CSS v4.

O jogo oferece partidas rápidas entre times fictícios ("Time A" vs "Time B"), com mecânicas de:

  • Movimentação WASD/Setas
  • Sprint (Shift) e Chute Carregado (Espaço)
  • Posse de bola e Física de colisão
  • IA com níveis de dificuldade (Hard/Insane)

🚀 Funcionalidades Principais

  • Gameplay Arcade: Física de bola, colisões jogador-jogador e jogador-bola, sistema de estamina e chutes com força variável.
  • Modos de Jogo:
    • Por Gols: Quem atingir o placar alvo primeiro vence.
    • Por Tempo: Partida com duração fixa.
  • Interface Reativa (HUD): Placar, tempo e estatísticas atualizados em tempo real via Alpine.js.
  • Configuração de Partida: Seleção de times, uniformes, posições táticas e dificuldade da IA.
  • Estatísticas Pós-Jogo: MVP da partida, posse de bola, histórico de gols e artilheiros.

🛠️ Stack Tecnológica

O projeto utiliza uma stack moderna e leve:

  • Core: JavaScript (ES Modules)
  • Renderização: HTML5 Canvas API
  • Gerenciamento de Estado/UI: Alpine.js
  • Estilização: Tailwind CSS v4
  • Build Tool: Vite
  • Gerenciador de Pacotes: Bun (compatível com npm)
  • Linting/Formatação: Biome

📂 Estrutura do Projeto

Abaixo uma visão resumida das principais pastas:

crossoverleague/
├── public/              # Arquivos estáticos servidos no final (HTML, Assets, JS buildado)
│   ├── index.html       # Entry point da aplicação
│   ├── app.css          # CSS gerado pelo Tailwind
│   └── main.js          # Bundle final do jogo (gerado pelo Vite)
├── src/                 # Código fonte
│   ├── core/            # Sistemas base (Input, UI Controller)
│   ├── game/            # Lógica do jogo
│   │   ├── modules/     # Módulos independentes (IA, Física, Render, Loop, etc.)
│   │   └── Game.js      # Singleton que orquestra os módulos
│   ├── main.js          # Ponto de entrada (Inicializa Alpine e Game)
│   └── app.css          # Fonte do CSS
├── package.json         # Dependências e Scripts
├── vite.config.js       # Configuração do Vite (Build IIFE)
└── biome.json           # Configuração de Linter

📦 Instalação e Execução

1. Clonar e Instalar Dependências

# Via Bun (recomendado)
bun install

# Via NPM
npm install

2. Desenvolvimento

O projeto utiliza o Tailwind v4 com watcher e o Vite para build.

Para desenvolvimento ativo (watch CSS):

bun run dev
# Ou: npm run dev
# Este comando roda: tailwindcss -i src/app.css -o public/app.css --watch

Para gerar o bundle JS (Vite):

bun run build
# Ou: npm run build
# Gera o arquivo src/main.js -> public/main.js

3. Times

Por padrão, o jogo não vem com times. Sim: é proposital. Sem clubismo e arquivos inúteis embutido no repo 😌 Pra conseguir jogar, você precisa criar pelo menos 2 times, seguindo a estrutura de pastas abaixo e registrando tudo no data.js.

1) Estrutura de pastas obrigatória

Crie seus times dentro de public/assets/teams/ (ou equivalente no seu setup), seguindo exatamente este padrão:

└── teams
    ├── infor
    │   ├── kitA
    │   │   ├── a1.jpg
    │   │   ├── a2.jpg
    │   │   ├── a3.jpg
    │   │   ├── a4.jpg
    │   │   └── gk.jpg
    │   ├── kitB
    │   │   ├── a1.jpg
    │   │   ├── a2.jpg
    │   │   ├── a3.jpg
    │   │   ├── a4.jpg
    │   │   └── gk.jpg
    │   └── logo.png
    ├── nine-z
    │   ├── kitA
    │   │   ├── b1.jpg
    │   │   ├── b2.jpg
    │   │   ├── b3.jpg
    │   │   ├── b4.jpg
    │   │   └── gk.jpg
    │   ├── kitB
    │   │   ├── b1.jpg
    │   │   ├── b2.jpg
    │   │   ├── b3.jpg
    │   │   ├── b4.jpg
    │   │   └── gk.jpg
    │   └── logo.png
    └── data.js

O que é o quê:

  • logo.png: logo do time (usado na UI).

  • kitA/ e kitB/: dois uniformes do time.

  • Dentro de cada kit:

    • a1.jpg, a2.jpg, a3.jpg, a4.jpg: texturas/skins dos jogadores de linha.
    • gk.jpg: textura/skin do goleiro.
  • Os nomes dos arquivos importam: eles precisam bater com os id do elenco que você declarar no data.js.

2) Indexação no data.js (sem isso o time “não existe”)

Depois de colocar os arquivos, você precisa registrar os times em data.js, populando window.GAME_TEAMS.

Exemplo (do jeito que está no teu data.js):

window.GAME_TEAMS = [
  {
    id: "infor",
    name: "INFOR-2",
    logo: "assets/teams/infor/logo.png",
    roster: [
      { id: "a1", name: "Guiga", pref: "ST" },
      { id: "a2", name: "Bruno H.", pref: "LB" },
      { id: "a3", name: "Zé Filho", pref: "RB" },
      { id: "a4", name: "Diogo", pref: "DM" },
      { id: "gk", name: "Chaves", pref: "GK" },
    ],
  },
  {
    id: "nine-z",
    name: "CMS Nine-Z",
    logo: "assets/teams/nine-z/logo.png",
    roster: [
      { id: "b1", name: "Hiury", pref: "ST" },
      { id: "b2", name: "Roberto", pref: "RB" },
      { id: "b3", name: "Gustavo", pref: "LB" },
      { id: "b4", name: "Matthews", pref: "DM" },
      { id: "gk", name: "Fábio", pref: "GK" },
    ],
  },
];

Regras importantes (pra não passar raiva):

  • id do time (ex: "infor", "nine-z") precisa ser igual ao nome da pasta do time.

  • logo precisa apontar pro caminho certo dentro de assets/teams/<id>/logo.png.

  • Cada item de roster precisa ter:

    • id: igual ao nome do arquivo do jogador (sem extensão). Ex: a1a1.jpg, gkgk.jpg.
    • name: nome exibido na UI/estatísticas.
    • pref: posição preferida (ex: ST, LB, RB, DM, GK).
  • Você precisa ter no mínimo 2 times no array pra conseguir iniciar partida.

4. Rodando o Jogo

Como o projeto é servido estaticamente a partir da pasta public/ (ou configurado via XAMPP/Apache na pasta htdocs):

Opção A (Vite Preview): Roda um servidor local servindo a pasta de distribuição.

bun run preview
# Acessar: http://localhost:4173 (ou porta indicada)

Opção B (Apache/XAMPP): Se estiver na pasta htdocs, certifique-se de acessar via: http://localhost/crossoverleague/public/

Nota: Se abrir o index.html diretamente no navegador (file://), pode haver bloqueios de CORS (Cross-Origin Resource Sharing) ao carregar módulos ou imagens. Recomenda-se usar um servidor local.


📄 Licença

Este projeto está licenciado sob a licença MIT.

About

Crossover League começou como uma brincadeira: um jogo de futebol hipotético entre minha turma atual do ensino médio e a do fundamental. O “crossover” veio daí. O que era piada virou um jogo arcade de futebol no navegador, com física própria, IA agressiva demais e zero motivos racionais para existir — mas existe.

Topics

Resources

License

Stars

Watchers

Forks