O DS é extremamente lento em operações de ponto flutuante. O autor do PAlib recomenda que, quando precisarmos de valores entre 0 e 1, se utilize um inteiro (s32, por exemplo) com bit shift. Ele utiliza 8 bits, dessa forma, 256>>8 é 1. Dessa forma eu poderia ter feito o seguinte no controle dos 3 fundos (sem usar o parallax):
while (1) {
x0+=512;
x1+=256;
x2+=128;
PA_EasyBgScrollXY(1, 0, x0>>8, 0);
PA_EasyBgScrollXY(1, 1, x1>>8, 0);
PA_EasyBgScrollXY(1, 2, x2>>8, 0);
}
Seria algo como dizer: x0+2; x1+=1; x2+=0.5; sem usar ponto flutuante.
Outra coisa: como eu havia notado, na rotação dos sprites, o giro completo é 512. A relação é a seguinte: 0 = 0°; 128 = 90°; 256 = 180°; 384 = 270°; 512 = 360°. A PAlib tem rotina para calcular seno e cosseno desse angulo do DS (PA_Sin e PA_Cos), só que os limites são -256 a 256, ao invés de -1 a 1 (justamente pelo bit shift). Isso é útil em cálculo de tragetória (esquerda e direita rotaciona o sprite, cima move para a frente, baixo move para trás). Daí a solução pode ser assim:
if (Pad.Held.Up){ // Move para a frente
x += PA_Cos(angulo);
y -= PA_Sin(angulo);
}
if (Pad.Held.Down){ // Move para trás
x += -PA_Cos(angulo);
y -= -PA_Sin(angulo);
}
Números aleatórios são gerados pela função PA_Rand, só que essa função é meio inútil pois a gente não tem controle sobre os limites dos números gerados. Para gerar um n° aleatorio entre 0 e x, usar PA_RandMax(x); para gerar um n° aleatorio entre x e y, usar PA_RandMinMax(x,y); PA_SRand(semente) serve para definir uma semente específica para os nros aleatórios; PA_InitRand() inicializa a semente de números aleatórios baseando no relógio do DS (fica muito mais aleatório).
O resto, em C é %. Assim 3%2 retorna 1. Quando o segundo valor for potência de dois, pode-se usar o resto binário (&), ganhando performance (só o segundo valor tem que ser diminuido 1). por exemplo x%4 retorna o mesmo valor que x&3.
True vale 1 e false vale 0. Com isso pode-se evitar o comando if, que é bastante lento por consumir muitos ciclos de clock para ser executado.
if (soma==true) {
x++
}
pode ser substituido por
x+=(soma==true);
Com essa lógica matemática fica fácil verificar colisões. Considerando que os desenhos nos sprites tendem a ter uma forma redonda, ou uma área de contato redonda, verificar a colisão significa ver se a distância dos centros dos dois sprites é menor ou igual à soma do raio das duas áreas redondas. Para ver a distância de dois pontos, tem a função PA_Distance(x1,y1,x2,y2).
Se os sprites tenderem à forma quadrada, basta verificar o contato das bordas.