Jogo de wingsuit e BASE jump feito só com HTML, CSS e JavaScript (Three.js). Você salta do cume de uma montanha, voa colado no relevo passando pelos portões, abre o paraquedas e tenta pousar no alvo — e a cada salto o mundo é outro: montanhas, cristas, lagos, neve, florestas, pássaros, portões e o local de pouso são gerados na hora.
Inspirado no vídeo “My Most Breathtaking Wingsuit Flight Ever – Monte Emilius”, do RitschWingsuit.
- Cada visita começa num mundo aleatório, com nome próprio (por exemplo "Aiguille d'Aurolara · 3508 m").
O botão Novo mundo (tecla
N) gera outro no menu e na tela de resultado; Voar de novo (R) repete o mesmo. - O cume, a crista que desce dele, os vales e o traçado mudam de mundo para mundo. Na maioria dos mundos o traçado cruza a crista por uma fenda entre duas torres.
- Portões aleatórios: portões normais, a fenda (vale mais), o portão sobre a saída de um lago e anéis de ouro, menores.
- Três tipos de pouso: um campo no vale principal, uma plataforma flutuando num lago (cair na água ao lado dela ainda conta como pouso, um "Splash!") ou uma encosta alta da montanha, com um refúgio.
- Estação do ano, linha de neve e de árvores, cor da rocha, posição do sol, vento, névoa e nuvens variam por mundo.
- Bandos de gralhas-alpinas na frente da saída e ao longo da linha, que se espalham gritando quando você passa perto, e águias girando nas térmicas.
- Anéis de velocidade roxos no meio dos trechos mais longos entre portões: passar por um dá um empurrão para a frente (e 100 pontos).
- Para repetir ou compartilhar um mundo, use o link com a semente (
?seed=12345); o menu tem um botão Copiar link deste mundo.
- Jetpack na wingsuit (
E/Shift, combustível infinito): empurra para a frente; com o nariz levantado dá até para subir. Pode ser desligado em Ajustes. - Corrida contra a IA: um rival de roupa vermelha salta logo depois de você (1,5 s) e voa a mesma linha, sem jetpack e um pouco mais devagar: um voo limpo, ou umas rajadas de jetpack, ganha dele. Quem cruzar o último portão primeiro vence (empate no décimo de segundo conta como vitória sua); se você vencer e pousar bem, ganha 1000 pontos. O HUD mostra a diferença em metros, e uma etiqueta no céu mostra onde ele está. Também pode ser desligada em Ajustes.
- Cutaway (
XouQsob o paraquedas): você solta o paraquedas, que sai voando sozinho, e volta a voar de wingsuit. Depois é só abrir o reserva comEspaço(dá para repetir quantas vezes quiser). Cada cutaway vale 500 pontos se você pousar bem.
Ou abra docs/index.html num servidor web (veja abaixo) ou publique no seu próprio GitHub Pages.
Funciona em Chrome, Edge, Firefox e Safari recentes (precisa de WebGL 2). No celular também dá para jogar, com controles de toque.
- Suba este repositório para o GitHub.
- Vá em Settings → Pages.
- Em Build and deployment, escolha Deploy from a branch, branch
maine pasta/docs. - Depois de um ou dois minutos, o jogo fica disponível em
https://SEU-USUARIO.github.io/NOME-DO-REPO/.
O docs/index.html já vem pronto e carrega o Three.js pela CDN do jsDelivr. Não precisa instalar nada para publicar.
| Wingsuit | |
|---|---|
W / ↑ |
Mergulhar: nariz para baixo, ganha velocidade |
S / ↓ |
Planar e fazer flare: troca velocidade por altura |
A / D |
Inclinar e curvar |
Espaço |
Saltar · abrir o paraquedas |
E / Shift |
Jetpack (combustível infinito) |
| Paraquedas | |
|---|---|
A / D |
Freio esquerdo / direito para curvar |
S ou Espaço |
Flare com os dois freios, a 3–5 m do chão |
W |
Tirantes dianteiros: desce mais rápido |
E / Shift |
Motor (paramotor): voa mais rápido e segura a altura, com 30 s de combustível |
X / Q |
Cutaway: soltar o paraquedas e voltar a voar de wingsuit |
Gamepad: analógico esquerdo pilota, A é a ação, B troca a câmera, os gatilhos são os freios, RB (ou X) liga o jetpack e o motor e LB faz o cutaway. Celular: arraste do lado esquerdo para pilotar, use o botão laranja para a ação, segure JATO na wingsuit e MOTOR sob o paraquedas, e toque em SOLTAR para o cutaway.
- Voe perto do relevo para somar pontos de proximidade. Ficar perto por alguns segundos sobe o multiplicador.
- Passe pelos portões: 250 pontos cada, 500 no portão do lago e nos anéis de ouro, 750 na fenda entre as torres. Os anéis de velocidade valem 100.
- Vença a corrida contra o rival (+1000) e faça cutaways (+500 cada), se pousar bem no fim.
- Abra o paraquedas na faixa laranja do altímetro (a altura é medida acima do pouso). O bipe avisa a hora.
- Pouse no alvo. Sob o paraquedas, o marcador laranja na tela aponta o alvo, e o anel amarelo no chão (ou na água) mostra onde você vai tocar se seguir reto. O anel fica verde quando está em cima do alvo. A fumaça laranja mostra a direção do vento.
- Se não for alcançar o alvo, segure o motor: o marcador avisa quando for preciso, e a barra de baixo mostra o combustível.
- A assistência de voo (em Ajustes, ligada por padrão) levanta o nariz antes de uma batida e transforma toques rasantes em "raspadas" que custam pontos em vez de acabar o voo.
- Mundo procedural (
src/terrain-core.js): a partir da semente, decide o cume, a crista principal, o traçado com os portões (e a fenda, quando há), os vales, os lagos, o rio e o tipo de pouso; depois esculpe o relevo com ruído com derivadas, fBm erodido, cristas multifractais e vales escavados, e aplica os detalhes da face de saída, dos lagos e do pouso. A mesma função roda no Node, nos Web Workers e no jogo. - Geração em Web Workers (
src/10-worldgen.js): dois campos de altura aninhados (4 m no desktop e 8 m no celular perto do corredor de voo, 40 m no resto), com normais, sombra do sol, oclusão ambiente, mapas de vegetação e posição de árvores pré-calculados. Tudo o que pertence ao mundo fica emR.worlde é descartado antes de gerar o próximo. - Terreno na GPU (
src/30-scene.js,src/20-shaders.js): chunks instanciados com 5 níveis de detalhe, geomorphing, saias contra frestas, textura de altura em float, sombreamento triplanar com bump por derivadas, névoa de altura, sombras analíticas do piloto e do velame e depth buffer logarítmico. - Física (
src/50-flight.js): passo fixo de 120 Hz, aerodinâmica da wingsuit com tabelas de sustentação e arrasto por ângulo de ataque e inclinação, sequência de abertura do paraquedas com choque de abertura, modelo de velame com freios, flare, vento e motor, e detecção de proximidade em 12 direções. - Pássaros (
src/30-scene.js): gralhas e águias instanciadas, com o bater das asas no vertex shader. - Câmeras (
src/60-camera.js), áudio sintetizado com WebAudio (src/70-audio.js), teclado, toque e gamepad (src/80-input.js). - Rival (
src/85-rival.js): o piloto da IA roda a mesma física e o mesmo piloto automático do jogador, com o próprio estado trocado a cada passo; também cuida da classificação da corrida e do paraquedas solto no cutaway. - Jogo (
src/90-game.js): pontuação, portões, replay gravado, HUD, minimapa, marcador do alvo, resolução adaptativa e ajustes salvos nolocalStorage.
src/ código-fonte (arquivos numerados na ordem em que são concatenados)
index.html HTML e CSS da interface; o build injeta o JavaScript em <!--SCRIPT-->
build.js junta tudo em um único HTML
docs/ versão pronta para o GitHub Pages (gerada pelo build)
tests/ testes visuais com Playwright (capturas de tela e simulação)
tools/ prévia do relevo em PNG, direto no Node
Requisitos: Node 18+ e Python 3 (só para o servidor local e os testes).
npm install # baixa o Three.js para o build local
npm run build # gera docs/index.html (GitHub Pages) e dist/emilius.html
npm run serve # build local com Three.js offline + servidor em http://localhost:8765/local.htmlDepois de editar qualquer arquivo em src/, rode npm run build de novo para atualizar o docs/index.html.
Os scripts em tests/ abrem o jogo num Chromium headless, pilotam com o piloto automático e salvam capturas de tela.
Eles esperam o servidor local rodando (npm run serve) em outro terminal.
pip install playwright pillow
python -m playwright install chromium
python tests/test_canopy.py saida/ # abertura do paraquedas, câmeras, pouso e replay
python tests/test_target.py saida/ # visibilidade do alvo sob o paraquedas
python tests/test_fixed.py # voa com comandos fixos e confere se não bate
python tests/test_worlds.py 1 12 # gera 12 mundos no jogo e voa cada um com o piloto automáticoPara conferir muitos mundos direto na função do relevo (traçado livre, portões acima do chão, lagos que seguram a água):
node tools/validate-worlds.js 300 # valida os mundos 1 a 300Para ver o relevo de um mundo de cima sem abrir o navegador:
node tools/terrain-preview.js 18 # mundo 18: gera preview.png com o traçado, os portões, os lagos e o alvoNo console do navegador, window.__emilius expõe o estado do jogo para depuração (por exemplo, __emilius.AUTO.on = true liga o piloto automático e __emilius.newWorld(42) gera o mundo 42).
Os testes abrem sempre o mesmo mundo (local.html?seed=18), para as capturas serem comparáveis.
- Voo original: RitschWingsuit — Monte Emilius.
- Three.js (licença MIT), carregado pela CDN do jsDelivr.
- Fontes: Big Shoulders Display, Barlow Semi Condensed e Chivo Mono, do Google Fonts.

