Problema con Bennugd

Started by oriun, October 01, 2010, 03:14:06 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

FreeYourMind


oriun

#16
Básicamente el código del programa es este:
INCLUDE "import.prg";          
//INCLUDE "jkeys.lib";
GLOBAL
int score=8001;
int font;
int counter=0;
int contador=0;

BEGIN
//jkeys_set_default_keys();
   //jkeys_controller();
set_mode(640,480,32,MODE_WINDOW);
load_fpg("images/sprite.fpg");
font=load_fnt ("font/title.fnt");
title();

END

PROCESS title()
PRIVATE
int texto;
int tempo;
BEGIN
x=320;
y=240;
LOOP
tempo=tempo+1;
IF (tempo == 100)
protagonista();
start_scroll (0, 0, 24, 0, 0, 0);
break;
END
texto = write (font, x, y, 4, "BOMB ATTACK");
frame;
delete_text ( texto );
END
END

PROCESS protagonista()
BEGIN
graph=1;
x=320; //Ancho
y=400; //Alto
LOOP //Repetición
IF (key(_left))
x=x-2-score/1000;
flags=0;
graph=graph+1;
IF (graph == 3)
graph=1;
END
ELSIF (key(_right))
x=x+2+score/1000;
flags=1;
graph=graph+1;
IF (graph == 3)
graph=1;
END
END
IF (x => 640)
x=1;
END
IF (x <= 0)
x=639;
END
IF (key(_space))
disparo();
END
IF (rand(1,100)+score/1000 > 99)
enemy();
contador=contador+1;
END
IF (key(_esc))
exit(0);
END
write_var (font, 80, 25, 2, score);
write_var (font, 80, 45, 2, contador);
frame;
END

END

PROCESS disparo()
BEGIN
graph=9;
x=father.x;
y=father.y;
flags=father.flags;
LOOP
IF (flags == 0)
x=x-3;
y=y-3;
ELSIF (flags == 1)
x=x+3;
y=y-3;
END
IF (y == 0)
break;
END
IF (collision ( type enemy ))
counter=counter+1;
END
IF (counter == 1)
counter=0;
break;
END
frame;
END
END

PROCESS enemy ()
BEGIN
graph=7;
x=rand(0,640);
y=0;
LOOP
y=y+1+score/1000;
IF (counter == 20)
counter=counter-1;
break;
END
IF (collision ( type disparo ))
score=score+100;
counter=counter-1;
explosion();
break;
END
IF ( y => 400)
explosion();
contador=contador-1;
break;
END
frame;
END
END

PROCESS explosion ()
BEGIN
graph=10;
x=father.x;
y=father.y;
LOOP
graph=graph+1;
IF (graph == 23)
break;
END
frame;
END
END

Mi problema llega cuando pasas de nivel, que los enemigos van más rapidos y van dando botes, y a veces se saltan los disparos o cosas de estas, y pasa lo mismo que con los disparos.
Mi idea era crear una trayectoria para cada cosa, y si las dos trayectorias coinciden, matar al proceso enemigo, pero me lleva de cabeza.
A ver si acabo y teneis otro juego en la Wiz.

Drumpi

Bien, creo que veo el fallo más común de los novatos, más bien, dos de ellos:

-El primero tiene que ver con la velocidad: a poco que el disparo y el enemigo cojan velocidad, y estos tengan gráficos pequeños, es posible que se "atraviesen" sin colisionar. Esto se debe a que collision no tiene en cuenta todas las posiciones por las que pasa, y se puede dar el caso de que A esté en (0,0) y B en (10,0) sin chocar, y en el siguiente frame A esté en (10,0) y B en (0,0), y siguen sin chocar, pese a que se han cruzado. En este caso deberías tener en cuenta los puntos intermedios, bien usando collision, bien comprobando las distancias, o como tu dices, las trayectorias.

-El segundo fallo tiene que ver con la sincronización de procesos: supongamos que disparo detecta la colisión con un enemigo, counter se pone a 1, lo detecta, ejecuta el break y muere. En el mismo frame, el enemigo con el que ha colisionado, tiene que detectar también la colisión, pero no lo hace, porque el proceso disparo ya no existe. La solución es que la colisión la detecte sólo uno de los procesos, en tu caso, el enemigo, porque como collision devuelve el ID del proceso con el que choca, le puedes mandar un signal(id_proceso,s_kill). También puedes hacer que el proceso disparo permanezca vivo un frame más, pero no es una solución elegante.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

SplinterGU

cuidado, ese frame que mencionas no tiene que ver con la velocidad del procesador o los frames que se hagan skip, sino que tiene que ver con frames de incremento de posicion, por mas que los frames no se dibujen, se ejecutan igual.

digo esto, para no confundir a los novatos y dejarlo bien claro.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

oriun

Ahí esta el asunto, en lo de las trayectorias, pero no sé como hacerlo... A ver si pensando un poco...

oriun

#20
Llegados a este punto, la ecuación de la linea recta es y=m·x+n, donde m es la inclinación, la altura entre la longitud, que en este caso es 1, y n la ordenada de origen, que en este caso es father.y.
Que decis de usar:
FOR (x=father.x;x<=220;x=x+1)
y=m+n
if(x==enemy.x AND y==enemy.y)
signal( get_id (type enemy) , s_kill);
frame;
END
frame;
END

oriun

#21
Ahora me da un error de tiempo de ejecución: ERROR: Runtime error in DISPARO(65574) - Process 65538 not active

Y aquí mi codigo de ahora
INCLUDE "import.prg";                  
//INCLUDE "jkeys.lib";
GLOBAL
   int score=8001;
   int font;
   int contador=0;
   int n;
   int enemy;
   
