Skip to content

Repository files navigation

Coletor de Cristais 3D

Jogo 3D interativo feito do zero em Python, com toda a renderização 3D implementada à mão — matrizes próprias de transformação, projeção em perspectiva, câmera e rasterização — usando apenas Pygame + NumPy, sem nenhuma biblioteca de 3D (OpenGL, Panda3D, etc.).

Você controla um cubo que percorre uma arena coletando cristais, desviando de obstáculos e fugindo de inimigos com inteligência artificial de busca de caminho (A*). Começou como trabalho da disciplina de Computação Gráfica (UTFPR, Prof. Dr. Marlon Marcon) e virou um projeto pessoal de motor gráfico.

Destaques técnicos

  • Pipeline 3D próprio: mundo → visão → projeção em perspectiva → divisão por w → viewport, tudo em matrizes 4x4 escritas à mão (engine/math3d.py).
  • Câmera: terceira pessoa que segue o agente, com órbita livre por arraste do mouse e retorno suave à posição padrão.
  • Iluminação: sombreamento difuso de Lambert com luz direcional.
  • Algoritmo do pintor com renderização em camadas (céu → chão → sólidos) e ordenação por objeto para evitar z-fighting.
  • Colisão:
    • esfera × esfera (coleta de cristais, dano de inimigos);
    • OBB × AABB via SAT (teorema dos eixos separadores) para o player girado contra obstáculos, com vetor de translação mínima.
  • IA dos inimigos: busca de caminho A* sobre grade de navegação (8 direções, sem corte de quina), com interceptação (miram onde o jogador vai estar) e campo de custo que os atrai levemente para rotas com cristais. Recálculo controlado para manter performance.
  • Geração procedural das fases: obstáculos e cristais posicionados por amostragem com rejeição (sem sobreposição, distância mínima entre cristais).
  • Áudio: música por fase e efeitos (coleta, dano, colisão), com controle de volume e pause.

Como executar

python -m venv .venv
source .venv/bin/activate        # Windows: .venv\Scripts\activate
pip install -r requirements.txt
python main.py

Áudio é opcional. Para instalar a playlist padrão com dez faixas eletrônicas CC0 somente na sua máquina, execute python -m scripts.baixar_musicas_livres. A opção recomendada é personalizar assets/musics/ com arquivos .mp3, .ogg ou .wav que você tenha direito de usar. Sem músicas, o jogo continua funcionando normalmente.

Controles

Tecla / Mouse Ação
W / S Avançar / recuar
A / D Girar à esquerda / direita
Arrastar mouse Orbitar a câmera
- / = Volume da música
[ / ] Volume dos efeitos
P Pausar / continuar
ENTER Iniciar / reiniciar
ESC Sair

Objetivo: colete todos os cristais de cada fase antes do tempo acabar, fugindo dos inimigos (encostar custa uma vida). As fases são infinitas e seguem uma curva de dificuldade progressiva; cair para fora do mapa também encerra o jogo.

Arquitetura

.
├── main.py                 # composição da aplicação e ciclo de vida do Pygame
├── config.py               # constantes e curva tipada de dificuldade
├── engine/                 # motor gráfico independente das regras do jogo
│   ├── math3d.py           # matrizes, perspectiva e look_at
│   ├── mesh.py             # primitivas e dados geométricos
│   ├── camera.py           # câmera em terceira pessoa
│   └── renderer.py         # projeção, recorte, Lambert e rasterização
├── game/
│   ├── entities.py         # Player, Cristal, Obstaculo e Inimigo
│   ├── collision.py        # esfera, AABB e OBB/SAT
│   ├── level.py            # geração procedural isolada
│   ├── pathfinding.py      # grade de navegação, A* e campo de custo
│   ├── state.py            # máquina de estados e transições válidas
│   ├── input.py            # eventos traduzidos em ações do jogo
│   ├── update.py           # regras de atualização da partida
│   ├── audio.py            # música, efeitos e pulso rítmico
│   ├── hud.py              # HUD, menu e overlays
│   ├── recorde.py          # persistência local do recorde
│   ├── telemetria.py       # coleta opcional de métricas
│   └── world.py            # composição, renderização e game loop
├── scripts/                # análises opcionais de áudio e dificuldade
└── tests/                  # testes da lógica pura

Jogo compõe os subsistemas, enquanto entrada, atualização e transições de estado têm componentes próprios. As dependências podem ser injetadas, mantendo o game loop desacoplado de áudio, telemetria, persistência, geração de fases e Pygame durante os testes.

Conceitos de Computação Gráfica (RT-01 a RT-06)

Req. Onde está
RT-01 engine/mesh.py (primitivas: pontos, linhas, polígonos), cores RGB
RT-02 engine/math3d.py + game/entities.py (matriz de modelo composta)
RT-03 engine/math3d.perspectiva + divisão por w em engine/renderer.py
RT-04 engine/camera.py + engine/math3d.look_at
RT-05 game/world.Jogo.rodar (entrada → atualização → renderização)
RT-06 game/collision.py (esferas, AABB e OBB/SAT)

Qualidade e testes

O projeto usa configuração centralizada em pyproject.toml, uma suíte baseada na biblioteca padrão unittest e um piso inicial de 70% de cobertura para engine/ e game/.

# ferramentas de desenvolvimento
python -m pip install -e ".[dev]"

# testes com o mesmo critério de cobertura usado pelo CI
coverage run -m unittest discover -v
coverage report

# análise estática e formatação
ruff check .
ruff format --check .

O workflow do GitHub Actions executa esses controles em Python 3.9 e 3.12. Como este é um projeto mantido individualmente, o pull request serve também como histórico de auto-revisão: a integração só deve ocorrer depois dos testes locais e do CI aprovados.

Os utilitários não executam código durante importação:

python -m scripts.analisar_dificuldade
python -m scripts.analisar_musicas

librosa faz parte da instalação padrão porque a análise de intensidade e a sincronização visual com as batidas são recursos centrais do jogo.

Stack

Python · Pygame · NumPy

Licença

Este projeto é disponibilizado sob a licença MIT.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages