Física e Inteligência Artificial para jogos utilizando XNA Nome Roger Tang Empresa GLU Mobile Agenda Física Primeira lei de Newton Modelando Velocidade, Atrito e Aceleração Impulso e Quantidade de Movimento Colisão e Conservação de energia Exemplo Engines de Física Inteligência Artificial Chase – Perseguição Evade – Fuga Exemplos Física Conceito de amostragem É necessário armazenar o tempo transcorrido entre duas amostragens para efetuar uma simulação física. A amostragem temporal do jogo (Frames por segundo) não é contínua. A variação temporal entre duas interações de “Update” não pode ser considerada 1 e deve ser calculada a cada interação O XNA possui a classe auxiliar GameTime que permite calcular o tempo transcorrido entre duas interações Primeira Lei de Newton Lei da Inércia Na ausência de forças, um corpo em repouso continua em repouso, e um corpo em movimento, continua em movimento retilíneo uniforme (MRU). Modelo Em uma simulação onde existe uma esfera rolando sobre uma superfície a força que faz com que o corpo desacelere e perca velocidade é a força de atrito. Esta força é contrária ao vetor velocidade. atrito velocidade Demonstração Modelando Velocidade em XNA A velocidade é a derivada do espaço no tempo ds v s f si vt dt Codificando em XNA private Vector3 posicao = new Vector3(-200, 0, 0); private Vector3 velocidade = new Vector3(1, 0, 0); public override void Update(Microsoft.Xna.Framework.GameTime gameTime) { // Calcula Dt - Tempo transcorrido float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds; // Calcula nova posição. sf = si + vDt posicao += velocidade * timeDelta; } Modelando Atrito em XNA O atrito é força contrária ao movimento atrito velocidade private Vector3 posicao = new Vector3(-200, 0, 0); private Vector3 velocidade = new Vector3(1, 0, 0); const float coeficienteAtrito = 0.1f; public override void Update(Microsoft.Xna.Framework.GameTime gameTime) { // Calcula Dt - Tempo transcorrido float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds; // Calcula atrito. Vetor contrário a velocidade Vector3 direcaoAtrito = -velocidade; direcaoAtrito.Normalize(); direcaoAtrito *= coeficienteAtrito; // Calcula nova velocidade velocidade += direcaoAtrito; // Calcula nova posição. sf = si + vDt posicao += velocidade * timeDelta; } Modelando Aceleração em XNA A aceleração é a derivada da velocidade no tempo dv a v f vi at dt Codificando em XNA private Vector3 posicao = new Vector3(-200, 0, 0); private Vector3 velocidade = new Vector3(0, 0, 0); private Vector3 aceleracao = new Vector3(1, 0, 0); public override void Update(Microsoft.Xna.Framework.GameTime gameTime) { // Calcula Dt - Tempo transcorrido float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds; // Calcula nova velocidade. vf = vi + vDt velocidade += aceleracao * timeDelta; // Calcula nova posição. sf = si + vDt posicao += velocidade * timeDelta; } Impulso e Quantidade de Movimento Para o caso do exemplo anterior, como a aceleração é constante, a velocidade cresce exponencialmente a cada ciclo de “Update”. Logo a velocidade tende ao infinito. Como queremos apenas alterar a velocidade em um curto espaço de tempo, vamos aplicar um Impulso I Ft mat v I m t mv P t I v f vi m No nosso modelo vamos aplicar o Impulso no intervalo de tempo de apenas um ciclo de “Update”. Desta forma assim que processarmos a nova velocidade vamos zerar o valor do impulso. Para o nosso exemplo, o Impulso continuará sendo aplicado enquanto o botão do “gamepad” estiver sendo pressionado Modelando Impulso em XNA O Impulso é aplicado em apenas em ciclo de update private Vector3 posicao = new Vector3(-200, 0, 0); private Vector3 velocidade = new Vector3(0, 0, 0); private Vector3 Impulso = new Vector3(1, 0, 0); public override void Update(Microsoft.Xna.Framework.GameTime gameTime) { // Calcula Dt - Tempo transcorrido float timeDelta = (float)gameTime.ElapsedGameTime.TotalSeconds; // vf = vi + I/m velocidade += Impulso / massa; // Calcula atrito. Vetor contrário a velocidade Vector3 direcaoAtrito = -velocidade; direcaoAtrito.Normalize(); direcaoAtrito *= coeficienteAtrito; // Modela a valiação (redução) de velocidade devido ao atrito velocidade += direcaoAtrito; // sf = si + v*Dt - Ajusta posição Posicao += velocidade * timeDelta; // O Impulso é aplicado em apenas um ciclo de update Impulso = Vector3.Zero; } Colisão e Conservação de Energia Conservação da Energia Cinética. A soma da energia antes da colisão é igual a Energia depois da colisão E1 E2 E1 E2 Conservação do Momento p1 p2 p1 p2 m1v1 m2v2 m1v1 f m2v2 f Coeficiente de Restituição. É a medida de quanto uma colisão é Elástica ou Inelástica e (v2 f v1 f ) (v1 v2 ) Resolvendo as velocidades finais Desta forma as novas velocidades depois da colisão são dadas por: (e 1)m2 v2 v1 (m1 em2 ) v1 f (m1 m2 ) v2 f (e 1)m1v1 v2 (m1 em2 ) (m1 m2 ) Detectando Colisão Cria-se uma esfera envolvendo a malha e verifica se uma esfera intercepta a outra public bool DetectaColisao(Esfera esfera) { // A massa escala o objeto BoundingSphere envolucroEsfera1 = new BoundingSphere(Posicao, Modelo.Meshes[0].BoundingSphere.Radius * Massa); BoundingSphere envolucroEsfera2 = new BoundingSphere (esfera.Posicao, esfera.Modelo.Meshes[0].BoundingSphere.Radius * esfera.Massa); if (envolucroEsfera1.Intersects(envolucroEsfera2)) { audio.PlayCue("Bola"); CalculaVelocidades(esfera); return true; } else return false; } Codificando novas velocidades private void CalculaVelocidades(Esfera esfera) { float produtoInversoMassas = 1.0f / (Massa + esfera.Massa); Vector3 velocidade1Nova = ( (coeficienteRestituicao + 1.0f)*esfera.Massa*esfera.Velocidade + Velocidade * (Massa - (coeficienteRestituicao * esfera.Massa)) ) * produtoInversoMassas; Vector3 velocidade2Nova = ( (coeficienteRestituicao + 1.0f) * Massa * Velocidade esfera.Velocidade*(Massa-(coeficienteRestituicao*esfera.Massa)) ) * produtoInversoMassas; Velocidade = velocidade1Nova; esfera.velocidadeColisao = velocidade2Nova; } Demonstração Engines de Física – Open Source Open Source Engines Box2D Physics Engine - Engine 2D Bullet – Multarefa, colisão 3D e Dynamic Rigid Body ODE (Open Dynamics Engine) - Dynamic Rigid Body OPAL (Open Physics Abstraction Layer) PAL (Physics Abstraction Layer ) Tokamak Game Physics Farseer Physics Engine (engine 2D para Microsoft XNA e Silverlight) Engines de Física – Profissinais PhysX – Nvidia – build-in editor, graficos Direct X e som, vertex based Phyz Torque X – Garage Games Newton Game Dynamics Phun 2D Physics Sandbox Havok AgX Multiphysics (software) Working Model Inteligência Artificial Chase - Perseguição O conceito de perseguição consiste em direcionar o agente para o alvo e iniciar a perseguição Vector3 direction = A.position – B.Position; Lógica para definir lado da rotação Implementando Perseguição public void Chase(Asteroids.Asteroid asteroid) { // Calculate ship vector between ship and asteroid Vector3 direction = asteroid.position - Position; // Calculate direction direction.Normalize(); Vector3 shipHead = HeadShip; Vector3 shipSide = HeadSide; // Calculate the angle between ship and asteroid float angle = GetAngleSignedBetween2Vectors(shipHead, direction); // Calculate side dot to verify if we need turn to rigth or left float sideDot = Vector3.Dot(shipSide, direction); // Prevent angle to be bigger MaxAngle if (angle > GameConstants.MaxRotationAngle) angle = GameConstants.MaxRotationAngle; if (sideDot > 0) Rotation -= angle; else Rotation += angle; // Updade velocity velocity += direction * GameConstants.VelocityScale / 3; } Exemplo de Busca e Perseguição Evade - Fuga O conceito de fuga consiste em direcionar o agente para a posição oposta ao alvo Vector3 posicaoFuga = 2 * A.posicao - B.posicao; Exemplo de Busca e Perseguição Estados da IA Vagando Capturando Fugindo Capturado Outras técnicas de IA Sterring Behaviours Chase and Evade Wander ... Redes Neurais Logica Fuzzy Pendencias Alterar a IA da nave de perseguicao Esplicar o conceito de tomada de decisão http://www.gamefestbrasil.net/ © 2008 Microsoft Corporation. All rights reserved. This presentation is for informational purposes only. Microsoft makes no warranties, express or implied, in this summary.