Wintermute Engine Forum

Spanish forum => Foro técnico => Topic started by: bamyito on December 07, 2010, 06:20:15 PM

Title: Empezando y con problemas.
Post by: bamyito on December 07, 2010, 06:20:15 PM
Lo primero, un saludo a todos.
Desde hace ya muchísimos años soy aficionado a los juegos de aventuras. El dia que conocí a Manny Calavera descubrí cómo se debe contar una buena historia interactiva. Pero no voy a aburriros con mi vida.
Llevo mucho buscando un tutorial en español para este programa, y lo encontré hace poco. Aunque ya domino bien el editor de escenas y el editor de sprites, siguen surgiendo problemas que me gustaria que resolvieseis. Empecemos por los mas graves y problemáticos. ya os iré exponiendo más.

Cuando cambio de escena con el personaje, siempre se me coloca en mitad de la escena. Antes no podía ni moverlo, ya que se colocaba en una region no transitable. lo solucioné ampliando esa zona, pero solo es una solución provisional. ¿Cómo se consigue que el personaje se coloque en la entrada de la escena, y no en el centro? ¿y si tiene mas de una entrada la escena, tambien puedo colocarlo para que entre por ambas? Por ejemplo, dos caminos, uno superior y otro inferior. El camino superior debería conectar con el superior de la otra escena, y el inferior con el inferior.
¿Cómo logro esto?

Gracias de antemano. ;D
Title: Re: Empezando y con problemas.
Post by: YO on December 08, 2010, 12:57:24 AM
wenas, esto es bastante sencillo, jeje segun vayas aprendiendo te parecera mas sencillo lo de que aparezca en un lugar determinado viene definido en el script del scene_init de cada escenario que haces, asi para que cuando cambies a otra escena te aparece en el lugar que quieres pones esto en el scene_init de la escena a la que va a ir el personaje:
Code: [Select]
if(Game.PrevScene=="Room")
{
  actor.SkipTo(X, Y);
  actor.Direction = DI_UP;
}
al principio la Room es la escena desde la que el personaje viene a esta escena, la posicion en la que aparece es X,Y que tu le tienes que poner el valor deseado y el direction es hacia donde mira, DI_UP hacia arriba, DI_LEFT hacia la izquierda etc, de todas formas esto viene muy bien explicado en el tutorial que trae el programa, echa un vistazo a los scripts
un saludo!!! si necesitas mas ayuda x aqui andamos ;)
Title: Re: Empezando y con problemas.
Post by: Juan Bonair on December 08, 2010, 02:01:47 AM
Por lo de las entradas múltiples, una solución más práctica vendría a ser algo así:

Code: [Select]
switch(Game.PrevScene)    // Acá establecés la variable a comparar, en este caso "Game.PrevScene".
    {
        case "UnaEscena":    // Si la escena anterior se llamaba "UnaEscena", ejecutar el código siguiente hasta "break;".
            actor.SkipTo(40, 267);    // Llevar al personaje a las coordenadas señaladas (en este caso "40,267").
            actor.Direction = DI_UP;    // Poner al personaje mirando hacia arriba (de espaldas al jugador).
            break;

        case "OtraEscena":   // Si, en cambio, se llamaba "OtraEscena", ejecutar el código siguiente hasta "break;"
            actor.SkipTo(303, 86);    // Llevar al personaje a estas otras coordenadas.
            actor.Direction = DI_DOWN;    // Ponerlo mirando hacia abajo (de cara al jugador).
            break;

        case "UnaEscenaMas": actor.SkipTo(27, 86);
            actor.Direction = DI_LEFT;
            break;

        default:    // Si la escena anterior no se llama "UnaEscena" ni "OtraEscena" ni "UnaEscenaMas", ejecutar el código siguiente hasta el final.
            actor.SkipTo(23, 112);
            actor.Direction = DI_RIGHT;
    }

Espero se entienda.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 08, 2010, 06:35:34 PM
OK, codigo apuntado, probado y comprendido. Muchas gracias.
perdonad si hago preguntas demasiado evidentes para ustedes o que se encuentran en el tutorial, pero es que gran parte del tutorial (sobre todo la parte de scripts, que es la que de verdad me da problemas) está en inglés, y si no soy capaz de entender el lenguaje de programación (variables y demás) mucho menos en inglés.

Deacuerdo, ya puedo colocar al personaje donde y como quiera cuando entra en una escena o aparece en ella directamente. Ahora tengo otra pregunta. Supongamos 2 scenes, A y B. Y ahora supongamos dos accesos (X e Y) de A hasta B diferentes, y viceversa (un camino superior (X) y uno inferior (Y) en el mapa, por ejemplo). ¿Podría, desde la entrada X de la scene A llegar a la entrada X de la scene B y viceversa? ¿Podría hacer lo mismo con el camino Y, en ambas direcciónes (de A a B y de B a A)?

Otra preguntilla: tengo un sprite de una fuente parada, y otro con la fuente animada echando agua. Intenté ponerle sonido a este último (un sonido bastante mas largo que la animación del sprite), pero el sonido empieza, se corta, y vuelve a empezar, cuando yo lo que busco es que el sonido sea continuo y vuelva a comenzar cuando se acabe la pista (un loop, igual que con la animación, pero de mayor duración). ¿cómo soluciono esto?

Tampoco sé cómo, al darle la opción con mi personaje de "acción" al boton de la fuente (o a la fuente directamente), se encienda la fuente (cambiarla por el sprite animado con sonido ya rectificado) y se apague si vuelvo a darle al botón o a la fuente(tanto la animación como el sonido).

Muchas gracias, y espero que tengan paciencia conmigo. ::slug
Title: Re: Empezando y con problemas.
Post by: bamyito on December 08, 2010, 07:22:26 PM
otra preguntilla que se me habia olvidado:
Cuando cambia el personaje a una escena bastante mas grande que la pantalla (el doble o así) la pantalla comienza en el extremo izquierdo, y el personaje en el derecho. La pantalla empieza en la izquierda, y se desliza hasta la derecha, hasta que se encuentra con el personaje y luego sigue normal. No es que sea especialmente molesto, ya que el personaje sigue respondiendo y demás, pero me gustaría saber cómo colocar desde el comienzo la pantalla en el lugar adecuado.
Gracias de nuevo. ::rock
Title: Re: Empezando y con problemas.
Post by: Juan Bonair on December 08, 2010, 08:50:54 PM
Bien, vamos por partes que si no me mareo.

¿Podría, desde la entrada X de la scene A llegar a la entrada X de la scene B y viceversa? ¿Podría hacer lo mismo con el camino Y, en ambas direcciónes (de A a B y de B a A)?

Es perfectamente posible, yo lo solucionaría con una variable global común y silvestre. Supongamos que tu entrada/salida X (de la escena A) es un objeto... cliqueable, si es que la palabra existe. Tons en su script deberías escribir algo así:

Code: [Select]

on "LeftClick"    // Al cliquear la salida...
    {
        global Entrada = "X";    // Declarar la variable global "Entrada" y darle el valor "X".
        Game.ChangeScene("scenes\B\B.scene");    // Cambiar a la escena B.
    }


Y en la entrada/salida Y (de la escena A) deberías escribir lo mismo, pero cambiando global Entrada = "X"; por global Entrada = "Y";. Luego, en el script de inicialización de la escena B...

Code: [Select]

