A mi el juego va bien, pero veo que tiene un consume de CPU del
25-32%, por empezar puedes optimizar lo siguiente:
1 - crear 2 variables globales
ID_PERSONAJE y
PERSONAJE_ANDANDO que sirviran para el proceso nieve, la primera fase es asignar a la variable ID el codigo identificativo del personaje:
- Code: Select all
ID_PERSONAJE = PERSONAJE();
El paso seguiente es modificar el proceso personaje para poner el estado de la variable andando:
- Code: Select all
IF(KEY(_LEFT)OR (GET_JOY_POSITION(0)<-300))
FLAGS=1;
PERSONAJE_ANDANDO = TRUE;
ELSE
PERSONAJE_ANDANDO = FALSE;
END
IF(KEY(_RIGHT)OR (GET_JOY_POSITION(0)>300))
FLAGS=0;
PERSONAJE_ANDANDO = TRUE;
ELSE
PERSONAJE_ANDANDO = FALSE;
END
Lo de asignar el codigo ID y la variable andando esta todo en el proceso
COPO_NIEVE que es lo seguiente:
- Code: Select all
IF((COLLISION(TYPE PERSONAJE)));ELSE X+=RAND(-3,3);X-=2;Y++;END
Tal como esta esa linea, consuma bastante de rendimiento, el motivo es simple...
En primer lugar
COLLISION por su nadura es una funcion lenta y llamarla con la forma
TYPE process lo es aun mas, porque tiene que rastrear toda la lista de procesos, averiguar si es del tipo pasado como parametro y comprobar la colision, en este caso hay ya 1000 procesos nieve, el prota y algo mas, eso porta a rastrear cada vez mas de 1000 procesos y como se puede entender la performance queda menos...
Entonces pasandole el ID directo evita de rastrear la lista y comprueba directamente la colision porque el prota es siempre 1, eso ya gana muchisimo de rendimiento en tu caso, visto la gran cantidad de los procesos en el juego.
En segun lugar tal como quieres programar el juego, la nieve tiene que pararse por encima del personaje SOLO cuando este ultimo esta parado, entonces no tiene sentido que a cada iteracion se haga una llamada a COLLISION para averiguar eso (por ejemplo cuando el personaje esta en movimiento), entonces el codigo anterior puede ser reescrito asi:
- Code: Select all
IF(PERSONAJE_ANDANDO)
X+=RAND(-3,3);X-=2;
Y++;
ELSEIF(!COLLISION(ID_PERSONAJE))
X+=RAND(-3,3);X-=2;
Y++;
END
2 - otra optimizacion por hacer es a nivel de restauro interno del motor del juego, es decir, sabemos que el juego tiene un scroll a pantalla completa en el cual se pintan encima de ello todos los otros graficos del juego...
Por default Gemix utiliza el sistema
RESTORE_TYPE = COMPLETE_RESTORE eso significa que a cada frame el motor interno limpia el buffer de pantalla y luego repinta todos los graficos para le nuevo frame, (si estuviese en NO_RESTORE, se podria ver como los graficos dejan rastros del frame anterior), entonces al tener un scroll a pantalla completa y todos los graficos que se ponen encima, no tiene sentido que el sistema limpie el buffer a cada frame, le digamos de ahorrar esa operacion, ganando otro rendimiento:
- Code: Select all
RESTORE_TYPE = NO_RESTORE;
START_SCROLL(0,GRAFICOS,32,31,0,0);
Hay pero que tener cuidado, porque cuando el nivel acaba y se deja el sistema de scroll, hay que reponer el sistema al estado anterior (COMPLETE_RESTORE) para no tener problemas de rastros, para el funcionamento de RESTORE_TYPE mira la DOC de DIV2.
3 - bajar los FPS de 60 a 40 (que sobran)
Con esas optimizaciones ya el consume de CPU en mi maquina ha bajado al
15-18% , todavia hay otros puntos que hay que verificar bien en la proyectacion del juego:
1- el codigo del proceso PERSONAJE:
- Code: Select all
IF((MAP_GET_PIXEL(GRAFICOS,34,X,Y)==15539236))TOCOSUELO=TRUE;ELSE TOCOSUELO=FALSE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-1)==15539236))Y-=0;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-2)==15539236))Y-=1;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-3)==15539236))Y-=2;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-4)==15539236))Y-=3;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-5)==15539236))Y-=4;TOCOSUELO=TRUE;END // COMPRUEVO LA COLISION CON EL SUELO TENIENDO EN CUENTA LA GRAVEDAD.
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-6)==15539236))Y-=5;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-7)==15539236))Y-=6;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-8)==15539236))Y-=7;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-9)==15539236))Y-=8;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-10)==15539236))Y-=9;TOCOSUELO=TRUE;END //
IF(TOCOSUELO==FALSE && (MAP_GET_PIXEL(GRAFICOS,34,X,Y-11)==15539236))Y-=10;TOCOSUELO=TRUE;END //
IF((MAP_GET_PIXEL(GRAFICOS,34,X+60,Y-10)==7287192))TOCOPARED_DERECHA=TRUE;ELSE TOCOPARED_DERECHA=FALSE;END
IF((MAP_GET_PIXEL(GRAFICOS,34,X-60,Y-10)==7287192))TOCOPARED_IZQUIERDA=TRUE;ELSE TOCOPARED_IZQUIERDA=FALSE;END
se puede optimizar mas ?, la respuesta es SI, porque llamar a cada iteracion 13 veces MAP_GET_PIXEL con datos casi iguales entre ellos no es optimal...
2 - el juego necesita una resolucion de 800x600 ? si la respuesta es si, hay que tener una buena razon, porque con 640x480 podria sobrar.
3 - la grafica del juego impone el utilizo de 32bits ? o puede sobrar con 16bits (es suficiente mirar juegos como
survivor o
boxland de BigHead, para averiguar que el efecto grafico es mas que suficiente en esos casos.
Intenta verificare de nuevo el motor del juego para optimizarlo mejor posible y no dudes en preguntar si hay problemas, intentaremos ayudar siempre con la experiencia que tenemos acumulada luego años y años de programacion
