Ponto V!

Home Matemática e Física Introdução a Física nos Jogos
Bruno Crivelari Sanches
Introdução a Física nos JogosImprimir
Escrito por Bruno Crivelari Sanches

Um grande destaque dos jogos modernos é a sua física extremamente realista, principalmente nos jogos de ação onde somos contemplados com grandes explosões, objetos voando, caindo e batendo de forma bastante realista, esses efeitos são produzidos com a ajuda de bibliotecas ou motores dedicados a realizar apenas a simulação física dos jogos e neste artigo iremos explorar os conceitos fundamentais para se aprender a utilizar essas bibliotecas e dar mais realismo a nossos jogos.

Motores de Física

Nos antigos jogos de plataforma e nos primeiros FPSs a física era feita apenas utilizando-se aproximações simplificadas do comportamento dos objetos, isso era feito para tornar o jogo mais divertido, pois nem sempre o mundo real é divertido, mas o principal fator era o desempenho, pois na década de 90, por exemplo, ainda era comum os jogos utilizarem apenas cálculos de ponto fixo devido ao custo de se trabalhar com ponto flutuante.

Com a chegada de processadores mais poderosos e o advento das GPUs, que começaram a fazer o trabalho gráfico mais pesado, os desenvolvedores passaram a ter a sua disposição muitos ciclos de processamento ociosos que passaram a então a fazer cálculos de física. Com o aumento da complexidade da física nos jogos ela passou então a ter programadores dedicados ao seu desenvolvimento e é claro, começaram a separar a simulação física em bibliotecas para que esta pudesse então ser re-utilizada em outros projetos, tendo surgido então os motores de física e até mesmo empresas especializadas em produzir esses motores.

Um motor de física é como já foi dito, um motor responsável por cuidar da parte física de um jogo (ou parte dela). Para se utilizar esses motores o jogo deve então criar objetos físicos que representem a estrutura de uma fase e seus objetos, configurar estes com suas propriedades como massa, forma de colisão, etc. Feito isso ele insere esses objetos no “mundo” físico e por fim pede ao motor que simule esses objetos. Todo quadro o jogo então deve consultar o sistema de física e “pegar” a nova posição dos objetos, modificando assim a posição gráfica dos objetos do motor gráfico.

Note que o motor de física não interfere na parte gráfica do jogo, o único trabalho que ele realiza é simular os objetos físicos. O jogo então precisa toda vez que vai desenhar um quadro acessar os objetos do motor de física e copiar sua posição e orientação para seus objetos gráficos.

Corpos Rígidos

O principal objeto utilizado por um motor de física é chamado de “corpo rígido”, que vem da parte da mecânica que estuda o movimento de corpos sólidos, que nunca sofrem deformações, isso quer dizer que, não importa o que aconteça, os objetos nunca vão mudar de forma. Apesar de ser uma representação a principio um tanto simplificada, os corpos rígidos representam bem boa parte dos acontecimentos de um jogo, além de serem um tanto simples de simular comparados com outros objetos.

Um corpo rígido possui propriedades como: posição, orientação, massa, tensor de inércia, etc. Além dessas propriedades que o programador deve configurar, este pode em tempo de execução aplicar forças a um corpo rígido para forçar ou parar um movimento.

Na maioria das bibliotecas os corpos rígidos se movem e sempre vão se mover quando ocorrer alguma colisão, mas existe um tipo especial chamado de corpo rígido estático que sempre se mantém fixo e é utilizado para representar pontos fixos do cenário (como uma casa). Geralmente são criados configurando-se a massa de um corpo rígido como zero.

Formas de Colisão

Já vimos para que serve um corpo rígido e agora vamos ver como complementar ele definindo sua forma física. A forma física é usada para descrever o formato do objeto, não necessariamente vai ter exatamente a mesma forma do objeto em questão, mas costuma ser uma aproximação bem próxima.

As bibliotecas suportam diversos tipos de formas de colisão, sendo as mais comuns:

  • Esferas
  • Caixas
  • Cilindros: podem existem versões com extremos arredondados (cápsulas) ou planos
  • Sólidos convexos: são definidos apenas por planos, como por exemplo, uma pirâmide
  • Malhas triangulares: são usadas para descrever formas mais complexas, como um cenário. Geralmente são objetos que não se movem (estáticos).
  • Formas compostas: uma forma de colisão formada por um ou mais objetos descritos acima, usado para modelar objetos mais complexos.

Um carro representado por um sólido convexo. Fonte: http://support.quest3d.com/index.php?title=Newton_Collision_Convex_Hull

Em boa parte das bibliotecas é esperado que as formas de colisão não mudem com o passar do tempo, ou seja, se você criar uma esfera com raio 10, ela vai ser assim durante toda a simulação, isso é feito de forma que as formas de colisão possam ser compartilhadas, assim, se no seu jogo for preciso criar 10 esferas com raio 5, basta criar uma forma de colisão de esfera com raio 5 e 10 corpos rígidos, associando cada um deles com a esfera.

É importante ressaltar que a escolha das formas deve levar em consideração também o custo de se processar suas colisões. Por exemplo, se no seu jogo é preciso simular uma caixa, ao invés de usar uma malha triangular, utilize uma primitiva do tipo caixa, pois o custo computacional vai ser muito inferior. O ideal é sempre consultar a documentação das bibliotecas para verificar quais primitivas são mais “leves” em termos computacionais.

Tratamento de Colisão

O tratamento de colisões costuma ser a parte mais complexa de uma biblioteca de física, mas o bom que toda a complexidade costuma ficar encapsulada e o desenvolvedor precisa apenas configurar alguns parâmetros e deixar a biblioteca fazer o trabalho “sujo”. O mais comum nessas bibliotecas é primeiramente simular o movimento dos corpos rígidos e depois verificar quais corpos estão colidindo e tentar resolver essas colisões.

Quando o motor detecta que dois corpos estão colidindo ele então calcula qual a penetração de um no outro e aplica uma força contrária ao movimento para afastar um objeto do outro. Perceba então que a biblioteca deixa os corpos colidirem e eles por alguns instantes podem estar dentro um dos outros, mas geralmente a penetração é algo bem pequeno e não costuma afetar o visual.

Uma vaquinha sendo arremessada contra uma parede, repare que devido ao tunelamento ela atravessa a parede como um fantasmaUm problema que pode ocorrer na colisão é o efeito do tunelamento, que é quando um objeto se movimenta muito rápido e durante a simulação ele acaba atravessando um outro objeto. Imagine aqui uma parede representada por um plano (que seria algo bem fino) e uma caixa sendo arremessada contra ela. No instante t0 a caixa se encontra alguns centímetros da parede, é então executada a simulação e calculada a nova posição da caixa, que agora no instante t1 se encontra do outro lado da parede, nesse caso, devido ao rápido movimento da caixa, a colisão com a parede nunca foi detectada e tem-se um erro na simulação. Boa parte das bibliotecas não resolvem esse problema e cabe ao desenvolvedor usar parâmetros que evitem esse acontecimento.

Respondendo a Eventos de Colisão

A biblioteca vai sempre de alguma forma informar à aplicação que alguma colisão ocorreu e cuidar para que o mundo físico sempre seja mantido de forma coerente. Mas a simulação física não sabe de detalhes do jogo ou do aplicativo que esta usando ela, por exemplo:

  • Tocar um som quando objetos colidem
  • Explodir algo quando uma pancada forte ocorrer
  • Tirar energia de um inimigo quando este for “esmagado” por algo
  • etc.

Nesse caso, o desenvolvedor deve então criar um código que ao ser notificado de colisões que ocorreram, verifica que tipos de objetos do jogo estão envolvidos e cuidar de tomar as ações necessárias, como tocar um som ou criar uma grande explosão.

