feat(jogo): expediente dos mortos, jogo de zumbis em primeira pessoa
Etapa 1 inteira (logica com 100% de cobertura, cena 3D, toque, sons, bancada de desempenho, e2e) e a base da etapa 2 (mapa novo no Tiled, texturas, imagens dos itens, sons conferidos, golpe recortado e medido). Pagina /jogo fora do menu e do sitemap ate a medicao no celular.
This commit is contained in:
1 parent
c7d09d63d4
commit
67b32fcab3
118 files changed
+16730
No files matched your search
@@ -0,0 +1,205 @@
|
||||
/** Números do jogo em um lugar só. São valores iniciais: mudam jogando, nunca espalhados pelo código. */
|
||||
|
||||
import GOLPE from "./golpe.json";
|
||||
import type { Dificuldade, TipoItem, TipoZumbi } from "./tipos";
|
||||
|
||||
/** Duração de um passo da lógica, em segundos. */
|
||||
export const PASSO = 1 / 60;
|
||||
export const PASSOS_POR_SEGUNDO = 60;
|
||||
|
||||
export const JOGADOR = {
|
||||
vida: 100,
|
||||
/** m/s */
|
||||
velocidade: 4.2,
|
||||
raio: 0.35,
|
||||
/** Altura dos olhos, de onde sai o tiro. */
|
||||
olhos: 1.6,
|
||||
/** Limite da inclinação, para cima e para baixo. */
|
||||
inclinacaoMax: 1.2,
|
||||
/** Vida devolvida quando uma horda cai. */
|
||||
curaPorHorda: 25,
|
||||
} as const;
|
||||
|
||||
export const ZUMBIS: Record<
|
||||
TipoZumbi,
|
||||
{
|
||||
vida: number;
|
||||
velocidade: number;
|
||||
dano: number;
|
||||
raio: number;
|
||||
altura: number;
|
||||
}
|
||||
> = {
|
||||
comum: { vida: 100, velocidade: 1.2, dano: 10, raio: 0.35, altura: 1.8 },
|
||||
rapido: { vida: 50, velocidade: 2.4, dano: 6, raio: 0.3, altura: 1.7 },
|
||||
blindado: { vida: 250, velocidade: 0.9, dano: 15, raio: 0.4, altura: 1.9 },
|
||||
chefao: { vida: 1500, velocidade: 1.0, dano: 25, raio: 0.6, altura: 2.4 },
|
||||
};
|
||||
|
||||
/** Passos de um golpe inteiro (preparo, impacto e volta): 0,8 s. */
|
||||
const PASSOS_DO_GOLPE = 48;
|
||||
|
||||
export const ATAQUE_DO_ZUMBI = {
|
||||
/** Distância entre as bordas do zumbi e do jogador para o ataque começar. */
|
||||
alcance: 1.0,
|
||||
/** Folga máxima, no passo do impacto, para o golpe acertar. Acima disso o golpe pega o ar. */
|
||||
alcanceDoGolpe: 1.4,
|
||||
/** Passos entre um golpe e o próximo. Etapa 2: passa a `PASSOS_DO_GOLPE`. */
|
||||
intervalo: 60,
|
||||
/**
|
||||
* Passo do ciclo em que a mão bate. Vem do clipe `atacar` medido no Blender
|
||||
* (`golpe.json`, gravado por `3d/jogo.py`): a tela toca o clipe no tempo do ciclo,
|
||||
* então o impacto do clipe e o da lógica caem no mesmo passo.
|
||||
*/
|
||||
passoDoGolpe: Math.round((GOLPE.impacto / GOLPE.duracao) * PASSOS_DO_GOLPE),
|
||||
/** Passos da animação de morte, até o zumbi sair da lista. */
|
||||
passosMorrendo: 90,
|
||||
} as const;
|
||||
|
||||
/** Acima desta fração da altura do zumbi o acerto é na cabeça e dobra o dano. */
|
||||
export const FRACAO_DA_CABECA = 0.86;
|
||||
export const MULTIPLICADOR_DA_CABECA = 2;
|
||||
|
||||
export const ARMAS = [
|
||||
{ nome: "Pistola", dano: 34, intervalo: 20, alcance: 40, gasta: false },
|
||||
{ nome: "Automática", dano: 20, intervalo: 6, alcance: 40, gasta: true },
|
||||
{ nome: "Faca", dano: 100, intervalo: 30, alcance: 1.5, gasta: false },
|
||||
] as const;
|
||||
|
||||
/** Meio ângulo do arco da faca, em radianos. */
|
||||
export const ARCO_DA_FACA = Math.PI / 4;
|
||||
|
||||
export const MUNICAO = {
|
||||
inicial: 90,
|
||||
porCaixa: 30,
|
||||
/** Chance de um zumbi morto largar uma caixa. */
|
||||
chanceDeCaixa: 0.25,
|
||||
/** Distância para o jogador recolher a caixa. */
|
||||
raioDeColeta: 0.9,
|
||||
} as const;
|
||||
|
||||
/** O que os zumbis largam ao morrer. */
|
||||
export const ITENS = {
|
||||
/** Chance de um zumbi morto largar um item. O chefão não larga. */
|
||||
chance: 0.3,
|
||||
/** Peso de cada tipo no sorteio. */
|
||||
pesos: { municao: 45, kit: 25, cafe: 15, bateria: 15 } as Record<
|
||||
TipoItem,
|
||||
number
|
||||
>,
|
||||
/** Abaixo desta vida o peso do kit dobra. */
|
||||
vidaBaixa: 40,
|
||||
/** Itens no chão ao mesmo tempo; com o teto cheio, o mais antigo some. */
|
||||
teto: 10,
|
||||
/** Passos até o item sumir (20 s). */
|
||||
duracao: 1200,
|
||||
/** Distância para o jogador recolher. */
|
||||
raioDeColeta: 0.9,
|
||||
/** Balas da automática por item de munição. */
|
||||
balas: 30,
|
||||
/** Vida devolvida pelo kit. */
|
||||
vida: 25,
|
||||
/** Café: fator da velocidade de andar e passos que dura (8 s). */
|
||||
cafe: { fator: 1.3, duracao: 480 },
|
||||
/** Bateria: fator da cadência dos drones e passos que dura (10 s). */
|
||||
bateria: { fator: 2, duracao: 600 },
|
||||
} as const;
|
||||
|
||||
export const DRONE = {
|
||||
dano: 25,
|
||||
intervalo: 30,
|
||||
alcance: 15,
|
||||
/** m/s */
|
||||
velocidade: 5,
|
||||
/** Distância que o drone mantém do jogador. */
|
||||
distancia: 2,
|
||||
} as const;
|
||||
|
||||
export const HORDAS = {
|
||||
/** Zumbis das três hordas, antes do multiplicador da dificuldade. */
|
||||
tamanhos: [12, 16, 20],
|
||||
/** Comuns que acompanham o chefão. */
|
||||
escoltaDoChefao: 6,
|
||||
/** Passos da pausa entre hordas. */
|
||||
pausa: 300,
|
||||
/** Passos da fase "inicio", antes da primeira horda. */
|
||||
preparo: 120,
|
||||
/** Passos entre dois nascimentos, por horda (a 4ª é a do chefão). */
|
||||
nascerACada: [90, 50, 30, 30],
|
||||
/** Fator da velocidade dos zumbis, por horda. */
|
||||
velocidade: [0.8, 1, 1.15, 1.15],
|
||||
} as const;
|
||||
|
||||
/** Quantas linhas o feed guarda. */
|
||||
export const LINHAS_DO_FEED = 5;
|
||||
|
||||
export const TETO_A_VISTA = 16;
|
||||
|
||||
export const DIFICULDADES: Record<
|
||||
Dificuldade,
|
||||
{ velocidade: number; dano: number; quantidade: number }
|
||||
> = {
|
||||
facil: { velocidade: 0.6, dano: 0.4, quantidade: 0.7 },
|
||||
normal: { velocidade: 1, dano: 1, quantidade: 1 },
|
||||
dificil: { velocidade: 1.3, dano: 1.5, quantidade: 1.3 },
|
||||
};
|
||||
|
||||
/**
|
||||
* O escritório, em células de 1 m. `#` parede, `M` mesa (não dá para andar, o tiro passa),
|
||||
* `J` onde o jogador começa, `N` onde os zumbis nascem, `.` chão.
|
||||
*/
|
||||
export const ESCRITORIO = [
|
||||
"############################",
|
||||
"#N.........#......#.......N#",
|
||||
"#..MM..MM..#......#..MM....#",
|
||||
"#..MM..MM.........#..MM....#",
|
||||
"#..........#...............#",
|
||||
"#..MM..MM..#......#..MM....#",
|
||||
"#..MM..MM..###..###........#",
|
||||
"#..........................#",
|
||||
"#............J.............#",
|
||||
"#..........................#",
|
||||
"#..MM..MM..###..###..MM....#",
|
||||
"#..MM..MM..#......#..MM....#",
|
||||
"#..........#......#........#",
|
||||
"#..MM..MM.........#..MM....#",
|
||||
"#..MM..MM..#...............#",
|
||||
"#N.........#......#.......N#",
|
||||
"############################",
|
||||
] as const;
|
||||
|
||||
/** Degraus de qualidade da tela, do melhor para o mais leve. Desce na ordem: resolução, sombras, zumbis à vista. */
|
||||
export const NIVEIS = [
|
||||
{ pixelRatio: 2, sombras: true, teto: 16 },
|
||||
{ pixelRatio: 1.5, sombras: true, teto: 16 },
|
||||
{ pixelRatio: 1, sombras: true, teto: 16 },
|
||||
{ pixelRatio: 1, sombras: false, teto: 16 },
|
||||
{ pixelRatio: 1, sombras: false, teto: 12 },
|
||||
{ pixelRatio: 1, sombras: false, teto: 8 },
|
||||
] as const;
|
||||
|
||||
/** Tempos em milissegundos. */
|
||||
export const REGULADOR = {
|
||||
/** Tamanho da janela em que o p95 do intervalo entre quadros e o do trabalho são medidos. */
|
||||
janela: 2000,
|
||||
/** p95 do intervalo acima disto na janela: desce um degrau. */
|
||||
limite: 20,
|
||||
/** Janela sem descida e com p95 do trabalho de JS abaixo disto conta como folga. */
|
||||
folgaDeTrabalho: 6,
|
||||
/** Tempo seguido de folga para subir um degrau. */
|
||||
subida: 10000,
|
||||
/** Quadro mais longo que isto é pausa da aba, não lentidão: não entra na conta. */
|
||||
ignorar: 250,
|
||||
/** Se descer de novo antes disto depois de subir, não sobe mais. */
|
||||
trava: 20000,
|
||||
/** Fração mínima em que o p95 do intervalo cai na janela seguinte a uma descida para ela contar como ganho. */
|
||||
ganho: 0.1,
|
||||
/** Descidas seguidas sem ganho que fazem o regulador voltar esses degraus e travar. */
|
||||
descidasSemGanho: 2,
|
||||
} as const;
|
||||
|
||||
/**
|
||||
* Raio máximo usado para andar e desviar de parede. O chefão é mais largo que meia célula (0,6 m): com o raio inteiro
|
||||
* ele nasce encostado na parede e não sai do lugar. Para levar tiro, vale o raio do tipo.
|
||||
*/
|
||||
export const RAIO_DE_PASSAGEM = 0.45;
|
||||
Reference in new issue
Block a user