Please login or register.

Login with username, password and session length
Advanced search  

News:

Forum rules - please read before posting, it can save you a lot of time.

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - Juan Bonair

Pages: [1] 2 3
1
Foro técnico / Re: Empezando y con problemas.
« on: January 12, 2011, 06:29:59 PM »
¿eso no tendría mucho mas código, al tener que dividir la pantalla de manera diagonal?
Sí, cortar la pantalla en diagonal requeriría mucho más código o mucho más conocimiento de trigonometría del que tengo de momento.

¿podrían hacerse animaciones para que, al girarse a un lado o a otro, quedara mas natural?
Sí, WME maneja animaciones intermedias para que los actores giren más naturalmente. Molly, el actor por defecto de WME, tiene para cada dirección un sprite llamado turn.sprite, y en la definición del actor —molly.actor— tiene dos campos llamados "turnleft" y "turnright" (girar a la izquierda y girar a la derecha). El problema es que por defecto está vacío, y yo nunca investigué mucho de eso. En la documentación dice que sirve para dar más naturalidad a los actores, como por ejemplo el hecho de que las personas en realidad giramos los pies primero para cambiar de dirección.

¿no podría activar un script para todas estas situaciones aparte, y enlazarlo desde los objetos para, así, tener menos código?
Sí. Tendrías que definir el método en un script aparte, usando la palabra method en lugar de function. Luego, en algún script del actor —preferentemente el que viene en la misma carpeta que su definición y sus animaciones— añadir
Code: [Select]
this.AttachScript(/* Acá, el script en que definiste tu método */);y listo, ya podrás usar el TurnToObject() con la misma soltura que el Talk() o el GoToObject(), sin tener que definirlo cada vez. El script podrías añadirlo a cualquier objeto, pero me parece más conveniente al actor, sólo por una cuestión de organización.

el codigo para activar otra animación en el prota (y ya que estamos, en el otro personaje), ¿cómo se haría?
Es muy fácil. Tendrías que crear un sprite con tu animación y luego
Code: [Select]
actor.PlayAnim("actors\molly\golpear.sprite");donde quieras que ejecute la animación.

Y sí, que se fue un poco por las ramas el hilo.


2
Foro técnico / Re: Empezando y con problemas.
« on: January 12, 2011, 06:12:30 AM »
Bien, lo del evento "Take" no es ningún misterio: simplemente hace que se ejecute la función TurnToObject() y que el personaje diga algo. Ahora bien, ¿cómo funciona el método TurnToObject()?
Pues a seguir te pongo el cógido bastante comentado:
Code: [Select]
function TurnToObject() // Acá declara la función —o método— y la llama "TurnToObject" (voltear hacia el objeto).
{ // Todo lo que sigue hasta que se cierre esta primera llave es la función TurnToObject().

/*

A continuación declara algunas variables que se van a usar en la función. En este caso las variables no son
necesarias. Es decir, podríamos sacar la línea "var ActX = actor.X;" siempre y cuando reemplacemos luego todos los
"ActX" por "actor.X". Al progamador simplemente le pareció que, ya que lo iba a tipear muy seguido, convenía algo
corto como "ActX" y no "actor.X", que tiene más letras y encima requiere el meñique de la mano derecha, que debe de
ser el dedo que menos se usa al teclear.

*/

var ActX = actor.X; /* La variable ActX será la posición X del actor. O sea, su posición horizontal. O sea, el
largo —medido en pixeles— de la recta más corta entre los pies del actor y el borde izquierdo del juego. */

var ActY = actor.Y; // Lo mismo, pero con la posición vertical. Del borde superior hasta sus pies.

var Entity = Scene.GetNode(self.Name); /* Entity será nuestro objeto hacia el que hay que mirar.
Supongo que también valdría "var Entity = self;". */

var EntityX = Entity.X; // Aquí tenemos cómo nos referiremos a la posición X del objeto (equivale a "self.X").

var EntityY = Entity.Y; // Y aquí su posición Y.

/*

Muy bien, a continuación empieza el código en serio.

*/

// Acá empieza la PRIMERA PARTE (hay tres), se ejecuta si el actor está más de 20 pixeles por debajo del objeto.
if(ActY > EntityY + 20)
{
if(ActX > EntityX + 30) // Si el actor está más de 30 pixeles a la derecha del objeto...
{
actor.TurnTo(DI_UPLEFT); // ...que mire arriba a la izquierda.
return;
}
else if(ActX < EntityX - 30) // Si está más de 30 pixeles a su izquierda...
{
actor.TurnTo(DI_UPRIGHT); // ...que mire arriba a la derecha.
return;
}// Y si no está tan a su izquierda ni tan a su derecha...
else if(ActX >= EntityX)
{
actor.TurnTo(DI_UP); // ...que mire directamente hacia arriba.
return;
}
else if(ActX <= EntityX) // Y aquí repite un poco. Pone una nueva condición que de todos modos hace mirar
{ // al actor hacia arriba. No sé por qué lo hace, pero lo hace.
actor.TurnTo(DI_UP);
return;
}
}

// Acá empieza la SEGUNDA PARTE, se ejecuta si el actor está más de 20 pixeles por encima del objeto.
else if(ActY < EntityY - 20)
{
if(ActX > EntityX + 30) // Si el actor está más de 30 pixeles a la derecha del objeto...
{
actor.TurnTo(DI_DOWNLEFT); // ...que mire abajo a la izquierda.
return;
}
else if(ActX < EntityX - 30) // Si está más de 30 pixeles a la izquierda...
{
actor.TurnTo(DI_DOWNRIGHT); // ...que mire abajo a la derecha.
return;
} // Si nada de lo anterior...
else if(ActX >= EntityX)
{
actor.TurnTo(DI_DOWN); // ...que mire directo hacia abajo.
return;
}
else if(ActX <= EntityX)
{
actor.TurnTo(DI_DOWN);
return;
}
}

// Acá empieza la TERCERA PARTE, se ejecuta si el actor está a 20 pixeles o menos de la altura del objeto.
else
{
if(ActX > EntityX + 30) // Si el actor está más de 30 pixeles a la derecha del objeto...
{
actor.TurnTo(DI_LEFT); // ...que mire a la izquierda.
return;
}
else if(ActX < EntityX - 30) // Si está más de 30 pixeles a la izquierda...
{
actor.TurnTo(DI_RIGHT); // ...que mire a la derecha.
return;
} // Y si no está tan a la derecha ni a la izquierda, teniendo en cuenta que tampoco está tan arriba ni abajo...
else if(ActX >= EntityX)
{
GoToObject(); // ...que directamente vaya hacia el objeto.
return;
}
else if(ActX <= EntityX)
{
GoToObject();
return;
}
}
}
No sé si es de lo mejor, porque digamos que corta la pantalla en cuadrícula para fijarse cuál es la posición del actor con respecto a la del objeto, cuando en realidad daría un efecto más realista cortarla en ocho partes, como de pizza. Pero bueno, me dejo de metáforas y explico un poco.

El código de la función cuenta con tres partes. Primero chequea si el actor está más de 20 pixeles por debajo del objeto, luego si está más de 20 por encima, y luego si ninguna de las dos anteriores. O sea, técnicamente, divide la pantalla en 3 franjas horizontales y se fija en cuál está el actor: si en la del medio, de 40 pixeles de alto (con centro en el objeto); en la de arriba (todo lo que está arriba de la del medio); o en la de abajo.

Cada una de esas tres partes del código está a su vez dividida en tres partes. Cuando ya identificó si está por encima, por debajo o ninguna, chequea si está más de 30 pixeles a la derecha del objeto, luego si está otro tanto pero a la izquierda, y luego si está más en el medio. Divide la pantalla (técnicamente) en tres columnas: una central (con centro en el objeto) de 60 pixeles de ancho, una a la izquierda y otra a la derecha. Y se fija en cuál está el actor.

Dividiendo la pantalla así en 9 partes, con centro en un rectángulo de 60 por 40 centrado al objeto, se fija qué hacer: si está en la parte que corresponde a la esquina superior izquierda, pues mirará abajo a la derecha, si está en la parte que está justo encima del objeto, pues mirará hacia abajo. Y si se encuentra en la parte central, está tan cerca del objeto que lo mismo vale un GoToObject() y listo.

Es decir, así es como yo lo veo. Lo que no entiendo es por qué en vez de subdividir las tres partes en otras tantas, las divide en cuatro. Si te fijás, cada una de las tres partes tiene en realidad cuatro bloques if(), y no entiendo por qué, ya que los últimos dos siempre dan el mismo resultado, lo mismo valdría que fueran uno solo.
Pero bueno, no sirve de nada intentar de descifrar las cosas raras que salen de las cabezas retorcidas de los programadores.

Como ya dije, cualquier explicación que invente se me hace igual de difícil que el código mismo, así que no te avergüences de no haberme entendido ni jota.

3
Foro técnico / Re: Empezando y con problemas.
« on: January 12, 2011, 02:34:05 AM »
¡Genial que hayas logrado sortear los pequeños problemas!
Es cierto, me había olvidado que el código del juego usa ego en vez de actor.
Y cazzo, sí, es italiano. Supongo que lo uso en reemplazo de carajo, aunque nunca supe exactamente qué significaba (su empleo en mi bocabulario es de herencia familiar).

Voy preparando una explicación más detallada del código...

4
Foro técnico / Re: Empezando y con problemas.
« on: January 06, 2011, 01:04:21 AM »
Sobre el bicho amarillo, ya me fijaré cómo se puede explicar más o menos bien la construcción de árboles de diálogo.
Para lo de mirar hacia el bicho sin caminar hacia él, tengo dos soluciones posibles. Una es difícil y no sé si funciona a la perfección, y la otra es fácil y no sé si funciona a la perfección.

La manera difícil la conozco del demo del juego Fred —creo que nunca se terminó—, cuyo código estaba a libre disposición de cualquiera pero no logro encontrar la descarga por ninguna parte, de modo que sólo tengo el que descargué yo mismo. El script de una caja en la escena dice así:
Code: [Select]
#include "scripts\base.inc"

//este script está asociado a la caja de madera de debajo de la estantería


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  TurnToObject();
  ego.Talk("/HABFRED012/Pone frágil.");
  ego.Talk("/HABFRED013/Esa caja ya estaba ahí cuando me instale hace 10 años.");     
  ego.Talk("/HABFRED014/Nunca ha sido abierta, la de misterios que debe esconder.");
}


////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  GoToObject();
  Game.Interactive = false;
  ego.Talk("/HABFRED015/¡NO! Yo no seré quien profane..."); 
  ego.TurnTo(DI_DOWN);
  ego.Talk("/HABFRED016/...LA CAJA...", "scenes\HabitFred\chan.ogg"); 
  ego.Talk("/HABFRED017/Además, conlleva ejercicio físico.");
  Game.Interactive = true;
 
}

////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  GoToObject();
}


////////////////////////////////////////////////////////////////////////////////
function GoToObject()
{
  ego.GoTo(385, 420);
  ego.TurnTo(DI_UP);
}

///////////////////////////////////////////////////////////////////////////////
function TurnToObject()
{
  var ActX = ego.X;
  var ActY = ego.Y;
  var Entity = Scene.GetNode(self.Name);
  var EntityX = Entity.X;
  var EntityY = Entity.Y;

  if(ActY > EntityY + 20)
  {
    if(ActX > EntityX + 30)
    {
      ego.TurnTo(DI_UPLEFT);
      return;
    }
    else if(ActX < EntityX - 30)
    {
      ego.TurnTo(DI_UPRIGHT);
      return;
    }
    else if(ActX >= EntityX)
    {
      ego.TurnTo(DI_UP);
      return;
    }
    else if(ActX <= EntityX)
    {
      ego.TurnTo(DI_UP);
      return;
    }
  }
  else if(ActY < EntityY - 20)
  {
    if(ActX > EntityX + 30)
    {
      ego.TurnTo(DI_DOWNLEFT);
      return;
    }
    else if(ActX < EntityX - 30)
    {
      ego.TurnTo(DI_DOWNRIGHT);
      return;
    }
    else if(ActX >= EntityX)
    {
      ego.TurnTo(DI_DOWN);
      return;
    }
    else if(ActX <= EntityX)
    {
      ego.TurnTo(DI_DOWN);
      return;
    }
  }
  else
  {
    if(ActX > EntityX + 30)
    {
      ego.TurnTo(DI_LEFT);
      return;
    }
    else if(ActX < EntityX - 30)
    {
      ego.TurnTo(DI_RIGHT);
      return;
    }
    else if(ActX >= EntityX)
    {
      GoToObject();
      return;
    }
    else if(ActX <= EntityX)
    {
      GoToObject();
      return;
    }
  }
}
En el evento "LookAt" hay una llamada al método TurnToObject() (línea 9), que no es de WME, sino que es creado por el programador en el mismo script (a partir de la línea 37). Cualquier manera posible de explicarlo se me hace igual de complicada que el mismo código, y no creo que pertenezca al nivel básico de programación que estamos barajando aquí.

La manera fácil se me acaba de ocurrir y es así:
Code: [Select]
on "LookAt"    // Al mirar al bicho
{
    actor.GoToObjectAsync(this);    // comenzar a caminar hacia él,
    Sleep(100);    // esperar una décima de segundo
    actor.Reset();    // y dejar de caminar.
    actor.Talk("Si tenemos suerte, estoy mirando hacia el bicho en cuestión.");
}
Los métodos GoToAsync() y GoToObjectAsync() hacen lo mismo que GoTo() y GoToObject() respectivamente, sólo que en vez de esperar a que el actor llegue a destino, continúan ejecutando el código. Es como darle el puntapié inicial para que comience a caminar. Lo que hacemos es meter un Sleep() de 100 milisegundos para que el actor camine un poquitín hacia el bicho y luego lo detenemos en seco con un Reset(), que lo que hace es resetear cualquier acción que esté ejecutando —como hablar o caminar o reproducir un sonido—. No estoy completamente seguro, pero se supone que si el actor comienza a caminar hacia el bicho debería estar apuntando hacia él cuando lo frenás, consiguiendo lo que querías.


