BUSCA: 


Se você encontrou algum artigo interessante mas não lembra sua localização, pode fazer uma pesquisa pelo seu nome, descrição ou categoria.

 

 

ALLEGRO

Simulando um carro de corrida


Oct 1st 2009, 00:23

Aprenda a simular a movimentação de um pequeno carro de corrida.

Bookmark and Share        

Hoje iremos aprender como simular um pequeno carro de corrida utilizando um pouco de trigonometria básica e criatividade.



Em especial, após o término deste tutorial você saberá:

  1. como realizar uma movimentação angular em um objeto;
  2. como desenhar apenas “partes” de uma imagem maior (faremos um carro que vem de uma imagem “maior” onde poderemos pegar outros tipos de carro apenas alterando algumas coordenadas);
  3. como converter entre graus, radianos e ângulos do allegro.

Para simplificar o tutorial e torná-lo acessível para o maior número de programadores o código será todo em C (nada de C++ e código orientado a objetos por hoje).

Bom, hora de acelerar…

Representando o carro


Para representarmos corretamente o carro na tela precisamos decidir como manipularemos sua movimentação. Observe a figura abaixo:



Para representarmos nosso carro precisamos das seguintes informações:

  • imagem para exibir;
  • posição atual (coordenada x, y em relação a tela);
  • ângulo em que o carro está virado (maiores explições adiante);
  • um fator para aceleração e outro para desaceleração do carro;
  • por enquanto não suportaremos derrapagens.

Basicamente utilizaremos coordenadas polares para manipular o nosso carro. Mas temos um problema: o Allegro em suas funções que pedem um ângulo para rotação os representa de uma maneira um pouco diferente do que estamos acostumados.

Allegro e ângulos


Como você já deve saber, em trigonometria podemos representar os ângulos atravês de números convencionais (0 a 360) ou radianos (0 a 2 * PI). Mas no Allegro temos um agravante: algumas funções (por exemplo a função rotate_sprite que usaremos no código) do Allegro aceitam como argumento um “ângulo” em um formato especial (que vai de 0 a 256).

Para programadores este valor é bem conveninente pois pode ser armazenado facilmente em um byte, mas como guardaremos nossos valores de ângulo na forma “padrão” precisamos saber converter estes valores (será exibido no código a seguir).

O código


Hora do código.

Crie um arquivo main.c em seu projeto e digite código abaixo:
Agora precisamos do nosso carro. Salve a imagem abaixo em seu projeto com o nome de “vehicles.bmp” (cortesia de Ari Feldman):



Vamos por partes:

linhas 22 a 32: definimos alguns macros necessários: PI (caso não esteja definido) e dois macros para conversões (um para converter graus para radianos e outro para converter graus normais para graus representados pelo Allegro).

linhas 35, 36: para facilitar, definimos alguns macros para representar cores (dica: poderíamos utilizar uma enumeração aqui se soubermos o valor da função makecol(255,255,255)).

linha 45: como estamos utilizando o C (que não possui um tipo booleano), definimos um por conveniência (neste exemplo utilizamos apenas em uma variável).

linhas 48 a 61: aqui definimos uma estrutura para guardar nossas informações relativas ao vídeo (dimensão da tela, profundidade de cores, nosso buffer para o double buffer e algumas variáveis para controle de fps).

linhas 64 a 66: por conveniência definimos uma estrutura para guardarmos valores relativos ao timer (no caso temos apenas uma variável).

linhas 69 a 78: aqui definimos uma estrutura para guardar os valores do nosso carro: note que estamos guardando a posição do carro em ponto flutuante (convertemos para inteiro apenas na hora de desenhar o carro na tela).

linhas 81 a 86: estrutura que guarda o nosso jogo, basicamente um timer, as informações do nosso vídeo e outras informações de controle: o título da janela e um boleano indicando se deve ou não continuar executando.

linha 88: aqui definimos uma variável global para representar o jogo (sim, ela poderia ser criada na função main).

linhas 90 a 98: protótipo das funções que manipulam as estruturas definidas anteriormente.

A partir daqui algumas funções são auto-explicativas e estão bem comentadas no código, mas algumas partes merecem uma atenção especial:

linhas 107 a 123: aqui definimos as variáveis que influenciaram o comportamento do carro, recomendo dar uma alterada nos valores para ver como mudam o comportamento do carro.

linhas 125 a 130: nesta parte carregamos a imagem do carro realizando um blit (linha 129) apenas de uma parte da imagem “vehicles.bmp”.

linhas 137 a 174: esta função é a principal do carro onde calculamos todas as forças que agem no carro baseado na entrada do usuário. Em especial:

linhas 140 a 144: diminui a velocidade do carro (mas sem deixar negativo). Sempre estamos diminuindo a velocidade do carro (mas isto é sobreescrito pelo jogador se ele acelerar).

linhas 146 a 148: acelera o carro mantendo o limite da velocidade máxima.

linhas 150 a 152: aplica a marcha-ré no carro.

linhas 154 a 165: nesta parte definimos a orientação do carro (o ângulo) apenas se o carro possui uma certa velocidade (e a alteração do ângulo é proporcional a velocidade atual do veículo) e mantendo o limite correto do ângulo (0 a 360).

linhas 168 a 173: nesta parte convertemos os valores que temos em coordenadas polares (o valor da velocidade e o ângulo da virada) para coordenadas cartesianas (guardando nas variáveis vx e vy). Note que a função sin e cos recebem argumentos em radianos (e por isso utilizamos o nosso macro definido anteriormente para convertemos estes valores) e que o valor da variável vy é invertido (pois o nosso sistema de coordenadas da tela é invertido nesse eixo em relação ao sistema cartesiano convencional). Maiores explicações no tutorial de trigonometria aqui do VSoftGames.

linhas 183 a 185: aqui desenhamos o carro na tela utilizando a função “rotate_spriute”. Note que a função rotate_sprite recebe o ângulo de rotação em um valor do Allegro (e em ponto fixo) e temos apenas o nosso valor em graus. Portanto precisamos converter nosso valor em graus para graus do allegro (graus_allegro) e depois converter este valor para um valor em ponto fixo (angulo_ponto_fixo). Observe também que aqui convertemos as coordenadas do carro para inteiro na hora de desenhar.

O restante do código inicializa o Allegro, faz o controle dos frames, insere o carro na tela e outras coisas mais simples.

Vídeo


E para aqueles que não digitaram o código fonte, segue um vídeo do exemplo em execução:



Conclusão


Trabalhar com ângulo no Allegro é um pouco chato por causa das conversões adicionais que devem ser feitas nas funções que recebem apenas números em ponto fixo (pelo Allegro já ser uma biblioteca antiga) como um ângulo.

O tutorial ficou um pouco mais longo do que eu esparava (mas espero que a explicação esteja simples).

Mas a parte boa é que dominada esta parte de movimentação angular da pra fazer bastante coisa bacana. O próximo passo é encontrar ângulo entre dois pontos e saber trabalhar com intersecções (mas isto fica para um próximo tutorial).

Até o próximo tutorial (provavelmente a versão revisada do tutorial de trigonometria).

Exercícios


Agora que você já sabe o básico sobre movimentação angular e sprites você pode tentar fazer o seguinte:

  1. faça o veículo não poder sair da tela (detecção de colisão nas bordas);
  2. insira uma imagem de um circuito no fundo e crie algumas “áreas de colisão” onde você aumenta ou diminui a velocidade do veículo dependendo de onde ele estiver;
  3. implemente um carro animado;
  4. mude o sprite do carro;
  5. altere as constantes de aceleração e velocidade, o ângulo da virada e veja como o carro se comporta;
  6. faça o carro suportar derrapagens (seria um vetor de força perpendicular à orientação atual do carro).






© 2010 - VSoftGames - Programação, jogos e um pouco mais