global Entrada;    // Declarar la variable "Entrada". Esto es sólo para poder usarla en el resto de este script.

switch(Entrada)    // Acá establecés "Entrada" como la variable a comparar.
    {
        case "X":    // Si "Entrada" tiene el valor "X"...
            actor.SkipTo(40, 267);    // Llevar al personaje a la entrada X de la escena B.
            actor.Direction = DI_UP;
            Game.Msg("¡Está en la entrada equis!");    // Líneas adicionales que lo hacen a uno sentirse mejor cuando el código funciona bien.
            actor.Talk("¡Estoy en la entrada equis!");
            break;    // ¡Esta línea es muy importante! Si no el código no va a saber dónde termina el "case X".

        case "Y":   // Si, en cambio, tiene el valor "Y"...
            actor.SkipTo(303, 86);
            actor.Direction = DI_DOWN;
            break;    // Este "break" es opcional, ya que acá termina el comando "switch", no hay necesidad real de decirle a WME que se detenga.
    }


Y calculo que más o menos se entiende cómo es que se hace. Al comenzar la escena B, coloca al personaje dependiendo de si la variable Entrada vale X o Y. Si el jugador ha cliqueado X, la variable valdrá X y entonces el personaje aparecerá en las coordenadas señaladas en el case "X":. La variable Entrada tranquilamente podría llevar los valores true y false, pero me parece que poner el nombre de la entrada a la que nos estamos refiriendo hace el código más entendible.
Las entradas X e Y de la escena B pueden llevar exactamente el mismo código que las de la escena A. En este caso, el scene_init de la escena A debería llevar un código casi igual al de B, sólo que con otras coordenadas y direcciones. Ah, y si A es la primera escena del juego, además de case "X": y case "Y": deberías agregar un default: para cuando el juego recién comienza y la variable Entrada todavía no tiene asignado ningún valor.

La pantalla empieza en la izquierda, y se desliza hasta la derecha, hasta que se encuentra con el personaje y luego sigue normal. No es que sea especialmente molesto, ya que el personaje sigue respondiendo y demás, pero me gustaría saber cómo colocar desde el comienzo la pantalla en el lugar adecuado.

Esta es fácil. En la inicialización de tu escena grande tendrías que agregar la siguiente línea:

Code: [Select]

Scene.SkipTo(actor);


No sé mucho de sonidos en WME así que no sabría qué decirte con respecto a lo de la fuente. Deberías poner acá en el foro el código que estás usando, así sería más fácil ubicar algún error, si lo hay.

El código que te mando lo escribí de memoria y no lo probé, de modo que si bien debería funcionar puede tener errores de tipeo o algo que se me haya olvidado (espero que no, cualquier cosa avisá si algo no funcionó como debía). Ojalá hayas entendido algo de lo que escribí. ¡Suerte!
Title: Re: Empezando y con problemas.
Post by: bamyito on December 10, 2010, 03:41:45 PM
 ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug
Lo siento, pero no termina de funcionarme como debiera. Probablemente el problema está en que no sé dónde hay que colocar exactamente el código, por lo que se me forma un batiburrillo sin sentido. El primer código juraría que sí lo he puesto sin problemas (Se supone que X e Y he de sustituirlos por los nombres que tengan los caminos, cierto?), pero el segundo y el tercero (el de las entradas y el de la escena que sigue desplazándose) no sé dónde van exactamente. el segundo código me da unos resultados rarísimos. El tercer código lo puse justo al principio del scene_init de la escena grande ("BUS" en este caso), pero la escena seguía iniciándose en la parte izquierda y se desplazaba a la derecha, en lugar de aparecer donde está el personaje (parte derecha).
Code: [Select]
#include "scripts\base.inc"

// here comes the stuff which initializes the scene (Opcion B)(en caso de que el lugar tenga accesos desde mas de una scene:)

switch(Game.PrevScene)    // Acá establecés la variable a comparar, en este caso "Game.PrevScene".
    {
        case "new_scene":    // Si la escena anterior se llamaba "UnaEscena", ejecutar el código siguiente hasta "break;".
            actor.SkipTo(586, 361);    // Llevar al personaje a las coordenadas señaladas (en este caso "40,267").
            actor.Direction = DI_DOWNLEFT;    // Poner al personaje mirando hacia arriba (de espaldas al jugador).
            break;

        case "BUS":   // Si, en cambio, se llamaba "OtraEscena", ejecutar el código siguiente hasta "break;"
            actor.SkipTo(52, 584);    // Llevar al personaje a estas otras coordenadas.
            actor.Direction = DI_UPRIGHT;    // Ponerlo mirando hacia abajo (de cara al jugador).
            break;

        default:    // Si la escena anterior no se llama "UnaEscena" ni "OtraEscena" ni "UnaEscenaMas", ejecutar el código siguiente hasta el final.
            actor.SkipTo(400, 400);
            actor.Direction = DI_RIGHT;
    }

////////////////////////////////////////////////////////////////////////////////
// scene state
global StateRoom;


// default values
if(StateRoom==null)
{
  StateRoom.Visited = false;
  // add scene states here
}



////////////////////////////////////////////////////////////////////////////////
// setup scene according to state variables



////////////////////////////////////////////////////////////////////////////////
if(!StateRoom.Visited)
{
  StateRoom.Visited = true;

  // this is our first visit in this scene...
}
Este es el código que tengo en scene_init de la room que tiene (o debería tener) 2 entradas con la escena "BUS" y una con la escena "new scene". ¿dónde he de colocar ese código que me diste Juan? Yo lo coloqué en el caso "BUS", pero está visto que no lo hice adecuadamente.

Siento las molestias. :-[
Title: Re: Empezando y con problemas.
Post by: Juan Bonair on December 11, 2010, 03:56:32 AM
Hombre, que no es molestia.
Sólo para saber cómo contestarte: ¿este script que acabás de postear te funciona? Es decir, ¿el personaje empieza en posiciones diferentes dependiendo de la escena en la que estuvo antes?
Porque primero que estemos hasta ahí y luego sí empezamos a pensar en lo de las dos entradas alternativas.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 11, 2010, 06:32:54 PM
Si. Este código va estupendamente. si vengo de BUS, aparece en el lado izquierdo en el camino 1 (venga del camino 1 o del 2). y si vengo de la "new scene" (que es una cabaña) aparece en la puerta de la cabaña. Todo correcto.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 11, 2010, 07:18:04 PM
Acabo de solucionar el problema de la escena grande que empezaba retirada del prota. habia que poner el código que me diste detrás de los datos del actor (en el scene_init, como dijiste)  ;)
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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á.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 12, 2010, 06:41:23 PM
Vale, está casi todo controlado. pero sigue habiendo 2 problemitas, que es el mismo: todas las entradas llevan a donde yo quiero, y el personaje se coloca en su sitio. Sin embargo, cuando clico para ir al camino 1 (tando desde una escena como de la otra) el personaje NO va hacia allá, aunque en el código está bien clarito:
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.GoToObject(this);
  global Entrada = "Camino1";
Game.ChangeScene("scenes\BUS\BUS.scene");
}
Sin embargo, el camino 2 no da ningún problema en ninguno de los dos sentidos (de una escena a otra y viceversa), y el código es idéntico excepto por el nombre del objeto:
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.GoToObject(this);
  global Entrada = "Camino2";
Game.ChangeScene("scenes\BUS\BUS.scene");
}

