0. Preliminares
0.1 prólogo

Flash no tiene 3D: esto es lo que comœnmente se cree. Lenguajes como C tienen su propio sistema y librerías de 3D (OpenGL), y en el mundo de internet los entornos más conocidos que involucren 3D son VRML y Director. Sin embargo, cualquier lenguaje de programación que genere gráficas y que posea las funciones matemáticas más básicas puede crear mundos tridimensionales interactivos. Como se verá, la matemática que hay detrás de la construcción tridimensional es simple: su momento más difícil llega con las rotaciones en más de un eje, en donde es necesario usar algo de álgebra lineal básica (es decir, la que se ve en primer semestre de cualquier ingeniería).

La creación de mundos tridimensionales es un proceso constructivo. De trazar una línea se pasa a un plano, luego a un bloque, y con bloques se pueden crear construcciones más complejas. Luego se enriquece la forma de visualizar y navegar las formas tridimensionales. DespuŽs se introduce la interactividad, comportamiento de los objetos, modelos físicos simples. Cuando trabajemos la idea de un paisaje tridimensional infinito, la clave será la construcción de segmentos de paisaje... algo similar ocurrirá con la pista de snowboard.

Parte de estas construcciones mezclarán algoritmos que involucran azar y parámetros. Pensando en la pista de snowboard: evidentemente hay parámetros que son más o menos fijos, o que variarán más o menos. Así que una vez uno sabe manejar las funciones 3D básicas, la clave es articular elementos constructivos con elementos interactivos para construir una narrativa.


0.2 acerca de la estructura de este tutorial

Cada tema o lección contendrá texto, ejemplos visualizables y descargables, enlaces externos a proyectos que involucren tŽcnicas desarrolladas en el tema, lista de tareas y retos creativos organizados por nivel de dificultad y, generalmente, un peque–o comentario que deja entender cómo el tema o lección va a ser œtil para el objetivo final: el desarrollo de un juego tridimensional interactivo, la pista de SnowBoard. Conforme se hagan preguntas podrá aparecer un peque–o FAQ en cada lección.


1. Introducción al 3D

La proyección tridimensional en una pantalla de ordenador se basa en las misma técnicas descubiertas o redescubiertas por los renascentistas, quienes asociarion a la luz un comportamiento rectilíneo (reafirmado por la física clásica y controvertido por la relatividad). Hay diversos sistemas de representación tridimensional o perspectiva, que se basan en formas distintas de proyección. Proyectar -exactamente como cuando se proyecta una película- quiere decir intersectar una línea con un plano. Hay proyecciones oblicuas o paralelas. El sistema de representación tridimensional más común en ordenadores, sencillo y que genera sensación de vértigo debido a poseer puntos de fuga, es la proyección cónica. Más simple aún es la axonometría, utilizada en esquemas técnicos -por ejemplo las instrucciones de Lego- y favorita del arte tradicional japonés. En la perspectiva cónica, a diferencia de la axonométrica, los objetos disminuyen su tamaño en función de su lejanía.

A continuación un pequeño esquema interactivo que ilustra diferentes tipos de proyección: abrir esquema tipos de proyección

Un buen ejemplo de proyecto en axonometría: http://moebio.com/santiago/diedrom

Y un esquema interactivo de la perspectiva acotada: abrir esquema curvas

 


1.1 introducción a proyección cónica

La proyección cónica funciona con un plano (la pantalla) y un punto detrás de ese plano -en relación a aquello que se quiere representar. Se trazan líneas rectas entre todos los puntos del objeto que se quiere representar y el punto detrás del plano que llamaremos punto de vista; todos los puntos que resulten de intersectar estas rectas con el plano constituyen la proyección. Es un objeto bidimensional (ya que "habita" dentro del plano).

El siguiente esquema lo deja claro:

 

imagen cónica

 

Y, de forma más detallada, en un esquema interactivo: abrir esquema interactivo

 

1.2 profundidad y escala

La primera aproximación a simulación de la tridimensionalidad en una pantalla -en donde los ejes x y y son reales, y el z será imaginado- es a través de la escala. Como sabemos, el aspecto más remarcable de la proyección cónica es que posee puntos de fuga, y esto implica que los objetos se representan de menor escala cuando están más lejos. La clave es encontrar la relación entre lejania y escala.

Podría pensarse que el tamaño de los objetos varía proporcionalmente con la distancia. Veremos que no.

Para encontrar la relación entre lejanía, o lo que desde ya podemos llamar valor de coordenada z de un objeto y su escala de representación, veamos el esquema anterior pero visto desde arriba.

 

imagen cónica desde arriba

 

En este esquema la distancia del objeto a la pantalla es su coordenada z. Su tamaño original es escala0 y su tamaño de representación es escala1. La distancia del punto de vista a la pantalla es ll. Este parámetro ll lo vamos a usar de ahora en adelante en todo lo que hagamos de 3D. Podemos llamar a ll la apertura focal, luego se verá porqué. Mientras que el valor de escala0 variará en función del objeto, el valor de z variará en función de la posición del objeto. Y el valor de ll, en cambio no variará. Al menos por ahora debemos pensar que el punto de vista está fijo en relación a la pantalla. Se trata entonces de deducir escala1, que depende de escala0, ll y por supuesto z.

El esquema contiene dos triángulos equivalentes (dibujados también aparte) que dejan establecer la siguiente relación (por teorema de Thales o de triángulos semejantes):

escala0/(ll+z) = escala1/ll

De donde obtenemos que:

escala1 = escala0*ll/(ll+z)

Es decir que ya sabemos con que tamaño se representa un objeto con base en su coordenada z.

Ahora bien, en actionscript, todo objeto gráfico tiene un par de propiedades que son: _xscale y _yscale: las escalas porcentuales del objeto. Si trabajamos con estas propiedades, la escala por defecto de un objeto, en vertical como en horizontal es 100, con lo cual podemos simplificar la fórmula anterior:

escala1 = 100*ll/(ll+z)

Y de esta forma no tenemos que preocuparnos por la escala del objeto que queremos representar.

 


1.3 proyección cónica

De forma similar a como se deduce la escala de un objeto en función de su coordenada z, la idea es deducir las coordenadas de proyección [xp, yp] de las coordenadas tridimensionales [x, y, z] de un punto en el espacio. Ver esquema:

 

 

Como muestra el esquema, el punto de vista tiene, además de una distancia a la pantalla, ll, unas coordenadas xf y yf.

Tenemos entonces los siguientes variables y parámetros:

xf, yf, ll: parámetros constantes, podemos pensar que estos son los valores que determinan las propiedades de la cámara. Luego veremos cómo controlarlos

x,y,z: variables, coordenadas del punto en el espacio tridimensional.

xp, yp: variables, dependen de todos los valores anteriores. La función de actionscript que construiremos (ya casi) calculará estos dos valores en función de todos los anteriores. De esta forma sabremos -la función lo hará por nosotros- en que coordenadas de la pantalla ubicar imágenes y puntos o trazar líneas para que se configure un espacio tridimensional.
La siguiente imagen muestra el anterior esquema desde arriba, y de ella se puede deducir el cálculo de xp. De nuevo, la técnica matemática es por vía de Thales.

 

proyección cónica desde arriba 2


Deducimos del esquema:

(xf-xp)/ll = (xf-x)/(ll+z)

Y esto lleva a:

xp = xf - (xf-x)*ll/(ll+z)

El cálculo de yp es idéntico (en vez de observar el esquema desde arriba se observa de lado). El resultado es:

yp = yf - (yf-y)*ll/(ll+z)


Llegó el momento de pasar a la acción, al actionscript, poner a prueba estas ecuaciones construyendo una función que ubique y escale objetos gráficos y, posteriormente, funciones que "dibujen" en un espacio tridimensional.


Nota: hasta este punto el contenido del curso ha sido totalmente teórico. A partir de ahora todo contenido teórico pasará rápidamente a la acción. Considero importante la comprensión de las bases matemáticas de la proyección cónica. Con esto me refiero no tanto a la deducción de las ecuaciones sino a la comprensión de los esquemas, entender geométricamente la proyección. Lo siguiente a partir de ahora será aprender a utilizar bien las funciones de proyección tridimensional.

Es importante también recalcar que las ecuaciones de proyección son muy simples, no requieren más de unos cuantos parámetros y las operaciones algebraicas básicas. Y que la forma de deducirlas también se basó en matemática sencilla (conocida por los griegos).

Finalmente, antes de pasar al trabajo con código, vale la pena comentar que la comprensión y el dominio formales de las proyecciones trdimensionales constituyen a la vez uno de los pilares del surgimiento de la modernidad y de la actual cultura de la imagen virtualizada.


2. Construcción de espacios tridimensionales simples

Resuelta la parte matemática se trata ahora de construir una primera función que permita proyectar objetos. Es decir, tomar un objeto gráfico y tres dimensiones, y darle una posición en la pantalla y una escala.

Por fuera de la función, antes de definirla, se asigna valor a los parámetros de la cámara: ll, xf, yf. He asignado a estos parámetros una serie de valores de los que por ahora sólo es necesario saber que su unidad es el píxel. Luego afectaremos estos valores para ver realmente sobre qué inciden en la proyección.

Veremos todo el jugo que se le puede sacar a esta función. A partir de ahora se trata de saber dominarla.

 

2.1 proyección de objetos

El primer código creado utliza las ecuaciones de proyección para transformar objetos. El resultado es poco impresionante.

He creado un objeto gráfico y lo he proyectado a las coordenadas [200, 200, 2000], es decir alejado 2000 píxeles de la pantalla en el eje z. Por eso su escala se reduce tanto.

swf para abrir >>>> proyeccion0.swf
archivo flash para descargar >>>> proyeccion0.fla

Pero la tridimensionalidad sólo se verá cuando haya más de un objeto proyectado.

El siguiente ejercicio saca varias copias del objeto gráfico y las ubica en una línea, variando únicamente la coordenada z (desde -150 a 350). Observar que el objeto humano, el original no se proyecta (por eso flota en los aires).

swf para abrir >>>> proyeccion1.swf
archivo flash para descargar >>>> proyeccion1.fla

Se puede observar ahora sí la profundidad: aparece un punto de fuga.

Pregunta: ¿qué coordenadas de pantalla tiene este punto de fuga?

El siguiente ejercicio duplica objetos (200) y los ubica en un plano horizontal: la coordenada y está fija y las coordenadas x y z son aleatorias.

swf para abrir >>>> proyeccion2.swf
archivo flash para descargar >>>> proyeccion2.fla

Las coordenadas x de los objetos, en este código, varían entre 2000 y -2000, superando con creces el ancho de la pantalla. Los objetos que están muy lejos (coordenada z alta) pueden tener una coordenada x muy grande y sinembargo aparecer en pantalla.

Ahora una pequeña variación, cambio únicamente el valor de yf, en vez de 300 vale ahora 50.

swf para abrir >>>> proyeccion2b.swf
archivo flash para descargar >>>> proyeccion2b.fla

Entonces, de nuevo, ¿a dónde se fugan los objetos cuando aumenta la coordenada z?

>>>tarea: tome 8 objetos gráficos y construya un cubo ubicando en el espacio sus vértices.

 

2.1.1 construcción de un cubo (con vértices)

Para crear el cubo lo más fácil es, quizá, pensar en en los 4 vértices de una cara frontal, y luego en 4 puntos iguales excepto por la coordenada z.

swf para abrir >>>> cubo.swf
archivo flash para descargar >>>> cubo.fla

Ojo: he variado los parámetros ll e yf. Insisto: luego veremos estos parámetros en qué inciden aunque ya debería haber al menos una intuición al respecto.

 

2.1.2 ¿qué pasa cuando un objeto se ubica atrás del punto de proyección?

En los ejemplos que hemos visto hemos utilizado coordenadas de z negativos, esto quiere decir que el objeto se sitúa por delante de la pantalla. Y no ha habido problema. Veamos los casos en el siguiente esquema:

 

proyección desde arriba 3


Cuando z es mayor que -ll, o, dicho de otra manera, cuando el objeto que queremos representar está atrás del punto de vista no es muy claro cómo debe proyectarse el objeto. Por lo pronto veamos qué es lo que hace nuestra función de proyección cuando se le pide que proyecto un objeto atrás del punto de vista:

swf para abrir >>>> proyeccion3.swf
archivo flash para descargar >>>>proyeccion3.fla

Empíricamente podemos comprobar que la función se comporta mal y que escala adquiere valores negativos.

¿Qué se hace para evitar este eventual problema? En algunos casos controlaremos que nunca se intente proyectar objetos en coordenadas inferiores a -ll. También es posible hacer una mejoría a la función para que cuando la coordenada z del objeto sea inferior a -ll en vez de proyectar el objeto lo haga invisible.

 

2.1.3 control de parámetros: ll, xf y yf

Para observar las consecuencias de modificar ll, zf e yf lo mejor es crear aplicaciones que me permitan cambiar estos parámetros de forma continua.

La siguiente aplicación asigna a los valores de xf e yf las coordenadas del cursor.

swf para abrir >>>> cubo2.swf
archivo flash para descargar >>>> cubo2.fla

La conclusión empírica es que xf y yf son las coordenadas del punto de fuga hacia atrás. Efectivamente esto es así y puede también ser deducido de los esquemas de 1.3.

Ahora, para observar el comportamiento de ll, vamos a modificarlo únicamente con el movimiento vertical del cursor:

swf para abrir >>>> cubo3.swf
archivo flash para descargar >>>> cubo3.fla

Observe que cuando la coordenada y del cursor es más pequeña que 100, se da el caso en el que se proyectan objetos (los 4 vértices anteriores del cubo) por detrás del punto de vista, dando lugar a extraños comportamientos.

Cuando ll se hace grande se ve cómo se pierde profundidad de campo. Cuando ll se reduce, en cambio, aumenta la profundidad de campo. Podemos asumir entonces que ll es el ángulo focal de la cámara.

Si bien aquí he realizado unos ejercicios en los que ll, xf y yf varían dando lugar a un movimiento continuo, a partir de ahora estos parámetros quedarán fijos, habiendo sido ajustados de la mejor forma posible para cada caso, y lo que variará en el tiempo son los objetos y sus coordenadas.

>>>tarea: cree una construcción más sofisticada que un cubo, que involucre más objetos. Luego construya tres scrolls que controlen ll, xf y yf, para poder observar el comportamiento de la proyección variando estos tres parámetros.

 

2.1.4 variando ll

El siguiente esquema muestra qué ocurre cuando el valor de ll cambia:

 

 

Para el mismo par de objetos proyectados (dos objetos iguales con diferente coordenada z), al variar ll se observa una diferencia en la proporción de los dos objetos proyectados. Si ll es pequeño, la diferencia de tamaños entre los objetos proyectados es grande. Si ll es grande no se aprecia tanta diferencia entre los dos objetos proyectados. Dicho de otra forma ll determina qué tan acentuada está la perspectiva, qué tan grande es la profunidad de campo. Podemos pensar entonces que el valor de ll es equivalente a la apertura focal de un lente en una cámara.

 

2.1.5 control de niveles (swapDepths) con la coordenada z

Recuerde el archivo en el que se replican varios seres humanos en un plano. Voy a retomar este ejercicio pero haré un sutil cambio: los humanos tendrán ahora un contorno negro y un relleno blanco:

swf para abrir >>>> proyeccion4.swf
archivo flash para descargar >>>> proyeccion4.fla

Se hace latente un error de representación: algunos objetos que pro su tamaño indican que están atrás de otros, aparecen delante en el sentido vectorial de niveles. Es un problema de incosistencia de lenguaje gráfico. Para solcuionarlo tenemos que ajustar los niveles por vía del método swapDepths, otorgando niveles más altos a los objetos que estén más cercanos.

Es decir que para z altos -> nivel bajo y para z bajo -> nivel alto. Para esto nos sirve la siguiente relación:

nivel = 999999 - z

Así, al crecer z el nivel disminuye (aun si z es negativo esta ecuación nos vale). Finalmente, el valor de z puede ser un número no entero y la función proyección funciona bien. En cambio los valores de nivel deben ser números enteros, para lo cual se utiliza la función Math.floor.

De esta forma tenemos ya una función de proyección que ubica los objetos en niveles correctos:

swf para abrir >>>> proyeccion5.swf
archivo flash para descargar >>>> proyeccion5.fla

 

2.2 trazado con tres coordenadas

Ubicando puntos y otros objetos gráficos en el espacio es posible construir paisajes y mundos tridimensionales. Sin embargo se requiere del trazado para poder, por ejemplo, crear un cubo con aristas. Para esto construiremos funciones equivalentes a moveTo y lineTo pero que trazan en un espacio 3D.

 

2.2.1 moveTo3D, lineTo3D

Las funciones trazado son variaciones de la función de proyección, pero más simples, ya que en ellas no se involucra ningún objeto. Esto implica, por ejemplo, que ya no es necesario calcular ninguna escala.

En el primer ejemplo se traza con ellas un cubo. En este ejemplo como en los siguientes, no borraré la función proyección aunque no se use, ya que así vamos acumulando diferentes funciones que luego se combinarán.

swf para abrir >>>> cuboTrazado.swf
archivo flash para descargar >>>> cuboTrazado.fla

La función recibe un objeto, donde traza. En el ejemplo el objeto que se envía siempre es this, es decir, el stage.

>>>tarea: construya otros objetos tridimensionales:
-prisma
-pirámide
-círculo horizontal*
-cilindro*
-esfera**

>>>tarea: cree una función cubo que reciba tres coordenadas y un tamaño de lado, y luego utilízela para rellenar un espacio de cubos.*

>>>tarea: construya combinando trazado y proyección, por ejemplo una paisaje de cubos con individuos en el interior.*

Nota: a partir de ahora opera la siguiente convención para las tareas: *un poco difícil / ** difícil / *** muy difícil

 

2.2.2 curveTo3D


curveTo es una función que recibe dos pares de coordenadas, el primero configura un vector de dirección y el segundo el punto de llegada de la curva. Creamos, con la lógica de la creación de las funciones anteriores, una función curveTo3D.

swf para abrir >>>> curvas3D.swf
archivo flash para descargar >>>> curvas3D.fla

 


2.2.3 planos

Con el BeginFill, como muestra el ejemplo anterior, se pueden crear superficies.

Creando planos se puede luego crear construcciones más interesantes, incluso volúmenes.

Para el ejemplo siguiente creé una función que traza planos horizontales.

swf para abrir >>>> planos.swf
archivo flash para descargar >>>> planos.fla

ídem, con planos verticales:

swf para abrir >>>> planos2.swf
archivo flash para descargar >>>> planos2.fla

>>>tarea: crear una función cubo, con caras de color, con planos horizontales y verticales

 

2.3 construcciones autónomas

Como en algunos ejemplos que he puesto, incluyendo los últimos, muchas veces es más fácil dejar que las cosas se construyan solas a construirlas, y más interesante. Esto evidentemente se hace bajo ciertos parámetros de control que, básicamente, se basan en ritmo y azar. Ritmo para repeticiones y secuencias, azar para ruido, desplazamientos, perturbación.

El siguiente ejemplo simula la creación de una ciudad, un modelo muy simple.

Para este ejemplo creé una función llamada cristal, que crea un polígono regular extrudeado, es decir un prisma de varias caras cuya base es un polígono regular.

swf para abrir >>>> ciudadcristal.swf
archivo flash para descargar >>>> ciudadcristal.fla

>>>tarea: ¿cómo moverse al interior de la ciudad?***

 

2.4 primer paso al movimiento en 3D

El movimiento en un espacio tridimensional se da de dos formas distintas: uno o varios objetos se mueven en el espacio, o, el espacio completo se mueve.

Decir que el espacio se mueve y la cámara se queda quieta es equivalente a decir que la cámara se mueve en el espacio. Así que si queremos crear un espacio en el cual moverse lo que haremos es, técnicamente, que todos los elementos del espacio se muevan en la misma dirección.

Comenzemos entonces por desplazar un objeto:

swf para abrir >>>> movimiento.swf
archivo flash para descargar >>>> movimiento.fla

En el ejemplo he atado las coordenadas x y z del cubo a la posición del cursor.

Más interesante es que el cursor no determine la posición del objeto sino la dirección de movimiento.

De esta forma el cursor marca una dirección de movimiento, un vector. Este vector [vx, vy] se llama vector velocidad.

swf para abrir >>>> movimiento2.swf
archivo flash para descargar >>>> movimiento2.fla

Y a continuación, una versión con más cubos, que fueron creados previamente y de forma aleatoria. El resultado es entonces una especie de viaje a través de un paisaje de cubos.