Ajustes e mais Ajustes

As bibliotecas costumam vir ajustadas com os valores mais comuns ou com os valores que produzem os melhores resultados, mas isso não garante que a simulação funcione bem em todos os casos e é muito comum os desenvolvedores gastarem inúmeras horas ajustando os mais variados parâmetros até deixarem a simulação estável.

Mas como assim estável? Quando vemos um jogo cheio de efeitos físicos funcionando de forma quase perfeita, pode-se ter certeza que alguns programadores gastaram muitas horas ali ajustando os valores, pois é comum nas primeiras simulações devido a erros numéricos a simulação ficar instável até o ponto de “explodir”, um efeito muito divertido onde todos os objetos do jogo são arremessados a velocidades absurdas para todos os lados em momentos aleatórios. Então se pretende colocar física no seu jogo, prepare-se para gastar muitas horas ajustando parâmetros.

A Influência do Tempo

Um item importante para a estabilidade dos motores de física é manter uma atualização da simulação em passos fixos, isso quer dizer que ao invés de você atualizar o motor toda vez que desenhar um quadro do jogo, você vai precisar fazer isso usando um ritmo fixo, algo como 60hz (60 vezes por segundo). Isso não significa, por exemplo, ter 40 quadros a cada 20 milissegundos e 20 quadros a cada 10. Se você atualizar a simulação física usando intervalos de tempo variáveis o sistema vai ficar instável e se seu jogo precisar de algum tipo de replay, esqueça, pois o tempo influi na simulação.

Isso ocorre devido a simulação de corpos rígidos depender de interpolação e integração, utilizando processos matemáticos que apenas aproximam valores. Dessa forma, quanto menor for o intervalo de tempo entre as atualizações, melhor vai ser a integração, pois o fator de erro vai ser menor. Com tempo variado, o erro varia e assim também varia a simulação.

Resumindo: se pretende usar um motor de física no seu jogo, o prepare para trabalhar com um passo de tempo fixo, ao menos para a física.

Diversão e Realismo

A não ser que esteja trabalhando em algum tipo de simulador é bem provável que você conclua o mesmo que eu e muitos outros: “o mundo real é chato”. Isso quer dizer que se você tentar configurar todos os objetos usando valores do mundo real seu jogo pode vir a ficar estranho e com movimentos lentos, nesse caso, não se preocupe em utilizar parâmetros que não façam sentido (como uma gravidade valor 500) com o objetivo de deixar o jogo divertido, pois afinal, o que importa mesmo é a diversão, certo? No vídeo abaixo podemos ver como uma física mal ajustada pode acabar com um jogo:

Infelizmente o autor marcou o vídeo como privado, então não é possível visualiza-lo. Como não foi possível achar um vídeo com explicações boas como esse o artigo vai ficar sem vídeo por enquanto, desculpem o transtorno.

Considerações Finais

Neste artigo o objetivo era dar ao programador uma visão geral dos conceitos mais comuns de qualquer motor de física, procurei deixar de fora particularidades de motores e focar na parte comum entre eles. Com base neste artigo, espero que seja mais simples a um programador entender e aplicar um motor de física em seu jogo. Em artigos futuros irei explorar esses e me aprofundar nesses conceitos utilizando um motor de física, provavelmente a Bullet.

Bibliotecas

