Arquivo para Oh crap

Python, lento?

Primeiramente, uma breve paráfrase do nosso colega Dilbert:

GAAAH!

Em um acidente de percurso, perdi todo o código-fonte da interface gráfica do editor. Ele tinha botões, checkboxes, janelas com “drag-and-drop”, tudo OO e fácil de usar. Era lindo.

Era.

Voltando à programação normal, vamos conversar um pouco sobre engines de plataforma. Mais especificamente, engines baseadas em tiles. A questão é: como mover o personagem e detectar colisões entre ele e o cenário?

Uma abordagem simples seria, a cada atualização, mover o personagem D pixels na direção desejada. Se a posição for inválida, o personagem é reposicionado.

Movimento e colisão em engine de plataforma 1

Mas… e se o movimento foi tão acentuado que impossibilitou a detecção?

Movimento e colisão em engine de plataforma 2

Uma solução é, dada uma reta entre o ponto de origem do personagem e o ponto de destino, testar a colisão com todos os blocos cuja intersecção com a reta não seja nula. Note que, para esse método funcionar, os blocos devem ser ordenados por ordem de intersecção.

Esse cara resolveu esse problema. Ele diz que o algoritmo é simples, rápido, etc etc (e realmente é!). Depois de relembrar as aulas de geometria vetorial, parti para implementar o algoritmo em Python. Vocês já devem imaginar o resultado. Embora deveria, ainda não trabalhei em uma implementação em C para comparar a performance, mas creio que isso não seja realmente necessário :-)

Entretanto, é suficiente. No meu teste, executei o algoritmo para 1000 pares de pontos de origem em destino, contidos entre (0,0) e (1000,1000). Isso seria como ter 1000 objetos se movendo a uma velocidade de até 1000 pixels por atualização de lógica. Com 30 atualizações de lógica por segundo, daria uns 30000 pixels por segundo. É um bocado, e provavelmente não vai acontecer. O resultado?

0.127067825659 segundos

Mudando para um cenário menos megalomaníacio: pontos entre (0,0) e (16,16), 128 objetos:

0.00307580991439 segundos

E mesmo se acontecer de se tornar um gargalo de desempenho, posso partir para a ignorância e usar artifícios com o psyco e bibliotecas como o mpmath.

Em breve faço um post com o código-fonte.

Deixe um comentário