Juegos de Ordenador

Desde mis inicios en la informática me apasionaron las figuras en 3D. Pero hubo un antes y un después cuando leí un articulo de la sección juegos de ordenador en la revista Investigación y Ciencia (en los años 80). Ese numero trataba en su totalidad sobre la teoría de fractales (conjunto de Mandelbrot y similares), todo era nuevo y muy interesante para mi. Pero esta vez en mi sección favorita de la revista aparecía una imagen similar a la siguiente :

1605361668882.png

Esta imagen me llamo poderosamente la atención, y leí cuidadosamente el articulo donde se explica la teoría de cómo realizarla. Ya no recuerdo el contenido completo del artículo, solo algunas explicaciones que me han permitido hacer un pequeño programa para obtenerlo.

Curiosamente, el procedimiento de elaboración del esqueleto de partida es “simple”. Se parte de un triángulo inicial (en negro), en el que se divide cada arista por la mitad, uniendo las divisiones obtenidas entre si (en rojo) como se muestra en este boceto:

1605361704601.png

Así obtenemos 4 triángulos (uno de ellos invertido). Ahora se debe repetir el mismo proceso con cada uno de los nuevos triángulos hasta la profundidad que se desee. Se trata un pequeño programa recursivo sencillo de implementar.

Después de repetir las acciones descritas unas cuantas veces, se obtiene una figura de este tipo:

1605361726641.png

Para obtener la imagen inicial en vez de esta, en el proceso intermedio de calculo para cada nuevo vértice se debe incluir una pequeña desviación aleatoria para cada coordenada (Δx, Δy).

Uniendo todos los pasos descritos obtenemos el siguiente resultado:

1605361751493.png