Observe que antes de representar cada cubo se verifica que la coordenada z de éste no sea muy pequeña para evitar el error antes mencionado.

swf para abrir >>>> movimiento3.swf
archivo flash para descargar >>>> movimiento3.fla

>>>tarea: compruebe qué ocurre si elimina el código (el if) que verifica que la coordenada z del cubo sea lo suficientemente grande para representarlo.

>>>tarea: construya una ciudad con prismas, personas, textos... el juego de 3D y texto es muy interesante

>>>tarea: cree una interface de información navegable*

>>>tarea: ¿cómo verificar cuando la cámara se acerca a un objeto? Es decir, cómo aprovechar el paisaje navegable para recrear situaciones típicas de juego: estrellarse contra objetos, recoger cosas... evidentemente esto ya alude al juego de snowboard.**


Nota: está claro que ya estamos aproximándonos a un 3D para juegos, con movimiento e interacción. El último ejemplo ya permite crear desde juegos hasta interfaces tridimensionales de información.

 

3. técnicas de movimiento

Por supuesto existen infinidad de técnicas de movimiento y movimiento interactivo. Pero hay unas pocas que son claves, porque son simples de usar, no consumen mucho procesador y son versátiles. Llamo movimiento interactivo a toda técnica de control de posición que se adapte fácilmente a cambio de parámetros.

Hay dos tipos de movimiento interactivo que son recurrentes:

- en el que un objeto se desplaza hacia una posición determinada
- en el que un objeto se desplaza en una dirección determinada

También conviene nombrar los movimientos más emergentes, en donde hay un comportamiento interesante que escapa -total o parcialmente- al control de la persona que interactúa. Aquí cabe nombrar los movimientos regidos por la aleatoridad, y los movimientos al interior de un sistema de simulación de espacio con reglas físicas (por ejemplo, la simulación del tiro parabólico).

Pensando en un snowboardista (¿como se dice correctamente esto?) mientras su tabla esté en contacto con la nieve éste puede girar y derrapar, pero luego de separarse del suelo (pasando una rampa) está a merced de la gravedad.

3.1 algoritmos de movimiento generales


3.1.2 algoritmo de frenado y variantes

El algoritmo de frenado es probablemente el más común ya que se basa en cálculos mínimos y se adapta a muchas situaciones. Sirve para llevar el valor de una variable a cualquier otro valor de forma no lineal, desacelerando para acercarse lentamente al valor de llegada. Aquí se puede ver el algoritmo en acción:

swf para abrir >>>> frenado.swf
archivo flash para descargar >>>> frenado.fla

Este algoritmo recuerda las paradojas de Zenon.

Es posible por supuesto variar la velocidad. Si el algoritmo se basa en obtener un promedio dos coordenadas, bajo la idea del promedio ponderado se puede hacer que la variable cambie de forma más conservadora dándole más peso a su valor presente en relación al valor final.

swf para abrir >>>> frenado2.swf
archivo flash para descargar >>>> frenado2.fla

Finalmente, controlando la variable lentitud, haciéndola variar a su vez con un algoritmo de frenado para que comienze siende muy grande y luego crezca podemos hacer que un objeto inicie lentamente su trayecto, acelere y luego desacelere:

swf para abrir >>>> frenado3.swf
archivo flash para descargar >>>> frenado3.fla

El algoritmo de frenado y sus variaciones es útil no sólo para desplazar objetos, sino también para rotarlos, escalarlos, modificar su color y en general, para modificar de forma elegante cualquier parámetro. A continuación un ejemplo que hace uso del algoritmo en el movimiento y cambio de escala:

swf para abrir >>>> mapa.swf

 

>>>tarea: cree un mosaico que conforma una imagen que se arma y desarma por medio de movimientos de frenado*

.>>>tarea: transforme el código del ejemplo de desplazamiento en un espacio 3D involucrando un movimiento de frenado**.

.>>>tarea: controle el ángulo de un objeto (una brújula, un esquiador en una pista circular...) por medio de un algoritmo de frenado.

 

3.1.3 movimiento browniano

Descubierto por un botánico que le dio el nombre, este movimiento genera trazos fractales interesantes. Por sí mismo no es muy útil, pero combinado con otros movimientos sirve para dar perturbación realista.

swf para abrir >>>> browniano.swf
archivo flash para descargar >>>> browniano.fla

 


3.2 velocidad, aceleración: bases para modelos físicos

En el ejemplo anterior tenemos un parámetro que es velocidad, una magnitud constante. El ángulo en cambio se calcula aleatoriamente en cada paso.

La velocidad es el cambio de la posición, y la aceleración es el cambio de la velocidad. En un modelo basado en mecánica clásica la fuerza es proporcional a la aceleración, así que si se conocen las fuerzas, se conoce la aceleración. La aceleración modifica la velocidad y la velocidad la posición.

Por ahora basta con controlar bien la velocidad y entenderla como un vector, esto es, en dos dimensiones, dos valores, un vector [vx, vy] que puede ser también visto como un ángulo y una magnitud.

swf para abrir >>>> velocidad.swf
archivo flash para descargar >>>> velocidad.fla

 


3.3 gravedad, caída libre, colisión, fricción

Es posible modelar un mundo con leyes físicas basado en la mecánica clásica. A continuación un ejemplo en el que se incluye el modelado de la gravedad, la colisión, la fricción, la adherencia y el comportamiento de los resortes.

