Comportamientos
De CursosGpl
Tabla de contenidos |
[editar] Módulos python de crystalspace y cel
Para poder acceder a toda la funcionalidad de crystalspace y cel desde python podemos importar los módulos correspondientes. Estos son cspace y blcelc.
Para tener todas las funciones de estos módulos directamente en nuestro espacio de nombres principal utilizamos:
from cspace import * from blcelc import *
en la cabecera de todos nuestros scripts de juego.
[editar] Estructura general de los scripts
Ya hemos comentado que la cabecera debe contener los import necesarios para los módulos de cspace y blcelc, además de esto cada script de comportamiento, incluyendo el script principal deben contener una clase con el mismo nombre que el fichero del script.
Dentro de esta clase podemos utilizar la función __init__ para inicializar los valores que necesitemos en el momento de crearse la entidad. Esta función recibe como parámetros el propio objeto (como todas las funciones pertenecientes a una clase) y la entidad que posee el comportamiento en ejecución.
Por ejemplo, en el fichero actor.py:
class actor:
def __init__(self,celEntity):
# inicialización de variables
def otras_funciones...
[editar] El script principal
En el script principal deberemos inicializar todas las factorías de clases de propiedad que vayamos a utilizar y cargar el mapa dejandolo todo listo para que pasen a tomar el control los scripts de comportamiento de las entidades.
Para registrar una clase de propiedad utilizamos la función celRegisterPCFactory:
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.solid")
[editar] Scripts de comportamiento
Los scripts de comportamiento definen diferentes puntos de entrada desde los que podemos controlar la aplicación. El primer punto de entrada es la función __init__ ya descrita, y aquí podemos obtener o inicializar las clases de propiedad que necesitemos en la entidad utilizando las funciones 'celGet* y 'celCreate*, que se utilizan con el nombre de la clase de propiedad que queremos obtener en lugar del *.
Por ejemplo, para obtener una clase de propiedad del tipo DefaultCamera y si no existe crearla en la fase de inicialización:
def __init__(self,celEntity):
self.camera = celGetDefaultCamera(celEntity)
if not self.camera:
self.camera = celCreateDefaultCamera(physicallayer_ptr,celEntity)
El script también puede tener puntos de entrada para los mensajes que nos lancen las clases de propiedad, como es el caso de pccommandinput, pctrigger, pctimer (los mensajes que lanza cada clase de propiedad están descritos en la sección Las clases de propiedad).
[editar] Código python de ejemplo
[editar] celtest.py (script principal)
from cspace import * from blcelc import *
class celtest:
[editar] createRoom
def createRoom(self):
vfs=CS_QUERY_REGISTRY(object_reg_ptr,iVFS)
loader = CS_QUERY_REGISTRY(object_reg_ptr,iLoader)
map = "/tmp/world.zip"
vfs.Mount("/test",map)
vfs.ChDirAuto("/test/");
# Entidad del ZoneManager
entity_room=celCreateEntity(physicallayer_ptr,"room")
zoneManager = celCreateZoneManager(physicallayer_ptr,entity_room)
zoneManager.Load("/test/","level.xml")
inv = celCreateInventory(physicallayer_ptr,entity_room)
# Actor tonto inicial
dummy = celCreateEntity(physicallayer_ptr,"dcamera")
dummy_cam = celCreateDefaultCamera(physicallayer_ptr,dummy)
dummy_cam.SetZoneManager(zoneManager,True,"main","Camera")
zoneManager.PointMesh("dcamera","main","camera")
inv.AddEntity(dummy)
# Inicializar actor real
actor = physicallayer_ptr.FindEntity("camera")
# Set zone manager
actor_cam = celGetDefaultCamera(actor)
actor_cam.SetZoneManager(zoneManager,True,"main","Camera")
inv.AddEntity(actor)
zoneManager.PointMesh("camera","main","Camera")
[editar] Inicializacion
def __init__(self,celEntity):
print "Initializing game..."
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.region")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.mesh")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.solid")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.meshselect")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.test")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.zonemanager")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.trigger")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.quest")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.light")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.inventory")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.tooltip")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.defaultcamera")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.gravity")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.movable")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.pccommandinput")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.linmove")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.actormove")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.colldet")
celRegisterPCFactory(object_reg_ptr,"cel.pcfactory.timer")
self.createRoom()
[editar] actor.py (personaje jugador)
from cspace import * from blcelc import *
class actor:
[editar] Inicialización
def __init__(self,celEntity):
print "Inicializando actor..."
self.camera = celGetDefaultCamera(celEntity)
if not self.camera:
self.camera = celCreateDefaultCamera(physicallayer_ptr,celEntity)
input = celGetCommandInput(celEntity)
if not input:
input = celCreateCommandInput(physicallayer_ptr,celEntity)
self.actormove = celGetActorMove(celEntity)
if not self.actormove:
self.actormove = celCreateActorMove(physicallayer_ptr,celEntity)
self.mesh = celGetMesh(celEntity)
if not self.mesh:
self.mesh = celCreateMesh(physicallayer_ptr,celEntity)
self.mesh.LoadMesh("box", "/cellib/objects/box")
pos = csVector3 (0, 1, 0)
self.mesh.MoveMesh(room,pos)
meshobj = self.mesh.GetMesh()
self.cal3dstate = SCF_QUERY_INTERFACE(meshobj.GetMeshObject(), iSpriteCal3DState)
self.select = celGetMeshSelect(celEntity)
if not self.select:
self.select = celCreateMeshSelect(physicallayer_ptr,celEntity)
self.linmove = celGetLinearMovement(celEntity)
if not self.linmove:
self.linmove = celCreateLinearMovement(physicallayer_ptr,celEntity)
self.tooltip = celGetToolTip(celEntity)
if not self.tooltip:
self.tooltip = celCreateToolTip(physicallayer_ptr,celEntity)
self.camera.SetModeName ("thirdperson")
self.actormove.SetMovementSpeed(1.2)
self.actormove.SetRunningSpeed (2.7)
self.actormove.SetRotationSpeed (2.0)
self.actormove.SetJumpingVelocity (5.5)
self.linmove.InitCD(csVector3(.5,1.0/3.0,.5),csVector3(.5,2.0/3.0,.5),
csVector3(0,0.0,0))
# XXX this should go in template
input.Bind("up", "forward")
input.Bind("down", "backward")
input.Bind("left", "rotateleft")
input.Bind("right", "rotateright")
input.Bind("a", "strafeleft")
input.Bind("d", "straferight")
input.Bind("+", "camcloser")
input.Bind("-", "camfurther")
input.Bind("pgup", "lookup")
input.Bind("pgdn", "lookdown")
input.Bind("d", "straferight")
input.Bind("shift", "run")
input.Bind("m", "cammode")
input.Bind(" ", "jump")
[editar] Movimiento
def pccommandinput_forward1(self,celentity,args):
self.actormove.Forward(1)
def pccommandinput_forward0(self,celentity,args):
self.actormove.Forward(0)
def pccommandinput_backward1(self,celEntity,args):
self.actormove.Backward(1)
def pccommandinput_backward0(self,celEntity,args):
self.actormove.Backward(0)
def pccommandinput_rotateleft1(self,celEntity,args):
self.actormove.RotateLeft(1)
def pccommandinput_rotateleft0(self,celEntity,args):
self.actormove.RotateLeft(0)
def pccommandinput_rotateright1(self,celEntity,args):
self.actormove.RotateRight(1)
def pccommandinput_rotateright0(self,celEntity,args):
self.actormove.RotateRight(0)
def pccommandinput_strafeleft1(self,celEntity,args):
self.actormove.StrafeLeft(1)
def pccommandinput_strafeleft0(self,celEntity,args):
self.actormove.StrafeLeft(0)
def pccommandinput_straferight1(self,celEntity,args):
self.actormove.StrafeRight(1)
def pccommandinput_straferight0(self,celEntity,args):
self.actormove.StrafeRight(0)
def pccommandinput_lookup1(self,celEntity,args):
self.camera.SetPitchVelocity(1.0)
def pccommandinput_lookup0(self,celEntity,args):
self.camera.SetPitchVelocity(0.0)
def pccommandinput_lookdown1(self,celEntity,args):
self.camera.SetPitchVelocity(-1.0)
def pccommandinput_lookdown0(self,celEntity,args):
self.camera.SetPitchVelocity(0.0)
def pccommandinput_jump1(self,celEntity,args):
if self.cal3dstate:
self.cal3dstate.SetAnimAction("Testjump1",0.1,0.1)
self.actormove.Jump()
def pccommandinput_run1(self,celEntity,args):
self.actormove.Run(True)
def pccommandinput_run0(self,celEntity,args):
self.actormove.Run(False)
[editar] Cámara
def pccommandinput_cammode1(self,celEntity,args): self.camera.SetMode(self.camera.GetNextMode ()) def pccommandinput_camcloser_(self,celEntity,args): self.camera.SetDistance(self.camera.GetDistance(-1)-0.1,-1) def pccommandinput_camfurther_(self,celEntity,args): self.camera.SetDistance(self.camera.GetDistance(-1)-0.0,-1)
[editar] npc.py (un no jugador)
from cspace import * from blcelc import *
import random
class npc:
[editar] Inicialización
def __init__(self,celEntity):
print "Inicializando npc..."
# pclinearmovement
self.linmove = celGetLinearMovement(celEntity)
if not self.linmove:
self.linmove = celCreateLinearMovement(physicallayer_ptr,celEntity)
# pcactormove
self.actormove = celGetActorMove(celEntity)
if not self.actormove:
self.actormove = celCreateActorMove(physicallayer_ptr,celEntity)
self.actormove.SetMovementSpeed(1.0)
self.actormove.SetJumpingVelocity (4.1)
[editar] Selección
def pcmeshsel_up(self,celEntity,args):
pl = physicallayer_ptr
actor = pl.FindEntity("camera")
toolt = celGetToolTip(actor)
if toolt:
toolt.SetText(celEntity.GetName())
[editar] WakeUp (pctimer)
def pctimer_wakeup(self,celEntity,args):
# AVANZAR
valor_avanzar = random.random()
esta_avanzando = valor_avanzar<0.5
if esta_avanzando:
self.actormove.Forward(1)
self.actormove.Backward(0)
else:
self.actormove.Forward(0)
self.actormove.Backward(0)
# ROTAR
valor = random.random()
if valor<0.3 and esta_avanzando:
self.actormove.RotateLeft(1)
self.actormove.RotateRight(0)
elif valor<0.8 and esta_avanzando:
self.actormove.RotateLeft(0)
self.actormove.RotateRight(1)
else:
self.actormove.RotateLeft(0)
self.actormove.RotateRight(0)
# SALTAR
if random.random()<0.1:
mesh = celGetMesh(celEntity)
meshobj = mesh.GetMesh()
cal3dstate = SCF_QUERY_INTERFACE(meshobj.GetMeshObject(), iSpriteCal3DState)
if cal3dstate:
cal3dstate.SetAnimAction("Testjump1",0.02,0.02)
self.actormove.Jump()
[editar] blender2crystal
Asignamos comportamientos a nuestras entidades asignandoles la propiedad behaviour a un STRING con el nombre del comportamiento que queramos utilizar. Esto utiliza por defecto la capa de comportamientos de python, que es la que se describe en este tutorial, aunque es posible cambiarlo utilizando la propiedad behaviour_layer.
También es conveniente no olvidar que la propiedad entity debe estar definida con el valor True para que el objeto sea considerado como una entidad.