Lo de la basura me tiene perdido. No debería desaparecer. Por supuesto que podrías solucionarlo con
Code: [Select]
var Basura = Scene.GetNode("basura");
Basura.Active = true;
en el scene_init de tu escena, pero sería mejor averiguar por qué cazzo desaparece en primer lugar. No veo nada fuera de lo común en el script que mostraste, fijate que todos los sprites estén bien escritos, porque puede ser que le asignaras un sprite inexistente y que por lo tanto se borrara. Si algo está mal, tiene que ser en alguno de los scripts en que cambiás la escena.

5
Foro técnico / Re: Empezando y con problemas.
« on: December 29, 2010, 10:49:23 PM »
Está bien, está bien, que me olvidé de aclarar qué cazzo significa this.Active = false.

Todos los objetos de escena en WME tienen la propiedad Active, que determina si el objeto se vé o no.
Como estamos en el script de tu caja —la de la escena—, this.Active es la propiedad Active de tu caja.
Al volverla false (this.Active = false) tu caja se vuelve invisible.

Vos seguramente le asignaste el ítem caja a tu caja de la escena en SceneEdit > Entity properties > Item (sin código, sólo escribiendo "caja" en el espacio en blanco).
Lo único que pasa al hacer esto es que TakeItem("caja") automáticamente cambia la propiedad Active de tu caja a false, y que DropItem("caja") automáticamente cambia la propiedad Active de tu caja a true. Es decir, la caja de la escena se vuelve invisible cuando agarrás el ítem y visible de nuevo cuando lo soltás.

La solución que yo te ofrezco es hacerlo todo a través del código, y es mucho más fácil de lo que suena.
Claro que para hacerlo con el código, primero tenés que no hacerlo de la manera automática. Es decir, para que esto funcione tenés que borrar "caja" de SceneEdit > Entity properties > Item.

En el script de la caja escénica —la voy a llamar así para ahorrarme palabras, por oposición al ítem caja de tu inventario—, agregá this.Active = false; en la parte en que el actor agarra la caja. Esto ya lo hacía WME automáticamente tras Game.TakeItem("caja"), pero ahora lo estamos haciendo manualmente, porque vos borraste "caja" de SceneEdit > Entity properties > Item.

Y no sólo en "Take", también deberías agregar la misma línea de código en "martillo", porque también ahí querés que la caja desaparezca de escena.

Luego, como el ítem caja y la caja escénica no están automáticamente ligados, en el script del ítem caja podés usar Game.DropItem("caja") tranquilamente —o bien Game.DropItem(this), que para el caso vendría a ser lo mismo—, sin que WME ponga automáticamente la caja escénica de nuevo en su lugar original.

Acordate de que todo esto no va a servir de nada a menos que borres "caja" de SceneEdit > Entity properties > Item, que esa es la parte importante.

Otra manera de explicarlo, por si todavía queda dudoso:
Al ponerlo de la manera automática, WME automáticamente invisibiliza y visibiliza tu caja escénica. Vos querés que la invisibilice pero que no la visibilice luego. La manera automática hace las dos, no podés pedirle que haga una y no la otra. Entonces eliminamos la manera automática, y manualmente invisibilizamos la caja escénica cuando corresponde, sin visibilizarla luego.

Espero que esté claro, si no seguí preguntando y haré lo que pueda.

6
Foro técnico / Re: Empezando y con problemas.
« on: December 28, 2010, 06:02:18 AM »
¡Ah, hombre, por supuesto que DeleteItem("caja") detiene el código!
Menos mal que posteaste el código, realmente no tenía ningún sentido.
Lo que pasa es que eliminás el ítem caja desde el script del ítem caja.
Con DeleteItem("caja") la caja —como objeto del inventario— se elimina a sí misma y, por estar eliminada, no puede seguir ejecutando su propio script. Es como escribir "suicidarme" en mi lista de cosas para hacer mañana: no tiene sentido a menos que lo ponga a lo último.
Como la caja de la escena y la del inventario son dos objetos completamente diferentes, eliminar el ítem caja desde el script de la caja de la escena no genera problema alguno. Por eso podés eliminar el ítem desde la escena.

La solución para esto tiene que ser agregar
Code: [Select]
this.Active = false;en el código de la caja —ese que ni te planteás resumirlo— después de agarrar el ítem, y de ahí en más usar DropItem(). Como invisibilizaste la caja, no hay posibilidad de que DropItem() la devuelva a su sitio.

7
Foro técnico / Re: Empezando y con problemas.
« on: December 23, 2010, 02:22:03 AM »
Veo que estás con el asunto de los ítems, así que dejemos por un momento el misterioso caso del tacho de basura fantasma.

