phoemur
(usa Debian)
Enviado em 08/08/2018 - 21:34h
Colisões são ao mesmo tempo uma das coisas mais complicadas e com a performance mais crítica em um jogo.
Quando você começar a incluir simulação física, múltiplas formas, não apenas detectar a colisão mas aplicar as leis da física e matemática vetorial para calcular o movimento resultante depois das colisões, você vai perceber que talvez seja mais fácil utilizar um Engine já pronto. Uma coisa é fazer um jogo, outra coisa mais complicada é programar um engine do zero...
O que não quer dizer que não seja muito proveitoso saber como as coisas funcionam. Eu mesmo tenho aprendido muito fazendo joguinhos com SDL2 ultimamente. Lembro de ter comentado contigo sobre o meu joguinho breakout um tempo atrás.
Recomendo esse tutorial que já é até de certa forma famoso:
http://lazyfoo.net/tutorials/SDL/index.php
Quanto à sua pergunta sobre otimização, assim de pronto eu teria 2 estratégias que podem fazer toda a diferença na sua performance:
Número 1:
Somente aquilo que se moveu pode colidir com alguma coisa. Já o que está parado pode sofrer uma colisão, mas nunca colidir ativamente com algo. De forma que você só precisa checar colisões dos objetos que se moveram contra os outros. Não precisa ser tudo contra tudo todas as vezes.
Desta forma você percebe que dá pra cortar a complexidade do seu algoritmo e fazer menos chamadas de função. Não precisa ser O(n^2). Será muito menos, por exemplo algo assim:
for A in apenas_objetos_que_se_moveram_neste_frame:
for B in todos_os_objetos_da_cena:
if A != B and bounding_box_collision(A, B):
handle_collision(A,B)
Número 2: https://www.toptal.com/game/video-game-physics-part-ii-collision-detection-for-solid-objects
Esse método do bounding box é um dos mais eficientes para checar colisões - mesmo não sendo o mais exato para todas as formas.
Contudo mesmo que o objeto tenha se movido, se ele estiver suficientemente longe do outro objeto uma colisão não ocorreu - seria impossível ocorrer.
Por exemplo, se um objeto está em um canto da tela e o outro no outro, ou seja, X vezes mais distantes que seu maior eixo, você pode inferir que uma colisão é impossível.
Você adiciona mais uma checagem na sua função de colisão, porém como a não-colisão é muito mais comum que a colisão em cada frame, você acaba obtendo um ganho de performance.
Tem muito mais coisas que você deve levar em consideração com colisões. É mais complicado do que parece.
Por exemplo, se a velocidade de um objeto for muito alta (um projétil por exemplo), esse objeto em um frame pode estar antes do anteparo em um frame e no outro frame já estar muito depois.
Dessa forma esse tipo de algoritmo de detecção que é baseada na verificação da penetração de um corpo (rigid body) no outro nem sempre vai funcionar.
Isso é o problema da penetração.
Existe uma técina chamada raycasting para resolver esse problema.
Enfim, o que eu lembro agora de cabeça é isso.
Abração.
______________________
https://github.com/phoemur