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.
puedePasarse ejecuta cada vez que el personaje intenta ir hacia una dirección, independientemente de dónde esté y hacia donde vaya.alMoverse 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.
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
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 implementa | Evento | Parametros que recibe | Notas |
|---|---|---|---|
| personaje | puedePasar | (direccion, destino, relaciondestino) | El personaje es #self, si el destino es una puerta, el parámetro recibido como destino es la puerta. |
| personaje | alMover | (direccion, destino, relaciondestino) | El personaje es #self. |
| localidad origen | alSalir | (personaje, direccion, destino, relaciondestino) | |
| localidad destino | alEntrar | (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?
puedePasarse ejecuta antes quealSalir,alMoveryalEntrar- 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étodo | Descripció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,alSaliryalMoverreciben 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,puedePasarrecibe la puerta, mientras quealMoveryalSalirreciben 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 :
| Orden | Objeto donde se ejecuta | Evento |
|---|---|---|
| 1 | McAventura | puedePasar |
| 2 | Habitacion | alSalir |
| 3 | McAventura | alMover |
| 4 | Salon | alEntrar |