Abaixo temos uma lista dos motores mais conhecidos e geralmente mais usados, focando em especial aqueles que são acessíveis sem custo, ao menos para avaliação e testes.

  • Bullet Physics, C++: Open source e aparentemente a biblioteca livre mais completa. Usada profissionalmente em vários jogos e produtos de animação, suporta também corpos macios.
  • ODE (Open Dynamics Engine), C: Open Source e a principio a mais simples de se utilizar para quem esta acostumado com OpenGL, mas aparentemente o desenvolvimento anda bem parado e não tem funcionalidades modernas se comparada com outras bibliotecas.
  • Newton Game Dynamics, C: Open Source (abriu o código recentemente) e bem popular. Tem suporte a flutuação.
  • Physx (C++): Desenvolvida pela NVidia, bem completa e possui versão não paga (código fechado) para uso comercial ou não. Exige registro para download.
  • Havok (C++): Provavelmente a mais famosa de todas e a mais completa, possui versão não paga para testes (código fechado), pode ser usada comercialmente com restrições e exige registro para download.
  • Box2D (C++): Provavelmente a mais famosa de todas bibliotecas para jogos 2d, código aberto e bem simples de usar.
  • chipmunk-physics (C): Uma outra alternativa de código aberto para quem quiser desenvolver jogos 2D.

