// Includes
#include <PA9.h> // Include for PA_Lib
#include "gfx/all_gfx.h"
#include "gfx/all_gfx.c"
u32 x=100;
u32 y=191-32;
u32 balay=383;
u32 velocidadbalay=0;
u32 noesta=0;
u32 marx=0;
u32 mary=0;
u32 movx=1;
u32 movy=0;
// Function: main()
int main(int argc, char ** argv)
{
PA_Init(); // Initializes PA_Lib
PA_InitVBL(); // Initializes a standard VBL
PA_InitText(1,1);
PA_SetScreenSpace(0);
PA_LoadSpritePal(0, // Pantalla
0, // Numero de paleta
(void*)nave_Pal); // Nombre de paleta
PA_DualLoadSpritePal(1,(void*)bala_Pal);
PA_DualLoadSpritePal(2,(void*)malo_Pal);
PA_DualCreateSprite(1,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,0,0);
PA_DualCreateSprite(2,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,32,0);
PA_DualCreateSprite(3,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,64,0);
PA_DualCreateSprite(4,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,96,0);
PA_DualCreateSprite(5,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,128,0);
PA_DualCreateSprite(6,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,160,0);
PA_DualCreateSprite(7,(void*)malo_Sprite,OBJ_SIZE_32X32,1,2,192,0);
PA_CreateSprite(0, // Pantalla
0, // Numero de sprite
(void*)nave_Sprite, // Nombre de sprite
OBJ_SIZE_32X32, // Tamaño de sprite
1, // Modo de 256 colores
0, // Numero de paleta
100, 100); // Posicion X e Y en la pantalla
while (1)
{
//movimiento nave
if(Pad.Held.Left) {PA_SetSpriteAnim(0,0,1); x-=1; };
if(Pad.Held.Right){PA_SetSpriteAnim(0,0,2); x+=1; };
if(x==220) x-=1;
if(x==0) x+=1;
PA_SetSpriteXY(0,0,x,y);
//movimiento bala
PA_DualSetSpriteY(10,balay);
balay+= velocidadbalay;
if(Pad.Newpress.A&&noesta==0){
PA_DualCreateSprite(10,(void*)bala_Sprite,OBJ_SIZE_8X8,1,1,x+16,y);
velocidadbalay = -2;
noesta=1;}
if(balay==1){ PA_DualDeleteSprite(10); velocidadbalay=0; balay=383; noesta=0; }
PA_OutputText(1,2,2,"%d", balay);
//malos
marx+= movx;
PA_DualSetSpriteXY(1,(marx>>8),mary);
PA_DualSetSpriteXY(2,(marx>>8)+32,mary);
PA_DualSetSpriteXY(3,(marx>>8)+64,mary);
PA_DualSetSpriteXY(4,(marx>>8)+96,mary);
PA_DualSetSpriteXY(5,(marx>>8)+128,mary);
PA_DualSetSpriteXY(6,(marx>>8)+160,mary);
PA_DualSetSpriteXY(7,(marx>>8)+192,mary);
if (marx >= 10000){
movx = -64;
mary =mary+5;} // Volvemos la velocidad negativa para que vuelva para atras
if (marx <= 1){
movx = +64;
mary =mary+5; } // Volvemos la velocidad positiva para que vuelva para adelante
//colision
PA_WaitForVBL();
}
return 0;
} // End of main()
if (borrardisparo==0 && dispx>zombi[nzom].x-32 && dispx<zombi[nzom].x+32 && dispy>zombi[nzom].y-64 && dispy < zombi[nzom].y + 64){
zombi[nzom].vida -=25; // le quito vida al zombi (en tu caso una nave)
PA_DeleteSprite(0, 127); //borro es sprite del disparo
borrardisparo=1; //borro el disparo
}
Plata escribió:yo uso algo como esto en mi proyecto:if (borrardisparo==0 && dispx>zombi[nzom].x-32 && dispx<zombi[nzom].x+32 && dispy>zombi[nzom].y-64 && dispy < zombi[nzom].y + 64){
zombi[nzom].vida -=25; // le quito vida al zombi (en tu caso una nave)
PA_DeleteSprite(0, 127); //borro es sprite del disparo
borrardisparo=1; //borro el disparo
}
Claro que hay estan las estructuras de mi proyecto, cambias las variables mias por las tuyas (el zombi es el enemigo, el personaje el que dispara xD) y a mi me va de maravilla.
salu2
highfredo escribió:que es nzom??
highfredo escribió:comenta un poco el codigo del "if" xfa, no se que he de sustituir
// si borrardisparo==0 (no se esta disparando, vamos), y la x del disparo es mayor que la x del zombi menos 32 y la x del desparo es menor que la x del zombi mas 32 y lo mismo pero con la y...
if (borrardisparo==0 && dispx>zombi[nzom].x-32 && dispx<zombi[nzom].x+32 && dispy>zombi[nzom].y-64 && dispy < zombi[nzom].y + 64){
zombi[nzom].vida -=25; // le quito vida al zombi (en tu caso una nave)
PA_DeleteSprite(0, 127); //borro es sprite del disparo
borrardisparo=1; //borro el disparo
}
highfredo escribió:ademas, como haria para eliminar una nave en concreto? tendria que repetir eso tantas veces como naves tenga? (con sus correspondientes cambios de coordenadas)
if(zombi[nzom].vida >0){
//aqui metes todo lo relacionado con la nave enemiga (IA, funciones, etc...)
}
else
{
//haces el efectillo de que explota si quieres
PA_DeleteSprite(10);
}
Blue escribió:Hay tres tipos de detección de colisiones: por caja, por vector y perfect pixel.
La más usual es la de caja, ya que es fácil y rápido de implementar. Es la que menos recursos consume, pero es la menos precisa, ya que no detecta los píxeles vacios.
La forma de implementar esto es sencilla: tienes 2 vertices por cada objeto: x,y que es la esquina superior izquierda y x2,y2 que es la inferior derecha. Solo tienes que comparar que obj2.x es menor o igual que obj1.x2 y que obj2.x2 es mayor o igual que obj1.x. Lo mismo para las coordenadas verticales.
La segunda forma requieres de la asignación de una estructura de vectores delimitados por dos puntos. El método anterior es una estructura con 4 vectoes que definen el cuadrado. En este método podemos usar los vectores para definir un borde. De esta manera formamos un dibujo a base de lineas uniendo puntos. El dibujo resultante, aunque no es preciso, ya que muchas veces parecen monigotes de palo, es bastante más preciso que la colisión por caja. Se usa bastante en 3D.
La forma de detectar la colisión es buscar los puntos de corte de todos los vectores. Por ejemplo, cojemos todos los vectores de colisión del personaje principal y comprobamos uno a uno los puntos de corte con los vectores del objeto a colisionar. Si ese punto está dentro de los rangos delimitados por las coordenadas de cada vector, quiere decir que se ha detectado la colisión.
La forma más precisa es la pixel perfection. El método comprueba pixel a pixel si uno de ellos está superpuesto a otro pixel del otro objeto. De esta manera solo se detectarán colisiones reales y precisas. Sin embargo esta es una taréa muy pesada. Mientras que con una buena fpu o una gráfica, el método de los vectores se calcula con asombrosa velocidad, el detectar todas las colisiones es una barbaridad, y más si hay muchos objetos en pantalla. 32x32 son 1024 píxeles a comprobar por imagen. A 3 objetos que haya en pantalla se nos va la cpu.
Para solventar este problema se extiende el método de las cajas. Lo primero es comprobar que haya una colisión por caja. Una vez hecha esta colisión tenemos que sacar el trozo donde colisiona. Imagínate un cuadrado de 32x32 cuya esquina superior izquierda está en la posición 1000,1000 y otro objeto de 64x16 que está en la posición 1010,1005. Tenemos que sacar dos trozos, el correspondiente al primer sprite el correspondiente al segundo, solo en las zonas en las que se solapa. De esta manera tenemos que comprobar las coordenadas 1010,1005 a 1032,1021 en ambos sprites.
Al primero le corresponde el recuadro de 10,5 a 32,21 y al segundo le corresponde el cuadrado 0,0 a 22,16. Ahora solo tenemos que buscar los píxeles no transparentes del primero y en caso de que no sea transparente, compararlo con su homólogo en el segundo sprite. Si no es transparente tampoco, se detecta la colisión. De esta manera, sacando el recuadro de colisión nos ahorramos que tener que iterar todos los píxeles de la colisión.