swf para abrir >>>> pegajoso.swf

La gravedad es una fuerza constante en el eje y. Como en las pantallas el eje y está orientado hacia abajo pues la gravedad es una cantidad psoitiva. Como dijimos antes, decir fuerza constante equivale a aceleración constante.

A continuación un pequeño modelo de caída libre con colisión. La colisión se modela de la siguiente forma: cuando el objeto llega a un obstáculo vertical, la magnitud le velocidad horizontal vx se invierte. Y la fricción del aire es un vector opuesto de magnitud proporcional a la velocidad, lo que es equivalente a decir que la velocidad pierde una fracción en cada paso.

swf para abrir >>>> gravedad.swf
archivo flash para descargar >>>> gravedad.fla

 

>>>tarea: cree un juego tipo pong*.

>>>tarea: cree un juego tipo bricker*

>>>tarea: cree un juego tipo bricker, pero con gravedad**

>>>tarea: modele la inercia de esta forma: con el cursor se puede "agarrar" un objeto, cuando el cursor suelta al objeto este debe continuar el movimiento.**

>>>tarea: ídem, pero con gravedad**

>>>tarea: cree un modelo de gravedad similar al último ejemplo, pero en 3D, dentro de un cubo**

>>>tarea: comience a reflexionar sobre el problema de un objeto que se desliza por una superficie con cierta topografía, y que de vez en cuando se desprende de ella para quedar a merced de la gravedad hasta que hace contacto de nuevo con el suelo.

 

3.4 movimiento circular

El esquema siguiente muestra las bases de la trigonometría, en la que se relacionan ángulos con distancias:

 

círculo

 

Las funciones coseno y seno (Math.cos y Math.sin) son la base de la descripción de todo movimiento no sólo circular, sino, en general, todo movimiento suave y cíclico. Estas funciones serán utilizadas en la creación de la pista de snow. Por eso conviene jugar un poco con ellas, aprender a dominarlas. A continuación una serie de archivos en donde se realizan diferentes ejercicios con estas funciones.

swf para abrir >>>> movimientocircular.swf
archivo flash para descargar >>>> movimientocircular.fla

swf para abrir >>>> senoycoseno.swf
archivo flash para descargar >>>> senoycoseno.fla

La medusa, a continuación, es un ejemplo de uso de funciones armónicas (seno y coseno) para crear simulación de movimiento suave:

swf para abrir >>>> medusa.swf


>>>tarea: modifique los archivos anteriores para crear otras nuevas funciones de movimiento basadas en seno y coseno. Por ejemplo: en el caso del movimiento circular, ¿qué pasa si el ángulo del coseno y el del seno son diferentes?

 

4. movimiento en espacio 3D a través de elementos


Ahora nos aproximaremos más al juego de snowboard. La idea es poder desplazarse por un espacio 3D en el que se hallen diferentes elementos. La dificultad de esto, si queremos crear un trayecto largo en el espacio, es que no es posible representar a la vez cientos de elementos. Pensando en una pista de snowboard, se deberían representar sólo objetos que estén adelante y relativamente cerca, conforme los objetos pasen atrás desaparecen, y nuevos objetos irán apareciendo adelante. Es una técnica muy común en videojuegos.

La cuestión es cómo hacemos esto.

En esta lección la clave está en estudiar muy bien los dos únicos archivos que la componen.

En el siguiente ejemplo creé un vector que guarda la información que será utilizada para ubicar personas en el espacio 3D. Ubica 500 personas en un rango de coordenadas estrecho horizontalmente pero muy amplio en el eje z (como ocurrirá con la pista de snow). Todos los elementos, que en este ejemplo son sólo clips (humanos) que tienen asociados sus coordenadas x y z y un color, están en orden en el vector, es decir, un elemento siguiente a otro está más atrás.

El criterio para representar un objeto es que su coordenada z esté entre dos valores límites, un valor hacia atrás y un valor grande. Entre más amplio sea este margen más objetos serán representados.

Como el vector de objetos está ordenado por coordenada z el conjunto de objetos representables es un segmento del vector, que empieza en un índice (min) y termina en otro (max).

Para saber cuáles son estos índices en el ciclo se verifica constantemente las coordenadas z de los elementos alrededor de los índices hasta entonces calculados, con la posibilidad de aumentarlos o disminuirlos. Si el límite inferior se reduce o el superior aumenta aparece un nuevo elemento en el espacio. En este primer ejemplo los elementos son clips que se descargan de la biblioteca y a los que se le asigna un color. Inversamente, si el límite inferior aumenta o el superior disminuye hay que eliminar los elementos. Está claro que si el desplazamiento es hacia adelante los índices sólo aumentan y aparecen elementos en frente y desaparecen atrás. A diferencia del juego de snow, en este ejemplo es posible retroceder.

swf para abrir >>>> movimiento4.swf
archivo flash para descargar >>>> movimiento4.fla

El siguiente ejemplo aumenta en complejidad incorporando diferentes elementos. La clave está en una variable llamada tipo que indica qué tipo de elemento tridimensional es.

swf para abrir >>>> movimiento5.swf
archivo flash para descargar >>>> movimiento5.fla

 

