Tudo ate agora foi programado usando apenas a tela de baixo, a tela 0. Mas este jogo deve ocupar as duas telas do DS. O nosso tanque tem que ficar so na tela de baixo, mas os tiros devem alcancar a tela de cima. Uma maneira de resolver isso seria bastante complexa, colocando os mesmos desenhos dos sprites de baixo nos sprites de cima e ficar controlando para ocultar um sprite em baixo quando ele passa a aparecer em cima.Outra opcao seria usar a propria PAlib para fazer esse controle. E o que nos faremos. Todos os comandos de sprites possuem um irmao "Dual", que nao precisa especificar qual a tela ele sera colocado, o valor de y e que definira isso. A altura padrao de tela passa a ser 432 pixels (192 pixels da tela de baixo, mais 192 pixels da tela de cima, mais 48 pixels que nao mostram imagem porque sao o espaco entre as duas telas). O espaco entre as duas tela pode ser alterado pela funcao PA_SetScreenSpace mas nos continuaremos a usar os 48 pixels pois isso da uma continuidade bem legal ao tiro.Ah, sim. Faltou falar que os comandos para trabalhar com as duas telas como se fossem uma, sao os mesmos comandos de gerenciamento de sprites, somente com a palavra "Dual" na frente (logo apos o "PA_") e sem o parametro do numero da tela.Tambem iremos colocar os fundos das telas. O fundo set_bg_1.gif vai na tela de baixo e o set_bg_2.gif vai na tela de cima.No programa, as alteracoes nao sao muito radicais:trocar os comandos de sprites para os dualtratar o tanque na tela de baixo, ou seja, y+240permitir que o tiro ande por todos os 432 pixelsnao desenhar mais o fundo de 16 bits amarelo sujocolocar os dois tiled backgroundsFonte do programa:// Includes#include <PA9.h> // Include for PA_Lib#include "gfx/all_gfx.c"#include "gfx/all_gfx.h"// Variaveis Globaiss16 angulo_body=0;s16 angulo_turret=0;s16 velocidade=1;s16 x=111;s16 y=79+192+48;s16 angulo_tiro=0;s32 x_tiro=-8<<8;s32 y_tiro=-8<<8;s16 vel_tiro=4;s8 atirando=0;void giraturret() { if (Stylus.Held) { angulo_turret=PA_GetAngle(x+16,y+16-240,Stylus.X,Stylus.Y); PA_DualSetRotsetNoZoom(0,angulo_turret); }}void movetanque() { if ((Pad.Held.Left && Pad.Held.A) || (Pad.Held.Right && Pad.Held.Y) || (Pad.Held.Up && Pad.Held.B) || (Pad.Held.Down && Pad.Held.X) || (Pad.Held.X && Pad.Held.B) || (Pad.Held.Y && Pad.Held.A)) { //o usuário está sacaneando, não executa nada } else if (!(Pad.Held.Up || Pad.Held.Down || Pad.Held.Left || Pad.Held.Right || Pad.Held.A || Pad.Held.B || Pad.Held.X || Pad.Held.Y)) { //nenhuma direção foi pressionada } else { if ((Pad.Held.Left || Pad.Held.Y || Pad.Held.Right || Pad.Held.A) && !(Pad.Held.Up || Pad.Held.X || Pad.Held.Down || Pad.Held.B)) { angulo_body=256*(Pad.Held.Left || Pad.Held.Y); x+=velocidade*(Pad.Held.Right || Pad.Held.A)-velocidade*(Pad.Held.Left || Pad.Held.Y); } else if (!(Pad.Held.Left || Pad.Held.Y || Pad.Held.Right || Pad.Held.A) && (Pad.Held.Up || Pad.Held.X || Pad.Held.Down || Pad.Held.B)) { angulo_body=128*(Pad.Held.Up || Pad.Held.X)+384*(Pad.Held.Down || Pad.Held.B); y+=velocidade*(Pad.Held.Down || Pad.Held.B)-velocidade*(Pad.Held.Up || Pad.Held.X); } else { angulo_body=256*(Pad.Held.Left || Pad.Held.Y); x+=velocidade*(Pad.Held.Right || Pad.Held.A)-velocidade*(Pad.Held.Left || Pad.Held.Y); if (angulo_body) { angulo_body=192*(Pad.Held.Up || Pad.Held.X)+320*(Pad.Held.Down || Pad.Held.B); } else { angulo_body=64*(Pad.Held.Up || Pad.Held.X)+448*(Pad.Held.Down || Pad.Held.B); } y+=velocidade*(Pad.Held.Down || Pad.Held.B)-velocidade*(Pad.Held.Up || Pad.Held.X); } if (x<0) { x=0; } if (x>223) { x=223; } if (y<240) { y=240; } if (y>399) { y=399; } PA_DualSetRotsetNoZoom(1,angulo_body); PA_DualSetSpriteXY(0,x,y); PA_DualSetSpriteXY(1,x,y); }}void atira() { if (atirando) { x_tiro+=PA_Cos(angulo_tiro)*vel_tiro; y_tiro-=PA_Sin(angulo_tiro)*vel_tiro; PA_DualSetSpriteXY(2,x_tiro>>8,y_tiro>>8); if (x_tiro<-8<<8 ||