Página 2 de 4

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 19 Ene 2014, 19:16
por elborra
$this->bbcode_second_pass_quote('na_th_an', 'E')n realidad la solución óptima para los tiles empujables es que fueran "otra capa" diferente a la del mapa, de forma que tuviésemos información sobre "qué hay debajo". El problema es el de siempre: a ver donde metemos tanta información :)

De necesitarlo (porque algún puzzle que estoy pensando conlleva usar más de un tile empujable y que el "fondo" no se pierda) voy a intentar hacer una pseudo capa que consistira en definir una estructura para cajas de tamaño finito (5 o 6) que guarde tilex, tiley y tile. y gestionar los movimientos.

A bote pronto se me ocurre que al mover el bloque primero se recorra la estructura en busca de un tilex y tiley que coincidan, si existe sacamos el valor de tile, seguidamente modificamos los valores de tilex,tiley,y tile con la nueva posición, y por último pintamos. En caso de no existir las coordenadas tilex,tiley meteriamos la información como nueva en el primer "registro" de la estructura libre.

Perdón por la terminología.. pero como no controlo c (y de asm ni hablamos) hago lo que puedo :P

Haré pruebas y ya comentaré si es que na_th_an no me dice que hay mejor forma de hacer esto aunque como ya me dijiste lo suyo es hacer la prueba e ir viendo que ocupa el binario, por velocidad no creo que sea un gran cambio, ya veremos en espacio... Por cierto, para hacerme una idea de espacio en memoria y todo el percal: Si hago un cambio para una funcionalidad mínima como esta de cuantos bytes estariamos hablando que es un buen código entendiendo por buen código que dicho cambio no suponga una merma de espacio significativo (y ya se que depende de todo lo que rodea motor, mapeado, tileset, scripting, extern.h, etc... Si vamos por la calle del "si cabe, cabe" pues no pasa nada, pero dentro de mis posibilidades me gustaría mantener cierto nivel y reducir al máximo el juego en tamaño: si puede ocupar 36KB que ocupe eso y no 40KB por poner)

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 19 Ene 2014, 20:44
por na_th_an
Yo a veces hago cambios aunque sólo sea para ahorrar 3 bytes. Por ejemplo, poner "(c == 0)" en un if ocupa 3 bytes menos que poner "(!c)" aunque los dos hagan lo mismo :lol:

La forma óptima de guardar objetos empujables que no formen parte del mapa es teniendo una lista global con dos bytes por entrada: n_pant y xy. En el primer byte metes la pantalla donde existe el objeto empujable, y en el segundo byte codificas x e y. Como ninguno sobrepasará el valor 15, te caben ambos en un byte guardando (x << 4) + y. Luego es fácil sacarlos:

$this->bbcode_second_pass_code('', 'x = xy >> 4;
y = xy & 15;')

Luego necesitas hacerte una estructura con sitio para el máximo número de objetos empujables que pueda llegar a haber en una pantalla. Aquí, por velocidad, separamos x e y:

$this->bbcode_second_pass_code('', '#define MAX_PUSHABLE 4
typedef struct {
unsigned char x, y;
} PUSHABLE;
PUSHABLE pushables [MAX_PUSHABLE];')

Cada vez que entres en una pantalla (puedes ponerlo al final de draw_scr) lo suyo es recorrer tu estructura general e ir rellenando el array pushables con los que encuentres que están en la pantalla actual.

Luego, en el motor del juego, es fácil detectarlos ya que tenemos un buffer de comportamientos (map_buff). Con rellenarlo con un "10" en las posiciones donde estén los pushables e ir actualizándolo con los movimientos.

Tiene su miga, pero en principio no debería ser complicado de hacer.

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 19 Ene 2014, 21:55
por elborra
Como siempre mucho más elegante, por llamarlo de alguna manera :oops:

Aunque de esta manera no se como puedo identificar que bloque estoy empujando además tendremos que guardar el tile sobre el que se mueve para poder reponerlo a posteriori (añadir a la estructura un ntile). Por último respecto a usar el buffer de comprotamientos yo pensaba usar directamente:
#define MOVED_TILE_FLAG 21 // Current tile "overwritten" with block is stored here.
#define MOVED_X_FLAG 22 // X after pushing is stored here.
#define MOVED_Y_FLAG 23 // Y after pushing is stored here.
Y programar en un EXTERN el read/write de pushables (siguiendo tu nomenclatura)

Re: Proyecto juego Churrera. Dudas

Publicado: Lun, 20 Ene 2014, 07:44
por na_th_an
A lo mejor me dejo algo, pero creo que no deberías tener problemas:

a) En draw_scr, se rellenan dos estructuras: map_buff y map_attr. La primera trae los 150 tiles que se ven en la pantalla, y la segunda sus atributos (comportamientos).
b) Como ahora los bloques que se empujan van "aparte", ni en map_buff ni en map_attr, en un principio, habrá nada sobre ellos. En draw_scr, al final, y cuando rellenamos el array de bloques empujables de la pantalla actual, aprovechamos para poner a "10" las casillas de map_attr correspondientes a los bloques empujables, además de dibujar el tile que le corresponde en pantallla. Nota que map_buff no lo tocamos: necesitamos que tenga una copia prístina de los tiles de la pantalla.
c) En el motor, se detecta si estamos empujando un tile cuyo comportamiento es 10, y si es así, se salta a la función process_tile, que recibe la posición donde está el bloque afectado (x0, y0) y adonde debería moverse, de ser posible (x1, y1). Esta es la función que tendrías que cambiar:

1.- Buscar qué bloque, en tu array de los bloques empujables de la pantalla, corresponde con las coordenadas (x0, y0). Esta búsqueda no debería ser muy costosa porque estamos limitando el máximo de móviles en pantalla a unos cuantos.
2.- Si lo encuentras, hay que ver que el comportamiento en (x1, y1) sea cero (attr (x1, y1) == 0) y que x1 e y1 no caigan fuera de pantalla. Si es así:
2.1.- Ponemos el comportamiento de (x0, y0) a 0 (map_attr).
2.2.- Ponemos el comportamiento de (x1, y1) a 1 (map_attr).
2.3.- Pintamos en (x0, y0) el tile que haya en map_buff (llamando a la función q_tile (x0, y0) lo tienes).
2.4.- Pintamos en (x1, y1) el tile correspondiente al bloque empujable.
2.5.- Actualizas x e y del bloque empujable en el array pushables con los valores x1, y1.

Para ahorrar código, deberías inicializar y = 99 en el array pushables (un valor fuera de rango).

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 26 Ene 2014, 18:36
por elborra
Bueno, he estado entretenido haciendo los cambios necesarios para que cuando se mueva un bloque empujable este no borre el "fondo"

He partido de la Churrera 3.99.3b para ello. El método es básicamente lo que na_th_an propuso pero enfocado de otra manera para generalizar el método sin realizar cambios profundos en el motor y hacerlo compatible con juegos anteriores con sólo unos añadidos.

No se si será la mejor forma, y hay varias cosas que se pueden implementar mejor, pero aquí van:

**Recomiendo encarecidamente que hagais copia de vuestro directorio de juego antes de empezar con los cambios**

1. Los tiles empujables tendrán que añadirse desde scripting. Esto lo he hecho así porque si se hace directamente desde el mapa el "suelo/fondo" cuando se carga la pantalla sería desconocido (¿que tile hay bajo el bloque empujable? ¿suelo? ¿una alfombra?). Así pues todo el "suelo/fondo" será conocido (pintado con Mappy/Tiled..) y posteriormente al entrar en una habitación colocariamos los tiles. Esto nos da además la elección de pintarlos o no dependiendo del resto de condiciones del script si así quisieramos. Ejemplo:$this->bbcode_second_pass_code('', 'ENTERING SCREEN 0
IF TRUE
THEN
SET TILE (3,6) = 14
SET TILE (3,4) = 14
END
END')

2. Modificar config.h . Definimos una nueva constante MAX_PUSHABLE que representa el número máximo de bloques + 1 gestionables por pantalla. Puedes cambiar el valor, pero no os paseis. Aparte añado aquí (no creo que sea el mejor sitio para ponerla, quizás sería mejor en definitions.h, pero bueno, yo lo dejo ahí) la estructura PUSHABLES y una variable pushables que no es más que un array de dicha estructura del tamaño de MAX_PUSHABLE. Añadir:$this->bbcode_second_pass_code('', '#define MAX_PUSHABLE 4 // donde 4 es el número máximo de bloques empujables por pantalla + 1
typedef struct {
unsigned char x, y, t;
} PUSHABLE;
PUSHABLE pushables [MAX_PUSHABLE];
unsigned char push_ord = 0;')

3. Copiar msc.exe modificado a \script\ . Para poder usar esta característica se tendra que hacer uso de la utilidad msc.exe modificada para ello donde se ha modificado el código del funcionamiento de SET TILE (desde tu churromain.spt). Si detecta que se trata de un tile empujable este se gestiona como de costumbre (actualizando tanto map_buff como map_attr) pero además guarda en la variable pushables los datos del tile sobre el que se pinta (tile, x, y). Un indice cutre push_ord se va incrementando segun se añaden los tiles empujables desde scripting. *Nota: por no añadir lineas innecesarias hay que tener en cuenta que si tu juego no va a usar tiles empujables no uses este msc.exe ya que tu tile 14 no se pintará.


4. Modificar engine.h . Para gestionar los tiles empujables se ha modificado la función process_tile de manera que si se ha definido MAX_PUSHABLE en lugar de mover el bloque y pintar el tile 0 se recorre la estructura pushables buscando una equivlencia de x0 e y0 con la posición inicial del bloque empujable (iniciada con SET TILE automáticamente), se modifica map_buff y map_attr de x0 e y0 con los valores de pushables (lo que había antes) y se pinta el "fondo/suelo", se actualiza pushables con los valores de x1 e y1. pintar el bloque empujable en su nueva posicion x1 e y1 se hará con normalidad. Los cambios en la linea 552$this->bbcode_second_pass_code('', '
if (qtile (x0, y0) == 14 && attr (x1, y1) == 0 && x1 >= 0 && x1 < 15 && y1 >= 0 && y1 < 10) {
#if defined(ACTIVATE_SCRIPTING) && defined(ENABLE_PUSHED_SCRIPTING)
flags [MOVED_TILE_FLAG] = map_buff [15 * y1 + x1];
flags [MOVED_X_FLAG] = x1;
flags [MOVED_Y_FLAG] = y1;
#endif
// Mover
map_attr [15 * y1 + x1] = 10;
map_buff [15 * y1 + x1] = 14;
map_attr [15 * y0 + x0] = 0;
map_buff [15 * y0 + x0] = 0;
// Pintar
draw_coloured_tile (VIEWPORT_X + x0 + x0, VIEWPORT_Y + y0 + y0, 0);
draw_coloured_tile (VIEWPORT_X + x1 + x1, VIEWPORT_Y + y1 + y1, 14);
// Sonido')cambiar por$this->bbcode_second_pass_code('', '
if (qtile (x0, y0) == 14 && attr (x1, y1) == 0 && x1 >= 0 && x1 < 15 && y1 >= 0 && y1 < 10) {
#if defined(ACTIVATE_SCRIPTING) && defined(ENABLE_PUSHED_SCRIPTING)
flags [MOVED_TILE_FLAG] = map_buff [15 * y1 + x1];
flags [MOVED_X_FLAG] = x1;
flags [MOVED_Y_FLAG] = y1;
#endif
map_attr [15 * y1 + x1] = 10;
map_attr [15 * y0 + x0] = 0;
#ifdef MAX_PUSHABLE
// Comprobamos que bloque es
for (gpt=0; gpt<MAX_PUSHABLE; gpt++) {
if (pushables[gpt].x==x0 && pushables[gpt].y==y0) break;
}
map_buff [15 * y0 + x0] = pushables[gpt].t;
draw_coloured_tile (VIEWPORT_X + x0 + x0, VIEWPORT_Y + y0 + y0, pushables[gpt].t);
pushables[gpt].x = x1;
pushables[gpt].y = y1;
pushables[gpt].t = map_buff [15 * y1 + x1];
#else
map_buff [15 * y0 + x0] = 0;
draw_coloured_tile (VIEWPORT_X + x0 + x0, VIEWPORT_Y + y0 + y0, 0);
#endif
map_buff [15 * y1 + x1] = 14;
draw_coloured_tile (VIEWPORT_X + x1 + x1, VIEWPORT_Y + y1 + y1, 14);

// Sonido')
5. Modificar engine.h . "Gracias" a push_ord tenemos que reiniciar dicha variable a 0 cuando cambiemos de pantalla. Para ello al final de draw_scr justo bajo el #endif de la línea 1477$this->bbcode_second_pass_code('', '#ifdef PLAYER_CAN_FIRE
init_bullets ();
#endif')añadir $this->bbcode_second_pass_code('', '#ifdef MAX_PUSHABLE
push_ord=0;
#endif')

Creo que no me dejo nada :roll: A continuación dejo el paquete con msc.exe + código fuente y engine.h (basado en la Churrera 3.99.3b) donde sólo se reflejan los cambios mencionados respecto a la versión origina del fichero. Si ya has hecho modificaciones en tu engine.h sigue los pasos explicados arriba (aunque estaran en otra linea) para no perder los cambios. Si veis algún error o cualquier cosa comentar por aquí.

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 26 Ene 2014, 19:09
por na_th_an
Oye, pues mola un huevo :D Lo estudiaré concienzudamente.

Deberíamos colocar esto en un sitio más visible. Tenemos este hilo -> viewtopic.php?f=12&t=1269 de modificaciones a la churrera. ¿Podrías copiarlo ahí? (podría hacerlo yo, pero así sale con tu usuario).

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 26 Ene 2014, 20:05
por elborra
Sin problema, de todas formas si puedes echarle un vistazo al código, antes de postearlo en ese hilo, para verificar que no estoy tocando donde no debería. Aparte no está muy testeado con diferentes configuraciones (aunque he sido bastante cauteloso en meter los cambios) y me da palo hasta que me des el OK.

Tampoco he mirado cuanto espacio extra suma esta característica para añadirlo como información, que siempre está bien tenerla, además el sistema que uso implica que se metan los bloques empujables por script => más tiles por script = más espacio, aunque eso ya es variable. Soy un zopenco, pero ¿cuánto implicaba un SET_TILE? ¿3 bytes?

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 26 Ene 2014, 21:13
por na_th_an
A ver si puedo encontrar un hueco para mirarlo bien, que ando muy liado con lo mío ;)

Un SET TILE son 4 bytes (opcode x y tile).

Otra forma de hacerlo sería generando una estructura de datos aparte, sin tener que tirar de script. Así ahorraríamos memoria.

Re: Proyecto juego Churrera. Dudas

Publicado: Dom, 26 Ene 2014, 21:18
por na_th_an
Sobre la corrección, hay tantas variaciones y posibilidades que siempre se escapa algo. Si te fijas, he resubido la 3.99.3b CINCO veces ya por tonterías que se me habían pasado. Muchas veces hay fallos que no dan la cara hasta dos o tres versiones más tarde, cuando alguien o nosotros mismos queremos usar una característica en combinación con otras por primera vez.

Yo no me dedico a perfeccionar el motor, sino a sacar juegos - y perfeccionar el motor cuando el juego que quiero hacer lo requiere, por eso os pido siempre que "me tengáis paciencia" con estas cosas.

Por cierto, mejor que vuelvas a descargar la 3.99.3b porque esta misma mañana he arreglado dos cosas :lol:

Re: Proyecto juego Churrera. Dudas

Publicado: Lun, 27 Ene 2014, 00:36
por elborra
$this->bbcode_second_pass_quote('na_th_an', 'S')obre la corrección, hay tantas variaciones y posibilidades que siempre se escapa algo. Si te fijas, he resubido la 3.99.3b CINCO veces ya por tonterías que se me habían pasado. Muchas veces hay fallos que no dan la cara hasta dos o tres versiones más tarde, cuando alguien o nosotros mismos queremos usar una característica en combinación con otras por primera vez.
Ya lo he visto ya xD... $this->bbcode_second_pass_quote('na_th_an', 'Y')o no me dedico a perfeccionar el motor, sino a sacar juegos - y perfeccionar el motor cuando el juego que quiero hacer lo requiere, por eso os pido siempre que "me tengáis paciencia" con estas cosas.
Tranki, paciencia es la que tú tienes, e infinita.