>>>tarea: ¿cómo detectar cuando uno pasa cerca a un elemento? no es muy difícil porque conocemos las cordenadas tridimensionales en las que se representa el objeto. En el humano, por ejemplo son:

[objetos[i][1]+xespacio, 300, objetos[i][2]+zespacio]

Así que para saber si estamos muy cerca a un humano basta con que

limiteizquierda < objetos[i][1]+xespacio < limitederecha

y

objetos[i][2]+zespacio < limiteprofundidad

donde limiteizquierda, limitederecha y limiteprofundidad son valores determinados que determinan que tan cerca se requiere pasar del objeto para detectar colisión.
La tarea es entonces adjudicar un comportamiento -ejecutar un sonido por ejemplo- cuando se pase cerca a un objeto*.

>>>tarea: cree un personaje que irá adelante de la cámara (se pierde el punto de vista subjetivo). Por medio de animación haga que el individuo se vea diferente cuando gira hacia un lado o hacia el otro*.

>>>tarea: con la función curve3D traze un camino curvo que uno pueda seguir**.

>>>tarea: con la función curve3D traze dos líneas curvas para que se genere así una pista curva**.

>>>tarea: añádale al anterior una forma de verificar cuándo uno está dentro o fuera de la pista**.

>>>tarea: introduzca la variable y, que el paisaje no sea plano sino que suba y baje***.

 

Nota: las tareas planteadas nos acercan bastante al juego de snowboard. Efectivamente, en el juego la pista se irá armando conforme se avanza, como en cualquier juego de este tipo.

Un ejemplo de espacio 3D navegable en varias direcciones y que también se va formando alrededor de uno conforme se avanza es la interface paisaje de GNOM:

>>>>> http://moebio.com/santiago/gnom

En este ejemplo también se puede observar una técnica que utilizaremos posteriormente que es representar los objetos de forma más simple cuando están lejos. Conforme se acercan adquieren apariencia más completa: más aristas, planos, colores.

En actionScript hay que cuidar mucho el gasto de procesador, y los espacios 3D en general consumen mucho debido a los cálculos matemáticos y gráficos.

Cuando creemos la pista de snow mostraremos detalles sólo en las partes de la pista más cercanas.

Es el momento de ir pensando en cómo se va a construir esta pista, de alguna manera ya tenemos todos los elementos.




Escalera de Pistas

A continuación una serie de archivos (una escalera) que paso a paso llevan a la creación de una pista de snowboard.

El resultado final no es sólo visual sino que comprende un modelo físico que calcula la velocidad del tablista en función de la inclinación de la pista y de su ángulo.

El último archivo ya está próximo a ser un videojuego, falta incluir elementos con los cuales colisionar o atravezar.


swf para abrir >>>> snow0.swf
archivo flash para descargar >>>> snow0.fla

snow0.swf > Basado en el ejercicio anterior de movimientos4.swf, en vez de objeto hay segmentos horizontales en el piso, regados un poco al azar.

swf para abrir >>>> snow1.swf
archivo flash para descargar >>>> snow1.fla

snow1.swf > Los segmentos se organizan bajo una función sinusioidal. Entre cada segmento hay la misma distancia (hay que recordar bien cómo funciona el ejercicio movimiento4.swf). Ya se sugiere una pista.

swf para abrir >>>> snow2.swf
archivo flash para descargar >>>> snow2.fla

snow2.swf > Se conectan los segmentos por los laterales, la pista se hace más evidente

 

OJO: conforme voy haciendo variaciones que aumentan la complejidad del archivo también voy variando algunos parámetros como ll, xf e yf.

swf para abrir >>>> snow3.swf
archivo flash para descargar >>>> snow3.fla

snow3.swf > Cambios en algunos parámetros para que no se vieran desaparecer los segmentos más próximos.

 

swf para abrir >>>> snow3b.swf
archivo flash para descargar >>>> snow3b.fla

snow3b.swf > Pequeña variación: elimino los segmentos horizontales, quedan sólo las curvas externas.

swf para abrir >>>> snow4.swf
archivo flash para descargar >>>> snow4.fla

snow4.swf > Ahora la pista no es plana, sino que sube y baja, también gracias a una función sinusoidal (observar que los bloques de pista son transparentes)

swf para abrir >>>> snow5.swf
archivo flash para descargar >>>> snow5.fla

snow5.swf > Ahora los bloques de pista son blancos; se cambió el orden en que se dibujaban, ahora los últimos en dibujarse son los más próximos, para que taapen a los que están atrás.

swf para abrir >>>> snow6.swf
archivo flash para descargar >>>> snow6.fla

snow6.swf > Ahora "la cámara va montada encima de la pista", esto quiere decir que todos los bloques de la pista suben y bajan para que respecto a las coordenadas fijas del espacio, la baldosa más cercana esté siempre a la misma altura, ya que el snowbordista está siempre encima de la pista.

swf para abrir >>>> snow7.swf
archivo flash para descargar >>>> snow7.fla

snow7.swf > Colores! creé una función que devuelve un color dependiendo de la coordenada z del bloque. utilizé funciones sinusoidales para que los colores variaran suave y cíclicamente.

swf para abrir >>>> snow8.swf
archivo flash para descargar >>>> snow8.fla

snow8.swf > Aquí tomé una vía de trabajo que luego abandoné, y es poner la pista sobre un piso; la pista ya no flota en los aires sino que reposa sobre un suelo. Tiene algunos problemas a los que habría que meterle un poco de trabajo, por ejemplo los bloques más lejanos aparecen bruscamente, y se siente como saltos... la idea para mejorar esto es que los bloques aparezcan paulatinamente. Para poder hacer este "suelo" tuve que trazar objetos a mitad bidimensionales y tridimensionales.. son rectángulos que tienen puntos comunes con los bloques de la pista (3D) y luego se van a los bordes de la pantalla (2D).

swf para abrir >>>> snow9.swf
archivo flash para descargar >>>> snow9.fla

snow9.swf > ¡Modelo físico! Hasta ahora la velocidad hacia adelante dependía de la posición vertical del ratón, ahora depende de la inclinación de la pista. La inclinación se mide restando la altura del segmento justo anterior a del más cercano adelante. La aceleración es proporcional a la velocidad y, como sabemos, la aceleración es el incremento de la velocidad.

swf para abrir >>>> snow10.swf
archivo flash para descargar >>>> snow10.fla

snow10.swf > Cambios en la forma de la pista. Se complejizó un poco, ya no es sólo una onda sinusoidal sino una suma de varias ondas, cada una con su frecuencia y amplitud diferentes. Entre más funciones sinusoidales haya más rica será la forma de la pista. Por otro lado controlar esta forma no es fácil, lo mejor es hacer muchas pruebas! Estas formas sinusoidales son usadas acá para la forma horizontal de la pista como la vertical.
Si hubiera tiempo, lo que debería hacerse aquí es una aplicación con la cual ecualizar ondas y diseñar pistas (exactamente como se diseña una onda con un sintetizador de sonido). Ver: http://moebio.com/santiago/sintetizador

swf para abrir >>>> snow11.swf
archivo flash para descargar >>>> snow11.fla

snow11.swf > Se sofistica un poco el modelo físico: el movimiento horizontal aumenta la fricción y disminuye la velocidad hacia adelante. Aquí se pone más en evidencia un problema que venimos arrastrando: la baldosa más cercana se representa con errores, se ve un ruido visual muy molesto.

swf para abrir >>>> snow12.swf
archivo flash para descargar >>>> snow12.fla

snow12.swf > con el ánimo de solucionar el problema del bloque más cercano, he aumentado limiteminz para que la baldosa más cercana estñe con seguridad suficientemente adelante, y aparte he dibujado un bloque cortado, que va desde la coordenada z=0 (es decir, la de la pantalla) hasta el primer bloque. Para esto he calculado donde cortan los puntos del bloque si lo hubiera representado completo, y dibujo un bloque cuyas aristas son estos dos puntos de corte y las aristas del siguiente bloque. Es equivalente a cortar el bloque con al plano de la pantalla. En esta versión se ve como la pista pasa un poco por encima del límite inferior de la pantalla, y podríamos pensar que se ve el corte.

swf para abrir >>>> snow13.swf
archivo flash para descargar >>>> snow13.fla

snow13.swf > Colores de nuevo, se baja la pista (se representa sumándole unos píxeles) para que no corte la pantalla.

swf para abrir >>>> snow14.swf
archivo flash para descargar >>>> snow14.fla

snow14.swf > Ahora el control de movimiento son las flechas del teclado. Una flecha nos enseña la dirección. Aquí hay sinembargo un pequeño error: la asceleración máxima se alcanza cuando uno se desplaza hacia adelante. Y lo que debería hacerse es que la aceleración máxima se alcance cuando la dirección de movimiento sea paralela a la pista.

 

swf para abrir >>>> snow15.swf
archivo flash para descargar >>>> snow15.fla

snow15.swf > Ahora la fricción aumenta en función de la diferencia entre el ángulo de la pista y el ángulo propio (del snowboardista), así, cuando los ángulos coinciden, la tabla es paralela a la pendiente, y se da el caso del mínimo rozamiento.

swf para abrir >>>> snow16.swf
archivo flash para descargar >>>> snow16.fla

snow16.swf > Curvatura en la pista! Ahora ya no hay segmentos sino curvas, tomando como punto de curvatura uno que esté en el centro de los dos extremos, y desplazado unos cuantos píxeles hacia abajo.

swf para abrir >>>> snow17.swf
archivo flash para descargar >>>> snow17.fla

snow17.swf > El mundo gira. Ojo a la nueva disposición de clips. las coordenadas del stage vuelven a ser 0,0, en cambio cree un clip llamada todo que contiene otro llamado espacio, que es donde se grafica ahora. Además de espacio hay otro clip llamada cielo en el que se descargar el clip gráfico con el cielo. Y el clip todo rota en función de mi distancia al borde de la pista. Para eso utilizo la variable xderecha (la coordenada en pantalla del extremo derecho del punto de la pista en coordenada z=0).

swf para abrir >>>> snow18.swf
archivo flash para descargar >>>> snow18.fla

snow18.swf > Este vale la pena verlo en pantalla completa. Pongo límites a xespacio, la coordenada x del snowboarder, así ya no se sale del espacio. El cielo cambia de posición vertical en función de la inclinación, y se acentúa así el vértigo vertical de la pista.

Observación: varias de las variables (como el ángulo o la posición vertical de la flecha) se manejan con un algoritmo de frenado para que cambien suavemente.