¿Probaste alternar Game.TakeItem() y actor.TakeItem() para ver qué resultados te da cada uno? No entiendo mucho del asunto, pero puede que esas dos maneras de implementarlo se comporten diferente. De todos modos no creo que modifique mucho, a menos que tu juego tenga más de un inventario.

La idea general es que, si le asignaste tu ítem a un objeto de la escena en SceneEdit, uses DropItem() para que el objeto vuelva a aparecer en la escena y DeleteItem() para eliminar tanto el ítem como el objeto correspondiente. (Justamente drop item significa soltar ítem y delete item significa eliminar ítem.) Claro que de pronto te surge esta cosa rara de que DeleteItem() no funciona apropiadamente —por lo que igual te sugiero que transcribas acá tu código, a ver si no será todo culpa de algún error corregible—, y hay que buscar alguna solución alternativa.

Se me ocurrió que hicieras toda la cosa manualmente, a través del cógido.
Si no te interesa en lo más mínimo que el personaje pueda soltar un ítem para que regrese a donde estaba antes de ser agarrado, directamente podrías hacerlo así en el script de la caja, por ejemplo:
Code: [Select]
on "Take"    // Al agarrar la caja.
{
    actor.TakeItem("caja");    // Sumar el ítem "caja" al inventario...
    this.Active = false;    // ...y volver la caja invisible.
}
Haciendo esto tendrías el mismo resultado, y DropItem() no devolvería la caja a su sitio.

Y está muy bien eso de que puedas combinar ítems directamente con la caja en la escena. Pero tendrías que repetir mucho código, creo que podría funcionar de la siguiente manera (en el script de la caja de tu escena):
Code: [Select]
on "martillo"    // Al usar el martillo en la caja...
{
    actor.Talk("Primero voy a agarrarla.");
    this.ApplyEvent("Take");    // ...agarrar la caja...
    actor.Talk("Ahora sí los combino...");
    var CajaDelInventario = Game.GetItem("caja");
    CajaDelInventario.ApplyEvent("martillo");    // ...y usar el martillo con el ítem "caja".
}
Al usar el método ApplyEvent() podés hacer que la caja sea agarrada sin que el jugador lo haga intencionalmente y podés combinar el martillo con la caja de la misma manera. Lo que hacés es forzar el evento "Take" en la caja en vez de hacerlo por acción del jugador. Sé que de momento no te ahorra tanto código, pero te lo comento porque quizá en el futuro agarrar un objeto desate muchas acciones (variables cambiando, mucho diálogo que va y viene) y de esta forma te asegurás que pase todo tal y como si lo hubieras agarrado antes de combinarlos.

8
Foro técnico / Re: Empezando y con problemas.
« on: December 19, 2010, 09:18:38 PM »
¡Gracias! No soy de tomar alcohol pero el jamón sí me gusta.

Si WME te recuerda la animación de la fuente andando debe ser porque tenés marcadas las opciones Remember nodes states (recordar los estados de los objetos) e Including sprites (inclusive sus sprites) en SceneEdit —en la pestaña Properties, que está justo debajo de la lista de objetos de tu escena—. Estas opciones hacen lo que dicen que hacen, y en este caso está bien que las tengas marcadas, pero recordá desmarcarlas en escenas donde no necesites recordar nada.

Para el sonido deberías agregar a tu scene_init.scipt algo así como
Code: [Select]
var Fuente = Scene.GetNode("fuente");    // Crear una variable Fuente que sea tu objeto "fuente", si es que se llama así.

switch(Fuente.GetSprite())    // ¿Qué sprite tiene tu fuente?
{
case "scenes\escena\fuenteon.sprite":    // Si tiene la animación "fuenteon.sprite"...
Fuente.PlaySound("sonidoareproducir.ogg",true);    // ...que reproduzca su sonido.
}
Es decir, al comenzar tu escena le preguntás a WME qué sprite tiene tu fuente, y si es "fuenteon" que reproduzca el sonido correspondiente. Le puse saltos de línea para los comentarios, pero también debería funcionar algo así como
Code: [Select]
var Fuente = Scene.GetNode("fuente");
switch(Fuente.GetSprite()) {case "scenes\escena\fuenteon.sprite":Fuente.PlaySound("sonidoareproducir.ogg",true);}

