Antes de incluir os tiros no jogo do tanque, vamos testar como atirar naquele programa de teste dos ângulos. Então iremos atirar em uma tela preta, a partir do centro da tela, conforme a stylus é usada.
Para processar o movimento, necessitamos usar seno e cosseno. Seno é a projeção do ponto da circunferência em determinado ângulo sobre o eixo Y. Cosseno é a projeção desse mesmo ponto sobre o eixo X. Seno e Cosseno são expressos em valores entre -1 e 1, o que é um problema no DS porque os processadores dele não processam ponto flutuante, tornando muito lento o uso de ponto flutuante. Mas é possível processar ponto fixo, ou ponto não-flutuante. É só fazer "bit shifting", que é o processo de determinar que uma quantidade x de bits vai ser considerada à direita da vírgula (aqui não podemos falar em ponto decimal pois estaremos trabalhando em binário). Os sinais para bit shifting são >> e <<. Por exemplo: 256>>8 retorna 1 em inteiro pois a gente moveu 8 bits para depois da vírgula. 256 em binário é 100000000, cortando os últimos 8 bits, fica 1. 256>>4 fica 16, pois eu estou cortando os últimos quatro bits, sobrando 10000, que é a representação binária de 16.
A PAlib tem funções de Seno e Cosseno para aqueles ângulos de 0 a 511, e o resultado é apresentado com bit shipfting para mais de 8 bits, ou seja, vai retornar de -256 a 256. Aí X e Y também têm que ser usados com bit shifting << para o cálculo e bit shifting >> para a apresentação. Pode-se dizer que <<8 é o mesmo que multiplicar por 256 e >>8 é o mesmo que dividir por 256, mas com um custo computacional muito menor.
Vamos ao programa, então:
// Includes
#include <PA9.h> // Include for PA_Lib
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"
void atira(angulo) {
s32 x=127<<8;
s32 y=95<<8;
while ((x>-8<<8&&x<262<<8)&&(y>-8<<8&&y<200<<8)) {
x+=PA_Cos(angulo);
y-=PA_Sin(angulo);
PA_SetSpriteXY(0,0,x>>8,y>>8);
PA_OutputText(1,0,5,"x=%d, x>>8=%d ",x,x>>8);
PA_OutputText(1,0,6,"y=%d, y>>8=%d ",y,y>>8);
PA_WaitForVBL();
}
}
// Function: main()
int main(int argc, char ** argv)
{
s16 angulo=0;
PA_Init(); // Initializes PA_Lib
PA_InitVBL(); // Initializes a standard VBL
PA_InitText(1,0);
PA_SetTextCol(1,31,31,31);
PA_LoadSpritePal(0, 0, (void*)tiro_Pal);
PA_CreateSprite(0, 0, (void*)tiro_Sprite, OBJ_SIZE_8X8, 1, 0, -8, -8);
PA_SetSpriteRotEnable(0, 0, 0);
// Infinite loop to keep the program running
while (1)
{
if (Stylus.Held) {
angulo=PA_GetAngle(127,95,Stylus.X,Stylus.Y);
PA_SetRotsetNoZoom(0,0,angulo);
PA_OutputText(1,0,4,"Angulo a partir do centro: %d ",angulo);
atira(angulo);
}
PA_WaitForVBL();
}
return 0;
} // End of main()
Como o programa funciona:
- primeiro é criada uma função que vai movimentar o tiro. Ela funciona da seguinte forma:
- recebe o parâmetro angulo.
- posiciona x e y no centro da tela.
- enquanto x ou y não passar para fora da tela faz o seguinte:
- soma o cosseno do angulo a x.
- diminui o seno do angulo de y. O eixo Y da circunferência cresce para cima, mas o eixo Y da tela do DS cresce para baixo, por isso diminuir o seno ao invés de aumentar.
- mostra o sprite do tiro na posição x,y (cortando 8 bits).
- escreve os valor de x e y e os mesmos valores cortando os 8 bits.
- aguarda o próximo frame
- depois o procedimento é igual ao nosso penúltimo programa, mas acrescentando o sprite do tiro, que é rotacionado conforme a stylus é usada. Esta parte não precisa comentar por já ter sido comentado nos dois últimos programas. A exceção é a chamada da função, que é a linha:
atira(angulo);
ou seja, chama a função atira passando o valor da variável angulo como parâmetro. Lembrem que na definição da função existe a leitura do parâmetro angulo. Neste caso foi usado angulo para a variável e angulo para o parâmetro da função, mas isso não é obrigatório nem necessário porque aqui estamos passando o valor, não interessando o nome da variável.
2 comentários:
Po, legal, ainda não testei mas vou testar quando chegar em casa.
Eu procurei uma engine pronta mas não achei.
Depois fui procurar se eu encontrava algo pra estudar no site que eu frequentava (gamingbrasil.mundoperdido.com.br) porém descobri que ele foi fechado :o
Eu dei uma revisada sobre seno e coseno com o professor da minha irmã. Não é tão complicado quanto parece, na verdade, é bem simples. Legal. Vou continuar estudando a trigonometria quando puder.
Postar um comentário