El resultado no esta nada mal teniendo en cuenta que se trata “solo” de una imagen plana. El efecto 3D es puramente un efecto óptico. (si alguien esta interesado en conocer como he realizado este código que me lo diga sin problemas, lo he realizado en C#)

El proceso de generación procedural utilizado en Elite, no lo conozco pero tiene que basarse en un concepto similar partiendo de una primera imagen tridimensional (pe. una pirámide, esfera, etc.).

Ahora bien, la grandeza del desarrollo que han realizado los chicos de FD para realizar la Forja Estelar, consiste en realizar todo este proceso cumpliendo dos premisas adicionales:
  • Que la desviación aleatoria sea siempre la misma para todos los jugadores (fractales)
  • Que el resultado sea estéticamente agradable (que me expliquen como lo han hecho, por favor).
Como os podéis imaginar el último punto es el que es verdaderamente complicado, y es la causa del éxito conseguido en la calidad de las imágenes finales.

9ognTUv.jpg


Ahora aplicad una teoría similar a todo lo demás que existe dentro de ED: Sistemas, asteroides, cañones, planetas, etc. Y además tiene mas mérito porque son pioneros en este tipo de desarrollos.

Este juego se puede utilizar perfectamente para explicar conceptos teóricos llevados a la práctica con éxito dentro la carrera de informática.

Una vez más, mis felicitaciones al equipo de FD. 👏 👏 👏 👏 👏 👏
 
Last edited:
La clave en los juegos procedurales no es más que definir una función que siempre nos va dar los mismo resultados para los mismos parámetros de entrada.

Haz una prueba rápida con excel, monta una tabla en que las filas vayan de 1 a 8 y las columnas lo mismo. El valor de la celda que sea la suma del seno del número de fila más el coseno del número de columna. Luego monta otra tabla igual en las que pintes una x si en esa celda, en la otra tabla el valor es mayor que por ejempo 1,2 (o cualquier otro valor que quieras).

Eso si quieres lo mezclas con una función de generación de números aleatorios (porque amiguitos, los números aleatorios en los ordenadores no son tales).

Una función de números aleatorios es xn+1= (axn + c) (mod m) donde se dice que el éxito de este tipo de generadores de valores de una variable aleatoria depende de la elección de los cuatro parámetros que intervienen inicialmente en la expresión anterior:

El valor inicial o semilla: x0
La constante multiplicativa: a
La constante aditiva: c
El número m respecto al cual se calculan los restos


(todo esto sacado de la wikipedia)

Ahora imagina que ese x0 es el valor de la tabla sen(a)+cos(b) y que te vas al 3er elemento de ese generador... o al c-ésimo elemento y así conviertes tu tabla en una matriz de 3 dimensiones... anda.... como las coordenadas...

Puedes seguir haciendo más compleja la cosa metiendo factores probabilísticos diciendo que en un sitio vas a representar algo si su valor es mayor (o menor) que un determinado valor (tal como hacíamos con la 2a tabla) Incluso puedes hacer que ese valor no sea fijo, sino que por ejemplo lo obtengas de otra función.

Imagina el valor que obtenemos de esa función que nos devuelve el valor de la matriz tridimensional. Vale, pues resulta que pintamos si su valor es mayor al área de un cono definido por las 3 variables de la función...

Braben es matemático (o físico, no recuerdo bien). Se le da bien jugar con números y hacer funciones... con las primeras versiones de elite simplemente era jugar para obtener un mapa equilibrado, con ED juguetear para que a parte de equilibrado, la probabilidad de que la estrella apareciera pintada se unía a que estuviera "dentro" de unos conos que son las ramas de nuestra galaxia (matemáticamente es posible dibujar las funciones de arco que son cada uno de los brazos).

Puedes variar la función levemente dependiendo del sector de la galaxia en las que estés intentando sacar el punto...

Lo cierto es que tiene que ser una función que sea una maravilla y además no muy compleja para que el conseguir que el generar en un punto determinado no se lleve mucho tiempo.

Por cierto, lo que hacen los generadores procedurales no es lo del triángulo que tu pones. Los generadores lo que hacen es dada una malla plana, calculan "aleatoriamente" (ya sabemos que esto es mentira) las alturas de los distintos vértices y luego lo pintan. Ahí no hay efecto vissual como el de los triángulos con vertices obtenidos de forma aleatoria, aquí lo que se calcula es la proyección a 2D de unos puntos que se definen en 3D.

Añado un excel para que jugueteis si quereis.
La primera tabla es la función seno(fila*pi)+coseno(columna*pi)
La segunda tabla es es la 3a iteracción de los valores "aleatorios" obtenidos por los parámetros de la columna n2 a n4 y como semilla el valor de la 1a tabla.
La tercera tabla dibuja una x si los valores de la función de la 2º tabla son mayores que el valor indicado al principio de la fila (por lo que es más probable tener una x en las primeras filas que en las últimas)
 

Attachments

  • Jugueteo con números.xls
    31 KB · Views: 309
Last edited:
La clave en los juegos procedurales no es más que definir una función que siempre nos va dar los mismo resultados para los mismos parámetros de entrada.
hombre, algo mas complejo que eso si es, ya que el resultado final tiene que ser atractivo por lo que hay que incluir una capa que a partir de los números elabore estructuras "coherentes", esta es la parte mas difícil.

El ejemplo que puse con un triangulo (o con una pirámide en 3D), es la malla inicial sobre la que aplicar las desviaciones. Pero podría ser cualquier figura, o incluso no existir ninguna. Se podría partir de una esfera.

Lo cierto es que tiene que ser una función que sea una maravilla y además no muy compleja para que el conseguir que el generar en un punto determinado no se lleve mucho tiempo.
completamente de acuerdo, debe ser una maravilla, y debe tardar el tiempo de la animación de salto entre sistemas.

Por cierto, lo que hacen los generadores procedurales no es lo del triángulo que tu pones. Los generadores lo que hacen es dada una malla plana, calculan "aleatoriamente" (ya sabemos que esto es mentira) las alturas de los distintos vértices y luego lo pintan. Ahí no hay efecto vissual como el de los triángulos con vertices obtenidos de forma aleatoria, aquí lo que se calcula es la proyección a 2D de unos puntos que se definen en 3D.
Aquí no estoy de acuerdo, el ejemplo que he mostrado no te pienses que es sencillo de implementar (ni mucho menos, reto a ver quien se atreve a implementarlo), la dificultad reside en que los puntos de los triángulos son compartidos entre ellos, un triangulo arrastra al de al lado (por decirlo de alguna manera). Si coges una malla plana y la deformas aleatoriamente obtienes un churro irregular, tienes que "simular" un efecto de arrastre o quedara mal.

Añado un excel para que jugueteis si quereis.
La primera tabla es la función seno(fila*pi)+coseno(columna*pi)
La segunda tabla es es la 3a iteracción de los valores "aleatorios" obtenidos por los parámetros de la columna n2 a n4 y como semilla el valor de la 1a tabla.
La tercera tabla dibuja una x si los valores de la función de la 2º tabla son mayores que el valor indicado al principio de la fila (por lo que es más probable tener una x en las primeras filas que en las últimas)
tu que manejas tan bien el Excel, intenta crear una malla tridimensional que intente simular una montaña, veras la dificultad de la que hablo.

Nota: lo de las funciones aleatorias que repiten números comenzando con la misma semilla lo conocía. En mi primer juego que hice (un Risk, me dieron una copa y todo) la semilla era la fila de renderización del tubo de rayos catódicos de la televisión. 🤣 que opinas, te parece suficientemente aleatorio?

Por cierto, el mismo código que parte del triangulo inicial, si los vertices son de 3 coordenadas (x,y,z), donde z sea un valor constante cualquiera en inicio, aplicando un Δz por iteración se obtiene una imagen 3D al final.
 
Last edited:
Había una asignatura en la carrera que te enseñaba a hacer una función que te garantizaba que pasaba por unos puntos. Pero las funciones son funciones, una vez está definida vas a garantizar siempre el mismo resultado para los mismos valores de entrada, y dichos valores de entrada (casi seguro) aquí deben ser las coordenadas. La aplicación aparte tiene su miga porque el universo procedural de ED tiene sus excepciones: sistemas que se saben donde están y que han de representarse independientemente del valor devuelto por la función.

Con lo de la malla estoy de acuerdo y no. A ver, tu representas una malla 2d, calculas posiciones de los vértices en 2d y esto "engaña al ojo" provocando un efecto 3d. La creación procedural parte de una malla 3d, inicialmente sobre un mismo plano (o no, como bien dices la malla original puede ser un cubo, un toroide, una esfera... ) y sobre los vértices que la componen meten la variación sobre cada uno de los vértices. Al final está la cámara que va a ver una proyección 2d de una cara del objeto. A diferencia de tu malla, es que tu malla si cambias el punto de vista verás que es plana. El objeto 3d será... pues eso un objeto.

No soy experto en juegos. Evidentemente el diseño de escenarios u objetos proceduralmente para un juego es más complejo. Pero todo consiste al final en meter funciones "aleatorias" que modifiquen la malla. En el caso ED la cosa puede ser tal que:
1) Procedimiento que modifique una esfera para darle el relieve.
2) ¿Hay asteróides? Si los hay, generar n de diversos tamaños "aleatorios" en diversas posiciones "aleatorias" y afectar la malla para representarlos.
3) ¿Hay piedras? ¿árboles? Generar "aleatoriamente" sus posiciones y que son.

