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);
         }
 }
Herramientas personales