Differences

This shows you the differences between the selected revision and the current
version of the page.


es:wmebook:ch4 2013/05/26 12:21 es:wmebook:ch4 2013/05/26 12:56 current
Line 1: Line 1:
 +====== 4. Empezar de cero ======
 +
 +
Hasta el momento hemos experimentado con los recursos que nos integra wme, hemos estado trabajando con las imágenes de la demo, ahora es el momento de tomar el control y comenzar a crear nuestro propio juego desde 0. Inicia el administrador de proyectos y presiona ctrl+N o presiona en File → New. Dale un nombre a tu proyecto y creemos nuestro propio juego. Hasta el momento hemos experimentado con los recursos que nos integra wme, hemos estado trabajando con las imágenes de la demo, ahora es el momento de tomar el control y comenzar a crear nuestro propio juego desde 0. Inicia el administrador de proyectos y presiona ctrl+N o presiona en File → New. Dale un nombre a tu proyecto y creemos nuestro propio juego.
Line 123: Line 126:
} }
</code> </code>
 +
 +Lo que conseguimos con esto, es que cuando pulsamos click con el botón izquierdo del ratón, comprobamos si el el click fue echo sobre un punto caliente esto lo sabemos mediante el atributo ActiveObject del objeto Game, que lo que hace es devolver el objeto que esta activo en cada momento. Por lo que reduciremos nuestras opciones a 2, si hacemos click en un objeto, aplicaremos el evento “LeftClick” sobre el objeto. Por otro lado, si hacemos clic sobre un punto de la escena, se aplicara el evento “LeftClick” sobre la escena.
 +
 +Si clickeamos en algún punto de la pantalla, donde no hay ningún cursor debajo, se dispara el evento “LeftClick” de la escena.y te preguntaras, ¿“LeftClick” de escena?
 +
 +Esto es otro de los trucos de WME, si vas a tu escena en el editor de escenas y vas a la tabla de propiedades de la escena, pulsa sobre Scripts y te sale una ventana donde puedes ver que hay dos scripts agregados: scene_init.script y scene.script. Y esta es la plantilla que cada escena nueva contendrá. El scene_init.script, ya lo habíamos estudiado en el capitulo anterior(contenía todas las instrucciones necesarias que queríamos que se ejecutaran al iniciar la escena). Ahora veamos que contiene el fichero “scene.script”:
 +
 +<code script>
 +#include "scripts\base.inc"
 +
 +on "LeftClick"
 +{
 +  actor.GoTo(Scene.MouseX, Scene.MouseY);
 +}
 +</code>
 +
 +Pues simplemente lo que vemos, cuando hacemos clic en algún lugar de la escena que no es un punto caliente se lanza el evento que se encuentra en este script, si hacemos clic en un punto caliente, el evento on “LeftClick” que se lanzará, sera el de ese objeto, región, entidad,... que pulsemos.
 +
 +Bueno, pues cuando se lanza el evento de la escena, simplemente lo que hará, sera ejecutar esta instrucción:
 +
 +<code script>
 +actor.GoTo(Scene.MouseX, Scene.MouseY);
 +</code>
 +
 +Que simplemente se encarga de mover a nuestro personaje al punto de la pantalla donde hayamos clickeado.
 +
 +Veamos ahora el próximo evento, el “RightClick”, vayamos al fichero game.script, y eliminemos todo el código que se encuentra en el evento on “RightClick”,  ya que lo único que hará sera marearnos y no nos es necesario, por lo tanto, borremos todo.
 +
 +Los últimos dos eventos, son “Keypress” y “QuitGame” estos dos controlan la pulsación de teclas, en este caso, cuando pulsamos escape, nos sale el menú del juego, pues esto es controlado por el evento “Keypress” y el evento “QuitGame” se encarga de todas las operaciones necesarias cuando se cierra el juego, no os preocupéis mucho por ahora por estos eventos, pues pronto los estudiaremos.
 +
 +Espero que sigáis bien las instrucciones, y lo mas importante que lo vayáis entendiendo, espero que vayáis entendiendo bien hasta aquí.
 +
 +Nota, no olvidar que cuando modificamos algún script, es necesario guardarlo, sino los cambios no servirán de nada.
 +
 +Bueno, recapitulemos un poco, y veamos que métodos y atributos hemos visto hasta ahora:
 +
 +**var window = Game.LoadWindow(window filename);** → carga un archivo de definicion de ventana y lo añade al objeto Game, y opcionalmente devuelve una referencia a el, que es posible almacenar en una variable.
 +
 +**window.Visible = true / false;** → es un atributo del objeto window, que hace que la ventana sea visible o invisible en la pantalla.
 +
 +**window.GetControl(controlname);** → devuelve una referencia a un control almacenado en una ventana.
 +
 +**Game.LoadActor(actor filename);** → carga un actor de un fichero de actor y lo añade al objeto juego.
 +
 +**Scene.LoadActor(actor filename);** → carga un actor de un fichero y lo añade al objeto escena.
 +
 +**Game.MainObject = actor;** → selecciona el actor como el objeto principal del juego y sera el que hara el seguimiento del scrolling.
 +
 +**Game.ActiveObject;** → almacena una referencia al objeto sobre el objeto sobre el que se posa el raton en cada momento.
 +
 +**Game.ApplyEvent(eventName);** → es un metodo que lanza un evento asociado al objeto Game.
 +
 +**Scene.ApplyEvent(eventName);** → igual que el anterior pero un evento asociado al objeto scene.
 +
 +**Node.ApplyEvent(eventName);** → lanza un evento asociado al objeto node sobre el que lo aplicamos.
 +
 +Para entender mejor estos últimos métodos, veamos un ejemplo aplicado a la puerta que vimos en el capitulo anterior:
 +
 +<code script>
 +var door = Scene.GetNode("Door");
 +door.ApplyEvent("LeftClick");
 +</code>
 +
 +Con esto lo que haríamos sera hacer un evento LeftClick sobre la puerta, sin que el jugador físicamente tenga que pulsar, esto a veces es útil en momentos de animación, por ejemplo cuando un jugador entra en una escena y el personaje automáticamente se va hacia un punto de la escena, y hace algo, pues estos eventos son útiles para eso.
 +
 +Antes de seguir, veamos si tu fichero game.script es como el mio.
 +
 +<code script>
 +#include "scripts\base.inc"
 +#include "scripts\keys.inc"
 + 
 +// almacena algunos atributos del juego en variables globales
 +Keyboard = Game.Keyboard;
 +Scene = Game.Scene;
 + 
 +// load the "caption" window
 +var win = Game.LoadWindow("interface\system\caption.window");
 +global WinCaption = win.GetControl("caption");
 + 
 +// carga el actor principal
 +actor = Game.LoadActor("actors\molly\molly.actor");
 +Game.MainObject = actor;
 + 
 +// ejecuta el script de demonios
 +Game.AttachScript("scripts\game_daemon.script");
 + 
 +// carga la escena inicial
 +Game.ChangeScene("scenes\Room\Room.scene");
 + 
 + 
 + 
 +on "LeftClick"
 +{
 +  var ActObj = Game.ActiveObject;
 +  if(ActObj!=null)
 +  {
 +    ActObj.ApplyEvent("LeftClick");
 +  }
 +  else
 +  {
 +    Scene.ApplyEvent("LeftClick");
 +  }
 +}
 + 
 +on "Keypress"
 +{
 +  // on Esc or F1 key
 +  if(Keyboard.KeyCode==VK_ESCAPE || Keyboard.KeyCode==VK_F1)
 +  {
 +    // carga y muestra la ventana del menu principal
 +    WinCaption.Visible = false;
 +    var WinMainMenu = Game.LoadWindow("interface\system\mainmenu.window");
 +    WinMainMenu.Center();
 +    WinMainMenu.GoSystemExclusive();
 +    Game.UnloadObject(WinMainMenu);
 +  }
 +}
 + 
 +on "QuitGame"
 +{
 +  // on Alt+F4 (window close)
 +  // carga y muestra la ventana de salir del juego
 +  WinCaption.Visible = false;
 +  var WinQuit = Game.LoadWindow("interface\system\quit.window");
 +  WinQuit.Center();
 +  WinQuit.GoSystemExclusive();
 +  // and if the user selected Yes
 +  if(WinQuit.xResult)
 +  {
 +    // sale del juego
 +    Game.QuitGame();
 +  }
 +  // en otro caso descarga la ventana de la memoria y del juego
 +  else Game.UnloadObject(WinQuit);
 +}
 +</code>
 +
 +Bien, ahora probemos el juego, y vemos, que aun funciona, solo hemos hecho unos pequeños cambios sobre el.
 +
 +Ahora para continuar, veamos el fichero game_loop.script.
 +
 +<code script>
 +#include "scripts\base.inc"
 +
 +global WinCaption;
 +global WinMenu;
 +</code>
 +
 +Podemos eliminar fácilmente la linea global WinMenu; ya que hemos decidido eliminar el menú en el botón derecho.
 +
 +<code script>
 +while(true){
 +</code>
 +
 +Esto siempre será verdadero. Se trata de un bucle infinito. Para finalizar este bucle, debemos llamar la función Game.DetachScript(“scripts\game_loop.scrip”);
 +
 +<code script>
 +var ActObj = Game.ActiveObject;
 +</code>
 +
 +Como vemos, la misma linea que en el fichero game.script, constantemente el juego esta comprobando cual es el objeto bajo el ratón.
 +
 +<code script>
 +if(Game.Interactive && ActObj!=null)
 + {
 +</code>
 +
 +Primero comprueba si el juego esta en modo interactivo, y después si el cursor del ratón esta sobre algún objeto activo. Hagamos esta condición mas simple.
 +
 +En el cuerpo de la condicion borraremos lo que ahi y meteremos lo siguiente:
 +
 +<code script>
 +if(Game.Interactive && ActObj!=null)
 +{
 +      WinCaption.X = Game.MouseX;
 +      WinCaption.Y = Game.MouseY + 20;
 +      WinCaption.TextAlign = TAL_LEFT;
 +      WinCaption.Text = ActObj.Caption;
 + 
 +      WinCaption.SizeToFit();
 +      if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width;
 +      if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height;
 + 
 +    WinCaption.Visible = true;
 +    WinCaption.Focus();
 +}
 +else WinCaption.Visible = false;
 +</code>
 +
 +Bien,¿ que pasara ahora si el cursor se encuentra sobre algún objeto?
 +
 +<code script>
 +WinCaption.X = Game.MouseX;
 +WinCaption.Y = Game.MouseY + 20;
 +</code>
 +
 +WinCaption contiene una referencia al campo de texto que se encuentra dentro de la ventana caption cargada en game.scipt. Con estas lineas, establecemos su posicion en las mismas coordenadas que nuestra posición X del ratón y la posición Y + 20 pixeles, de esta manera, el nombre del objeto sobre el que situamos el cursor, aparece cercano a este.
 +
 +<code script>
 +WinCaption.TextAlign = TAL_LEFT;
 +WinCaption.Text = ActObj.Caption;
 +</code>
 +
 +Con estas dos lineas, establecemos el alineamiento del texto de esta ventana a la izquierda, y establecemos que el texto de esta ventana, sea el nombre que le hayamos asignado a ese objeto en nuestra escena.
 +
 +<code script>
 +WinCaption.SizeToFit();
 +</code>
 +
 +Redimensionamos la ventana caption al mismo tamaño que el texto que se muestra.
 +
 +<code script>
 +if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth – WinCaption.Width;
 +</code>
 +
 +Si la anchura del campo excede de el ancho de la pantalla, establecemos la posición X de la ventana caption exactamente hasta el final, esto lo hace basándose en la resolución de la pantalla, se hace para evitar que el texto se pierda por los bordes de la pantalla.
 +
 +<code script>
 +if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight – WinCaption.Height;
 +</code>
 +
 +Exactamente hace lo mismo que la linea anterior, pero esta vez aplicado a la coordenada Y.
 +
 +<code script>
 +WinCaption.Visible = true;
 +WinCaption.Focus();
 +</code>
 +
 +Una vez que hemos aplicado todos esos cambios, hacemos la ventana caption visible y nos la activa( WinCaption.Focus() ) pero en nuestro caso no es necesario, ya que no interactuaremos sobre esa ventana, así que simplemente podemos eliminar esa linea.
 +
 +<code script>
 + }
 +else WinCaption.Visible = false;
 +</code>
 +
 +Esto significa que si el juego esta en modo no interactivo o el cursor se mueve fuera de algún punto caliente, mantenga esta venta oculta.
 +
 +<code script>
 + if(Game.Interactive && Game.MouseY < 45 && !Game.ResponsesVisible && !WinMenu.Visible) Game.InventoryVisible = true;
 +
 +  else if(Game.MouseY > 100 || Game.ResponsesVisible || !Game.Interactive) Game.InventoryVisible = false;
 +</code>
 +
 +Estas dos lineas, hacen que se muestre o no el inventario, y simplemente para nuestro ejemplo las eliminaremos.
 +
 +<code script>
 +Sleep(20);
 +</code>
 +
 +Recuerdas lo que comentábamos sobre los bucles infinitos, que era necesario realizar una pequeña pausa para dejar la cpu libre a otros procesos, pues bien aquí hacemos uso de esa técnica.
 +
 +Ahora revisemos como nos tiene que quedar nuestro fichero game_loop.script:
 +
 +<code script>
 +#include "scripts\base.inc"
 + 
 +global WinCaption;
 + 
 +//bucle infinito
 +while(true){
 +  var ActObj = Game.ActiveObject;
 + 
 +  if(Game.Interactive && ActObj!=null)
 +  {
 +      WinCaption.X = Game.MouseX;
 +      WinCaption.Y = Game.MouseY + 20;
 +      WinCaption.TextAlign = TAL_LEFT;
 +      WinCaption.Text = ActObj.Caption;
 +      WinCaption.SizeToFit();
 +      if(WinCaption.X + WinCaption.Width > Game.ScreenWidth) WinCaption.X = Game.ScreenWidth - WinCaption.Width;
 +      if(WinCaption.Y + WinCaption.Height > Game.ScreenHeight) WinCaption.Y = Game.ScreenHeight - WinCaption.Height;
 +    WinCaption.Visible = true;
 +  }
 +  else WinCaption.Visible = false;
 +  Sleep(20);
 +}
 +</code>
 +
 +Como puedes ver, esta es la columna vertebral de un proyecto. Sin inventario, sin menú, simplemente point and click game. Esto es algo que estamos viendo para que os deis cuenta la forma de funcionar de wintermute, si vais teniendo claras las ideas, podréis cambiar la forma en la que salen estas ventanas, el texto que sale, etc etc. poco a poco podréis modificar estos script y hacer cosas bastante potentes.
 +
 +Ahora pasaremos al siguiente elemento de nuestro proyecto, el actor.
 
es/wmebook/ch4.1369563696.txt.gz · Last modified: 2013/05/26 12:21 by dongo
Recent changes RSS feed Creative Commons License Driven by DokuWiki