BEGIN
   //jkeys_set_default_keys();
   //jkeys_controller();
   set_mode(640,480,32,MODE_WINDOW);    
   load_fpg("images/sprite.fpg");    
   font=load_fnt ("font/title.fnt");
   title();
   enemy=enemy ();
   
END                    

PROCESS title()
PRIVATE
   int texto;
   int tempo;
BEGIN
   x=320;
   y=240;
   LOOP
       tempo=tempo+1;
       IF (tempo == 100)
           protagonista();
           start_scroll (0, 0, 24, 0, 0, 0);
           break;
       END
       texto = write (font, x, y, 4, "BOMB ATTACK");
       frame;
       delete_text ( texto );
   END
END

PROCESS protagonista()
BEGIN
   graph=1;
   x=320;        //Ancho
   n=y;
   y=400;        //Alto
   LOOP    //Repetición
       IF (key(_left))
           x=x-2-score/1000;
           flags=0;
           graph=graph+1;
           IF (graph == 3)
               graph=1;
           END
       ELSIF (key(_right))
           x=x+2+score/1000;
           flags=1;
           graph=graph+1;
           IF (graph == 3)
               graph=1;
           END
       END
       IF (x => 640)
           x=1;
       END
       IF (x <= 0)
           x=639;
       END
       IF (key(_space))
           disparo();
       END
       IF (rand(1,100)+score/1000 > 99)
           enemy();
           contador=contador+1;            
       END
       IF (key(_esc))
           exit(0);
       END
       write_var (font, 80, 25, 2, score);
       write_var (font, 80, 45, 2, contador);
       write_var (font, 80, 65, 2, fps);
       frame;
   END
   
END

PROCESS disparo()
BEGIN
   graph=9;
   y=x+n;
   x=father.x;
   LOOP
       IF (father.flags==1)
           FOR (x=father.x;x<=220;x=x+1)
               IF(x==enemy.x AND y==enemy.y)
                   signal( get_id (type enemy) , s_kill);
                   frame;
               END
               frame;
           END
       END
       IF (father.flags==0)
           FOR (x=father.x;x>=-220;x=x-1)
               IF(x==enemy.x AND y==enemy.y)
                   signal( get_id (type enemy) , s_kill);
                   frame;
               END
               frame;
           END
       END    
       frame;
   END
END

PROCESS enemy ()
BEGIN
   graph=7;
   x=rand(0,640);
   y=0;
   LOOP
       y=y+1+score/1000;
       IF (contador == 20)
           break;
       END
       IF (collision ( type disparo ))
           score=score+100;
           signal( get_id (type disparo) , s_kill);
           explosion();
           break;
       END
       IF ( y => 400)
           explosion();
           break;
       END
       frame;
   END
END

PROCESS explosion ()
BEGIN
   graph=10;
   x=father.x;
   y=father.y;
   LOOP
       graph=graph+1;
       IF (graph == 23)
           contador=contador-1;
           break;
       END
       frame;
   END
END

Y aquí el programa compilado con todo el resto de cosas: http://forigu.net16.net/bennugd.7z

DCelso

No puedo probar el ejemplo porque a mi me sale una pantalla en negro sin nada y no se cierra hasta que toco esc.
prueba con esto

colision = collision ( type disparo );
IF (colision && exist(colision))
            score=score+100;
            signal( colision , s_kill);
            explosion();
            break;
        END
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

Windgate

Tu código tiene todo el aspecto de haber seguido mi tutorial xD

Creo que estás accediendo a identificadores de proceso de forma incorrecta, por ejemplo:

                IF(x==enemy.x AND y==enemy.y)
                    signal( get_id (type enemy) , s_kill);
                    frame;
                END


Eso mata a un emeigo cualquiera...

Para vacunarte frente al 99% de los posibles errores de ejecución, siempre que accedas a un identificador de proceso pon un IF ( exists ( .. ) ) antes.
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es

oriun

#24
Quote from: Windgate on October 09, 2010, 08:51:17 PM
Tu código tiene todo el aspecto de haber seguido mi tutorial xD
Cierto, fue el primero que me lei jaja!!! :D
Ahora tambien me estoy leyendo el de Osk.

Drumpi

Es más, puedes hacer el s_kill sobre enemy directamente, en lugar de usar GET_ID (porque ya tienes su ID ¡¡¡si es que aun existe!!!).
Es muy importante estar seguro de que aun existe un proceso si se va a acceder a sus variables locales o públicas, o dará un error de ejecución. No digo que se deba usar EXISTS constantemente, pero sí saber que está. Lo digo porque haces "enemy.x" en el proceso disparo, y este valor ya no sirve una vez que has matado a la nave, esa comprobación la sigue haciendo y de ahi el error.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

oriun

Muchas gracias Drumpi, Splinter, Windgate, DCelso y FreeYourMind por ayudarme y aconsejarme mientras que programo mi juego :D

FreeYourMind

Yo sólo he dicho chorradas!  ;D

oriun

Quote from: FreeYourMind on October 10, 2010, 02:30:06 PM
Yo sólo he dicho chorradas!  ;D
Eso es justamente un apoyo moral, el cachondeo. : ;D

Windgate

Quote from: oriun on October 10, 2010, 02:21:57 PM
Muchas gracias Drumpi, Splinter, Windgate, DCelso y FreeYourMind por ayudarme y aconsejarme mientras que programo mi juego :D

Pregunta lo que sea, me encantan los nuevos retos con este lenguaje xD
Iván García Subero. Programador, profesor de informática, monitor de actividades culturales y presidente de TRINIT Asociación de Informáticos de Zaragoza. http://trinit.es