Survive — Colisão de sprites II

survive-7_colisão_de_sprites
Por mais incrível que possa parecer, pois havia algum código por lá, a parte anterior contemplava apenas da “teoria” envolvida na coincidência/colisão de sprites com o TMS9128. Especificamente no caso dele saber que ela (a colisão) aconteceu é apenas o começo pois fica faltando a parte mais importante na história pois o VDP do MSX diz que dois (ou mais) sprites esbarraram em algum canto da tela mas não os identifica. E neste caso, até identificá-los todos os sprites na tela são suspeitos.

…aliás, que fique claro que não estou falando de Keyser Söze aqui! 🙂

Analisando o problema (a teoria)

Começando com a parte mais simples, a detecção da colisão em si. Isto pode ser feito no jogo lendo dentro do laço principal o registrador de status do VDP, verificar se o bit de colisão está com o valor 1 e em caso afirmativo desviar a execução do programa para alguma rotina que faça o tratamento adequado do evento.

Algo mais ou menos assim:

            ...
verificaColisao:
            ld a,(0xf3e7)               ; lê registrador de status
            bit 5,a                     ; bit 5 é igual a 1?
            jp nz,trataColisao          ; verifica a colisão
            ...

No caso usei JUMP mas  JUMP RELATIVE ou mesmo CALL poderiam ser utilizados dependendo da situação — até aqui é bastante parecido com o que foi feito lá no “Gotcha”.

Uma forma mais elegante seria pendurar a verificação no hook HTIMI e fazê-la acontecer toda vez que a tela for atualizada — o que faz muito sentido.

Agora a parte mais complicada…

Mecânica das colisões

Claro, a rotina de tratamento de colisão precisará ser específica para a mecânica do jogo. Pense em três jogos diferentes e  você terá uma rotina — ou rotinas — distintas em cada um deles.

Lá na primeira parte sobre o Survive escrevi algo que ajuda na definição:

(…) As listras horizontais são só a indicação dos “caminhos” que  as “caixas” percorrerão.

Isto quer dizer que cada “caixa” se movimenta em sua própria faixa sem esbarrar nas outras e portanto as colisões sempre ocorrerão entre “herói” e “caixa” e o resultado disto indicará a vida ou a morte para os envolvidos.

Recordando que todos os objetos na envolvidos são polígonos regulares com quatro lados iguais¹ em um espaço bidimensional, então a solução fica razoavelmente simples, consistindo de verificar, após a ocorrência de uma colisão, onde cada “caixa” se encontra² e comparar suas coordenadas com as do “herói”.

(¹) Conhecido vulgarmente como quadrado mas ideia funcionaria também com um retângulo. 🙂

(²) Agora está claro a necessidade de que cada sprite esteja na mesmas coordenadas que mandamos eles ficar, correto?

Protótipo de testes (a prática)

Se meus poucos conhecimentos em geometria não estiverem errados, preciso comparar os quatro vértices (A, B, C e D) do “herói” com dois vértices opostos de cada “caixa” (A’ e C’ ou B’ e D’)! Assim, se A, B, C ou D forem maiores que A’ e menores que C’ de uma determinada “caixa”então sabemos que foi com ela que o “herói” esbarrou.

A partir desta ideia escrevi a rotina de protótipo em MSX-BASIC para testar se meus conhecimentos em geometria estavam corretos:

A parte que realmente interessa no código são as linhas que estão entre 305 e 430, que é a rotina de tratamento da colisão propriamente dita. Todo o resto é um esqueleto para simular o ambiente do jogo — falta pouco para isto virar uma versão muito lenta do Survive… 🙂

survive-7_rotina de testes

Ao executar o programa você pode poderá usar as setas para mover o “herói”, a barra de espaço serve para alterar seu tamanho e usando «Esc» é possível sortear um novo conjunto de “caixas”(novos tamanho e posição).

Na detecção da colisão o programa irá verificar e imprimir as coordenadas dos vértices A’ e C’ de cada “caixa” seguida dos vértices³ A e C do “herói”, imprimirá o resultado da verificação e ficará piscando os sprites na tela — fiz isto para poder checar também de maneira visual o resultado.

E pressionando qualquer tecla ele retorna com um novo conjunto de caixas.

(³) Lembra que e um quadrado? Então os vértices B e D são combinações das coordenadas dos vértices A e C.

E agora?

Confesso que esta parte parecia fácil mas agora é converter a rotina de detecção para assembly (repare que a matemática utilizada é basicamente soma, subtração e multiplicação e divisão de potências de 2).

Mas antes disto é bom tratar de algo tão importante quanto mover objetos na tela e detectar/tratar a colusão entre eles: a leitura de teclado e/ou joysticks para fazer a movimentação do “herói” pela tela.

Então, até a próxima!

Anúncios

Deixe um comentário

Preencha os seus dados abaixo ou clique em um ícone para log in:

Logotipo do WordPress.com

Você está comentando utilizando sua conta WordPress.com. Sair / Alterar )

Imagem do Twitter

Você está comentando utilizando sua conta Twitter. Sair / Alterar )

Foto do Facebook

Você está comentando utilizando sua conta Facebook. Sair / Alterar )

Foto do Google+

Você está comentando utilizando sua conta Google+. Sair / Alterar )

Conectando a %s