Si te sirve de ayuda te comento la estructura que sigo yo para generar los escenarios:
El motor se compone de varias partes clave.
- PUT_LEVEL. <_< PAK_FILE.
-EVENT_MANAGER.
-EVENTS.
- PERSONAJE.
- MASCARA_PERSONAJE.
PUT_LEVEL:
* Cada vez que hay que generar un escenario, pasamos por este proceso, lo primero que mira es si existe valor de PAK_FILE, si PAK_FILE<>0, osea, si pak_file vale algo, si lo vale es que se ha utilizado PAK_FILE como identificador para un FPG del decorado, pues lo descarga:
if(pak_file<>0)unload_fpg(pak_file); es bastante básico.
Ahora, dependiendo del valor de la variable "ESCENARIO", si vale 0 carga el FPG del escenario 0, si vale 1 carga el del 1....
También, dependiendo de la variable "ESCENARIO" carga y reproduce una música concreta.
EVENT_MANAGER:
* Hace comprobaciones de este tipo: IF( EVENTO==FALSE && OVERLAP(ID_PERSO, TYPE PLANTA_MACETA) && key(_SPACE))LAUNCH_EVENT(-1);END // TOCO UNA MACETA
Con las nuevas potentes features de Gemix, es posible comprobar colisiones desde un tercero, asi puedes gestionar todo el contenido del nivle desde un EVENT_MANAGER, si te has vijado, para evitar errores de ejecución entre eventos, SIEMPRE, antes de lanzar un evento se comprueba que la variable "EVENTO" esté a false, así es imposible que entren en juego 2 eventos a la vez aunque estén solapados.
También hago comprobaciones que lanzan eventos o no dependiendo del estado del juego, en mi caso, utilizo la variable "GAME_DATA.ESTADO_PARTIDA", es in INT y pertenece a una pequeña estructura de variables llamada "GAME_DATA" la cual grabo en un file para guardar el estado de la partida, un ejemplo seria así:
IF(EVENTO==FALSE && GAME_DATA.ESTADO_PARTIDA==6 && GAME_DATA.ESCENARIO==1)LAUNCH_EVENT(20);END
Esto por ejemplo, comprueba que no hay eventos activos, que el estado del juego vale "6" y que estamos en el escenario "1", osea, el segundo escenario, entonces lanza un evento de presentación del escenario, un pequeño text_box con algo como "heyy estas en el escenario 1 ten cuidado!" y el propio evento incrementa en 1 a GAME_DATA.ESTADO_PARTIDA para bloquear este evento de nuevo, y así no aparece mas.
EVENTS:
*Un proceso que, al ejecutarse "CONGELA" al juego y al personaje y pone algo en pantalla como por ejemplo:
- Code: Select all
IF(CODE==2)
FACE_TEXT_BOX("BENSON"); // LLAMO A LA CARA
WHILE(SIZE_X<100)SIZE_X+=5;FRAME;END // ANIMACION DE LA VENTANITA
WHILE(SIZE_Y<100)SIZE_Y+=4;FRAME;END // ANIMACION DE LA VENTANITA
TEXT_BOX(0,TSR[6].LINE_0,X-150,Y-25);
WHILE(WRITING_TEXT==TRUE)FRAME;END
CURSOR_TEXT_BOX(X,Y);
END
La linea TEXT_BOX(0,TSR[6].LINE_0,X-150,Y-25); es porque uso una base de datos para contener todos los textos del juego, pero con un simple "hola pepito" es lo mismo. ej:
TEXT_BOX(0,"Hola pepito",X,Y);
Text_box es un proceso que escrive texto en pantalla LETTER-TO-LETTER con o sin sonido etc etc.. si quieres hecharle un ojo está en la sección recursos. es muy sencillito pero efectivo.
Y cursor text_box es un proceso simple que muestra un cursor parpadeando.
El "CODE" del proceso "EVENT" es simplemente para poder meter en un mismo proceso varios eventos, un ejemplo de este proceso es así:
- Code: Select all
PROCESS EVENT_TEXT_BOX(CODE); // DEPENDIENDO DEL CODIGO SALE UNA CONVERSACION U OTRA.
PRIVATE
STRING T1;
BEGIN
REGION=0;CTYPE=C_SCREEN;
FILE=F_MAIN;GRAPH=35;
SIZE_X=0;SIZE_Y=2;
X=160;Y=168;
FRAME;
SIGNAL(TYPE GAME, S_FREEZE_TREE); // DUERMO AL JUEGO
sound(s_select);
IF(CODE==2)
FACE_TEXT_BOX("BENSON"); // LLAMO A LA CARA
WHILE(SIZE_X<100)SIZE_X+=5;FRAME;END // ANIMACION DE LA VENTANITA
WHILE(SIZE_Y<100)SIZE_Y+=4;FRAME;END // ANIMACION DE LA VENTANITA
TEXT_BOX(0,TSR[6].LINE_0,X-150,Y-25);
WHILE(WRITING_TEXT==TRUE)FRAME;END
CURSOR_TEXT_BOX(X,Y);
END
IF(CODE==3)
FACE_TEXT_BOX("BENSON"); // LLAMO A LA CARA
WHILE(SIZE_X<100)SIZE_X+=5;FRAME;END // ANIMACION DE LA VENTANITA
WHILE(SIZE_Y<100)SIZE_Y+=4;FRAME;END // ANIMACION DE LA VENTANITA
TEXT_BOX(2,TSR[6].LINE_1,X-150,Y-25);
WHILE(WRITING_TEXT==TRUE)FRAME;END
TEXT_BOX(0,TSR[6].LINE_2,X-150,Y-15);
WHILE(WRITING_TEXT==TRUE)FRAME;END
CURSOR_TEXT_BOX(X,Y);
END
// AQUI ES DONDE DETECTO SI PULSO ESPACIO PARA CERRAR EL DIALOGO
WHILE(KEY(_SPACE))FRAME;END // SI ESTOY PULSANDO ESPACIO ESPERO..
LOOP
IF(KEY(_SPACE))BREAK;END // HASTA QUE NO PULSO ESPACIO ESPERO..
FRAME;
END
sound(s_aceptar);
DELETE_TEXT_INTRO=TRUE; // PASO PANTALLA, el process TEXT_BOX cuando esta variable vale "TRUE" borra el texto.
FRAME;
DELETE_TEXT_INTRO=FALSE;
SIGNAL(TYPE CURSOR_TEXT_BOX, S_KILL); // MATO AL CURSOR.
WHILE(SIZE_Y>1)SIZE_Y-=5;FRAME;END // animacion cerrar ventanita..
WHILE(SIZE_X>1)SIZE_X-=5;FRAME;END
SIGNAL(TYPE GAME, S_WAKEUP_TREE); // DESPIERTO AL JUEGO
EVENTO=FALSE; // PERMITO NUEVOS EVENTOS.
END
PERSONAJE:
*Es el proceso real que controla las colisiones, un simple cuadrado que hace sus coordenadas "PUBLICAS" para que las pueda recojer el proceso:
MASCARA_PERSONAJE:
* Es lo que se ve en pantalla, con sus animaciones y tal.. las coordenadas de este proceso son recogidas de las variables globales X_PERSO e Y_PERSO, que son asignadas en el proceso PERSONAJE(); a cada frame.
Como ves, está todo extremadamente modularizado, para que sea posible la futura implementación de nuevos tipos de eventos o de cualquier otra cosa, veo que tu programa da muchisima importancia a la modularidad de los procesos, eso me ha gustado mucho.
Espero que esto te haya dado alguna idea de como hacer algo si tenias alguna duda, y si no, pues nada, dale duro que hay ganas de ver este GAME MAKER para GEMIX!!