Intentando hacer un juego con PALib. Ayuda con un error

Buenas. Estoy intentando hacer un juego tipo space invaders o cualquiera de estos arcade de naves. Por ahora he hecho que la nave del jugador se controle con el pad y que al pulsar A dispare (utilizando el mismo sprite de la nave por ahora xD En cuando funcione bien le haré un sprite decente). El caso es que he puesto un condicional para que cuando un disparo llegue al final de la pantalla se elimine su sprite. Y el caso es que funciona... mientras no dispares más de uno antes de que éste haya desaparecido. Me explico: En el momento en que disparas varios, cuando el primero de ellos llega al extremo de la pantalla, desaparece, y los demás proyectiles se estropean, su sprite se ve mal, la variable que contiene el numero de disparos en pantalla se pone a 0 y se ralentiza todo... he probado de todo pero sigo sin encontrar el fallo. La última modificación es la siguiente:


// Includes
#include <PA9.h>
#include "gfx/all_gfx.c"
#include "gfx/all_gfx.h"


// Constantes
#define SHIPS 4 //Numero de naves enemigas
#define MAX_BULLETS 4 //Numero de disparos maximo

//Estructura para las naves:
struct shipinfo{
   s16 x, y, hspeed, vspeed;
};


//Funcion: enemy_movement (para mover las naves enemigas)
void enemy_movement(struct shipinfo enemies[SHIPS]){
   
   u8 i;
   for (i = 0; i < SHIPS; i++){ //Bucle para mover todas las naves enemigas
      enemies[i].x += enemies[i].hspeed; //Eje x
      enemies[i].y += enemies[i].vspeed; //Eje y
   }
}// Fin de la funcion enemy_movement

   
// Funcion: main()
int main(int argc, char ** argv)
{
   PA_Init();    // Initializes PA_Lib
   PA_InitVBL(); // Initializes a standard VBL
   
   PA_LoadSpritePal(0, 0, (void*)palette1_Pal);
   
   
   
   struct shipinfo player; //Estructura para la nave del jugador
   struct shipinfo enemies[SHIPS]; //Vector de estructuras para las naves enemigas
   struct shipinfo bullets[MAX_BULLETS]; //Estructura para los disparos
      
   s32 i = 0;
   s32 bullets_num = 0;
   u8 j = 0, k = 0; //Contador para mover los disparos
   
         
   player.x = 128 - 16; //Coordenadas de inicio de la nave del jugador
   player.y = 96 - 16;
   
   PA_CreateSprite(0, 0, (void*)player_ship_Sprite, OBJ_SIZE_32X32, 1, 0, player.x, player.y);
   //(pantalla, sprite, (void*)nombre, tamaño, modo (1=256 colores), num_paleta, posicion x, posicion y)
   PA_StartSpriteAnim(0, 0, 0, 3, 30); //Animamos el sprite player_ship (pantalla, sprite, frame inicial, frame final, fps)
   
   
   
   
   
   
   
   //Bucle infinito para mantener el programa en funcionamiento
   while (1)
   {
   
      PA_InitText(1, 0);
      PA_OutputText(1, 1, 1, "Player position:\nx: %d\ny: %d\n\nBullets at screen: %d\nBullet 1 Y position: %d", player.x, player.y, bullets_num, bullets[0].y);
      
      //Las dos proximas lineas permitiran mover el sprite player_ship con el pad direccional
      player.x += Pad.Held.Right - Pad.Held.Left;
      player.y += Pad.Held.Down - Pad.Held.Up;
      
      PA_SetSpriteXY(0, 0, player.x, player.y); //Actualizamos la posicion del sprite
      
    
      //Condicional para que al pulsar A se cree un sprite de disparo y se mueva hacia arriba
      if(Pad.Newpress.A && bullets_num != MAX_BULLETS){
      
         bullets_num++;
         bullets[bullets_num - 1].x = player.x; //Igualamos las coordenadas del player_ship con las del disparo para que salga de nuestra nave
         bullets[bullets_num - 1].y = player.y;
         
         PA_CreateSprite(0, bullets_num /*esto hara que los disparos sean distintos y no siempre el mismo */, (void*)player_ship_Sprite, OBJ_SIZE_32X32, 1, 0,  bullets[bullets_num - 1].x, bullets[bullets_num - 1].y);
       }
      
      for(i = bullets_num; i > 0; i--){ //Bucle para mover cada disparo
         bullets[i-1].y--;
         PA_SetSpriteXY(0, i, bullets[i-1].x, bullets[i-1].y);
      }
      
      j = bullets_num;
      
      for(i = j; i > 0; i--){ //Bucle para borrar los disparos que se salgan de la pantalla
         if(bullets[i-1].y < 0){
            PA_DeleteSprite(0, i);
            bullets_num--;
         }
      }       
      
      
      PA_WaitForVBL(); //Funcion para sincronizar a los 60fps reales de la pantalla
   }
   
   return 0;
} // Fin de main()



El problema creo que está en los dos bucles for que hay tras el if del disparo. Quizá si lo hiciera sin bucles funcionaría, pero quiero hacerlo con bucles por si quiero poner muchos disparos simultáneos en la pantalla, y no tener que escribirlo todo para cada uno. ¿Alguien ve el fallo?

Un saludo y gracias de antemano

Edito: Acabo de poner que muestre por pantalla la posición de cada proyectil y resulta que al disparar varios, cuando uno de ellos llega al extremo (es decir, su posición en el eje Y es menor que 0) los demás también se congelan en la posición en que están cuando deberían seguir porque los contadores no interfieren entre sí... ¿Qué es lo que está mal? No logro verlo ni tras saber que el contador se congela tras la primera eliminación.
for(i = j; i > 0; i--){ //Bucle para borrar los disparos que se salgan de la pantalla
if(bullets[i-1].y < 0){
for(k=i-1;k<j;k++)
bullets[k]=bullets[k+1];
bullets_num--;
PA_DeleteSprite(0, i);
}
}

O algo parecido, creo que estabas eliminando siempre el último con solo decrementar bullets_num
Gracias por la respuesta. De todas formas hacía mucho que no me pasaba por aquí y lo terminé solucionando de otra forma.

Saludos!
2 respuestas