inicio | documentación | contacto
Version para imprimir Imprimir
Inicio » Documentación » Impedir el movimiento de una localidad a otra

Impedir el movimiento de una localidad a otra

1 Impedir que un personaje salga de un sitio

Si queremos evitar que un personaje o nuestro jugador se mueva de un sitio a otro, tan solo tenemos que implementar el método alSalir de la localidad (u objeto) de donde no queremos que salga. En el siguiente ejemplo, no dejamos salir del la localidad Salon a ningún personaje sino ha cogido el Mechero, parando la ejecución del movimiento con stop:

object Salon:Localidad
    ...
    def alSalir(personaje, direccion, destino, relaciondestino)
        if not Mechero.esPosesionDe(personaje)
            println "Para salir debes haber cogido el mechero antes."
            stop
        endif
    end
endobject

El evento alSalir se ejecutará para cualquier personaje que intente salir de esta localidad, independientemente a donde vaya. Este método recibe como parámetros el objeto personaje que intenta salir, la dirección que ha tomado, el destino (que es la localidad u objeto a donde le lleva dicha dirección) y su relación ("dentro" para las localidades y objetos "entrables"; "encima" para los objetos "subibles"). Podemos ampliar la condición comprobando si el personaje que intenta salir es el objeto jugador u otro personaje o si el destino/relacion a donde intenta ir es un sitio concreto donde no queremos que vaya.

Dado que alSalir se ejecuta para cualquier personaje, si tenemos otros personajes moviéndose por esta localidad y solo queremos que se impida el movimiento al jugador actual, deberíamos cambiar la condición a:

        if personaje == #jugador and not Mechero.esPosesionDe(personaje)

2 Impedir que un personaje entre a un sitio

Podemos controlar el caso contrario, en el que un personaje o nuestro jugador no pueda entrar en un sitio sino cumple cierta condición. Para ello hay que implementar el método alEntrar de la localidad (u objeto) a donde no queremos que entre. En el siguiente ejemplo, no dejamos entrar a la localidad Oficina a ningún personaje si lleva la Pistola, parando la ejecución del movimiento con stop:

object Oficina:Localidad
    ...
    def alEntrar(personaje, direccion)
        if Pistola.esPosesionDe(personaje)
            println "No se puede entrar en la oficina con armas."
            stop
        endif
    end
endobject

El evento alEntrar se ejecutará para cualquier personaje que intente entrar a esta localidad, independientemente de donde venga. Este método recibe como parámetro el objeto personaje que intenta entrar y la dirección que ha tomado para llegar hasta aquí. El destino es el propio objeto donde estamos implementando el evento (en este caso la Oficina). Podemos ampliar la condición comprobando si el personaje que intenta entrar es el objeto jugador u otro personaje.

Dado que alEntrar se ejecuta para cualquier personaje, si tenemos otros personajes moviéndose por el esta localidad y solo queremos que se impida el movimiento al jugador actual, debemos cambiar la condición a:

        if personaje == #jugador and Pistola.esPosesionDe(personaje)

3 Impedir que un personaje se mueva

Podemos implementar dos métodos muy parecidos dentro del objeto jugador o personaje cuyos movimientos queremos controlar. Éstos métodos son los eventos puedePasar y alMover.

  • puedePasar se ejecuta cada vez que el personaje intenta ir hacia una dirección, independientemente de dónde esté y hacia donde vaya.
  • alMover se ejecuta cada vez que el personaje se mueve realmente de un sitio a otro, independientemente de dónde esté y hacia donde vaya, siempre que el objeto destino sea distinto al objeto origen donde se encontraba antes de moverse.

Ejemplo: supongamos que el objeto McAventura es el personaje jugador de la aventura, y que solo dejamos mover al personaje si no lleva la piedra encima, parando la ejecución del movimiento con stop:

