Buenas.
Soy nuevo con esto del BennuGD y estoy intentando programar un juego, que si no ;D.
El asunto es que yo compilo el juego y lo compila, aunque me da una advertencia en el compilador (/home∕oriun/proyectos/bennugd/librender:0: warning: Variable redeclared ("ALPHA_STEPS") pero eso no es mio :P. El caso es que se compila, pero al intentar abrirlo con el bgdi se atasca. Lo he compilado en Widows 7 64Bits(Bennupack 2.0), Ubuntu 10.04 LTS 64Bits(script) y lo he intentado abrir en estos dos con el bgdi, pero este se atasca.
Aquí abajo dejo el código a ver si es fallo mio y como puedo solucionarlo. Gracias: http://textsnip.com/my/bgdcode (http://textsnip.com/my/bgdcode)
Acá esta el problema:
[code language="bennu"]
PROCESS enemy ()
BEGIN
graph=7;
x=rand(0,320);
y=240;
LOOP
y=y-1-score/100;
IF (collision ( type disparo ))
score=score+50;
break;
END
END
END
[/code]
Se te olvido poner frame dentro del loop
Graaaaciaaaas por echarle un ojo!!
PD: Ya encontré el fallo, la profundidad de color era de 24 bits, cosa que no admite :P
No hay de qué, bienvenido!
Welcome to your DOOM!
(http://1.bp.blogspot.com/_zYnwMy50xXY/S_Ntcd9y5-I/AAAAAAAAAws/63aa7AhNb7A/s1600/chicoAsustado.jpg)
Quote from: FreeYourMind on October 01, 2010, 03:41:38 PM
Welcome to your DOOM!
(http://1.bp.blogspot.com/_zYnwMy50xXY/S_Ntcd9y5-I/AAAAAAAAAws/63aa7AhNb7A/s1600/chicoAsustado.jpg)
¿Esa es frase universal en todos los foros a los novatos? jaja!!
Es la bienvenida de gam... de FreeYourMind, aunque es la más light de los últimos 3 meses, has tenido suerte :D
PD: Free, ¡¡¡reportado!!! Mi Amstrad no puede cargar la página por tu culpa ;D
La diferencia esta en la foto, ya que teneis todos distintos padres ;D ;D
¡Bieeeeenveniiiiiidos!
Graciaas!!
Yo también soy usuario de Wiz ;D.
Otra cosa, ¿Como haríais que si tu ejecutas disparo, por ejemplo, todo lo que esté en una diagonal a partir del origen colisione con el proceso?
Pues primero obtener la ecuación de la recta:
y=x0+inclinación*x
O algo similar (lo siento, mi calculadora mental está sin pilas), de forma que sabiendo la X del proceso que queremos saber si colisiona, podemos obtener una Y dentro de la recta dañina, si esa Y está suficientemente cerca de dicha recta, es que colisiona (por suficientemente cerca queremos decir, seguramente, la mitad del alto del gráfico).
También podríamos despejar la X y hacer la operación usando la Y del proceso (necesario si el gráfico es rectangular).
Si queremos algo más preciso, se podría generar un gráfico que sea una linea, colocarla en la posición con el ángulo necesario, alpha=0, y usar collision, con todo el consumo que eso conlleva.
Si ahora no llevas pilas, no me imagino cuando las recargues :D
45º de inclinación con un aspecto de 4:3... se hace más dificil, o ¿Alguien sabe como girar una imagen 45º?
45º son 45º, da igual 4:3 que 16:9. En ese caso la ecuación es bien fácil: x=y.
A 22'5º: y=1/2*x
Siempre suponiendo que el proceso esté en (0,0), si no, tendrás que tener en cuenta el desplazamiento, por eso te decía que no me acordaba de la fórmula de la ecuación completa de la recta, que tiene eso en cuenta.
Estaba conversando conmigo mismo sobre la dificultad del juego, pero gracias por el dato :P
Y... gracias Drumpi, por ayudarme con el código, te pondré en creditos :D
Buaff, esto de trazar recorridos me lleva de cabeza. ¿Puedo postear el código para que opineis sobre él en este foro?
Claro que si hombre ;D
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.
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.
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.
Ahí esta el asunto, en lo de las trayectorias, pero no sé como hacerlo... A ver si pensando un poco...
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
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 (http://forigu.net16.net/bennugd.7z)
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
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.
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.
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.
Muchas gracias Drumpi, Splinter, Windgate, DCelso y FreeYourMind por ayudarme y aconsejarme mientras que programo mi juego :D
Yo sólo he dicho chorradas! ;D
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
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
Estoy pensando en hacer como en el tutorial de Osk, hacer que las acciones se ejecuten una de cada 80 veces que se ejecuta disparo, es decir, cuando disparo se ejecuta 80 veces, el resto se ejecuta uno, pero no se puede porque se crashea. Era cuestión de intentarlo...
Si alguien sabe como hacer que un proceso se ejecute el doble o el tríple de veces que los otros, es decir, todos-uno-uno-todos-uno-uno-todos...
que me lo diga para implantarlo.
Gracias, que se me han ocurrido muchas cosas para hacer en bennu.
FRAME(50) hace que se ejecute el doble de veces que el resto, pero sólo saca por pantalla 1 de cada dos "frames".
FRAME(33) hace que se ejecute el triple (más o menos, falla 1 frame de cada 100), pero sólo saca por pantalla 1 de cada 3 frames.
FRAME(200) hace que se ejecute la mitad de las veces (una vez cada dos frames), mostrando lo mismo dos frames seguidos.
FRAME(300) hace que se ejecute una vez cada 3 frames.
¿Se entiende el concepto? :D
Si alguien se acuerda de dónde leches escribí el ejemplo de la ventanilla y los 100 folios, que ponga el enlace, que tengo sueño :P
Graaaacias Drumpi.
Graaaaaaaaacias Drumpi.
Señores, hoy es un gran día para Bennu y para mí.
Gracias a vuestra colaboración he conseguido lo que me proponía con éxito.
Cuando lo acabe lo subiré y portaré a Wiz.
;D
Aunque es cierto que a veces no mata el proceso que colisiona, mata a esos y al resto, ahora subo el código.
import "mod_video";
import "mod_proc";
import "mod_map";
import "mod_key";
import "mod_rand";
import "mod_grproc";
import "mod_text";
import "mod_debug";
import "mod_scroll";
import "mod_proc";
//INCLUDE "jkeys.lib";
GLOBAL
int score=8001;
int font;
int contador=0;
int timer=0;
BEGIN
//jkeys_set_default_keys();
//jkeys_controller();
set_mode(640,480,32,MODE_WINDOW); //Resolución de pantalla a 320x240 píxel, 24 bits de color y en modo ventana
load_fpg("images/sprite.fpg"); //Carga el fichero para gráficos sprite.fpg de la carpeta images
font=load_fnt ("font/title.fnt");
title();
END //Fin del proceso principal del videojuego
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 //Repeticion
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 (collision (type enemy))
score=score+100;
explosion ();
signal (get_id (type enemy), s_kill);
break;
END
IF (flags == 0)
x=x-3;
y=y-3;
ELSIF (flags == 1)
x=x+3;
y=y-3;
END
IF (y == 0)
break;
END
frame(1);
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 ( 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
Porque es posible que haya un conflicto usando COLLISION y luego GET_ID: collision devuelve el ID del proceso con el que choca (no, no devuelve TRUE o FALSE, sino cero si NO colisiona, o el ID de uno de los procesos que colisiona), por lo que al pedir GET_ID, este tratará de devolver otra ID de un enemigo, y si no hay más pues devuelve cero y se hace el kill con resultados imprevisibles.
Mi consejo es que hagas esto:
[code language="bennu"] temp_id=collision (type enemy);
if (temp_id)
score=score+100;
explosion ();
signal (temp_id, s_kill);
break;
END[/code]
Quote from: Drumpi on October 13, 2010, 12:05:37 AM
Porque es posible que haya un conflicto usando COLLISION y luego GET_ID: collision devuelve el ID del proceso con el que choca (no, no devuelve TRUE o FALSE, sino cero si NO colisiona, o el ID de uno de los procesos que colisiona), por lo que al pedir GET_ID, este tratará de devolver otra ID de un enemigo, y si no hay más pues devuelve cero y se hace el kill con resultados imprevisibles.
Mi consejo es que hagas esto:
[code language="bennu"] temp_id=collision (type enemy);
if (temp_id)
score=score+100;
explosion ();
signal (temp_id, s_kill);
break;
END[/code]
Umn.... , y lo que me suena a mi esto...
Quote from: DCelso on October 09, 2010, 06:05:53 PM
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
DCelso, tienes razon, sois todos la leche y os pondré a todos en los creditos, es lo menos que puedo hacer. :P
Cuando lo implemente me estudiaré el tema de las durezas y pondré bloques por debajo que se rompan cuando les caiga una bomba.
Aquí estoy yo otra vez!!!
Bueno, pues ahora estamos con los bloques, que cuando cae un misil se rompen, pero el prota no debería poder pasar por encima de los bloques que están rotos.
Miré el tema de las durezas y vi que era casi imposible hacerlo así, también le puse un gráfico en alfa de color verde, pero tendría que poner que colisiona con los 64 bloques que tengo que poner y se quedaría atascado...
El caso es que os pongo el ejemplo, sin las librerias ni interpretes, con el código, con 35 bloques de prueba, para que le echeis un vistazo:
http://forigu.net16.net/ba.7z
Se me ocurre varias opciones:
1.- guardar los ids de todos los bloques, y comprobar que la x del personaje corresponda con alguna de algún bloque para poder continuar.
si x ==id_bloque1.x or x ==id_bloque2.x or etc... podemos andar sino no.
2.- crear un array de tamaño igual al ancho del escenario entre el ancho del sprite y poner unos o ceros indicando en donde hay bloques rotos y no puede seguir el prota. Po ejemplo si el escenario es de 320 y el sprite ocupa 10 de ancho pues un array de dimensión 32. luego para calcular la posicion del prota en el array sería pos_en_array=x/10, por ejemplo si el prota está en x = 310, pos_en_array es 31, mirarias si hay un cero en array[31] para saber si puede continuar.
Personalmente ahora lo que me preocupa es que se quede atascado en una casilla donde no hay bloque al romperse.
Había pensado en ponerlo con el sistema de Durezas, pero al parecer, eso sería mucha complicación del código.
Bueno, bueno...
Hoy traigo noticias frescas...
Esto está casi ya acabado, me falta la música y los highscores y un par de detallitos, pero ya se puede considerar la versión inicial.
http://forigu.net16.net/ba.zip (http://forigu.net16.net/ba.zip)
Bueno, bueno. Esto es embarazoso... jaj!! Mozilla Firefox.
Vamos al lio:
Ahora os voy a poner el código 'malvado' y os cuento los errores que me imprime la terminal:
http://textsnip.com/my/bgcode (http://textsnip.com/my/bgcode)
No me cabe en el post...
Los problemas que me da es del proceso marcador: ERROR: Runtime error in MARCADOR(65542) - Process 0 not active
y esta es la información del debug:
[ 7] 000000FF 00000165 ------ program.prg:357 -> x=idprota.x;
[ 9] 00000093 00000034 LOCAL 52
089F62FC
[ 11] 00000099 00000458 GET_GLOBAL 1112
089F62FC 00000000
[ 13] 0000009A 00000034 GET_REMOTE 52
ERROR: Runtime error in MARCADOR(65542) - Process 0 not active
Y otra cosa que os queria preguntar es: ¿Cómo puedo guardar en un archivo de texto los Highscores?
Y, ¿Cómo hacer un menú?, porque tal y como lo estoy intentando hacer solo me da problemas.
SplinterGU, atacale a las dudas.
Gracias.
te respondere la del proceso...
ese error lo da cuando quieres acceder a variables de un proceso que no existe, podrias usar exists antes de acceder a esa variable, con hacerlo una vez luego del frame es suficiete.
Splinter como te vas a lo fácil :D.
Yo veo varias cosillas en el código
1.- ¿Que quieres hacer con marcador() ?, a mi me parece que no debería ir en el loop del prota, porque sino crearás un proceso de tipo marcador cada vez que se llame a marcador().
if (key(_space))
disparo();
idmarcador=marcador();
end
A lo mejor tienes que ponerlo antes de loop, pero vamos lo digo sin conocer el código de lo que quieres hacer con éste al completo :D.
disparo();
LOOP //Repeticion
if (key(_space))
idmarcador=marcador();
end
luego, veo que marcador solo lo instancias en protagonista, osea que puedes solventar el problema de process not active haciendo referencia al padre en vez de a id_prota
PROCESS marcador()
PRIVATE
int tempor;
BEGIN
graph=25;
x=father.x;
y=father.y-16;
LOOP
if (exists(0))
say("ok");
else
break;
end
if (father.flags==1)
x=x+24;father
end
if (father.flags==0)
flags=1;
x=x-24;
END
tempor=tempor+1;
if (tempor==2)
tempor=0;
break;
END
frame;
END
END
Bien, el marcador es un proceso que sirve para indicar dónde va el disparo, porque este último es invisible.
Quote from: DCelso on November 15, 2010, 07:22:00 PM
luego, veo que marcador solo lo instancias en protagonista, osea que puedes solventar el problema de process not active haciendo referencia al padre en vez de a id_prota
PROCESS marcador()
PRIVATE
int tempor;
BEGIN
graph=25;
x=father.x;
y=father.y-16;
LOOP
if (exists(0))
say("ok");
else
break;
end
if (father.flags==1)
x=x+24;father
end
if (father.flags==0)
flags=1;
x=x-24;
END
tempor=tempor+1;
if (tempor==2)
tempor=0;
break;
END
frame;
END
END
Ahora, creo que esta parte si es para SplinterGU. Error de BennuGD:
bgdi: interpreter.c:348: instance_go: Assertion `i' failed.
Cancelado
posiblemente tengas versiones diferentes de dlls, o versiones mezcladas.
por algun motivo no es posible crear un nuevo proceso, aparentemente no se encuentra el tipo de proceso que se quiere crear, o quizas tengas demasiados tipos de procesos definidos.
tambien puede ser algun pise de memoria.
podrias dar mas detalles?
if (exists(0))
say("ok");
else
0 es invalido en exists, eso no esta permitido... retorna 0
el error esta en algun otro lado, intenta correrlo con log.
Frente a lo de las DLL's mezcladas no creo, porque uso Ubuntu 64bits, y no he instalado ninguna libreria adicional, excepto la libimage para el fpgeditor ese programado en bennu, el resto son del script.
Y con respecto al log: ¿Como se hace eso?
y otra cosa con respecto al crasheo del interprete: eso solo ocurre cuando en el marcador pongo father en vez de idprota.
que quieres hacer con exists(0)? a ver si es eso.
más fallos, falta un frame al siguiente proceso:
PROCESS start ()
BEGIN
LOOP
idprota=protagonista();
start_scroll (0, 0, 24, 0, 0, 0);
bloques();
END
END
a mi parecer, según creo que quieres hacer, sobra el loop end
PROCESS start ()
BEGIN
idprota=protagonista();
start_scroll (0, 0, 24, 0, 0, 0);
bloques();
END
estabas creando infinitos procesos prota y bloques, por eso seguro que peta todo.
PROCESS start ()
BEGIN
LOOP
idprota=protagonista();
start_scroll (0, 0, 24, 0, 0, 0);
bloques();
END
END
Con eso se podría terminar el mundo, ese fragmento de código debería estar prohíbido.
Nada, simplemente ten en cuenta que lo que hay dentro del LOOP se invoca unas 25 veces por segundo, hay que distinguir entre lo que quieres que suceda una vez y lo que quieres que suceda 25 veces por segundo :P
no, esto es más de 25 veces, porque no tiene la palabra frame, esto es las veces que pueda el procesador,jajaja.
O sea, ninguna...
no tiene que ver con contador, pero si puede ser esto que dicen aca.
la linea mencionada es cuando se lanza un proceso o llama a una funcion, cuando se quiere crear la instancia esta falla, no por memoria porque la memoria tiene un assert, sino cuando se intenta busca el tipo de proceso a crear, quizas algo se pisa al hacer semejante loop sin un frame.
Crucificadme!! ;D. Fallo de principiante.
Cuando lo pruebe os cuento.
¡¡¡Solucionado!!! Ahora solo hace falta la música y los highscores.
Por fin solo puedo preguntar cosas ¡¡Jaja!!
Mi pregunta es: Cuanto pulsas una tecla esa acción se repite como el Rapidfire en los emuladores. ¿Cómo puedo hacer que cuando le das a una tecla solo coja una pulsación?
dos formas:
1.- la que te puse en el menú.
if (key(_1))
//lo que sea que haga el _1
while(key(_1)) frame;end
end
2.-
global
misteclas[200];
end
....
if (key(_1)&& misteclas[_1]==0)
// lo que sea que haga el _1
misteclas[_1] =1;
else
misteclas[_1] =0;
end
frame
...
En el primer caso el proceso queda bloqueado hasta que se suelte la tecla (bueno para menues)
En el segundo caso el proceso no se bloquea pero tiene que estar haciendo asignaciones en todos los frames.
Gracias DCelso.
Implementado.
J**r DCelso, eres un maquina. :P
tambien puedes usar la libreria events que arme yo, y sirve para eso, para detectar cuando una tecla se pulsa, cuando esta pulsada y/o cuando la soltas.
http://forum.bennugd.org/index.php?topic=1494.0
Splinter, he utilizado el método de DCelso, porque cuando vi tu post ya lo implementé y porque me parecía más sencillo para un código tan corto.
cual quedo al final?
El de DCelso, pero le tuve que hacer una corrección ínfima a su código: no se debe poner
if (key(_space)&& misteclas[1]==0)
//lo que se supone q hace el space
misteclas[1]=1;
else
misteclas[1]=0;
end
Sino
if (key(_space))
if (misteclas[1]==0)
//lo que se supone que hace la tecla space
End
misteclas[1]=1;
Else
Misteclas[1]=0;
end
Aunque en mi caso utilizo una variable int, porque solo tengo que controlar la tecla space, para hacer un disparo por pulsación.
Quote from: oriun on November 18, 2010, 04:55:32 PM
El de DCelso, pero le tuve que hacer una corrección ínfima a su código: no se debe poner
if (key(_space)&& misteclas[1]==0)
//lo que se supone q hace el space
misteclas[1]=1;
else
misteclas[1]=0;
end
Sino
if (key(_space))
if (misteclas[1]==0)
//lo que se supone que hace la tecla space
End
misteclas[1]=1;
Else
Misteclas[1]=0;
end
Aunque en mi caso utilizo una variable int, porque solo tengo que controlar la tecla space, para hacer un disparo por pulsación.
es correcto, porque sino de la forma que puso DCelso, seria como un autodisparo (intermitente, un frame si, un frame no)
Me fijé mientras lo implementaba
umn, no se, a mi parecer es lo mismo, lo he probado en un ejemplo práctico y me va igual, pero es lo de menos.
De todas formas, para ser fiel a mi ejemplo deberías poner
if (key(_space))
if (misteclas[_space]==0)
//lo que se supone que hace la tecla space
End
misteclas[_space]=1;
Else
Misteclas[_space]=0;
end
Quote from: DCelso on November 18, 2010, 11:05:43 PM
umn, no se, a mi parecer es lo mismo, lo he probado en un ejemplo práctico y me va igual, pero es lo de menos.
De todas formas, para ser fiel a mi ejemplo deberías poner
if (key(_space))
if (misteclas[_space]==0)
//lo que se supone que hace la tecla space
End
misteclas[_space]=1;
Else
Misteclas[_space]=0;
end
Así si esta bien, pero si juntas los dos IF en un condicional con el operador &&, cada frame se cambia el valor de misteclas.
en este caso tambien, siempre estará la tecla escape pulsada o no pulsada. asi que entrará a poner a 1 mis teclas cuando esté pulsada y a 0 cuando no lo esté.
vamos a ver
if a==1 then
if b==2 then
if c ==3 then
//haz lo que sea
end
end
end
es exactamente lo mismo que
if a==1 && b==2 && c==3 then
//haz lo que sea
end
porque es eso mismo lo que hace internamente el compilador, mira si a vale uno, si lo vale mira si b vale 2 si lo vale mira si c vale 3.
Así que no me valen vuestras explicaciones de porqué no se comporta igual, pero sigo diciendo que es lo de menos usar la primera forma, ya que esta puede abrir más posibilidades en el futuro aún siendo menos óptima al necesitar un comparador más.
de todas formas la solución de splinter es mejor, creo, porque es más portable y cómoda de usar para futuros juegos :D.
Pero no consigo hacerla funcionar :P
DCelso no entendiste me parece.
Si vos ponés if if if y luego end end end, lo que está al medio de todo perfecto corresponde a hacer && && && porque es lo mismo, pero que tal si hay algo adentro de un if pero no adentro del otro? No es lo mismo.
if if if <algo> end end end, no es lo mismo que if <algo> if if <otro algo> end end end.
El algo primero se ejecuta solamente con el primer condicional pero el otro algo se ejecuta con los tres condicionales verdaderos. O sea que para ejecutar el primero se usa if <algo> end y para el segundo es donde podés usar &&: if esto && esto && esto <otro algo> end
La idea de ese algoritmo es que se detecte una tecla presionada, esa tecla presionada ejecuta algo y a su vez impide seguir ejecutando eso indefinidamente. (Bueno, es lo que querían hacer en este post). Y como lo hace? Activando una variable. Entonces luego para no volver a ejecutar eso comprueba la variable. Pero no modifica más la variable sino hasta que la tecla deje de estar apretada. Y para saber eso necesitas usar una condición aparte y no combinarla con && porque en cuanto la variable cambió la condición te va a dar falso y se ejecutaría el código una vez sí (cuando la variable no está seteada) y una vez no (cuando la variable estaba seteada). Eso haría un efecto intermitente que no era lo que querían hacer (bueno, depende el caso).
Yo para controlar disparos uso un "contador". Seteo una variable a un valor, por ejemplo 5, luego decremento esa variable (siempre la decremento). Y en una condición detectando cuando es <= 0 permito la ejecución del disparo. Y es ahí cuando la seteo a un valor (por ejemplo 5). Entonces los disparos saldrán cada 5 veces menos (algo así).
Eso me limita que los disparos salgan a cierto intervalo de tiempo y no todos juntos.
Cambiando el valor 5 por otro modificaremos el intervalo (cuanto mayor el número menos disparos van a salir o más largo será el intervalo entre disparo).
local
int rarma;
loop
...
<... codigo del proceso ...>
...
// Decremento la variable
rarma--;
// No dejo que rarma se haga negativa
if (rarma <= 0) rarma = 0; end
// Disparamos el laser
if (key(_L_Control))
if (rarma <= 0)
Laser(x, y, angle);
rarma = 5;
end
end
...
...
...
frame;
end
Gracias por el detalle. Pero DCElso no te va oir, se ha ido a la otra tierra.