Te explico un poco lo de la variable Fuente, por las dudas:
1) Para referirnos a tu objeto fuente, hasta ahora lo habíamos llamado this, porque siempre lo hacíamos desde su propio script. Como ahora estamos en el script de tu escena, this ahora se referirá a tu escena, y por eso tenemos que buscar otra manera de referirnos a tu fuente.
2) En principio es sencillo, porque tenemos el método GetNode() ("obtener objeto"). Así, podemos referirnos a tu fuente como Scene.GetNode("fuente") (siendo "fuente" el nombre que tenga el objeto en tu escena).
3) El problema viene cuando queremos que tu fuente haga algo (en este caso, reproducir un sonido). Se supone que deberíamos escribir Scene.GetNode("fuente").PlaySound("sonido.ogg"). Pero esto —que Scene ejecute el método GetNode() y que el resultado de ese método (tu fuente) a su vez ejecute PlaySound()— es un fenómeno llamado anidamiento o bien nesting y WME todavía no lo incorporó (aunque se supone que WME2, que saldrá dentro de mucho mucho muchísimo tiempo, sí permitirá anidamientos).
4) De modo que lo que hacemos (como está en el script de acá arriba) es crear una variable Fuente que equivalga a Scene.GetNode("fuente") y luego hacer que esta variable reproduzca el sonido: Fuente.PlaySound("sonido.ogg").

9
Foro técnico / Re: Empezando y con problemas.
« on: December 19, 2010, 07:14:29 AM »
No es necesario andar contando las líneas, que el mismo editor de código te muestra en una barra inferior en qué línea está posicionado tu cursor.

Ah, y el error de la línea 37 pasa porque recién al llegar a la línea on "Talk" WME descubre que te olvidaste de poner la llave de cierre de on "Take".

Y mañana continúo contestando, que seguro que allá todavía estará radiante el sol pero acá en Buenos Aires estoy madrugando.

10
Foro técnico / Re: Empezando y con problemas.
« on: December 19, 2010, 05:02:20 AM »
Lo de la salida rápida es fácil, al script de tu salida deberías agregarle, sin borrar nada que ya tenga,
Code: [Select]
on "LeftDoubleClick"    // Al darle doble clic izquierdo...
{
 Game.ChangeScene("scenes\otraescena.scene");    // ...cambiar la escena.
}
que, como verás, es remitirnos a la acción "LeftDoubleClick" (doble clic izquierdo) en vez del común "LeftClick" y poner exactamente el mismo código pero sin el actor.GoToObject(this). O sea, decirle a WME que al hacer doble clic cambie de escena y nada más.

Y ya voy preparando la respuesta más elaborada a tus otros problemas.

11
Foro técnico / Re: Empezando y con problemas.
« on: December 16, 2010, 04:05:07 AM »
¡Momento! Qué boludo que soy, recién me doy cuenta que no sólo dice caracter inválido sino también error de sintaxis. Te explico un poco:

El método GetSprite() funciona para preguntarle a WME qué sprite tiene actualmente el objeto en cuestión (en este caso la fuente). Al ponerlo en el comando switch() le decimos a WME que haga diferentes cosas dependiendo de qué sprite tiene tu fuente. Es mi manera (una de muchas posibles) de saber si la fuente está andando o está parada.

Es decir, si tiene el sprite fuente.sprite, sé que está parada y le digo a WME que mi actor vaya y la prenda. Si tiene el sprite fuenteon.sprite, sé que está prendida y le hago hacer todo lo que haya que hacer si está prendida.

Como al momento de llamar al comando switch() no sabemos cuál de las dos va a pasar (o más bien, queremos que funcione para los dos casos), le preguntamos a WME si this.GetSprite("scenes\BUS\fuente.sprite") o bien this.GetSprite("scenes\BUS\fuenteon.sprite"), que es lo mismo que decir que si tiene el sprite original o el de estar funcionando.

Como estamos preguntando qué valor tiene su parámetro (qué sprite tiene GetSprite() entre sus paréntesis) no podemos asignarle uno. Puedo expandir más la explicación pero, haciéndola corta, la línea debería decir
Code: [Select]
switch(this.GetSprite()) dejando el parámetro de GetSprite() en blanco, es decir no escribiendo nada entre sus paréntesis.
Así, case "scenes\BUS\fuenteon.sprite": significa lo mismo que if(this.GetSprite("scenes\BUS\fuenteon.sprite")), es decir, ejecutar el siguiente código si el valor de this.GetSprite() equivale a "scenes\BUS\fuenteon.sprite".

Así es el comando switch(). Se pone una variable sin asignarle un valor y después se especifica qué debe pasar si tiene el valor tal o el valor cual.

Espero no marearte mucho. Sé que el comando switch() cuesta un poco más de entender que un simple if(), pero creeme que switch() se lee mucho mejor y esto mejora el código un montonazo. No hace mucha diferencia para el programa, pero es clave para el proceso humano de desarrollar un juego.

Y vamos, que sería lindo ver de una vez por todas un programador que no maneja mucho el inglés. Que no se vé todos los días.

[EDIT]Distinción del código, que es la parte importante del mensaje.[/EDIT]