Comentários (28)
  • André Santee
    avatar

    Excelente artigo!
    faltou citar a Box2D: http://www.box2d.org/

  • Bruno Crivelari Sanches
    avatar

    Bem lembrado! Adicionei a Chipmunk também!

    obrigado André!

  • Shinayser  - Ótimo post
    avatar

    Parabéns pelo post. Muito bom mesmo. Sabe se existe algum motor feito em java?

  • Bruno Crivelari Sanches
    avatar

    Nunca ouvi falar, mas como dificilmente pesquiso algo relacionado a jogos com Java, logo não sou uma fonte confiável :).

    Alguns motores, como a Bullet, por exemplo, possuem interfaces para ser usado com Java, então se quer apenas um motor de física para usar com Java (não sendo necessariamente feito em Java), pode usar a Bullet.

    Acredito que os outros motores devem ter alguma interface para o Java também.

    T+

  • Vinícius Godoy de Mendonça
    avatar

    Existe a versão java da Box2D: http://www.jbox2d.org/

    Inclusive é uma boa engine para quem está aprendendo a usar física pela primeira vez, já que se integra de maneira quase transparente com a Java 2D.

    E existe também um port da Bullet Physics para java, a JBullet: http://jbullet.advel.cz/

    Usado inclusive na JMonkeyEngine.

  • Blaster Lizard GT  - Ótima matéria...
    avatar

    Existe sim Shinayser. Ela é a Unity. Existe uma versão paga e a versão gratuita. Até mesmo a paga chega a ser uma das mais baratas engines no mercado, com um preço acessível de R$4000,00 reais. Ela suporta jogos para Playstation. IOS, iPhone, Xbox 360, Macintosh entre outros.

    Eu mesmo desenvolvo os jogos da minha equipe com ela. Ela utiliza o Java Script e o C++ Script também. Mas é obrigatório o aprendizado de ambas. Mas fora isso, é uma engine poderosíssima e muito útil para quem quer começar a aprender, já que sua interface não é complicada de usar.

  • Vinícius Godoy
    avatar

    Entretanto, a Unity não é uma engine em Java. Ela usa Java Script, que não é Java. E sua base toda é em C# (e não C++), rodando sobre o Mono, linguagem concorrente do Java.

    Agora, sem dúvida é uma excelente engine e super multi-plataforma.

  • TheRockkyLee
    avatar

    Qual é a diferença entre Java Script e Engine em Java?

  • Anônimo
    avatar

    Javascript é uma linguagem, Java é outra.

    A única real semelhança entre as duas é o Java no nome.

  • Mario  - Parbens
    avatar

    Muito massa seu texto!!!! :woohoo:

  • Bruno Crivelari Sanches
    avatar

    Valeu Mario!

  • Marcos Vasconcelos  - Ótimo
    avatar

    Gostei do artigo, muito interessante, e realmente "a realidade é uma merda".

    E a diferença de fisica entre os sonics é frustrante.

  • Bruno Crivelari Sanches
    avatar

    É irritante as diferenças entre os dois, a animação do sonic então, parece que foi um sujeito que acabou de ler um tutorial sobre animações que fez!

  • Crítico
    avatar

    heheheh... esse vídeo é muito engraçado o cara realmente não tem o que fazer da vida rs....

  • Neto  - Nossa
    avatar

    Que fisica horrivel! Sério, ri pacas, mas se fosse eu q tivesse jogando eu ficaria furioso.


    Não li o artigo todo, mas duvido q não seja um ótimo artigo.


    Ps: Eu tinha o megadriver e o cartucho original dele, jogava muito isso!

  • Gabriel da Silva Moreira
    avatar

    òtimo Tutorial,
    eu uso a ODE e desenvolvimento anda bem, agora colocaram uma nova biblioteca de Colisão ""libccd"

    no svn sempre tem coisa nova. e grupo ode-users é bem ativo

  • Bruno Crivelari Sanches
    avatar

    O grupo do ODE realmente é ativo e costumavam ser bem prestativos, mas era fogo ter que ficar consultando o grupo e torcendo para alguém passar uma receita de bola para fazer coisa básicas.

    Lembro que só consegui fazer uma plataforma que carregava objetos depois que um bom samaritano teve a paciência de fazer um sample para implementar, pois era preciso implementar um bocado de código naquele handler de colisão que temos que usar e o código só quem conhecia muito bem o funcionamento interno do motor conseguia implementar.

    Enquanto isso na bullet você não faz nada, só manda a plataforma andar que o que estiver em cima dela vai junto.

    Eu gosto muito do design do ODE, principalmente a API "OpenGL like", mas pena que fica devendo muitas features.

    T+

  • Mateus Pires  - Tem a AndEngine
    avatar

    Ela é uma engine free para criação de jogos 2D para Android que usa OpenGL e tem extensão Box2D Physics.

    Video exemplo: http://www.youtube.com/watch?v=BZoyeYzCYO4

    Site oficial: http://www.andengine.org/

  • Bruno Crivelari Sanches
    avatar

    Boa dica Mateus.

    Mas como se trata de um Game Engine e não de um Physics Engine vou deixar ele de fora da lista, mas fica a dica para quem precisa de um Game Engine. ;)

  • Mateus Pires
    avatar

    Mencionei ela por que tem extenção da Box2D também.

    Aproveitando o post, queria saber se é possivel usar uma game engine e uma engine de física distinta, por exemplo a Unity e a Bullet?

  • Bruno Crivelari Sanches
    avatar

    Depende muito do engine. No caso da Unity não vejo como, a não ser numa licença com código fonte ou que permita você criar novos componentes.

    T+

  • SlippiN  - Video esta privado
    avatar

    O video do post esta privado,e nao tem como ve-lo :(

  • Bruno Crivelari Sanches
    avatar

    Poxa vida, mudou de um tempo para ca, não consigo achar outro link nem outro com explicações tão boas, então por enquanto vai ficar sem :(.

  • Hugo
    avatar

    Pessoal qual algoritmo de colisão eu poderia usar para um jogo 2d isométrico?

  • Ráfagan
    avatar

    Olá Bruno!

    Cara, uma dúvida que tenho a bastante tem tem relação aos métodos avançados de colisão utilizados para meshes uniformes. Por exemplo, podemos citar o Mesh Collider da Unity.

    Você tem alguma ideia de como o mecanismo de colisão nesse caso funciona? (desconfio que seja uma Oct Tree).

  • Ráfagan
    avatar

    ** que tenho a bastante TEMPO tem...

  • Anônimo
    avatar

    No Unity não sei, mas certamente usam alguma técnica de subdivisão para minimizar o trabalho.

    Sei que na Bullet eles usam um tipo de árvore também (não lembro o nome, mas não era octree) para subdividir a mesh e simplificar o trabalho.

    Modelos complexos geralmente possuem uma bounding box ou bounding sphere para teste inicial de colisão, somente se esta primitiva colidir é que começam a examinar a mesh.

  • Anônimo  - Excelente!
    avatar

    Excelente Artigo, Parabéns!!!

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter