Atirando
Autor: Guilherme - Homebrew Maker | Publicado: 2007-04-25T15:01:00-07:00

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 &gt;&gt; e &lt;&lt;. Por exemplo: 256&gt;&gt;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&gt;&gt;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 &lt;&lt; para o cálculo e  bit shifting &gt;&gt; para a apresentação. Pode-se dizer que &lt;&lt;8 é o mesmo que multiplicar por 256 e &gt;&gt;8 é o mesmo que dividir por 256, mas com um custo computacional muito menor.Vamos ao programa, então:// Includes#include &lt;PA9.h&gt;       // Include for PA_Lib#include "gfx/all_gfx.c"#include "gfx/all_gfx.h"void atira(angulo) {&nbsp;&nbsp;s32 x=127&lt;&lt;8;&nbsp;&nbsp;s32 y=95&lt;&lt;8;&nbsp;&nbsp;while ((x&gt;-8&lt;&lt;8&&x&lt;262&lt;&lt;8)&&(y&gt;-8&lt;&lt;8&&y&lt;200&lt;&lt;8)) {&nbsp;&nbsp;&nbsp;&nbsp;x+=PA_Cos(angulo);&nbsp;&nbsp;&nbsp;&nbsp;y-=PA_Sin(angulo);&nbsp;&nbsp;&nbsp;&nbsp;PA_SetSpriteXY(0,0,x&gt;&gt;8,y&gt;&gt;8);&nbsp;&nbsp;&nbsp;&nbsp;PA_OutputText(1,0,5,"x=%d, x&gt;&gt;8=%d      ",x,x&gt;&gt;8);&nbsp;&nbsp;&nbsp;&nbsp;PA_OutputText(1,0,6,"y=%d, y&gt;&gt;8=%d      ",y,y&gt;&gt;8);&nbsp;&nbsp;&nbsp;&nbsp;PA_WaitForVBL();&nbsp;&nbsp;}}// Function: main()int main(int argc, char ** argv){&nbsp;&nbsp;s16 angulo=0;&nbsp;&nbsp;PA_Init();    // Initializes PA_Lib&nbsp;&nbsp;PA_InitVBL(); // Initializes a standard VBL&nbsp;&nbsp;PA_InitText(1,0);&nbsp;&nbsp;PA_SetTextCol(1,31,31,31); &nbsp;&nbsp;PA_LoadSpritePal(0, 0, (void*)tiro_Pal);&nbsp;&nbsp;PA_CreateSprite(0, 0, (void*)tiro_Sprite, OBJ_SIZE_8X8, 1, 0, -8, -8);&nbsp;&nbsp;PA_SetSpriteRotEnable(0, 0, 0);&nbsp;&nbsp;// Infinite loop to keep the program running&nbsp;&nbsp;while (1)&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;if (Stylus.Held) {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;angulo=PA_GetAngle(127,95,Stylus.X,Stylus.Y);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PA_SetRotsetNoZoom(0,0,angulo);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PA_OutputText(1,0,4,"Angulo a partir do centro: %d   ",angulo);&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;atira(angulo);&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;PA_WaitForVBL();&nbsp;&nbsp;}&nbsp;&nbsp;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 framedepois 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.Imagem do tiro: