Migración de juegos Fenix a Bennu - Apuntes de diferencias y resoluciones.

Started by FreeYourMind, September 30, 2009, 05:20:12 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

FreeYourMind

Hola.
Bueno, despues de ponerme a migrar algunos juegos de Fenix o Div a Bennu, me entero que hay siempre pequeñas cosas que por un motivo o otro fallan despues en Bennu.

Creo que seria bueno empezar a poner aqui las pequeñas diferencias, errores, o sencillamente cosas que funcionaban de una forma poco lógica en alguna versión de Fenix, etc, y que en Bennu es necessário arreglar para que funcionen correctamente.

De una parte pondria diferencias identificadas, y de otra las cosillas que van surgiendo y buscar la forma de arreglar esa diferencia, para que otros usuarios que seguramente pasarán por alguno de estos problemas, puedan desde un principio con nuestra ayuda, resolver facilmente estas diferencias ya identificadas.

Esto para mi es un mal necessário, pues ya tuve algunos en el primer port, y en los que estoy trabajando tambien estoy encontrando cosas nuevas. Y como todos sabemos, si una cosa no se exprime al máximo, dificilmente sabremos si todo funciona al 100%


Empiezo con una diferencia, y os pido ayuda para ver la forma de poner a funcionar en Bennu:


Tengo un procedimiento disparo(x, y) que en Fenix (Versión 0.84) me funciona perfectamente (lo mismo que en DIV 2), utilizo el siguiente IF, para hacer swith entre distintas colisiones y identificar a cual enemigo estoy tocando:


If(id_colision = collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)

// Despues hago operaciones para el respectivo enemigo
id_colision.vida -= 1;

etc.


En Bennu me da el siguiente error:

Al colisionar con el enemigo: Process 1 not active
o sea, no reconoce el valor de id_colision



Si cambio por

If(id_colision == collision(Type enemigo1) XOR id_colision == collision(Type enemigo2) XOR...)

Error: Process 0 not active, tambien al colidir


Si cambio por

If(id_colision == collision(Type enemigo1) OR id_colision == collision(Type enemigo2) OR...)

me da el mismo error que el de arriba, pero aqui ni necessito que colida, con llamar la funcion disparo peta al instante.


Sugerencias ?¿

Gracias.












splinter_work

vamos por partes...

el proceso no active no te lo da ahi, sino el uso posterior que le das...

en la primer linea tenes  = y no ==

XOR es un operador logico, por ende retorna 0 o 1... lo que necesitas es un BXOR o un ^

aunque yo no lo haria de esa forma, ya que el XOR implica ejecucion de ambos terminos, y cuando llamas a un collision con un valor diferente de la llamada anterior, resetea el mismo... por otro lado, al usar XOR si ambos dan colision entonces estarias recibiendo cualquier cosa...

no te sugiero para nada esa forma de uso que le estas dando.

tampoco entiendo como eso funcionaba en Fenix o DIV2, deberia funcionar solo si al menos alguno de los 2 da falso... si ambos dar ok, deberia no detectar...

como bien has dicho, cosas que "funcionaban" de forma poco logicas en fenix, ahora no lo hacen en bennu, efectivamente porque eso se debe a correcciones de bugs... que fenix tenia y ahora bennu no... de no haber existido bennu, seguramente el fenix actual funcionaria de la misma forma que lo hace ahora bennu, ya que se deben a bugs corregidos.

gracias por la consulta.

FreeYourMind

Si, pero lo que quiero es una solución ;)

El original que funciona en Div1  y Fenix es el primero:

If(id_colision = collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)

, en el segundo pongo == porque sino me da error al compilar, ya que si pongo

If(id_colision = collision(Type enemigo1) XOR id_colision = collision(Type enemigo2) XOR...) me dice que requiere la variable '='.

Probando con BXOR o '^' me dice Process 0 not active al colisionar.

Vamos, lo unico que quiero es que el id_colision se atribuya al la colision originada, que se asigne al processo de esa colision...



SplinterGU

pero eso no te va a funcionar bien... si colisiona con mas de 1 objeto a la vez, no va a funcionar correctamente, va a retornar cualquier cosa como id_colision...

claro, por lo que te digo, no es correcto que eso funcione... y si funciona es erratico...

lo mas correcto seria OR

if ( ( id_colision = collision(type ...) ) OR ( id_colision = collision(type ...) ) OR ( id_colision = collision(type ...) ) )

pero... tene en cuenta que va a procesar la primera, si encuentra, no va a testear por las otras colisiones, o sea, que hasta que no termine de barrer el primer type, no va a pasar al 2do... y cuando complete el primero y pase al 2do, retornara solo la primer colision del 2do y luego volvera a escanear el primero...

te digo, esta mal que lo hagas asi

tenes que hacerlo por separado.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

1 - Entiendo perfectamente a que te refieres, pero creeme, funciona bien de esa forma aunque no lo parezca, el juego se juega perfectamente y los enemigos muerren todos en simultaneo o solos, y no se interfieren entre ellos.

Esto porque las operaciones que hago para cada uno de ellos es instantanea, se basa practicamente en quitarle enegia y el proceso disparo se hace un break, por eso creo que funciona bien de esta forma, esto hablando con lógica, porque en la practica funciona, recuerda que esto es un port, no me estoy inventando de nuevo el processo de disparo :)

El problema a que me referia no es ese, es que no se asignaba el id_colision a la respectiva colision dada en ese instante, para asignar la variable local al respectivo processo.


2 - Probando ahora mismo tu ejemplo:

Funciona!, a la perfección como en el original de DIV y Fenix :)

Muchas gracias.

Como curiosidad decirte que Bennu es el único que este tipo de condición se escribe de forma distinta a Div, Fenix y al otro comercial :) para que funcione.

Muchas gracias.
Mañana más ;)




DCelso

misterioso, no entiendo el XOR ese ni pa atrás. ¿De donde sacastes esa formula?
A mi me da que si trabaja a nivel de bits, en el caso de colisionar varios puede devolver un id inexistente, de ahí el error, el misterio es cómo lo resolverá DIV.
a= (0x0001) XOR (0x1011) XOR (0x1001)
          (     1010   )       
                    (             0011        )

Si trabaja a nivel de valor haría algo igual de raro porque siempre devolvería o 1 o 0 como id.
a =  true XOR true XOR true => da de resultado true 
En cambio
a =  true XOR false XOR true => da de resultado false

Podría valer para saber si hay un número par de procesos colisionados o no.

En serio, Me intriga pensar quien diseño esa funcionalidad y para qué.
Monstruos Diabólicos

"A PAck of classic GAMEs For BennuGD" en desarrollo
http://code.google.com/p/apagame4be/

SplinterGU

exacto dcelso, no deberia funcionar correctamente si colisionan mas de 1 a la vez
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Drumpi

Yo creo que lo que intenta es que colisione sólo con un único tipo de proceso, y a la vez guardar el valor de la colisión en la misma variable.
Creo que lo que realmente intenta es:
If(collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)
Y que el "id_collision=" es de copiar y pegar código sin entender por qué se hace así, si no, no entiendo que guarde TODAS las colisiones en la misma variable, machacando el dato una y otra vez para que sólo quede la última colisión que haga.

De todas formas, es posible que Fenix se hiciera un lio por no poner ningún paréntesis. No me he puesto a analizar el orden de operaciones, pero a poco que no sea el que el programador ha previsto o haya un pequeño bug/error en la interpretación, los resultados pueden ser, buf, ni me lo imagino.
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)

FreeYourMind

Os resuelvo el misterio chicos:

El XOR lo utilizaba cojido de un ejemplo que vi en DIV, esto hace 10 años.

Tampoco mire en su momento su lógica, solo me interesaban los resultados, ya que estaba prácticamente aprendiendo a programar algo que no fuera basic.

Siempre funciono bien el juego, incluso si el tiro cojia mas de un enemigo en simultaneo (lo que ya os digo que tambien es raro que ocurra).

Despues de este tiempo, lo miro como vosotros, no veo su utilidad, con OR tiene más logica, pero para respetar el original lo dejaria, aunque despues de tener que cambiar el IF en Bennu, tambien los cambie por OR, y funciona exactamente todo igual.

En realidad tambien me parece que funciona por una sencilla razón. el tiro se autodestruye al colidir, el IF asigna el id al primer processo que pille y se destruye el processo (tiro que tenia el IF), así que como dentro hay un case, seguramente el primer case que pille ya hace que el procedimiento asigne el id al primer processo enemigo que pille haciendo acto seguido un Break, el siguiente tiro ya será otro processo, que podrá o no pillar un enemigo distinto.

Tampoco le quiero dar más vueltas ;)




FreeYourMind

Quote from: Drumpi on October 01, 2009, 12:13:07 AM
Yo creo que lo que intenta es que colisione sólo con un único tipo de proceso, y a la vez guardar el valor de la colisión en la misma variable.
Creo que lo que realmente intenta es:
If(collision(Type enemigo1) XOR collision(Type enemigo2) XOR...)
Y que el "id_collision=" es de copiar y pegar código sin entender por qué se hace así, si no, no entiendo que guarde TODAS las colisiones en la misma variable, machacando el dato una y otra vez para que sólo quede la última colisión que haga.

De todas formas, es posible que Fenix se hiciera un lio por no poner ningún paréntesis. No me he puesto a analizar el orden de operaciones, pero a poco que no sea el que el programador ha previsto o haya un pequeño bug/error en la interpretación, los resultados pueden ser, buf, ni me lo imagino.

Exacto! Lo has entendido perfectamente, sólo quiero que lo asigne a un único tipo de proceso. Aunque con el OR da igual, va pillar sólo uno tambien.

Lo de los parentesis es cierto, Bennu parece que da importancia a la contrución lógica de if's con parentesis, pero por ejemplo en div o fenix, no necesitabas poner tantos parentesis, tenia un ejemplo en algun if que lo demonstraba no se ya donde se daba el caso, pero creo que es mas o menos esto que se me ocurre de ejemplo:

En Div o Fenix, esto te funcionaria correctamente, ejecutar la misma acción con los botones A + B, o solo con el boton C:

IF( key(_a) AND key(_b) OR key(_c) ) accion()

pero en Bennu, tienes que poner los parentesis para definir bien las agrupaciones, sino se lia:

IF( (key(_a) AND key(_b)) OR key(_c)) accion()


SplinterGU

Quote from: FreeYourMind on October 01, 2009, 12:20:39 AM
Os resuelvo el misterio chicos:

El XOR lo utilizaba cojido de un ejemplo que vi en DIV, esto hace 10 años.

Tampoco mire en su momento su lógica, solo me interesaban los resultados, ya que estaba prácticamente aprendiendo a programar algo que no fuera basic.

Siempre funciono bien el juego, incluso si el tiro cojia mas de un enemigo en simultaneo (lo que ya os digo que tambien es raro que ocurra).

Despues de este tiempo, lo miro como vosotros, no veo su utilidad, con OR tiene más logica, pero para respetar el original lo dejaria, aunque despues de tener que cambiar el IF en Bennu, tambien los cambie por OR, y funciona exactamente todo igual.

En realidad tambien me parece que funciona por una sencilla razón. el tiro se autodestruye al colidir, el IF asigna el id al primer processo que pille y se destruye el processo (tiro que tenia el IF), así que como dentro hay un case, seguramente el primer case que pille ya hace que el procedimiento asigne el id al primer processo enemigo que pille haciendo acto seguido un Break, el siguiente tiro ya será otro processo, que podrá o no pillar un enemigo distinto.

Tampoco le quiero dar más vueltas ;)





claro, ahi en lo ultimo esta la cosa... seguro funciona porque colisiona 1, lo mata, en el siguiente frame colisiona el otro, pero si fueran casos donde 2 procesos colisionan a la vez contra el objeto y solo en un unico frame, entonces en el siguiente la colision no se producira... como sea, es raro que funcione correctamente... pero bueno...
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

SplinterGU

en realidad no es que bennu se lia, sino que bennu maneja con mas logica las presendecias de los operadores.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

FreeYourMind

Quote from: SplinterGU on October 01, 2009, 12:53:43 AM
en realidad no es que bennu se lia, sino que bennu maneja con mas logica las presendecias de los operadores.

Si claro, es bueno para entender mejor las inumeras condiciones que pongamos, pero si te fijas casi todos los lenguajes evitan que pongamos tantos parentesis, que el resultado será el mismo.

SplinterGU

no son necesarios los parentesis mientras sigas estas reglas...

http://forum.bennugd.org/index.php?topic=124.0

lo que sucede es que en fenix se comportan diferente y en div tambien son diferentes a fenix... y si no estas ducho con las reglas es mejor usar los parentesis para evitar errores, ademas que deja bien claro para un analisis humano de los mismos.
Download Lastest BennuGD Release: http://www.bennugd.org/node/2

Drumpi

El problema viene con las asignaciones Y comparaciones lógicas sin usar paréntesis. Puedes usar los AND y OR sin paréntesis (álgebra aparte), pero con las asignaciones se puede liar.
Es una de las razones por las que nunca hago las asignaciones dentro de los IFs.
Y como dice mi profe de programación y mi profe de análisis vectorial: "los paréntesis, más vale que sobren que no que falten" ;D
Hala, como con 1001 procesos sólo va a 9 FPS, vamos a meterle 32 veces más, a ver si revienta.
(Drumpi epic moment)