domingo, 22 de fevereiro de 2015

Hardcore Devel #5

E estamos aqui com mais um episódio de Hardcore Devel!

Hoje vamos falar um pouco das dificuldades encontradas no projeto MinArena. Essa semana ele ganhou um pouco a mais de funcionalidades e de correções, mas ainda há muito trabalho a ser feito. Então vamos caminhar um pouco sobre o que foi realizado essa semana.

Os golpes dos personagens no jogo devem acertar seus antagonistas uma única vez. Dependendo de como você programa as suas rotinas de colisão, isso pode não acontecer. Veja bem, quando ocorre colisão, as coisas não estão bem definidas. Rotinas de colisão simplesmente verificam se uma coisa está dentro da outra, ou se ele em algum momento vai entrar em cima da outra, dependendo da abordagem que você toma.

Veja bem, tratar colisão é uma das coisas mais complicadas quando e fala em jogos é justamente tratamento de colisão, especialmente quando os objetos tendem a interagir diferentemente entre si de acordo com a sua superfície ou até mesmo sua natureza. Por exemplo, um raio elétrico tem uma natureza de colisão diferente de uma rocha.

Até aí tudo bem, mas quando você coloca tudo junto você começa a ver o que acontece e começa a ver a quantidade de coisas que você vai ter que fazer pra coisa funcionar. Peguemos a questão da colisão com raios. Vamos imaginar um raio passando passando na frente e um raio passando por trás de nosso personagem.

Agora vamos supor que nosso personagem é burro e ande pra frente. esse é o turno na qual os raios vão passar e no próximo turno os raios deverão sumir. Então supostamente ele vai chegar pra frente, e vai levar uma raiozada. A pergunta é: Ele deveria levar também a raiozada que passa por trás dele ou não?

Obviamente estamos supondo aqui que ao levar a raiozada ele vai ser jogado pra trás, mas a resposta é que depende do que você, programador quer. O que nos leva a duas formas de verificação de colisão e duas formas de tratamento de colisão. Vamos falar primeiro sobre verificação.

Verificação é basicamente um exercício de geometria. Estamos falando ainda de planos. A coisa pode ser estendida para volumes mas a complexidade aumenta espantosamente. Então iremos nos ater aos planos. A resposta para a pergunta de como verificamos a colisão é a presença de pontos de uma superficie no plano presentes também em outra superfície. Como superfícies podem ser interpretadas como conjunto de pontos, a idéia é que. Se A é uma superfície e B é outra superfície, a colisão acontece se a interseção entre o conjunto de pontos das superfícies não é vazia.

Legal, mas as superfícies tem conjuntos infinitos de pontos, e aí, como é que resolve isso?

Com geometria! Bom, na verdade o desafio em si ja é definir a superfície e você já precisa da geometria para fazer isso. E você vai usá-la para definir quando há interseção entre as superfícies ou não. O que você precisa basicamente é do contorno da superfície, Definir o contorno é o suficiente para definir quem ta dentro e quem ta fora. Uma vez que você define os contornos você compara primeiro se algum contorno cruza outro. Se nenhum contorno se cruzar, você tem que verificar ainda se um contorno está completamente dentro do outro.

Ok. Ponto 1 de detecção já foi, agora falta definir quando as coisas se encontram.

Uma das estratégias primarias é você deixar as coisas simplesmente correrem e verificar a existência da colisão exatamente quando a situação descrita acima acontece. Mas e se as velocidades de movimento forem extremamente grandes a ponto de parecer que as coisas dão saltos?

Aí você usa a segunda abordagem para deteccão que é a contínua. Com ela, você vai usar posição e velocidade e vai tentar prever se acontece uma colisão em algum momento no movimento entre as duas partículas. Isso dá mais trabalho e se você para pra pensar a colisão nunca acontece de fato. Você simplesmente prevê que ela vai acontecer e ajeita as coisas para o estado da pós-colisão.

Isso finaliza a detecção. Agora você tem que definir o que acontece depois da colisão.

Algumas coisas não podem ficar umas dentro das outras. Não é legal quando o personagem entra dentro da parede, não é?(Exceto para os caçadores de bugs. Cara, nós adoramos quando isso acontece) Então você tem que tirar o personagem de dentro da parede de alguma forma.

Você pode simplesmente pegar o personagem e tirar ele de dentro do outro objeto. Se você tiver as direções de movimento do objeto, é melhor ainda pois ai você sabe para que lado você deve retirá-lo. Basta calcular a nova posição dele. Isso pode ser dificultado de acordo com a geometria dos objetos, pois dependendo das superfícies, você pode querer obter um deslizamento de uma superfície sobre a outra.

Outra abordagem possível é adicionando velocidade. Isso faz com que a colisão só seja desfeita no turno de movimento seguinte. Essa é a abordagem que eu uso para quando os personagens recebem um golpe.

E uma última questão são colisões únicas, que só devem atingir o personagem uma vez. Você precisa de estruturas auxiliares. Isso se torna especialmente fácil quando a quantidade de objetos que você tem para fazer isso é limitada, mas a idéia é basicamente você ter um indicador de colisão por objeto. Se a quantidade de objetos é ilimitada, então você precisa de uma lista desses indicadores e de identificar os elementos com essa lista.

Exatamente como fizemos!

Esse foi mais um pouco do que aconteceu durante o desenvolvimento do projeto MinArena. Fiquem ligados para mais informações sobre o desenvolvimento! Abraços!

Nenhum comentário:

Postar um comentário