He leído por ahí que había procedimientos que consistían luego en soltar un "gusano" que se movía "aleatoriamente" creando túneles. Creo que no será aquí en ED, no obstante siempre puedes proyectar sobre la malla del planeta líneas que vayan a representar fisuras o pliegues tectónicos y sobre dichas líneas acentuar la variación de altura.

No te quito el mérito del programa. He de confesarte que ayer estuve dándole vueltas al cómo, al procedimiento durante un rato. Imagino que tienes una función tipo Triangulo[] divide(Triangulo _iTriangulo) que luego llamas n veces. Me da envidia que hagáis cosas tan chulas.

¿Excel para generar montañas? no se si se puede hacer esto (bueno, se me ocurrió hacer una gráfica metiendo un incremento para dar perspectiva... pero no es excel el programa para hacer esto), no obstante se de programas de diseño que te pueden leer coordenadas indicadas en un excel... aunque lo suyo sería pasar las funciones a c#, buscar una librería gráfica y deformar una malla acorde a esas coordenadas. Si sabéis de alguna librería os lo agradezco (a ser posible antigua compatible con el framework 2.0 os lo agradezco, si no... por ahí tengo montada una máquina virtual con el último visual studio 😓)
 
Last edited:
¿Excel para generar montañas? no se si se puede hacer esto (bueno, se me ocurrió hacer una gráfica metiendo un incremento para dar perspectiva... pero no es excel el programa para hacer esto), no obstante se de programas de diseño que te pueden leer coordenadas indicadas en un excel... aunque lo suyo sería pasar las funciones a c#, buscar una librería gráfica y deformar una malla acorde a esas coordenadas. Si sabéis de alguna librería os lo agradezco (a ser posible antigua compatible con el framework 2.0 os lo agradezco, si no... por ahí tengo montada una máquina virtual con el último visual studio 😓)
Si que sabes, no te infravalores. Creando una maya de valores en Excel se pueden utilizar en una grafica que los represente en el mismo Excel, no se si lo has utilizado alguna vez, pero es sencillo. En dos pestañas, una con datos y otra con el grafico. Pero te lo decia solo por que vieras la complejidad para generar los datos.

A diferencia de tu malla, es que tu malla si cambias el punto de vista verás que es plana.
por supuesto, esta construida solo con coordenadas (x,y), se vería plano en 3D, por eso comentaba que incluyendo la coordenada z el resultado visual sería muy parecido pero en 3D (como una sabana volando). No lo he hecho por pereza de buscar documentación de librerías gráficas en 3D, pero no descarto un cruce de cables futuro, la programación para mi es un Hobbie (y muchas veces programo en el trabajo, todo un lujo)

todo esto lo estoy haciendo en C# sobre la base de EDExplorer (por vagancia), pero utilizo el framework 4.5 por lo menos, uno de los mas altos. Ya que aprendía desde cero, prefería estar a la ultima. Si tienes interés explico como se programa, no me importa.

para este programa uso estas librerías, que son para 2D:
using System.Drawing;
using System.Drawing.Drawing2D;


Imagino que tienes una función tipo Triangulo[] divide(Triangulo _iTriangulo) que luego llamas n veces. Me da envidia que hagáis cosas tan chulas.
si supieras el tiempo que me ha llevado... No programarlo que ha sido fácil, si no "pensar" el algoritmo adecuado para hacer esa función divide que indicas. La teoría es sencilla, pero...
 
Last edited:
Si que sabes, no te infravalores. Creando una maya de valores en Excel se pueden utilizar en una grafica que los represente en el mismo Excel, no se si lo has utilizado alguna vez, pero es sencillo. En dos pestañas, una con datos y otra con el grafico. Pero te lo decia solo por que vieras la complejidad para generar los datos.

Los excel que hago no suelen incluir mucha gráfica... soy más de datos que de dibujos, no obstante un día de estos le hecho un vistazo a ver que me deja la versión del 2002 que es la que suelo manejar.

por supuesto, esta construida solo con coordenadas (x,y), se vería plano en 3D, por eso comentaba que incluyendo la coordenada z el resultado visual sería muy parecido pero en 3D (como una sabana volando). No lo he hecho por pereza de buscar documentación de librerías gráficas en 3D, pero no descarto un cruce de cables futuro, la programación para mi es un Hobbie (y muchas veces programo en el trabajo, todo un lujo)

Te pasa lo mismo que a mí, la pereza de no buscar la documentación y las librerías... pero es que aunque la programación empezó siendo un hobbie para mi, lo cierto es que en mi trabajo también programo muchas veces... vamos como que soy programador! 😅

todo esto lo estoy haciendo en C# sobre la base de EDExplorer (por vagancia), pero utilizo el framework 4.5 por lo menos, uno de los mas altos. Ya que aprendía desde cero, prefería estar a la ultima. Si tienes interés explico como se programa, no me importa.

para este programa uso estas librerías, que son para 2D:
using System.Drawing;
using System.Drawing.Drawing2D;

Llevo ya más de 10 años con el C#, no obstante sigo limitándome al Framework 2.0: aún tenemos muchos clientes con WinXP y a menos que te metas en cosas muy novedosas que te compliquen la vida, me permite hacer las aplicaciones que necesitamos. Lo malo es eso, cuando llega el día que tienes que meter funcionalidades que comuniquen con API y te digan "la comunicación con JSON"... y este Framework no lo llevaba 😰. Toca tirar de S. Google y buscarte la vida.

La System.Drawing la uso algo, poco, para unos albaranes que imprimimos, la otra creo que también la he usado alguna vez, pero para juguetear no más.

si supieras el tiempo que me ha llevado... No programarlo que ha sido fácil, si no "pensar" el algoritmo adecuado para hacer esa función divide que indicas. La teoría es sencilla, pero...

Me hago una idea. Yo siempre digo que programar es fácil... siempre que tu sepas hacer "a mano" lo que quieres hacer "automáticamente" con el programa.

Lo de la envidia viene mucho porque mola más hacer un gráfico y "arrugarlo" que crear un formulario, llenarlo de textbox, combobox y pasear los datos a una BD o archivo. Juguetear con cosas que se ven mola más que tirarte dos días aporreando código para que aprietes un botón en un sitio y digas: "mira, se puesto este dato correcto allí, la cosa funciona"
 
Bueno... yo lo haría de forma escalada. Con esto quiero decir que todo está dividido en sectores, y digamos que cada sector puede tener dos tipos de configuración, por ejemplo, colinas escarpadas y montaña. Entonces, ya sea que usemos la malla o la teoría de fractales, que ambas son muy válidas, simplemente se diferencian en que en una ya tenemos todos los vértices generados pero hay que darles posiciones espaciales, y en el otro los vamos generando hasta completar el total necesario, definimos una función acorde a lo que tenemos que ver, es decir, si es terreno montañoso con colinas escarpadas lo más lógico es que la montaña esté en el centro y se cree un núcleo de vértices altos, y que luego, según probabilidades, vaya bajando (aquí aplicamos algo de "azar" para ver si vuelve a subir o baja, por ejemplo), hasta llegar al terreno escarpado que lo más probable es que esté rodeando el núcleo montañoso, y hacemos que los vértices de las colinas sean pronunciados en sus puntos más altos.

En el fondo, si os dais cuenta, la función es básicamente la misma, pero se varían ciertos parámetros, así que lo que haces es partirte la cabeza una vez, y luego ir probando los parámetros para que aparente lo que quieres que aparente, ya sean colinas, valles, montañas o ríos. Por último, una vez creada la superficie, pondría por medio de otro algoritmo los elementos decorativos, este más sencillo porque sólo tiene que poner los objetos sobre la superficie creada y que cumpla con unos requisitos, por ejemplo, cantidad de árboles en un terreno rocoso, que deben ser pocos o ninguno. De hecho, esto creo que se crea "in situ" para cada uno, porque yo lo definiría como de "datos tangenciales", enviaría el tipo de adornos, la cantidad y que lo generase al momento.

Así que, al final, lo que hay que guardar son las posiciones de los vértices... el problema es el espacio físico que esto ocupa, porque son muchísimos vértices. Si quisiera que se redujera la cantidad de datos que transmitir, entonces lo que haría son varias funciones generadoras de esas montañas y esas colinas, por ejemplo, 10 por cada tipo de terreno... luego los combinas aleatoriamente y... magia ¿No habéis notado que se parecen mucho los paisajes en ocasiones?. De hecho, puedes incluso limitar el uso de unas funciones que continúen a otras para que no se vea raro. Como si fueran piezas de puzzle.

Como se ve, y teniendo en cuenta que la función inicial es la misma, es fácil de generar algo que te interese simplemente probando combinaciones, y, de repente, en vez de guardar montañas de datos, guardamos grupos de funciones (que ya están en nuestras máquinas) y unos pocos datos, que definirán qué funciones usar y generarán siempre los mismos paisajes para todos los jugadores.

Por último, para cambiar de sector, por ejemplo, y para que haya continuidad, pondría una probabilidad de que uno de los dos efectos, o los dos, continúen en un sector adyacente, en el caso de viejos lechos o cadenas montañosas, las probabilidades aumentan en los lados, y disminuyen o son nulas en el lado incorrecto. Y vuelta a empezar.

Bien... yo creo que lo que hacen es dividir el cuerpo espacial en sectores grandes que abarcan una cantidad de sectores, estos macro sectores definen el terreno general que habrá, por ejemplo, impacto de asteroide, luego, empezando por el macro sector 1 ya definido su "rol", luego van al dos, con las mismas leyes que dije de continuidad, y así hasta completar el planeta entero. Con esto conseguimos no guardar información específica de ningún planeta que no se esté pisando, pero de cara al público parece que está todo creado. Cuando baje alguien, es cuando generamos los terrenos al detalle.

Así que yo lo que creo es que en ED hay muchas fachadas... Es más, en los sistemas menos visitados, incluso borraría la información de tierra si no se visita cada x tiempo ¿quién se acordaría si no hay nada en especial?

Es mi humilde opinión... hace ya casi 20 años que no programo, pero es como lo haría.
 
Last edited:
Muy buenos apuntes @YoEgo

No obstante, salvo generación de excepciones (como el sistema solar), la propia definición de funciones con semilla conocida (como puedan ser las coordenadas) te evitan tener que guardar nada, no obstante tu apunte de sectorizar es muy muy interesante. Esto haría que fueras usando generadores aleatorios a distintos niveles como por ejemplo

1º hay o no hay sistema
2º tipo de sistema
3º Cantidad y posición de cuerpos
4º Tipo del cuerpo (que pueda venir influenciado por el tipo de sistema)
5º Sectores en cuerpo estelar (zona llana, zona montañosa...)
6º Relieve del sector
7º Detalles del entorno.

Todo esto puedes combinarlo con fractales y cualquier otra función, pero sin tener que guardar nada porque todo te va a venir dependiendo de la posición en la que estés, ya que las funciones "aleatorias" siempre funcionaran igual ante los mismos parámetros de entrada.

@3navis he estado jugueteando con el excel y he visto lo de los gráficos de relieve (creo que nunca me había fijado en ellos). He estado jugueteando con valores y me he estado acordando de todo lo dicho por @YoEgo . Si fijas una escala de gráfico a un valor (como por ejemplo 15) y luego vas variando el valor del módulo, vas obteniendo relieves más suaves o abruptos (a menor módulo más suave y viceversa). De hecho, en la definición del sector lo que se podría fijar para el subsector podría ser el valor máximo del módulo de modo que indicarían el tipo de terreno que tienes.

A este paso entre todos sacamos aquí el algoritmo de la forja 😅
 
Last edited:
Top Bottom