12
Foro técnico / Re: Empezando y con problemas.
« on: December 16, 2010, 03:22:36 AM »
Y sí, molesta bastante no entender tu propio código, y peor si no se entiende mucho inglés, pero con el tiempo se le va agarrando la mano.
Por eso trato de comentártelo lo más que puedo.

Igual si te fijás en el reporte del compilador, te dice que la línea 18 del código tiene un caracter inválido, y eso pasa porque te olvidaste de poner scenes\BUS\fuente.sprite entre comillas.
Que es un error fácil de cometer, pero crucial a la hora de ejecutar el código.

13
Foro técnico / Re: Empezando y con problemas.
« on: December 15, 2010, 01:22:57 AM »
Por lo de la fuente, un demo de WME que yo tengo —y no encuentro el enlace de descarga en ningún lado— tiene un ventilador que funciona de la siguiente manera:

Code: [Select]
on "Take"
{
  actor.GoToObject(this);
  Game.Interactive = false;

  // get the fan entity
  var EntFan = Scene.GetNode("fan");

  // set the fan etity sprite depending on the state variable
  // (0-off, 1-normal, 2-false)

  if(StateRoom.FanSpeed==0)
  {
    actor.Talk("It's turned off. I'll turn it on...");
    actor.PlayAnim("actors\molly\ur\take1.sprite");
    EntFan.PlaySound("sounds\fan_start.ogg");
    actor.PlayAnim("actors\molly\ur\take2.sprite");
    Sleep(1400);
    EntFan.SetSprite("scenes\room\sprites\fan.sprite");
    StateRoom.FanSpeed = 1; // save the new fan state
  }

  else if(StateRoom.FanSpeed==1)
  {
    actor.Talk("It's running at normal speed. Let's make it spin faster...");
    actor.PlayAnim("actors\molly\ur\take1.sprite");
    EntFan.SetSprite("scenes\room\sprites\fan_fast.sprite");
    actor.PlayAnim("actors\molly\ur\take2.sprite");
    StateRoom.FanSpeed = 2;
  }

  else if(StateRoom.FanSpeed==2)
  {
    actor.Talk("OK, I'll turn it off.");
    actor.PlayAnim("actors\molly\ur\take1.sprite");
    EntFan.PlaySound("sounds\fan_stop.ogg");
    EntFan.SetSprite("scenes\room\sprites\fan_off.sprite");
    actor.PlayAnim("actors\molly\ur\take2.sprite");
    StateRoom.FanSpeed = 0;
  }

  Game.Interactive = true;
}

Sin embargo, me parece que puedo simplificarlo a lo siguiente:

Code: [Select]
on "Take"    // Al usar la acción en el objeto...
{
  actor.GoToObject(this);    // Que el actor vaya a él (opcional).
  Game.Interactive = false;    // Que el juego deje de ser interactivo (opcional).

  switch(this.GetSprite())    //  Establecemos el "sprite" de la fuente como variable a comparar.
  {

  case "scenes\MiEscena\sprites\fuente_normal.sprite":    // Si la fuente tiene su "sprite" por defecto.
    actor.Talk("Voy a cambiar el ''sprite'' de esta fuente");
    this.PlaySound("sounds\AguaCorriendo.ogg",true);    // Que la fuente reproduzca el sonido y que lo repita.
    this.SetSprite("scenes\MiEscena\sprites\fuente_haciendo_algo.sprite");    // Asignarle otro "sprite".
    break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\MiEscena\sprites\fuente_haciendo_algo.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Mejor la vuelvo a como estaba antes.");
    this.StopSound();    // Detener el sonido que estaba reproduciendo.
    this.SetSprite("scenes\MiEscena\sprites\fuente_normal.sprite");    // Devolverle su "sprite" anterior.

  }

  Game.Interactive = true;

Algunas claves para comprenderlo mejor:

1) Este no es el código entero que debería llevar tu fuente, es solamente el que corresponde a la acción "Take".

2) En realidad el comando switch() podría llevar una variable que adquiriera los valores true o false dependiendo de si la fuente está andando o no. En ese caso tendrías declararla (var FuenteAndando;) y escribir al final de cada case algo así como FuenteAndando = true; (o false, según sea el caso). Me pareció complicártela demasiado, ya que es más fácil directamente cotejar qué sprite tiene, como en mi ejemplo, que andar creando variables todo el tiempo. Por supuesto que ya es otro tema si querés que el juego recuerde en qué estado está la fuente anque hayas salido y entrado nuevamente a la escena, pero ya veremos eso cuando te haya funcionado y hayas entendido este script.

