Ponto V!

Home Matemática e Física Queda Livre (XNA)
Kléber de Oliveira Andrade
Queda Livre (XNA)Imprimir
Escrito por Kleber Andrade

Continuando as aulas de físicas para jogos, agora vamos ver que a expressão queda livre significa “cair no vazio”. Você pode até pensar como é possível pensarmos em queda livre sem considerar a resistência do ar. De fato, eu também pensei, mas em algumas situações é fundamental a resistência do ar como no salto de um paraquedista. Já em outras situações, como no lançamento de uma esfera de aço, o ar interfere tão pouco ao movimento, que pode se desprezado. O código deste tutorial foi criado e testado no XNA 4.0, ou seja, qualquer mudança de versão pode acarretar em reajustes no código.

Por mais estranho que pareça, e realmente é, o fato é que “no vácuo” todos os corpos, quando são soltos simultaneamente de uma certa altura, atingem o solo ao mesmo tempo e com a mesma velocidade. Isso acontece sempre, quaisquer que sejam suas massas, formatos ou o material de que são feitos. Mas por que isso acontece? Porque o que faz um objeto cair mais rápido que o outro é justamente o efeito do atrito do ar sobre o objeto, então se os objetos estão no vácuo, ambos caem ao mesmo tempo.

Visto que a medida de distância nos jogos é dada em pixels, e não em metros, seria então um erro dizer que a gravidade é igual a 9.8f. Então o que fazemos? precisamos encontrar um valor para a gravidade que seja aceitável visivelmente para o jogo que você esta desenvolvendo, no nosso exemplo a gravidade será a 400.0f.

Durante a queda de objetos no mundo real, existe um momento em que a força que o atrito exerce sobre o corpo se iguala à força gravitacional. Nos jogos simulamos este evento definindo um valor máximo para a velocidade de queda. Quando esse valor é atingido, a aceleração pára de agir sobre o objeto.

Para simular então a queda livre precisamos simular a gravidade sobre um objeto no jogo, então aplicamos uma aceleração no eixo Y fazendo a atualização de sua posição e velocidade a cada quadro.

h = vo * t + (g * t*t)/2

v = vo + g * t

Onde, (h) é a altura do objeto, ou seja sua posição Y, (vo) sua velocidade anterior, (t) tempo, (g) aceleração gravitacional, (v) velocidade atual. O sinal de + que tem na função não é original dela, pois o sinal real é negativo, mas como a origem do sistema de coordenadas em jogos 2D é no canto superior direito, temos que fazer um ajuste trocando o sinal.

Exemplo no XNA

O exemplo mostra a gravidade atuando sobre um objeto. A gravidade foi definida como 400 pix/s² e a velocidade inicial como zero tanto em X quanto em Y. No método Update é feito uma atualização na posição Y do objeto e na velocidade Y do mesmo. A última operação da rotina garante que a velocidade não será maior que 300 pix/s, simulando assim o equilíbrio entre a gravidade e o atrito que o corpo sofreria.

1º passo: Crie um novo projeto (Windows Game) e crie variáveis para armazenar a posição, velocidade, gravidade e textura do objeto.

//  Informações da bola
Texture2D imagem;
Vector2 posicao;
Vector2 velocidade;
// Informação do ambiente (gravidade = g)
float gravidade;

2º passo: Inicialize a posição do objeto e defina a sua velocidade inicial e a aceleração da gravidade do seu ambiente que será constante, tudo isso dentro do método Initialize()

protected override void Initialize()
{
      // Inicializa a posição da bola
      posicao = new Vector2(360.0f, 0.0f);
      // Configura o valor da gravidade
      gravidade = 400.0f;
      // Configura a velocidade inicial em X e Y
      velocidade = new Vector2(0.0f, 0.0f);
      base.Initialize();
}

3º passo: Copie a textura abaixo ou outra imagem de sua preferência para você carregar e aplicar a queda livre

protected override void LoadContent()
{
     // Create a new SpriteBatch, which can be used to draw textures.
     spriteBatch = new SpriteBatch(GraphicsDevice);
     // Carrega a textura da bola
     imagem = Content.Load<Texture2D>(@"ball");
}

4º passo: Vamos desenhar a imagem na tela

protected override void Draw(GameTime gameTime)
{
     GraphicsDevice.Clear(Color.CornflowerBlue);
     spriteBatch.Begin();
     // Desenha a bola
     spriteBatch.Draw(imagem, posicao, Color.White);
     spriteBatch.End();
     base.Draw(gameTime);
}

5º passo: Para concluir vamos aplicar a fórmula descrita no nosso objeto

protected override void Update(GameTime gameTime)
{
      // Tempo passado desde a ultima atualização
      float tempo = (float)(gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f);
      // Atualiza a posição Y da bola
      posicao += velocidade * tempo;
      // Se não atingiu a velocidade máxima, sua gravidade (h = vo * t + (g * t*t)/2)
      posicao.Y += (velocidade.Y * tempo) + (gravidade* (float)Math.Pow(tempo, 2)) / 2.0f;
      // Atualiza a velocidade Y do objeto ( v = vo + g * t )
      velocidade.Y += gravidade * tempo;
      // A velocidade máxima é 300.0f
      velocidade.Y = (velocidade.Y > 300.0f) ? 300.0f : velocidade.Y;
      base.Update(gameTime);
}

Com esta rotina é chamada a cada laço do jogo, o que será exibido na tela é um objeto (bola) que inicia uma queda com aceleração gravitacional de 400 pix/s² e que pára de acelerar quando atinge a velocidade de 300 pix/s.

Resultado

Após compilar (F5) seu código sem erro é para você obter o seguinte resultado.

Download

Para fazer download do código criado neste tutorial, clique no ícone de download abaixo.

image


Comentários (13)
  • Wellington
    avatar

    Muito interessante o artigo e código simples, porém tenho uma dúvida, diferentes objetos reagem diferentemente à ação do ar, conforme dito no arquivo. Porém, se não estou errado, a medida que um corpo acelera em sua queda, aumenta a resistência do ar sobre a mesma. Ou seja, a cada posição caminhada a força resultante diminui (gravidade - resistência do ar). Então o cálculo em si deveria considerar algo mais que um limite de velocidade.

    Sei que há um pouco de preciosismo de minha parte, mas faria mais sentido. A queda continua acelerando até as forças se anularem e a queda passar a ser uma velocidade uniforme, mas a força deve variar também no tempo.

  • Bruno Crivelari Sanches
    avatar

    É importante esse fato que você levantou, mas nos jogos temos que também analisar o que queremos simular.

    Num jogo de platforma básico ou num fps, algo mais arcade e não simulação, geralmente a resistência do ar não é modelada, pois as quedas que existem ele acaba não impactando tanto e não chega nesse efeito da velocidade "estabilizar".

    Então depende muito do que se procura modelar. Eu as vezes modelo esse efeito da resitência do ar para movimentação de personagens, pois acaba servindo como um limitador para a velocidade maxima do personagem e como um "freio" para quando ele para de se mover. Claro que de realismo não tem nada, mas da um efeito bom.

    T+

  • Kleber Andrade
    avatar

    Realmente e uma boa observação, porém consideramos um corpo abandonado de certa altura nas proximidades da superfície da Terra. Devido à resistência do ar, sempre existe, sobre esse corpo, uma força de arraste.

    Porém, este modelo fica bastante realista usando objetos pesados, porém é claro para objetos leves ele não será realista pois a força de arraste não atua nele.

    Mas o objeto do artigo é mostrar a fisica básica ensinada no ensino fundamental (geralmente o corpo esta no vacuo), porém esta anotado aqui o seu comentário e vou pensar em representar todos estes detalhes que você mencionou em um próximo artigo, ai é claro teremos que definir força (F = m * g) e outras coisas também.

    Outro fato a se atentar são os detalhes que o Bruno Sanches comentou também, para um jogo simples não é necessário tudo isso.

    Abraços.

  • Wellington
    avatar

    Vou aproveitar esta resposta para responder a ambos (Bruno e Kleber).

    Como disse, meu comentário foi um pouco de preciosismo meu ;) mas como foi considerado que há a resistência do ar, achei importante observar estes fatos mesmo que na prática (na hora de implementar) possa ser irrelevante como, por exemplo, num jogo mais básico.

    Porém, concordo com o ponto de vista posto por vocês ;)

  • Andre
    avatar

    Opa, que bacana, to tentando fazer um jogo de plataforma tipo super mario. Tem algum tutorial de pulo/varios objetos na tela? Tentei fazer o piso na mesma logica que as barras do pong, porém é anti-pratico criar uma variavel para cada bloco de chao.

    Valeu!

  • Kleber Andrade
    avatar

    Logo teremos um artigo explicando como criar um jogo de plataforma no XNA.

  • Bruno
    avatar

    Varios artigos desta seção vão lhe ajudar na questão de como gerenciar varios objetos: http://pontov.com.br/site/arquitetura/51-programacao

    Em especial: http://pontov.com.br/site/arquitetura/51-programacao/112-funcionamento -de-um-jogo

  • Andre
    avatar

    Isso é bom! Estou lendo uma apostila sobre XNA, quem sabe eu não escreva uns tutoriais tbm e mande pra vcs postarem se acharem legal.

    O tutorial de pong de vcs me ajudaram muito a entender a estrutura basica do XNA, se tiverem algumas referencias de livros e apostilas em algum topico seria sobre o XNA seria legal

    Abraço!

  • Anônimo
    avatar

    :D parabens
    :woohoo:

  • Cláudio  - Erro no download
    avatar

    O download do arquivo não está dando certo, vocês poderiam arrumá-lo por gentileza, agradeceria muito....

  • Anônimo
    avatar

    Consertado, por favor tente novamente.

    Obrigado

  • Dailson Campos  - Mudanças no XNA 4.0
    avatar

    Salve galera!

    Tô criando um pequeno jogo que utiliza a queda livre. Eu já cheguei a utilizar esse código na versão anterior do XNA e funcionou. Porém, agora com a nova versão não consigo trabalhar a questão do tempo. É apresentado um erro no GameTime... quando quero colocar (gameTime.ElapsedGameTime.TotalMilliseconds / 1000.0f); não é reconhecido . Outra! o compilador informa que os recebimentos de valores da velocidade e da posição estão incorretos, sendo que fiz igual ao exemplo. Mudou alguma coisa na sintaxe depois da mudança de versão?

    Desde já obrigado!

  • Dailson Campos  - Problema resolvido!
    avatar

    Galera, consegui resolver uma parte do problema. O qual persiste agora é o do recebimento dos valores da velocidade e da posição.

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