object McAventura:Personaje
    ...
    def puedePasar(direccion, destino, relaciondestino)
        println "Has intentado moverte desde "+#self.getLocalidad()+" hacia "+destino+" ("+relaciondestino+") usando la direccion "+direccion
        if Piedra.esPosesionDe(#self)
            println "La piedra pesa demasiado y no puedes moverte."
            stop
         endif
    end
    ...
    def alMover(direccion, destino, relaciondestino)
        println "Has intentado moverte desde "+#self.getLocalidad()+" hacia "+destino+" ("+relaciondestino+") usando la direccion "+direccion
        if Piedra.esPosesionDe(#self)
            println "La piedra pesa demasiado y no puedes moverte."
            stop
         endif
    end
endobject

La implementación de los dos métodos es exactamente igual, incluso el mensaje mostrado es el mismo. Los dos eventos también reciben los mismos parámetros: la dirección en la que se ha movido, el destino a donde le llevará esa dirección y la relación ("dentro" para las localidades). Sin embargo, hay una pequeña diferencia en el parámetro destino:

Si el destino es una puerta, y esta a su vez nos lleva a otro nuevo destino, por ejemplo, una localidad, puedePasar recibirá como parámetro la puerta, mientras que alMover (al igual que alSalir) recibirá la localidad, ya que ese es el destino final. Si el destino no es una puerta y es directamente un objeto o una localidad, los dos eventos reciben el mismo objeto destino como parámetro.

Puedes ver todo lo que sucede internamente cuando se mueve un personaje y entender mejor en qué orden se lanzan los eventos en Mover personajes.

4 Ejemplo completo

En el siguiente ejemplo, tenemos dos localidades: la calle, donde hay una piedra y un carnet; y una biblioteca, donde hay un libro. Necesitamos tener el carnet para entrar en la biblioteca. Una vez dentro, podemos coger el libro, pero no podremos salir con el, ni tampoco si nos dejamos el carne olvidado, ya que no podríamos volver a entrar. Además, hay una piedra que pesa mucho, y si la cogemos simplemente no nos podremos mover.

Copiar | Descargar
include system/default

object Main:MainBase
    def start
        Estado.jugador = McAventura
        #jugador.accion(Mirar)
    end
endobject

object McAventura:Personaje dentro:Calle
    nombre MS:Mc Aventura
    def alMover(direccion, destino, relaciondestino)
        if Piedra.esPosesionDe(#self)
            println "La piedra pesa mucho y no te deja mover."
            stop
        endif
    end
endobject

object Carnet dentro:Calle
    nombre MS:carnet
    def alMirar: "Es un carnet de la biblioteca."
endobject

object Piedra dentro:Calle
    nombre FS:piedra
    def alMirar: "Es una piedra muy pesada."
endobject

object Calle:Localidad
    nombre MS:Calle
    var al_n = Biblioteca
    var adentro = Biblioteca
    def alMirar: "Estás en la calle, en frente de la biblioteca."
endobject

object Libro dentro:Biblioteca
    nombre MS:libro
    def alMirar: "Titulado 'La historia interminable'."
endobject

object Biblioteca:Localidad
    nombre MS:Biblioteca
    var al_s = Calle
    var afuera = Calle
    def alMirar: "Hay un gran silencio."

    def alEntrar(personaje, direccion, destino, relaciondestino)
        if not Carnet.esPosesionDe(personaje)
            println "Para entrar debes tener el carne de la biblioteca."
            stop
        endif
    end

    def alSalir(personaje, direccion, destino, relaciondestino)
        if Libro.esPosesionDe(personaje)
            println "Antes de salir debes devolver el libro."
            stop
        elseif not Carnet.esPosesionDe(personaje)
            println "Si te dejas el carnet dentro, no podrás volver a entrar."
            stop
        endif
    end

endobject
Archivo: system/repositorio/!A-1-1-Impedir movimiento.k | Abrir el repositorio de ejemplos

5 Resumen

Hemos visto las distintas maneras que tenemos de controlar los movimientos del jugador o cualquier personaje, ya sea interceptando el movimiento del personaje con los eventos alMover y puedePasar o desde la localidad origen/destino con alSalir y alEntrar.

Por lo general, no conviene abusar de los eventos que se implementan en el jugador como alMover y puedePasar, ya que puede que se ejecuten muchas más veces de manera innecesaria que si fueran implementados convenientemente como alSalir y alEntrar en las localidades origen o destino del movimiento que queremos controlar.

Objeto donde se implementaEventoParametros que recibeNotas
personajepuedePasar(direccion, destino, relaciondestino)El personaje es #self, si el destino es una puerta, el parámetro recibido como destino es la puerta.
personajealMover(direccion, destino, relaciondestino)El personaje es #self.
localidad origenalSalir(personaje, direccion, destino, relaciondestino)
localidad destinoalEntrar(personaje, direccion)El destino es #self

6 Preguntas frecuentes

¿Cuál es el evento más apropiado para impedir que el jugador (o cualquier personaje) se mueva de un sitio a otro?

Implementar alSalir de la localidad origen de donde no queremos que salga o alEntrar en la localidad destino donde no queremos que entre.

¿Cuando puede ser necesario implementar alMover o puedePasar en el objeto jugador?

Cuando necesitemos que se controle el movimiento del jugador durante toda la partida, independientemente a donde vaya o de donde venga.

¿Qué diferencia hay entre alMover y puedePasar?

  • puedePasar se ejecuta antes que alSalir, alMover y alEntrar
  • Si el movimiento se produce a través de una puerta, el único método que recibe la puerta como destino es puedePasar, el resto de métodos recibirán el objeto destino final del movimiento (un objeto o una localidad).

¿Cómo obtengo la localidad origen del movimiento donde está el jugador o de cualquier personaje?

MétodoDescripción
personaje.getLocalidad()Devuelve la localidad origen donde se encuentra
personaje.getParent()Devuelve el objeto padre donde se encuentra, que puede ser una localidad, o un objeto como un mesa donde está subido.
personaje.getRelation()Devuelve la relación con el padre donde se encuentra, que puede ser "dentro" para una localidad o un objeto "entrable" o puede ser "encima" para un objeto "subible".

¿Cómo obtengo la localidad destino a donde se quiere mover?

  • Los métodos puedePasar, alSalir y alMover reciben como parámetro el destino (además de la relación, que en el caso de las localidades es siempre "dentro"). Si el destino es una puerta, puedePasar recibe la puerta, mientras que alMover y alSalir reciben el destino final a donde les lleva la puerta.
  • En el método alEntrar, el destino es el propio objeto donde se implementa, por lo que es #self.

¿Cómo obtengo la dirección en la que se ha querido mover el personaje?

Todos los eventos reciben la dirección como parámetro. Además, si el movimiento se produce como fruto de una acción Ir, la dirección estará siempre accesible en la variable global #uno.

En un movimiento entre dos localidades distintas ¿qué eventos se ejecutan y en qué orden?

Siendo Habitacion la localidad origen, Salon la localidad destino y McAventura el personaje que hace el movimiento :

OrdenObjeto donde se ejecutaEvento
1McAventurapuedePasar
2HabitacionalSalir
3McAventuraalMover
4SalonalEntrar
Última modificación: lunes 21 de abril de 2008 12:52:43
Fecha de creación: sábado 12 de abril de 2008 18:51:22
Categorías: