¿Alguien puede decirme qué falla en este código? Por qué no me anda el personaje, no me salta y el progrpio programa se trunca... Hay una línea comentada que todavía me empeora el problema, una ayuda por favor :)
lo bajo y luego le echo un ojo, no prometo nada, porque ando corto de tiempos, pero intentare.
Me conformo, gracias!
BlySntK .... estoy mirando tu codigo ... sinceramente no se donde he tocao pero ya no se cuelga xDDD estoy seguro q era algun if que causaban conflictos .. q por cierto ... me cago en ti vaya manera de encadenar ifs! mete todas esas comprobaciones de estados del proceso muñeco en un swith!!! ... otra cosa q he hecho es cambiarle el nombre al proceso .. ahora se llama muneco xD q seguro q la ñ causa problemas. Al archivo funciones inc le he añadido un say para q ponga en q x esta el personaje .. borralo si no te sirve. Por cierto .. creo q en todas las funciones de este archivo puedes cambiar pPersonaje por father y te quedara un codigo mas flexible para usar con procesos enemigos o algo y mas bonito xDD Seguire mirandolo mas tarde.
ah .. y otra cosa .. haz algo con ese fpg de 36 Mb xDDDD
xDDDDDDDDDDDDDDDDDDD Sí, ya sabía yo que eran demasiados ifs, que le vuelven a uno tarumba xDDDD Programando sin planificación es lo que tiene ??? Pero bueno, gracias por mirarmelo a ti también. Ya me irás comentando qué te parece y qué cambios debería de hacer para mejorar el código, que sé que se puede simplificar mucho más.
de momento cargate esos ifs y metelos en un switch
Lo sé, es lo primero que iba a hacer de aquí a un ratejo o ya mañana :) Además de mirar los cambios realizados por ti y comprenderlos (que será fácil porque por ahora comprendo perfectamente qué es lo que has hecho, escepto la tropelia que hayas hecho para que no trunque xD)
El código me supera :( En un primer momento me estaba saltando, moviendoseme hacia lados contrarios y tal... No sé exactamente que he cambiado... más que nada algún operador o algo y otra vez me pasa: es muy inestable... Intento poner los ifs dentro de un switch pero se me complica...
Bueno, yo estoy haciendo otro tipo de juego y hacía mucho que no hacía uno y me había olvidado que hay ciertos detalles que te pueden complicar un poco la vida pero no es imposible siempre hay una manera de solucionarlo.
Lo primero que tienes que tener en claro es como va a ser tu juego (calculo que esa parte ya la pensaste). Luego del dicho al hecho... ya sabes, vas a tener que adaptar tu idea a la realidad de lo que se puede hacer. Muchas veces sale muy parecido pero otras veces vas a tener que cambiar algunas cosas para que funcione bien. O te das cuenta de que no tenía sentido que fuera así porque te encuentras en un callejón sin salida o te das cuenta de que esa idea aunque parecía buena no era práctica o útil. Bueno, tu sabrás, ahí te vas a ir arreglando.
De todos modos puedo intentar ayudarte pero deberías practicar tu mismo para que vayas mejorando.
Voy a ver que puedo arreglar de tu juego y luego tu sigues mejorándolo.
Por otro lado, no sé cuál sea tu caso pero a mi se me complicó la cosa con los fpg. Preferí usar png pelados. Aunque quedaría más "bonito" con fpgs resulta que a mi por lo menos se me hace impráctico. Porque modificar un contenido de un fpg es como un poco tedioso porque no dispongo de buenas herramientas para eso. No sé, vos como lo hacés?
Yo por ahora preparé una función sencilla que abre una sucesión de pngs y crea un fpg dentro del juego.
No te prometo nada para ya, pero en un par de días quizá.
Saludos.
estoy viendo tu juego, un poco.
veo que hay un gran lio de cosas.
no tenes que hacer una animacion completa de caminar cada vez que se pulsa una tecla, y mucho menos tras esa animacion moverse solo 1 pixel X, por eso parece que tu animacion el personaje flota o patina sobre el suelo.
cada vez que se pulsa una tecla, y mientras la tecla se este pulsando tenes que ir cambiando de frame de animacion 1 por 1, si el personaje se detine, ahi pones el grafico del personaje detenido.
como sea, nunca deberia hacer una animacion completa sin mover el grafico segun la animacion.
Por otro lado no vi aun como estas moviendo el grafico, pero me suena que estas moviendo el scroll, no el personaje.
hay muchas formas de hacer esto, pero si quieres mantener la forma de levantar primero las teclas y setear variables, te digo que en lugar de usar += uses |= y que chequees usando &.
por otro lado, manten la direccion anterior y el grafico de animacion actual, en cada pulsacion de tecla dentro de cada frame incrementa la animacion y luego resetea si llega al final.
si cambia el sentido/direccion, debes cambiar el grafico y proceder igual que en la linea anterior.
para hacerlo saltar, debes hacer basicamente lo mismo que al moverte, ir guardando la coordenada y el estado anterior en cada frame e ir moviendo las coordenadas Y (y X, si corresponde) para simular un salto, y en ese caso, las teclas de direccion las puedes deshabilitar o puedes hacer que el personaje varie ligeramente el salto, hasta que toque nuevamente el suelo.
no se si esto te sirve de algo, pero creo que deberias empezar tu codigo de cero o por lo menos reescribir gran parte.
empieza primero por mover un personaje sin mapa de durezas, simplemente moverlo por la pantalla, luego mas avanzado empieza con las durezas.
a ver... te he cambiado un poco el codigo... ahora salta, pero elimine algunas cosas como transporte y la deteccion de paredes, que no va bien eso... no entre en detalles.
igual insisto que te convendria empezar de cero.
Concuerdo con SplinterGU el código tiene demasiadas cosas mezcladas.
Yo lo simplificaría, o sea, lo empezaría por partes, primero probando el personaje solo y luego le iría agregando las demás partes (como la detección del suelo y eso).
Y ahora me acordé que hay un juego de esos de saltar que usaba una variable que seteaba para saber si había tocado piso o no. De esa forma sabía si estaba en el aire o no. Bueno, es una idea. De todos modos tengo un ejemplo del DIV2 de plataformas te lo pego acá por ahí te puede servir para empezar.
Considerá que hay que adaptarlo al nuevo formato de BennuGD porque este es para el DIV Game Studio 2 del DOS. Pero la adaptación no es muy complicada solamente hay que añadir algunas cosas (como los import "mod" y al menos el seteo del video que es diferente).
//-----------------------------------------------------------------------------
//
// ************************************************
// ***** Ejemplo de juego de plataformas *****
// ************************************************
//
// Creado por: Carlos Dominguez
// Para cualquier comentario (que agradeceria)
// E-Mail: carlosd@lettera.skios.es
//
// Proceso 'gravedad (offset_sup,offset_inf)' basada en
// el proceso 'gravedad()' del juego Castle of Dr Malvado de
// Daniel Navarro (espero que no te importe, funciona muy bien)
//
// Agradecimientos a todo el equipo de DIV Games Studio, que hace
// posible a programadores 'no tan buenos' realizar programas GENIALES
// de una forma sencilla.
//
//
// * Instrucciones: Usa las granadas atomicas para acabar con todos los
// tanques de vigilancia enemigos. Si te quedas sin municion te
// enviaremos otra carga desde el avion nodriza. Ten cuidado! Si el
// enemigo detecta que has destruido todas sus tropas, enviara
// refuerzos.
//
//
// Teclas: Arriba - Salto
// Derecha - Derecha
// Izquierda - Izquierda
// Espacio - Disparo
//
// Esc - Salir del juego
//
//-----------------------------------------------------------------------------
PROGRAM Plataformas;
GLOBAL
fuerza_salto=17; // Fuerza con que salta el personaje
municion=0; // Cantidad de municion que le queda al personaje
sin_municion=TRUE; // Indicador para "mandar" mas municion si te quedas sin balas
enemigos=0; // Cantidad de enmigos que hay en la pantalla (se podria usar para cambiar de fase cuando llege a 0
LOCAL
incx=0; // Cantidad que avanza el objeto
velocidad_gravedad=0; // Velocidad a la que esta bajando o subiendo el objeto
en_suelo=FALSE; // Indica si el objeto esta sobre el suelo o en el aire
BEGIN
set_mode(m640x480); // Ajustamos el modo de pantalla
load_fpg ("user\platafor\platafor.fpg"); // Cargamos los graficos
put_screen (0,500); // Pintamos el fondo
write (0,15, 20, 0, "MUNICION:"); // Pintamos los marcadores
write_int (0, 80, 20, 0, &municion);
write (0, 520, 20, 0, "N§ Enemigos:");
write_int (0, 600, 20, 0, &enemigos);
personaje(70,350); // Creamos a nuestro personaje
bonus(590,15); // Creamos un objeto (en este caso municion)
enemigo (160,260,90,230); // Creamos los enemigos
enemigo (110,35,65,150);
enemigo (130,400,100,600);
plataforma (590,230,80,230); // Creamos una plataforma que sube y baja
control(); // Pasamos a la rutina de control general del programa
END
//-----------------------------------------------------------------------------
// Control general del juego
//-----------------------------------------------------------------------------
PROCESS control();
PRIVATE
id_txt; // Identficador para poder borrar el texto que escribimos
BEGIN
timer=0; // Inicia el timer (cronometro)
LOOP // Comienza el bucle
// Comprueba si no hay enemigos. Si no quedan pone un mensaje
IF (enemigos==0) id_txt=write (0,320,240,4,"TE LOS HAS CARGADO A TODOS");
FRAME (10000); // Pausa
delete_text(id_txt); // Borra el texto
enemigo (160,260,90,230); // Pone mas enemigos
enemigo (110,35,65,150);
enemigo (130,400,100,600);
END
// Comprueba que no te quede municion y que no haya ningun objeto de bonus en la pantalla y escribe un mensaje
IF (municion==0 AND NOT get_id(TYPE bonus)) id_txt=write (0,320,240,4,"ATENCION! Municion agotada");
FRAME (10000); // Pausa
delete_text(id_txt); // Borra el texto
bonus (rand(20,620),-40); // Crea un nuevo objeto en una posicion (de x) al azar
END
IF (timer>100) timer=0; END // Inicia el timer cada segundo
IF (key(_esc)) let_me_alone(); BREAK; END // Sale del programa si se pulsa Esc
FRAME; // Pasa el control a los demas procesos
END
END
//-----------------------------------------------------------------------------
// Proceso para el personaje principal
//-----------------------------------------------------------------------------
PROCESS personaje(x,y);
PRIVATE
pri_cuad=1; // Control de la animacion
ult_cuad=1;
disparo=1; // Bloqueo de la tecla de disparo
BEGIN
LOOP
FOR (graph=pri_cuad ; graph<=ult_cuad ; graph=graph+1) // Animacion del personaje
IF (key(_left))
incx=-10; pri_cuad=2; ult_cuad=12; flags=1; // Movimiento a la izquierda
ELSE IF (key(_right)) // Movimiento a la derecha
incx=10; pri_cuad=2; ult_cuad=12; flags=0;
ELSE pri_cuad=1; ult_cuad=1; incx=0; END // Si no se mueve ni hacia la izquierda ni la derecha ponemos la animacion de quieto
END
IF (key(_up) AND en_suelo) velocidad_gravedad=-fuerza_salto; END // Salta si esta sobre el suelo
IF (velocidad_gravedad<>0 OR NOT en_suelo) graph=14; END // Ajusta los graficos segun suba o baje
IF (velocidad_gravedad > 0 AND NOT en_suelo) graph=15; END
IF (key(_space)) // Dispara si tiene municion
IF (disparo)
disparo=0;
IF (municion>0) disparo_yo(x,y,flags); municion--; END
END
ELSE disparo=1; END
corrige_coordenadas(); // Si sale por un lado, entra por el otro
gravedad(16,23); // Fuerza de gravedad y suelos
paredes (42); // Choque con las paredes
x+=incx; // Movimiento horizontal
FRAME;
END
END
END //Fin de PERSONAJE
//-----------------------------------------------------------------------------
// Proceso para la muerte del prota
//-----------------------------------------------------------------------------
PROCESS muerto(x,y,direccion);
BEGIN
graph=96; // Pone el grafico inicial del proceso
velocidad_gravedad=-10; // Lo hace subir un poco
IF (direccion) incx=-10; ELSE incx=10; END // Mueve el grafico segun de donde le venga la bala
FROM angle=0 to 90000 STEP 6000; // Va girando el grafico
IF (angle>40000) graph=97; END // y cambiandolo segun el angulo
IF (angle>60000) graph=98; END
x+=incx; //Lo hace avanzar
IF (incx>0) incx--; ELSE IF (incx<0) incx++; END END // y lo va frenando poco a poco
IF (en_suelo) incx=0; angle=90000; graph=98; END // Si toca el suelo lo pone horizontal de golpe
corrige_coordenadas();
gravedad(11,11);
FRAME;
END
LOOP
x+=incx; // Es lo mismo de antes, por si antes de llegar
IF (incx>0) incx--; ELSE IF (incx<0) incx++; END END // al suelo se puso en posicion horizontal
IF (en_suelo) incx=0; END
corrige_coordenadas();
gravedad(11,11);
IF (en_suelo) FRAME(800); fade_off(); // Cuando llega al suelo hace una pequeña pausa
personaje(70,350); fade_on(); signal (id,s_kill); END // crea un nuevo personaje, y se auto-destruye
FRAME;
END
END
//-----------------------------------------------------------------------------
// Proceso para el disparo del prota
//-----------------------------------------------------------------------------
PROCESS disparo_yo(x,y,direccion);
PRIVATE
id2=0;
BEGIN
velocidad_gravedad=-20; // Lo hace subir
size=50;
IF (direccion>0) incx=-20; ELSE incx=20; END // Ajusta incx segun la direccion del muñeco
WHILE (NOT en_suelo) // Repite hasta llegar al suelo
FROM graph = 52 to 62; // Animacion
x+=incx; // Avanza en la direccion horizontal
IF (incx>0) incx--; ELSE IF (incx<0) incx++; END END // Lo frena poco a poco
corrige_coordenadas();
gravedad (11,11);
paredes(23);
FRAME;
END
END
size=100;
FROM graph = 63 TO 75; // Comienza la explosion
id2=collision (TYPE enemigo); // Mira si toca algun enemigo
IF ( id2 ) // Si lo toca
explosion (id2.x , id2.y, 50); // Crea una explosion
signal (id2,s_kill); // Se carga al enemigo
enemigos--; // Quita un enemigo de la cuenta
END
FRAME;
END
END //Fin de ENEMIGO
//-----------------------------------------------------------------------------
// Proceso plataforma
//-----------------------------------------------------------------------------
PROCESS plataforma(x,y,y1,y2);
PRIVATE
id2=0;
direccion=-1;
BEGIN
graph=99; size=50;
LOOP
//Movimiento
IF (direccion==-1 ) y+=2; IF (y>y2) direccion=1; END // Mueve la plataforma en la direccion indicada por direccion
ELSE y-=2; IF (y<y1) direccion=-1; END // Si llega al limite cambia direccion
END
// Deteccion de colision con personaje
id2=collision (TYPE personaje); // Si colisiona con el personaje
IF ( id2 )
IF (id2.y < y ) // y esta por debajo de el,
id2.y = y - 28; // lo sube un poco
id2.en_suelo=true; // le activa en_suelo
id2.velocidad_gravedad=0; // y le quita la gravedad
END
END
// Deteccion de colision con disparos personaje
id2=collision (TYPE disparo_yo); // Igual que en personaje
IF ( id2 )
IF (id2.y < y )
id2.y = y - 10;
id2.en_suelo=true;
id2.velocidad_gravedad=0;
END
END
// Deteccion de colision con objeto
id2=collision (TYPE bonus); // Igual que en personaje
IF ( id2 )
IF (id2.y < y )
id2.y = y - 20;
id2.en_suelo=true;
id2.velocidad_gravedad=0;
END
END
FRAME;
END
END //Fin de PLATAFORMA
//-----------------------------------------------------------------------------
// Proceso que crea una explosion
//-----------------------------------------------------------------------------
PROCESS explosion(x,y,size);
BEGIN
FROM graph = 76 TO 95; // Ajusta la animacion
y-=5; // La hace subir un poco
FRAME;
END
END
//-----------------------------------------------------------------------------
// Proceso para objeto de ejemplo
//-----------------------------------------------------------------------------
PROCESS bonus(x,y);
PRIVATE
id2=0;
BEGIN
LOOP
FROM graph = 50 to 51; // Ajusta la animacion
id2=collision (TYPE personaje); // Si el personaje lo toca...
IF ( id2 )
municion=5; // le da 5 de municion
signal (id,s_kill); // Se auto-destruye
END
IF (en_suelo) velocidad_gravedad=-10; END //Si toca el suelo, lo hace botar
gravedad (11,11);
FRAME;
END
END
END //Fin de BONUS
//-----------------------------------------------------------------------------
// Proceso para enemigo de ejemplo
//-----------------------------------------------------------------------------
PROCESS enemigo(x,y,x1,x2);
PRIVATE
id2=0;
direccion=-1;
BEGIN
enemigos++; // Acaba de crear un enemigo, suma uno al contador
LOOP
FROM graph = 30 to 31; // Pone la animacion
id2=collision (TYPE personaje); // Si toca al personaje
IF ( id2 )
signal (id2,s_kill); // se lo carga
muerto(id2.x, id2.y,direccion); // y pone un muerto en su lugar
END
//Movimiento
IF (en_suelo) // Solo se mueve si esta en el suelo
IF (direccion==-1 ) x+=2; flags=0; IF (x>x2) direccion=1; END
ELSE x-=2; flags=1; IF (x<x1) direccion=-1; END
END
END
IF (rand(1, 100) > 95) disparo( x - 10 * direccion , y - 10 ,direccion); END // Disparo al azar
// IF (timer<10) disparo( x - 10 * direccion , y - 10 ,direccion); END // Disparo cada segundo
corrige_coordenadas();
gravedad (15,11);
FRAME;
END
END
END //Fin de ENEMIGO
//-----------------------------------------------------------------------------
// Proceso para el disparo de los enemigos
//-----------------------------------------------------------------------------
PROCESS disparo(x,y,direccion);
PRIVATE
id2=0;
BEGIN
graph=32;
IF (direccion>0) incx=-25; ELSE incx=25; END // Ajusta la direccion del proyectil
WHILE (NOT out_region(id,0)) // Mientras este en la pantalla
id2=collision (TYPE personaje); // Si toca al personaje
IF ( id2 )
signal (id2,s_kill); // Se lo carga y
muerto(id2.x, id2.y,direccion); // pone un muerto en su sitio
END
x+=incx; // Avance horizontal
FRAME;
END
END
//-----------------------------------------------------------------------------
// Proceso para continuidad horizontal
//-----------------------------------------------------------------------------
PROCESS corrige_coordenadas()
BEGIN
IF (father.x<1) father.x=father.x+640; END // Si se va a salir por un lado, lo mete por el otro
IF (father.x>639) father.x=father.x-640; END
END
//-----------------------------------------------------
// Proceso para calcular el choque con las paredes
//-----------------------------------------------------
PROCESS paredes(alto);
PRIVATE
c_pared=73; // Posicion en la paleta del color para las paredes
contx,new_incx=0;
BEGIN
IF (father.incx <> 0) // Solo se efectua la comprobacion si se mueve
contx=father.incx/abs(father.incx); // Hallamos la direccion del movimiento 1 o -1
FOR (new_incx=0; new_incx <> father.incx ; new_incx=new_incx + contx) // Recorremos los puntos entre el grafico y la posicion que ocupara
// Si encuentra una pared, ajusta el nuevo incx y sale
// Realiza comprobaciones a distintas alturas del grafico
IF (map_get_pixel (0,999, father.x + new_incx + contx, father.y + alto /2 ) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y + alto /4) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y ) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y - alto /4) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y - alto /2) == c_pared)
father.incx=new_incx; BREAK; END
END
END
END
//-----------------------------------------------------------------------------
// Proceso para la gravedad
//-----------------------------------------------------------------------------
PROCESS gravedad(offset_sup, offset_inf);
PRIVATE
c_suelo=228;
c_techo=40;
gravedad_temp;
BEGIN
father.en_suelo=FALSE;
gravedad_temp=(father.velocidad_gravedad+=2); // Aumenta la gravedad del objeto
IF (gravedad_temp>15) // Y establece un limite de gravedad de 15
father.velocidad_gravedad=15;
gravedad_temp=15;
END
IF (gravedad_temp<0) // Si el objeto sube
WHILE (gravedad_temp++!=0) // Hasta que deje de subir
IF (map_get_pixel(0,999,father.x,(father.y-offset_sup))<>c_techo) // Comprueba que no da con el techo
father.y--; // Lo mueve, o
ELSE father.velocidad_gravedad=0; BREAK; END // lo para y sale
END
ELSE father.y+=gravedad_temp; // Si el objeto baja
FROM gravedad_temp=-15 TO 8; // Establece un rango de comprobacion
IF (map_get_pixel(0,999,father.x,(father.y+gravedad_temp+offset_inf))==c_suelo) // Si toca el suelo
father.en_suelo=TRUE; BREAK; // Pone en_suelo y sale
END
END
IF (gravedad_temp<9) // Ajusta los nuevos valores de y
father.y+=gravedad_temp;
father.velocidad_gravedad=0;
END
END
END
//-----------------------------------------------------
// Fin del listado
//-----------------------------------------------------
Quote from: SplinterGU on February 11, 2012, 04:29:47 AM
a ver... te he cambiado un poco el codigo... ahora salta, pero elimine algunas cosas como transporte y la deteccion de paredes, que no va bien eso... no entre en detalles.
igual insisto que te convendria empezar de cero.
Quote from: Anyeos on February 11, 2012, 06:17:13 AM
Concuerdo con SplinterGU el código tiene demasiadas cosas mezcladas.
Yo lo simplificaría, o sea, lo empezaría por partes, primero probando el personaje solo y luego le iría agregando las demás partes (como la detección del suelo y eso).
Y ahora me acordé que hay un juego de esos de saltar que usaba una variable que seteaba para saber si había tocado piso o no. De esa forma sabía si estaba en el aire o no. Bueno, es una idea. De todos modos tengo un ejemplo del DIV2 de plataformas te lo pego acá por ahí te puede servir para empezar.
Considerá que hay que adaptarlo al nuevo formato de BennuGD porque este es para el DIV Game Studio 2 del DOS. Pero la adaptación no es muy complicada solamente hay que añadir algunas cosas (como los import "mod" y al menos el seteo del video que es diferente).
//-----------------------------------------------------------------------------
//
// ************************************************
// ***** Ejemplo de juego de plataformas *****
// ************************************************
//
// Creado por: Carlos Dominguez
// Para cualquier comentario (que agradeceria)
// E-Mail: carlosd@lettera.skios.es
//
// Proceso 'gravedad (offset_sup,offset_inf)' basada en
// el proceso 'gravedad()' del juego Castle of Dr Malvado de
// Daniel Navarro (espero que no te importe, funciona muy bien)
//
// Agradecimientos a todo el equipo de DIV Games Studio, que hace
// posible a programadores 'no tan buenos' realizar programas GENIALES
// de una forma sencilla.
//
//
// * Instrucciones: Usa las granadas atomicas para acabar con todos los
// tanques de vigilancia enemigos. Si te quedas sin municion te
// enviaremos otra carga desde el avion nodriza. Ten cuidado! Si el
// enemigo detecta que has destruido todas sus tropas, enviara
// refuerzos.
//
//
// Teclas: Arriba - Salto
// Derecha - Derecha
// Izquierda - Izquierda
// Espacio - Disparo
//
// Esc - Salir del juego
//
//-----------------------------------------------------------------------------
PROGRAM Plataformas;
GLOBAL
fuerza_salto=17; // Fuerza con que salta el personaje
municion=0; // Cantidad de municion que le queda al personaje
sin_municion=TRUE; // Indicador para "mandar" mas municion si te quedas sin balas
enemigos=0; // Cantidad de enmigos que hay en la pantalla (se podria usar para cambiar de fase cuando llege a 0
LOCAL
incx=0; // Cantidad que avanza el objeto
velocidad_gravedad=0; // Velocidad a la que esta bajando o subiendo el objeto
en_suelo=FALSE; // Indica si el objeto esta sobre el suelo o en el aire
BEGIN
set_mode(m640x480); // Ajustamos el modo de pantalla
load_fpg ("user\platafor\platafor.fpg"); // Cargamos los graficos
put_screen (0,500); // Pintamos el fondo
write (0,15, 20, 0, "MUNICION:"); // Pintamos los marcadores
write_int (0, 80, 20, 0, &municion);
write (0, 520, 20, 0, "N§ Enemigos:");
write_int (0, 600, 20, 0, &enemigos);
personaje(70,350); // Creamos a nuestro personaje
bonus(590,15); // Creamos un objeto (en este caso municion)
enemigo (160,260,90,230); // Creamos los enemigos
enemigo (110,35,65,150);
enemigo (130,400,100,600);
plataforma (590,230,80,230); // Creamos una plataforma que sube y baja
control(); // Pasamos a la rutina de control general del programa
END
//-----------------------------------------------------------------------------
// Control general del juego
//-----------------------------------------------------------------------------
PROCESS control();
PRIVATE
id_txt; // Identficador para poder borrar el texto que escribimos
BEGIN
timer=0; // Inicia el timer (cronometro)
LOOP // Comienza el bucle
// Comprueba si no hay enemigos. Si no quedan pone un mensaje
IF (enemigos==0) id_txt=write (0,320,240,4,"TE LOS HAS CARGADO A TODOS");
FRAME (10000); // Pausa
delete_text(id_txt); // Borra el texto
enemigo (160,260,90,230); // Pone mas enemigos
enemigo (110,35,65,150);
enemigo (130,400,100,600);
END
// Comprueba que no te quede municion y que no haya ningun objeto de bonus en la pantalla y escribe un mensaje
IF (municion==0 AND NOT get_id(TYPE bonus)) id_txt=write (0,320,240,4,"ATENCION! Municion agotada");
FRAME (10000); // Pausa
delete_text(id_txt); // Borra el texto
bonus (rand(20,620),-40); // Crea un nuevo objeto en una posicion (de x) al azar
END
IF (timer>100) timer=0; END // Inicia el timer cada segundo
IF (key(_esc)) let_me_alone(); BREAK; END // Sale del programa si se pulsa Esc
FRAME; // Pasa el control a los demas procesos
END
END
//-----------------------------------------------------------------------------
// Proceso para el personaje principal
//-----------------------------------------------------------------------------
PROCESS personaje(x,y);
PRIVATE
pri_cuad=1; // Control de la animacion
ult_cuad=1;
disparo=1; // Bloqueo de la tecla de disparo
BEGIN
LOOP
FOR (graph=pri_cuad ; graph<=ult_cuad ; graph=graph+1) // Animacion del personaje
IF (key(_left))
incx=-10; pri_cuad=2; ult_cuad=12; flags=1; // Movimiento a la izquierda
ELSE IF (key(_right)) // Movimiento a la derecha
incx=10; pri_cuad=2; ult_cuad=12; flags=0;
ELSE pri_cuad=1; ult_cuad=1; incx=0; END // Si no se mueve ni hacia la izquierda ni la derecha ponemos la animacion de quieto
END
IF (key(_up) AND en_suelo) velocidad_gravedad=-fuerza_salto; END // Salta si esta sobre el suelo
IF (velocidad_gravedad<>0 OR NOT en_suelo) graph=14; END // Ajusta los graficos segun suba o baje
IF (velocidad_gravedad > 0 AND NOT en_suelo) graph=15; END
IF (key(_space)) // Dispara si tiene municion
IF (disparo)
disparo=0;
IF (municion>0) disparo_yo(x,y,flags); municion--; END
END
ELSE disparo=1; END
corrige_coordenadas(); // Si sale por un lado, entra por el otro
gravedad(16,23); // Fuerza de gravedad y suelos
paredes (42); // Choque con las paredes
x+=incx; // Movimiento horizontal
FRAME;
END
END
END //Fin de PERSONAJE
//-----------------------------------------------------------------------------
// Proceso para la muerte del prota
//-----------------------------------------------------------------------------
PROCESS muerto(x,y,direccion);
BEGIN
graph=96; // Pone el grafico inicial del proceso
velocidad_gravedad=-10; // Lo hace subir un poco
IF (direccion) incx=-10; ELSE incx=10; END // Mueve el grafico segun de donde le venga la bala
FROM angle=0 to 90000 STEP 6000; // Va girando el grafico
IF (angle>40000) graph=97; END // y cambiandolo segun el angulo
IF (angle>60000) graph=98; END
x+=incx; //Lo hace avanzar
IF (incx>0) incx--; ELSE IF (incx<0) incx++; END END // y lo va frenando poco a poco
IF (en_suelo) incx=0; angle=90000; graph=98; END // Si toca el suelo lo pone horizontal de golpe
corrige_coordenadas();
gravedad(11,11);
FRAME;
END
LOOP
x+=incx; // Es lo mismo de antes, por si antes de llegar
IF (incx>0) incx--; ELSE IF (incx<0) incx++; END END // al suelo se puso en posicion horizontal
IF (en_suelo) incx=0; END
corrige_coordenadas();
gravedad(11,11);
IF (en_suelo) FRAME(800); fade_off(); // Cuando llega al suelo hace una pequeña pausa
personaje(70,350); fade_on(); signal (id,s_kill); END // crea un nuevo personaje, y se auto-destruye
FRAME;
END
END
//-----------------------------------------------------------------------------
// Proceso para el disparo del prota
//-----------------------------------------------------------------------------
PROCESS disparo_yo(x,y,direccion);
PRIVATE
id2=0;
BEGIN
velocidad_gravedad=-20; // Lo hace subir
size=50;
IF (direccion>0) incx=-20; ELSE incx=20; END // Ajusta incx segun la direccion del muñeco
WHILE (NOT en_suelo) // Repite hasta llegar al suelo
FROM graph = 52 to 62; // Animacion
x+=incx; // Avanza en la direccion horizontal
IF (incx>0) incx--; ELSE IF (incx<0) incx++; END END // Lo frena poco a poco
corrige_coordenadas();
gravedad (11,11);
paredes(23);
FRAME;
END
END
size=100;
FROM graph = 63 TO 75; // Comienza la explosion
id2=collision (TYPE enemigo); // Mira si toca algun enemigo
IF ( id2 ) // Si lo toca
explosion (id2.x , id2.y, 50); // Crea una explosion
signal (id2,s_kill); // Se carga al enemigo
enemigos--; // Quita un enemigo de la cuenta
END
FRAME;
END
END //Fin de ENEMIGO
//-----------------------------------------------------------------------------
// Proceso plataforma
//-----------------------------------------------------------------------------
PROCESS plataforma(x,y,y1,y2);
PRIVATE
id2=0;
direccion=-1;
BEGIN
graph=99; size=50;
LOOP
//Movimiento
IF (direccion==-1 ) y+=2; IF (y>y2) direccion=1; END // Mueve la plataforma en la direccion indicada por direccion
ELSE y-=2; IF (y<y1) direccion=-1; END // Si llega al limite cambia direccion
END
// Deteccion de colision con personaje
id2=collision (TYPE personaje); // Si colisiona con el personaje
IF ( id2 )
IF (id2.y < y ) // y esta por debajo de el,
id2.y = y - 28; // lo sube un poco
id2.en_suelo=true; // le activa en_suelo
id2.velocidad_gravedad=0; // y le quita la gravedad
END
END
// Deteccion de colision con disparos personaje
id2=collision (TYPE disparo_yo); // Igual que en personaje
IF ( id2 )
IF (id2.y < y )
id2.y = y - 10;
id2.en_suelo=true;
id2.velocidad_gravedad=0;
END
END
// Deteccion de colision con objeto
id2=collision (TYPE bonus); // Igual que en personaje
IF ( id2 )
IF (id2.y < y )
id2.y = y - 20;
id2.en_suelo=true;
id2.velocidad_gravedad=0;
END
END
FRAME;
END
END //Fin de PLATAFORMA
//-----------------------------------------------------------------------------
// Proceso que crea una explosion
//-----------------------------------------------------------------------------
PROCESS explosion(x,y,size);
BEGIN
FROM graph = 76 TO 95; // Ajusta la animacion
y-=5; // La hace subir un poco
FRAME;
END
END
//-----------------------------------------------------------------------------
// Proceso para objeto de ejemplo
//-----------------------------------------------------------------------------
PROCESS bonus(x,y);
PRIVATE
id2=0;
BEGIN
LOOP
FROM graph = 50 to 51; // Ajusta la animacion
id2=collision (TYPE personaje); // Si el personaje lo toca...
IF ( id2 )
municion=5; // le da 5 de municion
signal (id,s_kill); // Se auto-destruye
END
IF (en_suelo) velocidad_gravedad=-10; END //Si toca el suelo, lo hace botar
gravedad (11,11);
FRAME;
END
END
END //Fin de BONUS
//-----------------------------------------------------------------------------
// Proceso para enemigo de ejemplo
//-----------------------------------------------------------------------------
PROCESS enemigo(x,y,x1,x2);
PRIVATE
id2=0;
direccion=-1;
BEGIN
enemigos++; // Acaba de crear un enemigo, suma uno al contador
LOOP
FROM graph = 30 to 31; // Pone la animacion
id2=collision (TYPE personaje); // Si toca al personaje
IF ( id2 )
signal (id2,s_kill); // se lo carga
muerto(id2.x, id2.y,direccion); // y pone un muerto en su lugar
END
//Movimiento
IF (en_suelo) // Solo se mueve si esta en el suelo
IF (direccion==-1 ) x+=2; flags=0; IF (x>x2) direccion=1; END
ELSE x-=2; flags=1; IF (x<x1) direccion=-1; END
END
END
IF (rand(1, 100) > 95) disparo( x - 10 * direccion , y - 10 ,direccion); END // Disparo al azar
// IF (timer<10) disparo( x - 10 * direccion , y - 10 ,direccion); END // Disparo cada segundo
corrige_coordenadas();
gravedad (15,11);
FRAME;
END
END
END //Fin de ENEMIGO
//-----------------------------------------------------------------------------
// Proceso para el disparo de los enemigos
//-----------------------------------------------------------------------------
PROCESS disparo(x,y,direccion);
PRIVATE
id2=0;
BEGIN
graph=32;
IF (direccion>0) incx=-25; ELSE incx=25; END // Ajusta la direccion del proyectil
WHILE (NOT out_region(id,0)) // Mientras este en la pantalla
id2=collision (TYPE personaje); // Si toca al personaje
IF ( id2 )
signal (id2,s_kill); // Se lo carga y
muerto(id2.x, id2.y,direccion); // pone un muerto en su sitio
END
x+=incx; // Avance horizontal
FRAME;
END
END
//-----------------------------------------------------------------------------
// Proceso para continuidad horizontal
//-----------------------------------------------------------------------------
PROCESS corrige_coordenadas()
BEGIN
IF (father.x<1) father.x=father.x+640; END // Si se va a salir por un lado, lo mete por el otro
IF (father.x>639) father.x=father.x-640; END
END
//-----------------------------------------------------
// Proceso para calcular el choque con las paredes
//-----------------------------------------------------
PROCESS paredes(alto);
PRIVATE
c_pared=73; // Posicion en la paleta del color para las paredes
contx,new_incx=0;
BEGIN
IF (father.incx <> 0) // Solo se efectua la comprobacion si se mueve
contx=father.incx/abs(father.incx); // Hallamos la direccion del movimiento 1 o -1
FOR (new_incx=0; new_incx <> father.incx ; new_incx=new_incx + contx) // Recorremos los puntos entre el grafico y la posicion que ocupara
// Si encuentra una pared, ajusta el nuevo incx y sale
// Realiza comprobaciones a distintas alturas del grafico
IF (map_get_pixel (0,999, father.x + new_incx + contx, father.y + alto /2 ) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y + alto /4) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y ) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y - alto /4) == c_pared
OR map_get_pixel (0,999, father.x + new_incx + contx, father.y - alto /2) == c_pared)
father.incx=new_incx; BREAK; END
END
END
END
//-----------------------------------------------------------------------------
// Proceso para la gravedad
//-----------------------------------------------------------------------------
PROCESS gravedad(offset_sup, offset_inf);
PRIVATE
c_suelo=228;
c_techo=40;
gravedad_temp;
BEGIN
father.en_suelo=FALSE;
gravedad_temp=(father.velocidad_gravedad+=2); // Aumenta la gravedad del objeto
IF (gravedad_temp>15) // Y establece un limite de gravedad de 15
father.velocidad_gravedad=15;
gravedad_temp=15;
END
IF (gravedad_temp<0) // Si el objeto sube
WHILE (gravedad_temp++!=0) // Hasta que deje de subir
IF (map_get_pixel(0,999,father.x,(father.y-offset_sup))<>c_techo) // Comprueba que no da con el techo
father.y--; // Lo mueve, o
ELSE father.velocidad_gravedad=0; BREAK; END // lo para y sale
END
ELSE father.y+=gravedad_temp; // Si el objeto baja
FROM gravedad_temp=-15 TO 8; // Establece un rango de comprobacion
IF (map_get_pixel(0,999,father.x,(father.y+gravedad_temp+offset_inf))==c_suelo) // Si toca el suelo
father.en_suelo=TRUE; BREAK; // Pone en_suelo y sale
END
END
IF (gravedad_temp<9) // Ajusta los nuevos valores de y
father.y+=gravedad_temp;
father.velocidad_gravedad=0;
END
END
END
//-----------------------------------------------------
// Fin del listado
//-----------------------------------------------------
MUCHÍSIMAS gracias chicos. Karma++ para ambos. Sé que tenéis muchísima razón, el código estaba muy enrevesado y me estaba perdiendo, lo empezaré desde cero con lo que me has pasado Splin e iré mirando el código que me paso Anyeos para tener mayor comprensión de cómo realizar los movimientos, tanto para andar como para saltar. Porque realmente sabía que algo estaba haciendo mal y por ello el propio personaje me iba a zancadas, las durezas no me asustan porque es lo que mejor sé hacer, el personaje es lo que me va a costar prácticar pero me pondré a ello en seguida, tengo muchísimo interés para poder seguir avanzando.
Por cierto, gracias Anyeos, te agradezco que me quieras echar una mano y, si no te importa, sí me gustaría que medijeras cómo puedo mejorar el juego en general, ya que comprendo que Splin está liado con muchas cosas y no puede estar en todo lo que los novatos tenemos encima, ya hace demasiado :)
Bueno, leyendo un poco el tema, no he visto tu juego pero si he visto que teneis algunos problemillas con los FPG,
y ya que yo este tema lo sobrellevo muy bien :) voi a darte un pequeño truco.
Usa FPG, siempre que quieras hacer animaciones con cualquier personaje, ya que te lo organizaras mejor y para calcular
e implementar los graficos por secuencia yo uso esto... :
Es un codigo echo ( por mi ) que te copias y ya esta, tu simplemente usa las directrices que te doi, y si tienes tiempo, intenta
averiguar como funciona :)
private
int graphini; //Cualidad: Primer grafico a reproducir
int graphfin; //Cualidad: Ultimo grafico de reproduccion - Posteriormente se repiten
int grafico_velocidad; //Lo necesita el sistema para funcionar
int velocidad_grafico; //Cualidad: Velocidad a la que se moveran los graficos
int grafico_tope = 0; //Cualidad: Grafico donde separara el tiempo seleccionado
int tiempo_grafico_tope; //Lo necesita el sistema para funcionar
int tiempo_parada_grafico = 30; //Cualidad: Tiempo que se para en el grafico seleccionado
int graphini_repeticion = 0; //Cualidad: Primero de los graficos a repetir
int graphfin_repeticion = 0; //Cualidad: Final de los graficos a repetir
int veces_repeticion; //Cualidad: Tiempo que va a estar repitiendose la cualidad
int tiempo_repeticion; //Lo necesita el sistema para funcionar
loop
//Gestiona las animaciones ( Siempre al final para poder ser procesado )
if ( graph < graphini_repeticion or graph > graphfin_repeticion )
if ( graph != grafico_tope ) grafico_velocidad ++; end
if ( grafico_velocidad > velocidad_grafico ) graph++; grafico_velocidad = 0; end
if ( graph == grafico_tope ) tiempo_grafico_tope ++; end
if ( tiempo_grafico_tope > tiempo_parada_grafico )
grafico_tope = 0; tiempo_grafico_tope = 0; tiempo_parada_grafico = 0; graph++; end
if (graph<graphini or graph>graphfin) graph=graphini; end
elseif ( graph > graphini_repeticion or graph < graphfin_repeticion )
grafico_velocidad ++;
if ( grafico_velocidad > velocidad_grafico ) graph++; grafico_velocidad = 0; end
if (graph<graphini_repeticion or graph>graphfin_repeticion) graph=graphini_repeticion; end
tiempo_repeticion ++;
if ( tiempo_repeticion > veces_repeticion) tiempo_repeticion = 0; graph = graphfin_repeticion + 1; end
end
Ejemplo:
if ( estado == defensa )
velocidad_grafico = 3;
graphini = 39;
graphfin = 40;
graphini_repeticion = 0;
graphfin_repeticion = 0;
veces_repeticion = 0;
grafico_tope = 40;
tiempo_parada_grafico = 10;
end
Espero que te valga, y segun lo que he leido, haberte ayudado en algo. Un saludo.
Gracias, lo probaré para ver qué tal va... Siento que no te haya respondido antes, estoy metido en un proyecto que acabo de empezar ahora y estoy preparando la historia, las fases y, por último, haré la codificación, que eso para mí, suele ser lo sencillo. En cuanto vaya a por el código, miraré de qué manera va más ligero el personaje y te comentaré :)
karma++