3) No sé cómo estabas implementando tu sonido. Creo más práctico usar un PlaySound("sonido.ogg",true) que insertar el sonido en el sprite mismo. Fijate que el método  PlaySound() tiene tres parámetros: el primero es qué sonido se reproduce y el segundo es si debe o no debe reproducirse en bucle, que por defecto queda en false si no lo especificás de otra manera (el tercero es a partir de qué punto comienza a repetirse el bucle y se mide en milisegundos, en este caso no lo usamos, es decir, lo dejamos en 0 por defecto y por lo tanto el sonido se repite desde el principio).

Y vamos, lo mismo de siempre, que avises de tus problemas y dudas si los hay. Primero esto de la fuente y después las demás dudas.

14
Foro técnico / Re: Empezando y con problemas.
« on: December 13, 2010, 05:49:27 AM »
Creo que sé lo que puede estar pasando y es un error bastante simple:

Cuando usás el método GoToObject(), WME primero se fija si el objeto en cuestión —en este caso el camino, representado en el script por la palabra this— tiene asignadas unas coordenadas a las que caminar, y si no las tiene directamente manda al actor a la posición del objeto en la escena.

Lo que supongo es que no le asignaste coordenadas a las que caminar en SceneEdit, y que tu actor sólo puede caminar a tus Camino2s porque tus Camino1s están fuera del área caminable (generalmente floor).

Estas coordenadas, y la dirección a la que debe apuntar el actor, se establecen sin script en SceneEdit, donde dice Walk to:. Espero que sea este el problema, porque no se me ocurre otra cosa. Si no era esto avisá, y si todo lo demás falla siempre podrás usar un GoTo() y marcar las coordenadas específicas, aunque entiendo que no es lo mejor.

15
Foro técnico / Re: Empezando y con problemas.
« on: December 11, 2010, 11:25:23 PM »
¡Excelente! Y sí, lo de dónde poner el Scene.SkipTo(actor); fue un error mío, te dije en qué script pero me olvidé de aclarar en qué parte. Aunque ya te haya salido, te hago una breve explicación: la cosa es primero posicionar al actor (con actor.SkipTo()) y recién después mover la escena al actor. De otra forma, la escena va a ir al actor, pero el actor —aún no posicionado— estará en la posición en que lo dejaste en la escena anterior.

Ahora vamos con lo de las entradas. Voy a ver cuán simple puedo contarlo.

1) En SceneEdit, seleccioná la entrada "X" (o el nombre que tenga) y luego cliqueá en "Scripts...". Creá un nuevo script y escribí lo siguiente:
Code: [Select]
#include "scripts\base.inc"

////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
global Entrada = "X";    // O el nombre que tenga, claro.
Game.ChangeScene("scenes\caca\caca.scene");    // Y acá la dirección real de tu segunda escena.
}
(Tené en cuenta que este es un ejemplo simple, tu entrada puede tener más código, como por ejemplo un buen actor.GoTo() para que tu personaje camine hacia la entrada antes de cambiar la escena. Lo importante es que el cambio de escena sea la úlitma línea antes de la llave de cierre.)

2) Idéntico procedimiento con la otra entrada, pero cambiando el valor de Entrada por su otro nombre.
Code: [Select]
#include "scripts\base.inc"

////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
global Entrada = "Y";
Game.ChangeScene("scenes\caca\caca.scene");
}

3) Editá el scene_init de tu segunda escena (en mi ejemplo, "caca.scene") para que empiece así:
Code: [Select]
#include "scripts\base.inc"

// here comes the stuff which initializes the scene
global Entrada;
switch(Entrada)
{
 case "X": actor.SkipTo(143, 422); break;
 case "Y": actor.SkipTo(637, 417);
}
(Cambiando "X" e "Y" por los respectivos valores que le hayas asignado a Entrada en los scripts anteriores. Después de este código vendría el actor.Active = true y el Scene.SkipTo(actor). Para mantenerlo simple, resumí cada caso (el X y el Y) en una sola línea que solamente manda al actor a su posición. En un ejemplo real tendrías que agregar la dirección a la que mira y cualquier otra cosa que quieras que pase según cuál entrada cliqueaste. Y siempre conviene poner saltos de línea en el código para que se vea más organizado.)

4) Arrancá el juego en modo de prueba (F5). Guardá la partida no bien empezaste. Cliqueá la primera entrada y fijate si funciona. Cargá la partida que guardaste y probá la otra entrada.

Y ya está. Este código lo probé yo mismo y a mí me funciona. Con esto ya tendrías una escena con dos salidas y otra con dos entradas. Probalo y decime si funcionó. Recién ahí preocupate por hacer el camino inverso (las dos entradas de la otra escena), aunque es prácticamente lo mismo que esto, e incluso podrías utilizar la misma variable global "Entrada". Cualquier cosa que no entiendas o no te salga, avisá.

Pages: [1] 2 3

Page created in 0.033 seconds with 21 queries.