Cargando un personaje cal3d
De CursosGpl
código de esta parte en http://delcorp.org/cgi-bin/cvsweb/curso_crystal/08cal3d/
Tabla de contenidos |
[editar] Introducción
En esta parte del tutorial vamos a cargar un mundo con una factoría de personaje cal3d y luego vamos a crear el personaje, asignarle un colisionador físico y asignar algunas teclas a movimiento y cambio de acciones.
[editar] Conceptos
[editar] La Factoría
El personaje está presente en el mundo xml únicamente como factoría ya que CrystalSpace no permite definir personajes cal3d directamente en los sectores.
La factoría es un objeto que contiene los planos de cómo debe crearse un determinado objeto de malla. A partir de la factoría podemos crear muchos objetos iguales, pero que luego podremos manejar por separado, por ejemplo con los personajes podemos tener muchos personajes salidos de la misma factoría pero luego tener a cada uno en un punto del mapa, realizando diferentes acciones, con diferentes texturas u objetos anclados...
Para crear la factoría le pediremos la referencia de la factoría al motor usando
engine->GetMeshFactories()->FindByName(fact_name)
[editar] Colisionador Físico
Para que el personaje choque correctamente con los objetos del mundo es necesario asignarle algún tipo de colisionador. En CrystalSpace tenemos dos opciones:
- Usar el sistema de colisiones
- Usar un sistema físico (de momento la única opción es ODE)
[editar] Asignación del teclado
Vamos a asignar las teclas para mover el personaje, para esto vamos a responder al teclado de dos maneras.
[editar] Comprobación contínua
Para los casos en que queremos responder siempre que una tecla esté presionada lo que tenemos que hacer es comprobar todos los frames las teclas que nos interesen.
Cuando detectemos que una tecla está presionada deberemos usar el tiempo transcurrido desde el último frame para que la animación se vea igual en ordenadores de diferentes capacidades.
Usamos el plugin de entrada del teclado:
csRef<iKeyboardDriver> kbd = CS_QUERY_REGISTRY (object_reg, iKeyboardDriver); // El Teclado
kbd->GetKeyState ('w')
[editar] Respuesta a eventos
Para detectar cuando una tecla se ha presionado por primera vez o dejado de presionar lo mejor es responder a los eventos de teclado que llegan a la función de respuesta a eventos que tengamos asignada.
Para detectar los eventos del teclado
ev.Type == csevKeyboard
Para detectar el tipo de evento de teclado:
csKeyEventHelper::GetEventType (&ev) == csKeyEventTypeDown
Para detectar el código de la tecla:
csKeyEventHelper::GetCookedCode (&ev) == 'w')
[editar] Código
[editar] Cargando el Personaje
// Función que crea carga un personaje del mundo
bool DelBase::CreaHombrecilloDePrueba(const csVector3 &posicion, char *fact_name)
{
// La referencia a la malla
csRef<iMeshWrapper> mallapruebas;
csRef<iMeshFactoryWrapper> myFact = engine->GetMeshFactories()->FindByName(fact_name); mallapruebas = engine->CreateMeshWrapper (myFact, "hombrecillo", room);
// Creamos un cuerpo en el sistema físico miCuerpo = miSistemaDinamico->CreateBody (); miCuerpo->MakeDynamic(); miCuerpo->SetProperties (2, csVector3 (0), csMatrix3 (0)); //masa centro inercia miCuerpo->SetPosition (posicion); miCuerpo->SetLinearVelocity(csVector3 (0, 0, 0)); miCuerpo->SetAngularVelocity (csVector3 (0, 0, 0));
// anclamos la malla al cuerpo del sistema físico miCuerpo->AttachMesh(mallapruebas);
// definimos el entorno de colisión const csMatrix3 tm; const csVector3 tv (0); csOrthoTransform tt (tm, tv); miCuerpo->AttachColliderSphere (1, csVector3(0,1.0,0), 1.0f, 10, 0.5f,0.1f);
// obtenemos el interfaz iSpriteCal3DState y definimos una animación
csRef<iSpriteCal3DState> spstatecal = SCF_QUERY_INTERFACE (mallapruebas->GetMeshObject(),iSpriteCal3DState);
if (spstatecal)
spstatecal->AddAnimCycle("Testanda", 0.5,0.0);
}
[editar] Asignación de Teclas
[editar] Comprobación contínua
if ( kbd->GetKeyState ('w'))
{
miCuerpo->Enable();
miCuerpo->SetLinearVelocity (miCuerpo->GetOrientation() * csVector3 (0, 0.0, 2));
csRef<iMeshWrapper> mallapruebas = miCuerpo->GetAttachedMesh ();
csRef<iSpriteCal3DState> spstatecal = SCF_QUERY_INTERFACE (mallapruebas->GetMeshObject(),iSpriteCal3DState);
if (spstatecal)
{
spstatecal->AddAnimCycle("TestAndadef", 1.0,0.5);
spstatecal->ClearAnimCycle("Teststop",0.5);
spstatecal->ClearAnimCycle("TestsIGILOSO",0.5);
spstatecal->SetTimeFactor(1);
}
}
[editar] Comprobación de eventos
if ((ev.Type == csevKeyboard) &&(csKeyEventHelper::GetEventType (&ev) == csKeyEventTypeUp) &&
((csKeyEventHelper::GetCookedCode (&ev) == 'x') ||
(csKeyEventHelper::GetCookedCode (&ev) == 'w')) || (csKeyEventHelper::GetCookedCode (&ev) == 'W') || (csKeyEventHelper::GetCookedCode (&ev) == 'X') )
{
csVector3 avel = miCuerpo->GetLinearVelocity();
miCuerpo->SetLinearVelocity(csVector3 (0, avel.y, 0));
csRef<iMeshWrapper> mallapruebas = miCuerpo->GetAttachedMesh ();
csRef<iSpriteCal3DState> spstatecal = SCF_QUERY_INTERFACE (mallapruebas->GetMeshObject(),iSpriteCal3DState);
if (spstatecal)
{
spstatecal->AddAnimCycle("Teststop", 0.5,0.5);
spstatecal->ClearAnimCycle("TestAndadef", 0.5);
spstatecal->ClearAnimCycle("TestsIGILOSO", 0.5);
spstatecal->SetTimeFactor(1);
}
}

