====== 5. Personajes (Actors) ====== Este capitulo cubrirá el tema del actor de forma general y de los detalles 2D del actor durante su creacion. Para el que este interesado en actores 3D, habrá un capítulo dedicado a ello llamado “ir al 2.5D”, así que tened paciencia, que ya llegaremos. Anteriormente, ya habíamos visto varios métodos asociados al objeto actor, hemos visto como agregar un actor tanto al juego como a la escena. Bien ahora veremos como hacer al actor andar, hablar, establecer su dirección, etc. bien, veamos como esta formado el actor molly incluido en el juego, así que abre el fichero “data\actors\molly\molly.actor” y enseguida vemos que no es un script, sino que es un fichero de definición. Bien dividamos el archivo en varias partes y explicaremos cada una poco a poco. ; $EDITOR_PROJECT_ROOT_DIR$ ..\..\..\ Normalmente, los ficheros de definición de WME empiezan con ; Esto significa que esas lineas son comentarios( // o /* */ no esta soportado en los ficheros de definición y serán causa de error ). Pero esta linea que tenemos aquí, es especial y lo que indica es la profundidad en la que estamos en la estructura de carpetas del proyecto, es decir, donde esta la raíz del proyecto. Esto es importante mas adelante en los ficheros de escena, donde si se mueve a una escena que esta mas profundamente dentro del directorio, deberemos cambiar este valor para que cuadre con nuestra estructura, o si no el juego no funcionara correctamente. Importante: En los ficheros de definicion, las lineas no acaban con el punto y coma, como ocurre en los ficheros de scripts. ACTOR { Así empieza el bloque de datos cuando definimos un actor. NAME = "molly" CAPTION="" SCALABLE = TRUE INTERACTIVE = FALSE X = 400 Y = 460 SCRIPT="actors\molly\molly.script"   FONT = "fonts\outline_red.font" **NAME** → Es el nombre interno del actor. **CAPTION** → Es la etiqueta que habíamos visto en el fichero game_loop.script para mostrar la etiqueta de cualquier nodo de nuestra escena. **SCALABLE** → Puede tomar el valor true, o false, y define si el actor sera afectado por los niveles de escalado de nuestra escena, o escalado manualmente mediante un método interno. **ROTATABLE** → También puede tomar true o false, lo que haría seria que nuestro personaje se vea afectado por los niveles de rotación de la escena que ya vimos en el capitulo dedicado a las escenas. **INTERACTIVE** → Significa que el actor es sensible al control del ratón. Si ejecutamos nuestro juego, y ponemos el cursor del ratón sobre el personaje de molly, el juego no realiza nada, ya que INTERACTIVE esta establecido en falso. Si cambias este valor a true, puedes ver como molly se convierte en un objeto mas interactuable de la escena. **X and Y** → son las coordenadas iniciales del actor en la pantalla. **SCRIPT** → especifica un fichero de script que será automáticamente cargado al actor cuando este se carga. Puedes tener múltiples lineas como esta para indicar que queremos cargar varios scripts. **FONT** → es el fichero de fuente de texto usada para el metodo actor.Talk que ya hemos usado varias veces. Y hay dos mas: **SOUND_PANNING** → permite true o false, y que si se define como true sería desplazar automáticamente el sonido de la izquierda a la derecha según la posición en pantalla del actor. **COLORABLE** → también permite true o false, y si lo establecemos a true, hace que el actor se vea afectado por las regiones de decoración. Bien, veamos un poco de teoría, para tener un actor completamente definido en nuestra escena, necesitamos definir cinco grupos de animaciones básicas( andar(walk), hablar(talk), desocupado(idle), turnleft(girar a la izquierda), turnright(girar a la derecha) ). En la documentación de wintermute, claramente se dice que: Recuerda que el actor es capaz de caminar en ocho direcciones, por lo que necesitaras ocho versiones de esta animación para cada una de las direcciones. Si solo tienes cuatro creadas para tu carácter, es posible usar una animación para varias direcciones, pero en el archivo de definición, es necesario definir estas ocho direcciones. Por ejemplo, si tienes una animación para que el actor ande hacia la izquierda, puedes establecer esta animación tanto para andar a la izquierda, como para andar diagonalmente hacia la izquierda. Bien, veamos nuestra primera animación llamada walk(andar): ANIMATION { NAME = "walk"   LEFT = "actors\molly\ll\walk.sprite" RIGHT = "actors\molly\rr\walk.sprite" UP = "actors\molly\uu\walk.sprite" DOWN = "actors\molly\dd\walk.sprite"   UP_LEFT = "actors\molly\ul\walk.sprite" UP_RIGHT = "actors\molly\ur\walk.sprite" DOWN_LEFT = "actors\molly\dl\walk.sprite" DOWN_RIGHT = "actors\molly\dr\walk.sprite" } Como ves, asignamos diferentes sprites a cada una de las ocho posibles direcciones, y esto es lo que vemos en estas lineas. Hay una cosa especial sobre las animaciones de andar, cuando construyes tu actor con el editor de sprites, tienes que establecer el parámetro “Move By” para cada frame. Esto define como de rápido se moverá el actor por nuestra escena. La siguiente animación que vemos es llamada idle(desocupado): ANIMATION { NAME = "idle"   LEFT = "actors\molly\ll\stand.sprite" RIGHT = "actors\molly\rr\stand.sprite" UP = "actors\molly\uu\stand.sprite" DOWN = "actors\molly\dd\stand.sprite"   UP_LEFT = "actors\molly\ul\stand.sprite" UP_RIGHT = "actors\molly\ur\stand.sprite" DOWN_LEFT = "actors\molly\dl\stand.sprite" DOWN_RIGHT = "actors\molly\dr\stand.sprite" } No hay nada especial que comentar sobre la animación de desocupado. Puedes añadir animaciones en las que el personaje estornuda, tose, o da una voltereta, eso queda a gusto del diseñador. Las siguientes dos animaciones, se denominan turnleft(giro a la izquierda) y turnright(giro a la derecha) y con ellas podemos conseguir que cuando el actor gire se pueda ver de forma mas real. Como son idénticas, pondré solo el código correspondiente a una de ellas: ANIMATION { NAME = "turnleft"   LEFT = "actors\molly\ll\turn.sprite" RIGHT = "actors\molly\rr\turn.sprite" UP = "actors\molly\uu\turn.sprite" DOWN = "actors\molly\dd\turn.sprite"   UP_LEFT = "actors\molly\ul\turn.sprite" UP_RIGHT = "actors\molly\ur\turn.sprite" DOWN_LEFT = "actors\molly\dl\turn.sprite" DOWN_RIGHT = "actors\molly\dr\turn.sprite" } El ultimo bloque corresponde a la animación talk(hablar): ANIMATION { NAME = "talk"   LEFT = "actors\molly\ll\talk.sprite" RIGHT = "actors\molly\rr\talk.sprite" UP = "actors\molly\uu\talk.sprite" DOWN = "actors\molly\dd\talk.sprite"   UP_LEFT = "actors\molly\ul\talk.sprite" UP_RIGHT = "actors\molly\ur\talk.sprite" DOWN_LEFT = "actors\molly\dl\talk.sprite" DOWN_RIGHT = "actors\molly\dr\talk.sprite" } Podemos definir mas de un bloque de la animación de talk(hablar). Si lo hacemos, wme aleatóriamente reproducirá las animaciones y hará que el actor parezca mas real. También es posible definir estancias de Talk que posteriormente podremos invocar con un parámetro especial en el método Talk. Si creamos una animación especial como por ejemplo guiñar un ojo, entonces podremos con una linea invocar esta animación, así podremos añadir todas las estancias de talk que queramos. Bien, resumiendo, por defecto si llamamos al método actor.Talk(“Hola, como va todo? Bla bla bla”); todas las animaciones llamadas talk se reproducirán aleatoriamente. El método completo es actor.Talk(texto, fichero_sonido, duración, estancia_talk, alineamiento_de_texto); Como veis permite muchos mas parámetros de los que veníamos usando. **Texto** → Es el texto que nuestro actor dira. Hasta ahora era el único parámetro que veníamos usando. **Fichero_sonido** → este es un parámetro obsoleto, veremos porque cuando lleguemos al capitulo de localización, ya que en la ultima versión del motor, wme automaticamente selecciona el fichero de sonido a reproducir de acuerdo al fichero de la tabla de cadenas. Así que si no vamos a usar voces, pondremos null en este parámetro. **Duración** → normalmente, tampoco es usado. El texto automáticamente es sincronizado con el fichero de voz, luego podremos volver a usar null. **estancia_talk** → aquí es donde podemos especificar el orden y las instancias que usaremos al hablar. Si este parámetro no se proporciona, solo podrá usar un subconjunto de las posturas al hablar. **alineamiento_texto** → Define el alineamiento de las lineas escritas. Luego un ejemplo del método Talk totalmente definido, seria: actor.Talk(“hola”,null,null,”guiño”); nuestro actor dice hola, usando la animación guiño que previamente hubiéramos definido en el fichero actor. Como nota comentar que siempre usamos la variable actor para interactuar con el actor, pero si queremos cambiar esto, podemos hacerlo de la siguiente forma: En el fichero base.inc declararemos: global Peter; global Sally; Peter = Scene.LoadActor("ruta del fichero actor peter"); Sally = Scene.LoadActor("ruta del ficehro actor sally");   Peter.GoTo(100,100); Sally.Talk("blahblahblah"); Como ves, de esta manera podemos ver que ya no usamos actor.GoTo() ni actor.Talk() sino que hemos creado dos variables nuevas, y en este caso 2 actores. Volvamos a las animaciones: También es posible crear animaciones no estandars como(coger, empujar, pulsar, etc), las cuales serán referenciadas a partir de scripts. Como vemos, no es difícil crear nuevos actores, siempre y cuando tengamos los gráficos adecuados. Ahora veamos algunos métodos mas del objeto actor: **actor.PlayAnim(“ruta del sprite”)** → reproduce una animación definida como un fichero sprite y espera hasta que la animacion a terminado. **actor.PlayAnimAsync(“ruta del sprite”)** → reproduce una animación definida en el fichero del actor, y después continua. **Actor.reset()** → cancela la accion actal que esta realizando el actor (hablar, andar) **actor.TurnTo(objeto o dirección)** → hace que el actor gire a la dirección a la que apunta un objeto definido en el editor de escenas, o usando una constante de dirección. Finalmente, puedes modificar las animaciones por defecto( por ejemplo correr, nadar, o volar sustituyen andar). Este libro no intenta sustituir la documentación de wme. Hay otros métodos y atributos que podemos usar con nuestros actores. Es recomendable mirarlos y ver que mas cosas podemos hacer con nuestros actores, de esa manera tendremos un gran control sobre ellos.