¿qué ocurre? ::slug
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 13, 2010, 01:37:48 PM
 :D Yeah! caminos correctos! Efectivamente, no le asigné las coordenadas.::thumbup
No sé qué haría si tí. ;D, pero sigamos:

hay cosas que probablemente sean sencillas, pero que yo no sé cómo hacerlas. Como por ejemplo:
-Combinar objetos del inventario y obtener un tercero.
-Usar un objeto del inventario con entidades (objetos, personajes o lo que sea) y que dé como resultado otro objeto, un dialogo, un cambio de escenario,...
-Activar la ya mencionada fuente ("usar" un objeto y que su sprite cambie por otro o se active otro sprite, que active un archivo de sonido, que una vez activado el segundo sprite se pueda interactuar con éste segundo sprite y otro objeto de mi inventario,...o que el jugador cambie de localización,...)

Le estoy dando vueltas al tutorial y no veo cómo resolverlo. O estoy ciego, o está en inglés... ::slug
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 15, 2010, 06:25:53 PM
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.GoToObject(this);
  actor.Talk("Es una fuente apagada. Tiene un botón.");
}


////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  actor.GoToObject(this);    // Que el actor vaya a él (opcional).
  Game.Interactive = false;    // Que el juego deje de ser interactivo (opcional).

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

  case "scenes\BUS\fuente.sprite":    // Si la fuente tiene su "sprite" por defecto.
    actor.Talk("Voy a cambiar el ''sprite'' de esta fuente");
    this.PlaySound("scenes\BUS\stream-3.wav",true);    // Que la fuente reproduzca el sonido y que lo repita.
    this.SetSprite("scenes\BUS\fuenteon.sprite");    // Asignarle otro "sprite".
    break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\BUS\fuenteon.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\BUS\fuente.sprite");    // Devolverle su "sprite" anterior.
 break;
  }

  Game.Interactive = true;
 
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.GoToObject(this);
  actor.Talk("Fuentecita fuentecita, ¿quien es de todas la mas fresquita?");
}


////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.Talk("¡¡Ya voy!!");
  actor.GoToObject(this);
}

Así ha quedado el script de mi fuente. Pues bien, ya no puedo ni observarla, ni ir a ella, ni hablar con ella, ni por supuesto usarla.
Ojalá supiera lo que hago cuando meto código, porque luego pasan estas cosas y me quedo sin ideas... :-\

El error que me da: compiling script "scenes\BUS\scr\fuente.script"...
Error@line 18: Invalid character
compiling script "scenes\BUS\scr\fuente.script"...
Error@line 18: syntax error
 :'(
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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]
Title: Re: Empezando y con problemas.
Post by: bamyito on December 19, 2010, 04:45:39 AM
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.GoToObject(this);
  actor.Talk("Es una fuente apagada. Tiene un botón.");
}


////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  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\BUS\fuente.sprite":    // Si la fuente tiene su "sprite" por defecto.
    actor.Talk("Voy a cambiar el ''sprite'' de esta fuente");
    this.PlaySound("scenes\BUS\stream-3.wav",true);    // Que la fuente reproduzca el sonido y que lo repita.
    this.SetSprite("scenes\BUS\fuenteon.sprite");    // Asignarle otro "sprite".
    break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\BUS\fuenteon.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\BUS\fuente.sprite");    // Devolverle su "sprite" anterior.
break;
  }

  Game.Interactive = true;
 
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.GoToObject(this);
  actor.Talk("Fuentecita fuentecita, ¿quien es de todas la mas fresquita?");
}


////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.Talk("¡¡Ya voy!!");
  actor.GoToObject(this);
}

Muchas gracias por tu explicación. Creo que he entendido aproximadamente cómo funciona, pero ahora la consola me da un error tal que así:

Compiling script "scenes\BUS\scr\fuente.cript"...
Error@line 37: syntax error

Lo que supongo que quiere decir (si no he contado mal) que da un error el la linea que pone "on talk", la llamada para que el actor hable.
Y no solo eso. En la consola salen todos los scripts que tengo (en la parte superior izquierda), y el de la fuente no está. Por mas que lo he vuelto a cambiar y a sustituirlo, no aparece. ¿qué ocurre?


Y otra preguntilla rápida: ¿existe algún metodo para salir de la escena mas rápidamente, haciendo doble click en la salida? No para que el personaje corra, sino para que se salte la transición y aparezca directamente en la otra escena.
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 19, 2010, 05:45:57 AM
Doble click funcionando a las mil maravillas, incluso con las entradas múltiples. han surgido problemas que he sabido solventar (añadir la "global entrada" de su camino correspondiente ;D).
Animado y dispuesto para más. ::rock
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 19, 2010, 08:08:57 AM
 :-[ No te voy a decir la hora que es aquí porque me da verguenza :-[, pero que muchisimas gracias!!!! ::thumbup

He conseguido que la fuente se encienda, que diga distintas cosas dependiendo de si está encendida o apagada (al observar), e incluso el sonido va bien, como yo quería (se enciende y se apaga adecuadamente).
Tambien he comprobado que si salgo de la escena y vuelvo, la fuente sigue como yo la dejé (lo cual mola mucho), pero el sonido al volver no se reproduce, a menos que la apagues y la vuelvas a encender. ¿eso tiene solución?

Y tranquilo si no tienes tiempo para responder rapidamente. No me corre prisa. Mientras me contestes (aunque sea una semana después) te lo seguiré agradeciendo igual. Es mas que comprensible que tengamos que prestarle atención a nuestras vidas. ;)

de verdad, muchisimas gracias por todo. No te puedes hacer una idea de la ilusión que me hacen los grandes avances que realizo gracias a ti.
Te debo unas cervezas y un jamón, por lo menos. ::beer ;D
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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 (http://es.wikipedia.org/wiki/Anidamiento_%28inform%C3%A1tica%29) 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").
Title: Re: Empezando y con problemas.
Post by: bamyito on December 20, 2010, 12:53:47 AM
 ::thumbup Estupendo. Fuente funcionando a las mil maravillas, con su sonido y todo al salir y al entrar. ::thumbup
Pasemos a otra cosa:

He conseguido usando un script muy parecido al de la fuente (mediante swith y sprites), rebuscar entre la basura con el actor y recoger 2 objetos de allí y cambiar el sprite de la basura por otro de la basura abierta. incluso dice cosas diferentes dependiendo del estado del sprite (basura abierta o cerrada). El problema me surje al salir de la scene y luego al volver. Directamente, la basura desaparece. Aunque no la hubiera usado antes, con lo cual pierdo los objetos en el espacio-tiempo  :o. La consola tampoco da errores. No sé si el problema estará en el scene.init y debo cambiar allí algo (con la fuente no hizo falta, excepto por el sonido), pero por allí no he tocado nada. Aquí tienes el script de la basura:

Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  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\Room\basuraclosed.sprite":    // Si la fuente tiene su "sprite" por defecto.
     actor.Talk("puaj, basura.");
    break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\Room\basuraopen.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Antes he tocado algo muy blando... y húmedo...");
break;
  }

  Game.Interactive = true;
 
}


////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  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\Room\basuraclosed.sprite":    // Si la fuente tiene su "sprite" por defecto.
    actor.Talk("A ver qué encuentro...");
 actor.Talk("Un segundo.");
   this.SetSprite("scenes\Room\basuraopen.sprite");    // Asignarle otro "sprite".
  Game.TakeItem("albal");
  actor.Talk("esto podrá serme util. A ver algo más...");
  actor.Talk("...");
  Game.TakeItem("martillo");
    actor.Talk("¡Un martillo y un trozo de papel albal!");
break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\Room\basuraopen.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Bastante he buscado ya. ¿No crees?");
break;
  }

  Game.Interactive = true;
  }
 
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.Talk("¿saldrá el bicho de barrio sésamo?");
}


////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.Talk("¡¡Ya voy!!");
  actor.GoToObject(this);
}
¿Dónde está mi problema?
Sigo dándole vueltas a lo de combinar objetos del inventario, pero bueno. Poco a poco. ^^

Gracias de nuevo! :D
Title: Re: Empezando y con problemas.
Post by: HelLRaiseR on December 20, 2010, 12:37:49 PM
Hola bamyito,

Te explico brevemente el tema de combinar objetos.

Imagina que tienes dos objetos, una rama y una goma y que combinandolos puedes hacer un tirachinas, mas o menos, lo que hay que hacer es lo siguiente.

1. Definir tres objetos, la rama, la goma y el tirachinas montado.

2. Coger el objeto rama y añadirlo al inventario.

Esto se hace con una llamada a la función Game.TakeItem("rama"); esto hará que la rama nos aparezca en el inventario. Esta llamada debe ir en el evento on "Take" del objeto a coger.

3. Coger el objeto goma y añadirlo al inventario.

Igual que con la rama pero para el objeto goma.

4. Combinarlos. O lo que es lo mismo, que desaparezca la rama y la goma y aparezca el tirachinas. Cuando en el inventario coges un objeto A y lo combinas con otro B, en el objeto B se produce un evento con el nombre del objeto A, te lo explico con un ejemplo

Supongamos, como hemos dicho que tenemos un objeto "rama" y otro "goma" y el jugador coge el objeto "goma" y lo suelta sobre el objeto "rama" con el objetivo de crear un nuevo objeto "tirachinas"

El código, que estaría en el script del objeto rama, sería mas o menos este:

Code: [Select]
on "goma"
{
actor.Talk("Pongamos la goma en la rama.");
Game.DropItem("goma");
Game.DropItem("rama");
Game.TakeItem("tirachinas");
}

Como vez cuando se suelta el objeto "goma" sobre el objeto "rama" se ejecuta este código que hace desaparecer los objetos "rama" y "goma" del inventareio y añade el objeto "tirachinas", a partir de aqui usaremos el tirachinas de la forma que consideremos necesario.

Title: Re: Empezando y con problemas.
Post by: bamyito on December 20, 2010, 01:41:06 PM
Vale, probado y entendido. Casi todo. Me han surgido unos problemillas (pa no perder la costumbre).
Los objetos a combinar son martillo y caja, y el nuevo objeto es jarra.

Si lo hago tal como me lo dices, la cosa funciona perfectamente, EXCEPTO porque si los combino estando en la habitación en la que he encontrado la caja, ésta vuelve a aparecer de donde mismo la he recogido.
Si los combino en otra room, no hay problema. Los objetos desaparecen y aparece el nuevo objeto en el inventario.

He intentado solucionarlo utilizando el comando (o la llamada o como se llamen estas cosas) Game.DeleteItem(""), y funciona bien única y exclusivamente cuando lo coloco en ultimo lugar de las acciones a realizar. Me explico: Si coloco este comando (Game.DeleteItem("")) antes del comando de hablar, o de eliminar objeto, o de añadir objeto al inventario, no realiza estas últimas acciones. Y claro, lo ideal sería que desapareciera del inventario justo antes de que aparezca el nuevo objeto y antes de que dijese la frase.
Os dejo el código de la caja:

Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.Talk("Una caja azul MUY bien cerrada.");
}

////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  Game.SelectedItem = "caja";
}
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.Talk("¿Hay alguien dentro?");
}
on "martillo"
{
actor.Talk("DESTROY!!");
Game.DropItem("martillo");
Game.TakeItem("jarro");
actor.Talk("¡Bien! ahora tengo un jarrico.");
Game.DeleteItem("caja");
}

¿qué ocurre? ¿cómo consigo que desaparezcan en el orden correcto?
Muchas gracias. ::rock
Title: Re: Empezando y con problemas.
Post by: bamyito on December 20, 2010, 02:00:52 PM
SIM EMBARGO, acabo de darme cuenta que puedo hacer la misma operación (combinar los 2 objetos y que me dé un tercero) sin coger la caja en el inventario, y combinandolas desde su lugar de la scene. Refiriendome al script de la scene de la caja (en lugar de el que tengo en el inventario) y utilizando Game.DeleteItem(this); se eliminan ambos y me dan el tercero sin problemas.
Code: [Select]
on "martillo"
{
actor.GoToObject(this);
actor.Talk("DESTROY!!");
Game.DropItem("martillo");
Game.DeleteItem(this);
Game.TakeItem("jarro");
actor.Talk("¡Bien! ahora tengo un jarrico.");
}
Este avance me mola. XD

Pero aún no consigo combinarlo adecuadamente cuando ya lo tengo en el inventario (que se elimine en el orden que yo quiera). He probado la misma fórmula (copy&paste) en el script del inventario, pero si allí me refiero a la caja como this, me da error y no se elimina.
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 24, 2010, 02:07:46 AM
Vale, mis preguntas van a ir divididas en 3 apartados esta vez: Caja que no se borra, bicho amarillo no-dialogante y basura que desaparece.
Caja que no se borra
::rock
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.GoToObject(this);
  actor.Talk("Anda! una cajita azul!");
}
////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  actor.GoToObject(this);
  actor.Talk("pa la saca.");
  Game.TakeItem("caja");
}
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.GoToObject(this);
  actor.Talk("Cajita cajita, vaya que eres feita.");
}
////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.GoToObject(this);
}
////////////////////////////////////////////////////////////////////////////////
on "martillo"
{
actor.GoToObject(this);
actor.Talk("DESTROY!!");
Game.DropItem("martillo");
Game.DeleteItem(this);
Game.TakeItem("jarro");
actor.Talk("¡Bien! ahora tengo un jarrico.");
}

Este es el código que utilizo en la caja como objeto de la scene, y me funciona estupendamente por ahora, asi que ni me planteo resumirlo.
Si utilizo el martillo sobre la caja estando ésta sobre la mesa, las acciones se realizan sin ningún problema (habla, desaparece martillo, desaparece caja, obtengo jarro y habla de nuevo).
 ::slug
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.Talk("Una caja azul MUY bien cerrada.");
}

////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  Game.SelectedItem = "caja";
}
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.Talk("¿Hay alguien dentro?");
}
on "martillo"
{
actor.Talk("DESTROY!!");
Game.DropItem("martillo");
Game.TakeItem("jarro");
actor.Talk("¡Bien! ahora tengo un jarrico.");
Game.DeleteItem("caja");
}

Este es el código que tiene la caja como objeto del inventario (ya lo puse anteriormente). Como ves, la linea [Game.DeleteItem("caja");] está la última de toda la línea, ya que si no, esa es la última acción que realiza. Si, por ejemplo, la colocase antes de [Game.TakeItem("jarro");], lo cual sería ideal, las 2 lineas que quedan ([take jarro] y [actor talk]) no se realizarían ???. Lo cual, no tiene mucho sentido para mi.


Bicho amarillo no-dialogante
::slug
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.Talk("¿un bicharraco amarillo flotando?");
    this.Talk("El coco.");
  actor.Talk("Qué sitio mas raro.");
}
////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  actor.Talk("No llego.");
}
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
actor.Talk("Hola coco.");
this.Talk("Hola Tarzana, ¿cómo estás?");

Game.AddResponse(0, "Tururú");
Game.AddResponse(1, "Flufluturutú");
Game.AddResponse(2, "Debería irme");

var Res = Game.GetResponse();

actor.Talk("bueno chico, aquí te quedas.");
this.Talk("Venga Tarzana, feliz navidad.");
}
////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.GoToObject(this);
}

Este código pertenece a un bicho flotante amarillo. Pues bien, hay dos cosas que me gustaría solucionar en su código.

1º- Que, cuando le dé (por ejemplo) a observar bicho, el personaje se vuelva hacia el bicho  ::)(que lo mire), pero que no avance hasta él (esto ya sé hacerlo sin problemas).

2º- Con este código en el comando hablar, consigo que el personaje y el actor hablen al principio (cada uno diga una frase) y al final de la conversación. Sin embargo, no sé qué codigo poner para que puedan mantener una conversación (que el bicho conteste a mis preguntas, se habran nuevas ramas de diálogo dependiendo de la opción que yo haya escogido, etc). He intentado usar el codigo que viene en el tutorial, pero nada. No funciona ni lo mas mínimo. :'(


Basura que desaparece
::slug
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  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\Room\basuraclosed.sprite":    // Si la fuente tiene su "sprite" por defecto.
     actor.Talk("puaj, basura.");
    break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\Room\basuraopen.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Antes he tocado algo muy blando... y húmedo...");
break;
  }

  Game.Interactive = true;
 
}
////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  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\Room\basuraclosed.sprite":    // Si la fuente tiene su "sprite" por defecto.
    actor.Talk("A ver qué encuentro...");
 actor.Talk("Un segundo.");
   this.SetSprite("scenes\Room\basuraopen.sprite");    // Asignarle otro "sprite".
  Game.TakeItem("albal");
  actor.Talk("esto podrá serme util. A ver algo más...");
  actor.Talk("...");
  Game.TakeItem("martillo");
    actor.Talk("¡Un martillo y un trozo de papel albal!");
break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\Room\basuraopen.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Bastante he buscado ya. ¿No crees?");
break;
  }

  Game.Interactive = true;
  }
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.Talk("¿saldrá el bicho de barrio sésamo?");
}
////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.Talk("¡¡Ya voy!!");
  actor.GoToObject(this);
}

Siempre comienzo las pruebas en la escena en la que está la basura. Pues bien:

1º- Si abandono la scene y vuelvo, la basura ha desaparecido >:(, con todos sus sprites, objetos y letreros en el ratón.

2º- Si no abandono la escena, la basura funciona estupendamente: La observa de diferentes formas dependiendo de su sprite, la usa y coge los objetos sin problemas, añadiendolos al inventario y no permitiéndome volver a cogerlos de la basura, cambia el sprite como debe,... en fin, todo estupendo :D. Pero en cuanto salgo de la scene y vuelvo, ocurre lo mismo que en el caso 1: desaparece, y ya no puedo ni observarla, ni marcarla con el ratón ni nada. >:(



Espero no agobiar demasiado, ni ser demasiado exigente con ustedes. Hace poco pensaba que jamás coseguiría mezclar objetos del inventario, ni encender la fuente ni poder llenar una jarra de agua con la fuente encendida. Y ahora puedo hacerlo. Asi que cualquier solución que podais encontrar a cualquiera de estos problemas es bien recibida.
Muchas gracias por vuestra paciencia.
¡Feliz navidad! ;D
Title: Re: Empezando y con problemas.
Post by: HelLRaiseR on December 24, 2010, 04:45:31 PM
Bueno, te conmtesto muy rápido y solo a lo del dialogo, porque dado el dia que es no me puedo liar y pro otra parte supongo que hoy a estas horas no estarás liado.

Te paso un script de un dialogo, con posibles preguntas y respuestas a esas preguntas, para que lo vayas estudiando, a ver si el domingo mas tranquilo te contesto a otras cosas.

Unas cosas:

- Esto es un dialogo sacado de nuestro juego, por lo que veras cosas que no sabras ni que son, entre ellas, las siguientes.
- El WinNarrator.DisplayText, lo usamos en vez del actor.Talk
- El ExpandString, coge los textos de un fichero en funcion del idioma del juego.
- El Bill_flores, Bill_dani, Bill_curro, etc son variables para cambiar las preguntas en funcion de si se han hecho o no.
- Fijate solamente en AddREesponse, GetResponse, etc que son las funciones para montar los dialohgos.

Y si te lias, no pasa nada, el domingo te pongo un código limpio, que en este no hay quien entienda nada ya que ni siquiera hay frases.

Feliz Navidad
Code: [Select]
function BillDialogue()
{
  var Responses;
  var Selected;

  var Loop = true;

  while(Loop)
  {
    // prepare the sentences
if (!Bill_flores)
Responses[0] = Game.ExpandString("/WOF0001038/");
else
Responses[0] = Game.ExpandString("/WOF0001039/");

if (!Bill_curro)
Responses[1] = Game.ExpandString("/WOF0001040/");
else
Responses[1] = Game.ExpandString("/WOF0001041/");

if (!Bill_dani)
Responses[2] = Game.ExpandString("/WOF0001042/");
else
Responses[2] = Game.ExpandString("/WOF0001043/");

Responses[3] = Game.ExpandString("/WOF0001044/");

    // fill the response box
    Game.AddResponse(0, Responses[0]);
    Game.AddResponse(1, Responses[1]);
    Game.AddResponse(2, Responses[2]);
    Game.AddResponse(3, Responses[3]);

    // let the player choose one
    Selected = Game.GetResponse();

    // let the actor say the selected sentence
    // (that's why I use the array for storing the sentences)
actor.PlayAnimAsync("Hablar");
    WinNarrator.DisplayText(Responses[Selected], "Jhonny", -1); //Dejamos que la máquina calcule el tiempo que se muestra la frase.
actor.PlayAnimAsync("IdleHablar");

    // now let Bill reply depending on the selected sentence
    if(Selected==0)
    {
if (!Bill_flores)
{
this.PlayAnimAsync("Hablando");
WinNarrator.DisplayText(Game.ExpandString("/WOF0001045/"),"Bill",-1);
this.PlayAnimAsync("Idle");
actor.PlayAnimAsync("Hablar");
WinNarrator.DisplayText(Game.ExpandString("/WOF0001046/"),"Jhonny",-1);
actor.PlayAnimAsync("IdleHablar");
this.PlayAnimAsync("Hablando");
WinNarrator.DisplayText(Game.ExpandString("/WOF0001047/"),"Bill",-1);
this.PlayAnimAsync("Idle");
actor.PlayAnimAsync("Hablar");
WinNarrator.DisplayText(Game.ExpandString("/WOF0001048/"),"Jhonny",-1);
actor.PlayAnimAsync("IdleHablar");
this.PlayAnimAsync("Hablando");
WinNarrator.DisplayText(Game.ExpandString("/WOF0001049/"),"Bill",-1);
this.PlayAnimAsync("Idle");
actor.PlayAnimAsync("Hablar");
WinNarrator.DisplayText(Game.ExpandString("/WOF0001050/"),"Jhonny",-1);
actor.PlayAnimAsync("IdleHablar");
Bill_flores=true;
}
else
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001051/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001052/"),"Jhonny",-1);
}
}
else
{
if(Selected==1)
{
if (!Bill_curro)
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001053/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001054/"),"Jhonny",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001055/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001056/"),"Jhonny",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001057/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001058/"),"Jhonny",-1);
Bill_curro=true;
}
else
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001059/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001060/"),"Jhonny",-1);
}
}
else
{
if(Selected==2)
{
if (!Bill_dani)
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001061/"),"Bill",-1);
BillDialogue2();
Bill_dani=true;
}
else
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001062/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001063/"),"Jhonny",-1);
}
}
else
{
if(Selected==3)
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001064/"),"Bill",-1);
Loop = false; // we want to end the dialogue
}
}
}
}
}
// Comprobamos si Bill le ha contado todo y en caso afirmativo
// se puede ya cerrar el cementerio
 
if(Bill_flores && Bill_curro && Bill_dani)
  EstadoJuego.CementerioCerrado = true;
else
  EstadoJuego.CementerioCerrado = false;
}




////////////////////////////////////////////////////////////////////////////////
function BillDialogue2()
{
  var Responses;
  var Selected;
  var Loop = true;

  while(Loop)
  {
    // prepare the sentences
    Responses[0] = Game.ExpandString("/WOF0001065/");
    Responses[1] = Game.ExpandString("/WOF0001066/");
    Responses[2] = Game.ExpandString("/WOF0001067/");

    // fill the response box
    Game.AddResponse(0, Responses[0]);
    Game.AddResponse(1, Responses[1]);
    Game.AddResponse(2, Responses[2]);

    // let the player choose one
    Selected = Game.GetResponse();

    // let the actor say the selected sentence
    // (that's why I use the array for storing the sentences)
    WinNarrator.DisplayText(Responses[Selected], "Jhonny", -1);

    // now let the Old Guy reply depending on the selected sentence
    if(Selected==0)
    {
WinNarrator.DisplayText(Game.ExpandString("/WOF0001068/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001069/"),"Jhonny",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001070/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001071/"),"Jhonny",-1);
    }
else
{
if(Selected==1)
{
WinNarrator.DisplayText(Game.ExpandString("/WOF0001072/"),"Bill",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001073/"),"Jhonny",-1);
WinNarrator.DisplayText(Game.ExpandString("/WOF0001074/"),"Bill",-1);
}
else
{
if(Selected==2) Loop = false;
}
}
  }
}
Title: Re: Empezando y con problemas.
Post by: bamyito on December 26, 2010, 07:38:12 PM
Lo siento, pero aparte de no entender nada de todo eso, el programa de da un error en la primera linea. Es exactamente igual que en el tutorial. Tu "function BillDialogue()" falla lo mismo que el "function MyTestDialogue()" del tutorial. :'(

Seguiré investigando. :)
Title: Re: Empezando y con problemas.
Post by: HelLRaiseR on December 27, 2010, 01:23:11 AM
Hoy no he podido, a ver si manana saco un rato y te explico
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on December 29, 2010, 08:24:19 PM
No me sale. Me explico:

He puesto el  this.Active = false; en todos sitios, y no veo cambio alguno. Tu dices que ha de ir en el script de la caja cuando está puesto en la scene. Voy a explicar el efecto que crea este script, por si no me he explicado bien: Cuando uso MARTILLO sobre CAJA sin haber añadido CAJA al inventario (o sea, sin cogerlo y usando martillo en el objeto CAJA que está en la scene) las situaciones se producen si error: habla, los objetos desaparecen (CAJA de la scene y MARTILLO de mi inventario), aparece un nuevo objeto en mi inventario (JARRO), y habla de nuevo. y la Caja no vuelve a aparecer en el escenario. Por eso no entiendo que tenga que poner el  this.Active = false; (que por cierto, no sé para que es exactamente) en este script, ya que funciona bien. Además, he probado a ponerlo en todos los lugares que me han parecido lógicos, y no produce cambios.

-->Script de la CAJA del inventario. Aunque no sea ahí donde me dijiste que debía ponerlo, he probado sin obtener resultados (o sea, la caja se elimina al final, colocandose antes de tiempo en su sitio de la scene):
Code: [Select]
on "martillo"
{
actor.Talk("DESTROY!!");
Game.DropItem("caja");
Game.DropItem("martillo");
this.Active = false;
Game.TakeItem("jarro");
actor.Talk("¡Bien! ahora tengo un jarrico.");
Game.DropItem("caja");
}

-->Script de la CAJA en la scene. He probado colocando el this.Active = false; en todos los sitios, cambiando el delete por el drop, pero el efecto cuando cojo la caja en el inventario y uso el martillo sobre ella en el inventario sigue siendo el mismo (la CAJA aparece en la scene, y luego desaparece). Y la verdad, no entiendo cómo cambiando este script voy a solucionarlo. Según mi lógica (que ya hemos comprobado que es errónea), este problema debería solucionarse en el otro script, no?

En fin, a ver si encontramos entre todos lo que falla... ::slug
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on January 05, 2011, 07:52:22 PM
 ;D Yeah!! ¡¡Problema de la caja solucionado!! ::rock
Soy tan paquete en esto de programar que el fallo lo he cometido al olvidar el punto y coma";" despues del (this.Active = false). Cuando he dicho: ¿llevará esto una coma aquí, como todo lo demás? y lo he probado, ha sido como... WTF? :-\
En fin, un error que no volveré a cometer. :P

Ahora mismo estoy intentando aplicar este método a la basura, para que no desaparezca y tal, pero está visto que no lo estoy haciendo bien, ya que sigue desapareciendo cuando salgo de la scene. ::slug

Y bueno... aparte del problema del bicho no-dialogante no tengo mas inquietudes por ahora. Solventemos esto y ya iré inventando mas cosas. ::)

PD: Expongo aquí los 2 problemas que aún tengo, a ver qué podemos hacer.
 ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug ::slug
Bicho amarillo no-dialogante

Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  actor.Talk("¿un bicharraco amarillo flotando?");
    this.Talk("El coco.");
  actor.Talk("Qué sitio mas raro.");
}
////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  actor.Talk("No llego.");
}
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
actor.Talk("Hola coco.");
this.Talk("Hola Tarzana, ¿cómo estás?");

Game.AddResponse(0, "Tururú");
Game.AddResponse(1, "Flufluturutú");
Game.AddResponse(2, "Debería irme");

var Res = Game.GetResponse();

actor.Talk("bueno chico, aquí te quedas.");
this.Talk("Venga Tarzana, feliz navidad.");
}
////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.GoToObject(this);
}
Este código pertenece a un bicho flotante amarillo. Pues bien, hay dos cosas que me gustaría solucionar en su código.

1º- Que, cuando le dé (por ejemplo) a observar bicho, el personaje se vuelva hacia el bicho ::)(que lo mire), pero que no avance hasta él.

2º- Con este código en el comando hablar, consigo que el personaje y el actor hablen al principio (cada uno diga una frase) y al final de la conversación. Sin embargo, no sé qué codigo poner para que puedan mantener una conversación (que el bicho conteste a mis preguntas, se habran nuevas ramas de diálogo dependiendo de la opción que yo haya escogido, etc). He intentado usar el codigo que viene en el tutorial, pero nada. No funciona ni lo mas mínimo. :'(

Basura que desaparece
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
  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\Room\basuraclosed.sprite":    // Si la fuente tiene su "sprite" por defecto.
     actor.Talk("puaj, basura.");
    break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\Room\basuraopen.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Antes he tocado algo muy blando... y húmedo...");
break;
  }

  Game.Interactive = true;
 
}
////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  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\Room\basuraclosed.sprite":    // Si la fuente tiene su "sprite" por defecto.
    actor.Talk("A ver qué encuentro...");
 actor.Talk("Un segundo.");
   this.SetSprite("scenes\Room\basuraopen.sprite");    // Asignarle otro "sprite".
  Game.TakeItem("albal");
  actor.Talk("esto podrá serme util. A ver algo más...");
  actor.Talk("...");
  Game.TakeItem("martillo");
    actor.Talk("¡Un martillo y un trozo de papel albal!");
break;    // ¡Línea importante! Nunca la olvides.

  case "scenes\Room\basuraopen.sprite":    // Si la fuente ya tiene su otro "sprite".
    actor.Talk("Bastante he buscado ya. ¿No crees?");
break;
  }

  Game.Interactive = true;
  }
////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.Talk("¿saldrá el bicho de barrio sésamo?");
}
////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.Talk("¡¡Ya voy!!");
  actor.GoToObject(this);
}
Siempre comienzo las pruebas en la escena en la que está la basura. Pues bien:

1º- Si abandono la scene y vuelvo, la basura ha desaparecido >:(, con todos sus sprites, objetos y letreros en el ratón.

2º- Si no abandono la escena, la basura funciona estupendamente: La observa de diferentes formas dependiendo de su sprite, la usa y coge los objetos sin problemas, añadiendolos al inventario y no permitiéndome volver a cogerlos de la basura, cambia el sprite como debe,... en fin, todo estupendo :D. Pero en cuanto salgo de la scene y vuelvo, ocurre lo mismo que en el caso 1: desaparece, y ya no puedo ni observarla, ni marcarla con el ratón ni nada. >:(


¡¡Feliz año nuevo y gracias por todo!! O0
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on January 06, 2011, 03:28:27 AM
YEAH!! ::rock
he probado tu método (el sencillo) y funciona exactamente como me has explicado. Eso si, como emplea un tiempo en girarse el personaje, el 100 que le habias asignado inicialmente lo he cambiado por un 250 despues de probar varias opciones, por el sencillo hecho de que si estaba de espaldas, al actor no le daba tiempo a girarse completamente y miraba donde no debía. Eso si, si inicialmente el actor está mirando hacia el objeto, pues el actor da un pasito y se detiene. Que vale, lo ideal sería que solo girase, pero vamos, por ahora voy que me mato. ¡¡gracias!!

Tambien he probado el método complicado con otro objeto cualquiera, y me da este error:
Compiling script 'scenes\Room\scr\Chabolaca.script'...
3:09:58:    Error@line 42: Variable 'ego' is referenced but not defined
3:09:58:  Compiling script 'scenes\Room\scr\Chabolaca.script'...
3:09:58:    Error@line 43: Variable 'ego' is referenced but not defined


No sé si el problema radica en que "ego" se refiere al actor, y al buscarlo, no lo encuentra. Según este razonamiento, cambiando todos los "ego" por "actor" debería funcionar. ¿o no? ??? Te dejo tambien el código, por si te ayuda a ver el error:
Code: [Select]
#include "scripts\base.inc"


////////////////////////////////////////////////////////////////////////////////
on "LookAt"
{
TurnToObject();
  actor.Talk("Una chabola muy muy fea.");
}


////////////////////////////////////////////////////////////////////////////////
on "Take"
{
  actor.Direction = DI_DOWN;
  actor.Talk("¿Y despues me la guardo en el bolsillo?");
}


////////////////////////////////////////////////////////////////////////////////
on "Talk"
{
  actor.GoToObject(this);
  actor.Talk("Hola, Chozaca fea y espantosa.");
}


////////////////////////////////////////////////////////////////////////////////
on "LeftClick"
{
  actor.GoToObject(this);
}

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;
    }
  }
}

Bueno, y ya que estamos, si me pudieras dar unas direcciones de juegos descargables que tengan el código manipulable te lo agradecería muchisimo. he probado con The white chamber, pero en lugar del código este que usamos nosotros salen unos recuadritos de 3 letras muy extraños, que puede que sean el código, pero yo de ahí no puedo copiar las lineas que me interesan ni borrar otras para probar los efectos... no sé si me explico :-\

¿y qué es un cazzo? Me lo has nombrado dos veces, pero ni idea de lo que es.

Gracias de nuevo :D
Title: Re: Empezando y con problemas.
Post by: bamyito on January 07, 2011, 11:59:31 PM
 ::rock Y EFECTIVAMENTE!!
En el codigo complicado, cambiando los ego por actor, funciona a las mil maravillas. Se gira hacia el objeto, y luego cumple el resto de órdenes. ;D

Voy a seguir con la basura, a ver qué descubro. Lo empezaré desde el principio, a ver si así encuentro el error. Mientras, esperaré ansioso alguna explicación más. ;)
Title: Re: Empezando y con problemas.
Post by: Jose on January 08, 2011, 11:42:24 AM
Buenas bamyito,

el mes pasado a mí me sucedió algo parecido a lo que comentas de la basura. Tenía en mi escena inicial una serie de sprites que cargaba en función de la acción que realizase sobre determinadas regions, y resulta que mientras permanecía en la escena todo funcionaba correctamente pero en cuanto iba a otra escena y volvía a la inicial, era como si todo se hubiese "reinicializado". Al principio pensé que era problema de que la escena no estaba guardando el estado pero después de darle muchas pero que muchas vueltas, descubrí que el error era algo de lo más tonto ya que en el cambio de escena para volver a la inicial tenía puesto lo siguiente:

Code: [Select]
   Game.ChangeScene("\scenes\lobby\lobby.scene");
 

La primera "\" sobra y estaba haciendo que por alguna razón WME volviese a cargar la escena correcta pero sin respetar el estado de sus elementos. Solamente tuve que quitarle la famosa "\" y empezó a funcionar correctamente. Al final la instrucción correcta quedó así:

Code: [Select]
   Game.ChangeScene("scenes\lobby\lobby.scene");

Naturalmente en tu caso tendrías que cambiar "lobby" y "lobby.scene" por el nombre de la carpeta y el archivo .scene que apliquen en tu caso.

A ver si hay suerte y esto te ayuda porque la verdad es que a mí me volvió loco una buena temporada.

Un saludo.

P.D. Respecto a lo que preguntas del significado de la palabra cazzo te diré que es italiano y que siendo "muy fino" podrías traducirla por pene.  ;D
Title: Re: Empezando y con problemas.
Post by: bamyito on January 09, 2011, 12:40:55 AM
creo que no es el mismo problema, ya que, segun tu, tus sprites se reinician y se ponen como al principio. Lo que le ocurre al mio es que, sencillamente, desaparece. Interactue o no interactue con el antes de salir de la scene, al volver, desaparecen ambos (basura abierta y cerrada). Además, no hago referencia a la basura en el scene.init, y creo que no hace falta. tampoco sé si es ahí donde te refieres que tendría que corregir la refencia. En cualquier caso, he comprobado las referencias de los sprites, y están bien escritos, asi que el error debe estar en otro lugar.

Y lo del cazzo... XD
Seguro que esa es la traducción... pero no sé si es a eso a lo que se refería Juan bonair. Supongo que si. XD

En cualquier caso, muchas gracias por tu interés.
Un abrazo.
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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...
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.
Title: Re: Empezando y con problemas.
Post by: bamyito on January 12, 2011, 02:19:38 PM
Vale, la explicación la he entendido (casi todo), y ya creo que voy entendiendo cómo he de pensar. Lógica e imaginación mezclados... mola. Cortarlo en modo de pizza 8 en lugar de 9 cuadrados... tomando como centro, el pixel del objeto,... ¿eso no tendría mucho mas código, al tener que dividir la pantalla de manera diagonal? Investigaré el asunto.

Y como ya te dije, conseguí que el código funcionase, tanto este como el otro que se te ocurrió. lo curioso es que me da la impresión de que el otro método que se te ocurrió a ti, queda como mas natural al avanzar un poco. Con este método, rota sobre sí mismo con sus posiciones de "parado" (parado mirando abajo, parado mirando en diagonal abajo-derecha, parado mirando a la derecha, parando mirando a derecha- arriba, parado mirando arriba) hasta que se qeuda mirando al objeto en cuestión.
Mi pregunta es: ¿podrían hacerse animaciones para que, al girarse a un lado o a otro, quedara mas natural? o sea, una animación intermedia para cuando gire de posición.

otra pregunta: Supongo que todo este código he de repetirlo en todos los objetos si quiero que haga esa función (girarse al objeto), ¿cierto? La pregunta es: ¿no podría activar un script para todas estas situaciones aparte, y enlazarlo desde los objetos para, así, tener menos código? creo que me estoy complicando demasiado por ahora...

y otra pregunta: Si quisiera que el actor tuviese alguna animación especial (Como por ejemplo dar un puñetazo), ¿cómo haría eso? Supongo que si el actor da el puñetazo al usar determinado objeto con otro personaje u objeto, (por ejemplo, martillo y bicho amarillo), en el bicho pondría el código "on martillo, go to object, actor talk o lo que sea" la pregunta es: el codigo para activar otra animación en el prota (y ya que estamos, en el otro personaje), ¿cómo se haría? creo que con el otro personaje quizá lo consiguiese, pero con el actor no estoy seguro.

Y nada, esperando un pequeño resumen sobre cómo tratar con el texto y los diálogos. No estoy repitiendome por impaciente, sino como recordatorio. Sin prisas ni agobios, ok?

Gracias de nuevo ;D
Title: Re: Empezando y con problemas.
Post by: HelLRaiseR on January 12, 2011, 03:34:14 PM
A ver, los dialogos:
Estudia este código que te pongo, es muy simple, cuando lo tengas claro seguimos con conversaciones dependientes de determinadas respuestas y demas.

Por supuesto, esta función debe ser llamada, cuando se desencadene el evento hablar:

on "Talk"
{
    Dialogo();
}

Otra cosa, en este hilo se están mezclando un montón de cosas, a partir de ahora cada cosa nueva que te surja, ponla en un post nuevo, asi no se mezclan temas y es mas facil encontrar las cosas para la gente que venga después. En el titulo pon algo significativo, como por ejemplo "Dudas sobre los dialogos"


Code: [Select]
function Dialogo()
{
  var Responses;
  var Selected;

  var Loop = true;

  while(Loop)
  {
// preparamos las frases, hablar_barco y hablar_coche lo usamos para saber si ya ha hecho la pregunta con anterioridad y cambiar la foma de hacerla
// en función de si se ha hablado o no
// Se entiende que previamente estas variables estan declaradas globalmente e inicializadas a false, o sea:
// global hablar_barco = false; // y lo mismo con hablar_coche
// De esta forma, la primera vez que se ejecute el código, se dice la primera frase y se indica que ya se ha hablado para que las sucesivas veces
// Salga lo de "Vuelveme a contar"

if (!hablar_barco)
Responses[0] = "Hablame del barco";
else
Responses[0] = "Vuelveme a contar lo del barco");
if (!hablar_coche)
Responses[1] = "Hablame del coche";
else
Responses[1] = "Vuelveme a contar lo del coche");

    // Creamos el cuadro de conversación con las frases que hemos preparado
    Game.AddResponse(0, Responses[0]);
    Game.AddResponse(1, Responses[1]);

    // Ahora lo presentamos en pantalla para que el jugador seleccione una, el resultado se almacena en Selected
    Selected = Game.GetResponse();

    // El actor repite lo que hemos seleccionado
    actor.Talkt(Responses[Selected]);

   // Ahora el personaje contesta en función de la pregunta que se ha hecho y si ya se habia hecho antes o no
    if(Selected==0) // Pregunta de los barcos
    {
if (!hablar_barco)
{

personaje.Talk("Los barcos flotan");
hablar_barco=true;
}
else
{
personaje.Talk("Como ya te dije, los barcos flotan, excepto si tienen un agujero, claro");
}
}
    if(Selected==1) // Pregunta de los coches
    {
if (!hablar_barco)
{

personaje.Talk("Los coches van rodando");
hablar_barco=true;
}
else
{
personaje.Talk("Como ya te dije, los coches van rodando, excepto por cuestiones de gasolina, pinchazos y similares, por supuesto");
}
}
}
Title: Re: Empezando y con problemas.
Post by: bamyito on January 12, 2011, 03:53:41 PM
Buf, eso de separar las dudas va a estar complicado, porque conforme me van saliendo, voy preguntando, pero intentaré organizarme para el próximo post, y abriré varios, intentando organizar mis dudas por secciones. Este es el último post que pongo de manera "desorganizada".

Acabo de probar tu diálogo (o sea, copio la función al final del script, y lo llamo desde on talk), y resulta que me da un error de sintaxis en la linea 60, que coincide con la linea 20 en tu codigo. No sé por qué será. Pensaba que el error me lo daría al intentar encontrar el nombre del actor, pero ha fallado antes. XD

Y un último problema que me ha surgido: he probado a compilar el juego completo. resulta que, al ir a una de las scenes (BUS concretamente), el personaje no se coloca donde debe. sin embargo, cuando lo pruebo desde el wintermute, va perfecto. Con el resto de escenas no me da problemas: el personaje acaba donde debe. ¿a qué puede deberse esto? Pensaba que el resultado final y la "simulación" del wintermute serían idénticas...
Title: Re: Empezando y con problemas.
Post by: Jose on January 12, 2011, 04:02:42 PM
Si la línea que te da error de sintaxis es

Code: [Select]
Responses[0] = "Vuelveme a contar lo del barco");

creo que es porque le sobra el cierre del paréntesis, la línea correcta debería ser

Code: [Select]
Responses[0] = "Vuelveme a contar lo del barco";

De la misma manera, la línea

Code: [Select]
Responses[1] = "Vuelveme a contar lo del coche");

debería darte también error de sintaxis, lo correcto sería

Code: [Select]
Responses[1] = "Vuelveme a contar lo del coche";

Un saludo.
Title: Re: Empezando y con problemas.
Post by: HelLRaiseR on January 12, 2011, 04:39:38 PM
Cosas del corta-pega  :D
Title: Re: Empezando y con problemas.
Post by: Juan Bonair 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.