DevLog 2022.10.27 do Game Space Punkers: Galactic Wars

Estação Espacial gerada randômicamente

DevLog 2022.10.27

Alguns dos meus projetos entraram em um pequeno iato esse ano. Um desses projetos é o game 2d cuja versão demo batizei de Space Punkers; um space shooter 2D bem clássico. Essa versão demo está disponível na loja da Microsoft e pode ser jogado no Xbox e no PC.

Resolvi dar continuidade a esse projeto, agora criando uma versão comercial desse game.

A primeira coisa que me veio à cabeça é que um jogo precisa passar uma noção de evolução para o Player. Uma forma clássica de fazer isso é gravar a quantidade de Naves Inimigas que foram abatidas e desafiar o Player a bater seu próprio record. Aliás, a versão demo já possui esse mecanismo quase pronto. Eu digo "quase" porque o jogo ainda não salva essa informação para ser usada em uma nova sessão e nem permite vincular um nome ao record em questão. Mas isso é algo fácil de implementar e com certeza estará na versão comercial do jogo.

Mas ainda assim eu queria criar uma mecânica mais complexa do que essa. Aliás, eu adoro complicar as coisas. Eu diria até que tenho um talento nato para isso; talento esse que constantemente preciso controlar.

Então pensei um pouco e tive uma ideia: implementar um sistema de Fases Procedurais. Cada fase possui um numero de desafios e, após completada a Fase, uma nova é gerada com desafios cada vez mais difíceis.

Como se trata de um Space Shooter, a ideia de fase que veio na minha cabeça é a seguinte:

O jogo irá gerar um determinado numero de "lugares" espalhados pela "galáxia" em que o Player se encontra. Para marcar estes lugares os pontos de referências serão estrelas (e às vezes buracos negros) que ficarão navegando pelo espaço em círculos. Em torno dessas estrelas haverão planetas e também as Estações Espaciais inimigas. O Player deverá destruir as Estações Espaciais, que além de combater o Player com seus canhões, irão dropar frotas de naves inimigas para atacar o Player e até mesmo caçá-lo.

Neste cenário, cada Galáxia que o Player livrar das Estações Espaciais inimigas será uma "fase" concluída. Daí o subtítulo provisório "Galactic Wars" ou Guerras Galacticas.

Pretendo ainda enriquecer essa dinâmica adicionando outros desafios mais estratégicos, como áreas bloqueadas que o player só conseguirá acessar em uma fase após conseguir itens especiais, que poderão ser adquiridos ao se destruir Estações Espaciais específicas ou realizando outros desafios. Missões que envolvam mais do que destruir as Estações Espaciais inimigas; como levar carregamento de uma área X para uma área Y.

Ainda há muito o que ser feito, certamente. Por enquanto implementei os seguintes recursos:

> Estações Espaciais;
> Sistema de Vida;
> Radar para detectar a aproximação do Player;
> Capacidade de Gerar Frotas Inimigas para proteger as Estações Espaciais dos ataques do Player (este tipo de inimigo é chamado de Guardian e nunca deixa os limites da Estação Espacial) e às vezes frotas de caçadores que buscam o Player por toda a Fase (não se importando em se afastar da Estação Espacial que o gerou);
> Gerador de Fases;
> Gera Estrelas e/ou Buracos Negros;
> Cada Estrela possui um Gerador de Planetas;
> Cada Planeta possui um gerador de "Luas" (satélites naturais);
> Um sistema gravitacional que prende o Player em sua órbita e, caso este se aproxime do Horizonte de Eventos, ele é arrastado até o corpo celeste (estrela, buraco negro, planeta e/ou satélite natural);
> Um Bussola que indica a localização das Estações Espaciais que o Player precisará enfrentar para "Zerar" uma fase.

Além dessas novas criações eu resolvi alguns problemas antigos na codificação original; como a criação de polígonos inválidos na codificação que gera a aparência randômica das naves. Eu já havia tentado anteriormente, mas não tinha encontrado qual função a Godot disponibiliza para validar se um polígono é válido ou não. Mas finalmente descobri qual função usar. Trata-se da Geometry.triangulate_polygon( ARRAY ).empty() onde ARRAY é a matriz que armazena as coordenadas do polígono a ser testado. Caso essa função retorne "verdadeiro", então o array não é válido (sendo uma forma geométrica inválida ou vazia).

Eu encontrei a dica sobre essa função no link:


Com essa função eu valido se as formas geometricas de cada parte/camada da Nave são válidas e, caso não sejam, gero uma nova até obter um polígono válido.

Desde que retomei o projeto tenho usado a versão 3.5 da Godot Engine (eu sempre tenho o hábito de usar as versões mais recentes da engine, ainda que isso signifique ter que mudar alguma coisa no código ou ter que enfrentar algum eventual novo bug). Felizmente não tive muita dor de cabeça com essa versão da engine; na verdade o único problema que enfrentei foi com alguma váriaveis numéricas retornando o valor "nan". Pesquisei um pouco sobre o assunto e não consegui descobrir o que ocasiona esse erro.

No meu código eu percebi que esse erro ocorre, fazendo as variáveis retornarem esses valores estranhos, quando os obejtos presentes na cena principal possuem diferenças de escala muito grandes. Mas, no geral, o porque disso continua sendo um mistério para mim. Abaixo deixo um link que encontrei falando sobre esse problema do Nan:


Mas, neste artigo, a situação que provocou o retorno Nan é outra. Eu até suspeitei que quando os objetos na minha cena principal possuem tamanhos (escalas) muito discrepantes, os calculos de distância que eu efetuo retornam numeros muito grandes e em um dado momento isso extrapola a limitação das variáveis numéricas. Mas para testar essa tese eu criei um código simples para realizar uns calculos que retornam numeros muito grandes (absurdos até) e o erro não foi provocado. Então percebi que a minha pista estava equivocada (quanto ao problema ser provocado pela limitação de memoria das variaveis) e deixei de investigar (ao menos por hora) essa situação.

Bom, vou ficando por aqui. Retorno quando for possível trazer novidades sobre o Space Punkers e/ou quando conseguir gravar um vídeo de teste dessa nova versão do jogo.

Comentários

Populares