Início > Física, Tutoriais, XNA > [XNA] Movimento de uma flecha ao ser disparado em um jogo 2D

[XNA] Movimento de uma flecha ao ser disparado em um jogo 2D

Olá pessoal, estamos desenvolvendo um joguinho que se chama Balloons Buster, baseado nos jogos de atirar nos balões com flechas Balloon Hunter, neste caso estamos fazendo em XNA. Tirando algumas dúvidas nos livros de física e no fórum da Unidev implementei de maneira simples a trajetória de uma flecha ao ser disparada com um determinado ângulo e força de um ponto inicial. Então hoje vamos aprender como isso funciona para vocês verem que não é difícil.

Mas antes de começarmos precisamos entender corretamente o que precisamos fazer, então vamos analisar o imagem abaixo.

Então é o seguinte, precisamos lançar uma flecha com uma determinada força ou velocidade e ela também deve modificar ao longo da trajetória modificar sua orientação. Temos, o vetor V que representa a direção e velocidade que a flecha é disparada. Como obtemos ela.

Decompondo o vetor V em:

vetor.X = velocidade * Cos(θ);

vetor.Y = velocidade * Sin(θ);

Veja a velocidade e o angulo θ (theta) são dados pelo jogador. Como assim, se pensarmos que o jogador quer tentar atingir algo ou um lugar, então ele vai mirar e atirar a flecha com uma força inicial (velocidade e ângulo da mira).

Tendo nosso vetor de direção inicial, precisamos agora somar sempre este vetor a nossa posição inicial, ou seja:

posicao.X = posicao.X + vetor.X;

posicao.Y = posicao.Y + vetor.Y;

Perceba estamos incrementando nossa posição X e Y inicial da flecha, fazendo ela se movimentar. Mas se você analisar você esta somando sempre e a flecha vai seguir o veto como se fosse uma reta. Porém o que queremos é que a flecha perca a velocidade por causa da gravidade do nosso planeta. Se não existisse a gravidade provavelmente se você lançar algo para uma direção, o objeto iria permanecer nesse trajeto até bater em algo. Então precisamos agora diminuir Y.

vetor.Y = vetor.Y – gravidade; (errado para um jogo)

Note que o eixo Y no jogo é inverso ao plano cartesiano que aprendemos na escola, ou seja ao invés de diminuirmos Y, vamos aumentá-lo.

vetor.Y = vetor.Y + gravidade; (correto para o jogo)

Legal, perceba que agora a cada atualização a posição X continua aumentando constantemente e a Y vai diminuindo aos poucos pela ação da gravidade. Mas se pararmos para pensar, nossa flecha esta subindo em direção ao nosso vetor, e aos poucos o Y vai diminuindo fazendo nossa flecha descer, mas nossa flecha continua com a mesma orientação que ela saiu pois não estamos mudando esta orientação. E como vamos fazer isso ?

Utilizando a tangente podemos calcular o ângulo com base em dois pontos num plano cartesiano, ou seja se temos a posição inicial da  flecha e temos a próxima posição, é possível calcular com Atan2 a orientação da flecha.

rotacaoFlecha = Atan2(novaPosicao.Y – posicao.Y, novaPosicao.X – posicao.X);

Agora temos a cada atualização do jogo o calculo da próxima posição da flecha, mais a sua rotação dado a posição passada e a próxima calculada.

Vamos ver como ficaria isso no XNA, então crie um novo programa (LancamentoFlecha), e adicione a imagem abaixo ao seu projeto dentro da pasta Content.

flecha
flecha.png

O Solution do programa é para ficar desta maneira.

solu

Agora vamos definir as variáveis que precisaremos, mas iremos acrescentar também uma resistência no ar contra a flecha para deixar mais real.

O próximo passo é inicializarmos as variáveis que precisamo ser inicializadas, veja com isso deve ficar:

Você deve estar se perguntando o porque de certos valores, não se preocupe, quando você executar o projeto você poderá analisar o que cada valor faz com sua flecha.

Se você colocar um valor alto para a gravidade, sua flecha irá cair muito rápido. Se a velocidade for alta a flecha ira deslocar rapidamente pela tela e você não vai acompanhar o movimento dela. A posição inicial nossa é só para um chute para vermos o movimento. Vale também a pena lembrar que ao usar funções como seno e coseno, os valores usados devem ser sempre em radianos.

O próximo passo é carregar a textura da flecha.

A cada atualização precisamos calcular o próximo ponto, aplicar a gravidade ao vetor Y, verificar a nova orientação da flecha, e aplicar a nova posição a posição dela. Veja como fica:

O valor da resistência do ar neste exemplo é de 0.01f, esse valor deve ser menor que a gravidade, por que se não for, a flecha irá entrar em rotação.

Enfim , só falta desenhar

Vamos entender o porque desse Draw enorme.

SpriteBatch.Draw(Texture2d texture, Vector2 position, Rectangle ? sourceRectangle, Color color, float rotation, Vector2 origin, SpriteEfects effects, float LayerDepth)

Vamos analisar o que fizemo no Draw:

  1. Colocamos nossa texturaFlecha
  2. A posição calculada da flecha
  3. Definimos o tamanho do retângulo da figura, ou seja, definimos que nossa imagem é do tamanho total dela
  4. Colocamos como sempre a cor branca
  5. Aqui vem a orientação calculada pelo Atan2(y,x)
  6. Definimos a partir de qual a figura vai sofre rotação, então colocamos a ponta da flecha
  7. Valor 1 padrão
  8. Definimos sem efeito
  9. Valor 0 para profundidade

Agora é só executar o programa e ver o resultado:

Se você quiser, brinque um pouco com os valores da gravidade, velocidade, ângulo e até mesmo a resistência do ar.

Para fazer download do projeto completo com o código fonte clique aqui.

Agradecimentos especiais a Kamus do Poder e RafaGamer2005 membros da Unidev.

Abraço galera, espero que tenham gostado.

CategoriasFísica, Tutoriais, XNA Tags:, ,
  1. rafael módolo
    11/17/2009 às 4:16 am | #1

    Ae Klebão, tá de parabéns :D

    • Kleber Andrade
      11/17/2009 às 11:29 pm | #2

      Obrigado, valeu kakaroto !

  2. 11/17/2009 às 9:11 pm | #3

    Show de bola Kleber… Pelo visto o jogo vai ficar muito bom.
    Aguarde meu pac-man revolucionário… rsrsrsrs

    Abração!

    • Kleber Andrade
      11/17/2009 às 11:28 pm | #4

      Eai André, espero que o jogo fique bom sim… mas vamos ver como vai ficar. Quero só ver, pelas imagens seu pacman vai ficar legal mesmo, estou louco para ver ele pronto também.
      Abraços t+

  3. Mateus Pires
    03/22/2010 às 3:50 pm | #5

    Parabéns cara, muito bom o tutorial! Só tenho uma duvida, a posição que você passa (x,y) para o Vector2 é tratada como int ou como float?? Por que no caso (corrija-me se eu estiver errado xD) você manda a coordenada do pixel onde sera iniciado o desenho da sprite, mas se esse valor for um float (ex: 230,35) ele desenharia nessa posição ou arredondaria para 230/231?

    Flw, Vlw!

    • Kleber Andrade
      03/22/2010 às 3:56 pm | #6

      Obrigado amigo. No caso o Vector2 trabalho com float. Ou seja, você pode fazer as divisões sem se preocupar, pois o XNA posiciona em float também.
      Abraços, t+

  4. Nivea
    04/12/2010 às 9:41 pm | #7

    Desculpe, eu segui seu tutorial passo a passo para me ajudar com o problema que estou tendo com o meu projeto, pois estou tendo dificuldade com lançamento obliquo. Mas infelizmente no meu caso, isso não deu certo! Se puder entrar em contato comigo, ficarei grata!

    • Kleber Andrade
      04/12/2010 às 9:45 pm | #8

      Olá, sem problemas, é só me mandar um email ou me add no msn que te ajudo com seu problema.

      Att,

  5. Rodrigo Kazuma
    09/30/2010 às 5:29 pm | #9

    Opa.

    Ajudou muito cara.

    Apesar de não precisar agora, certamente um dia irei precisar.
    Abraços.

    • Kleber Andrade
      09/30/2010 às 9:49 pm | #10

      Por nada, quando precisar é só lembrar onde você viu o exemplo.
      Abraços,

  6. Jorjão
    02/22/2011 às 10:52 am | #11

    Amo seu site, se eu fosse mulher eu dava pra você huauhauhauhauhauhauha

    • Kleber Andrade
      02/27/2011 às 10:28 pm | #12

      Não precisa amigo, mesmo se fosse mulher, já encontrei a mulher da minha vida faz 2 anos :D

  7. Alvaro
    04/20/2011 às 9:35 pm | #13

    Bem basicamente gostaria de saber como eu poderia atirar outra flecha, apertando algum botao.

    • Kleber Andrade
      04/20/2011 às 11:47 pm | #14

      Olá amigo, é só adicionar cada flecha atirada numa lista de flechas, e mandar sempre atualizar e desenhar a lista toda.

      []s

  8. Décio Silva
    01/08/2012 às 8:24 pm | #15

    e aw klebão , parabéns pelo trabalho , mt massa .

    me diz uma coisa , se eu quiser fazer esse movimento infinitas vezes eu devo usar o
    for( ; ; ) ? se sim , onde ??
    valeu , abraçãoo

    • Kleber Andrade
      01/09/2012 às 12:09 am | #16

      Obrigado Décio.

      Sobre sua pergunta, se você colocar um loop infinito em algum método do seu jogo (por exemplo, Update(GameTime)) você ira travar o método, pois o laço de repetição nunca vai acabar, então seu método nunca será finalizado para que o loop do game possa proseguir.

      O que você pode fazer é simples criar uma flag de tempo, dizendo por exemplo, a cada 10 segundos passados você criar uma nova flecha e adiciona em uma lista, ai você fica atualizando e desenhando as informações dessa lista. Porém, você ainda terá um problema, que é quando a lista ficar muito grande como ocupação de memória ou até mesmo lentidão para percorrer a lista, para resolver isto você teria que ficar analisando os limites do seu jogo e remover as flechas inúteis.

      Abraços.

  9. Allan de Oliveira
    01/23/2012 às 9:56 pm | #17

    Kleber, gostei muito… parabpens.

    • Kleber Andrade
      01/25/2012 às 8:53 pm | #18

      Por nada amigo, continue estudando.
      Abraços.

  10. Lucio Pelizer
    01/25/2012 às 8:44 pm | #19

    Parabéns Kleber.
    Estou apenas engatinhando em desenvolvimento de games, mas tudo que aprendo eu ensino para meus alunos e agora estou com um mini curso de jogos eletronicos (voluntario), e seu Blog tem me ajudado muito.

    • Kleber Andrade
      01/25/2012 às 8:54 pm | #20

      Obrigado Lucio, é bom poder sempre ajudar os outros. Eu também, não sei tanto assim, mas sempre que posso ajudar é bom.
      Abraços.

  11. Lucio Pelizer
    01/25/2012 às 9:02 pm | #21

    Motivado por seu Blog, já estou planejando criar um também, mas voltado para Lógica de programação e quem sabe Allegro. Já adicionei seu blog como referência na apostila e notas de aula do mini curso de jogos.
    Abraços

    • Kleber Andrade
      01/25/2012 às 9:04 pm | #22

      Legal, obrigado pelas referências no curso.
      Sobre o blog de lógica e allegro, isso seria bem legal também, quando montar me passe o link que terei o prazer de adicionar nos meu blog.
      Não deixe de acessar também o nosso portal de games: http://www.pontov.com.br
      Espero esse ano conseguir reformatar meu blog, vamos ver se vai dar certo.
      Abraços.

  1. Nenhum trackbacks ainda.

Deixe uma resposta

Preencha os seus dados abaixo ou clique em um ícone para log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Sair / Alterar )

Imagem do Twitter

You are commenting using your Twitter account. Sair / Alterar )

Foto do Facebook

You are commenting using your Facebook account. Sair / Alterar )

Connecting to %s

Seguir

Obtenha todo post novo entregue na sua caixa de entrada.

Join 29 other followers