Shoot the Food

Shoot the Food

Shoot the Food

Este es el tercer entregable para el Curso de Experto en Desarrollo de Videojuegos (6ª Edición) de la UCLM.

En esta ocasión creamos, mediante una estructura propia en C++ con el motor gráfico Ogre 3D, un minijuego basado en el clásico Disparar al plato.

Cuando empezamos la partida comienzan salir alimentos por los diferentes cañones, cuanto más aguantemos más deprisa saldrán. Tenemos un número limitado de vidas y de disparos por lo que si nos quedamos sin disparos o sin vidas será el fin del juego. El cañón del fondo dispara cada cierto tiempo vidas y munición para poder seguir avanzando.

Para este minijuego dejamos de utilizar la estructura básica en C++ que nos dieron desde el inicio del curso y creamos una propia. Las partes que reutilizamos del código y las nuevas están adaptadas a C++11 y la estructura utilizada es ECS (Entidad-Componente-Sistema).

Todo el escenario y modelado se hizo en Blender y después desarrollamos un parseador que dada la exportación de todo el escenario de blender en .xml era el encargado de crear cada elemento en el ECS. Haciendo así de Blender nuestra herramienta «integrada» para la creación de niveles. A continuación parte del código del parseador de Blender -> C++/ECS:

void DotSceneLoader::processECS() {
  for(std::vector<shared_ptr<EntityComp>>::iterator it = mECS.begin(); it != mECS.end(); it++) {
    shared_ptr<EntityComp> entComp = *it;
    ::Entity::ID id = entComp->mEntity->getId();
    _gameManager->setEntity(entComp->mEntity->getName(), entComp->mEntity);
    if(entComp->mGraphic != nullptr) {
      mGraphicSystem->addComponent(id, entComp->mGraphic);
    }
    if(entComp->mPhysicData != nullptr) {
      mPhysicsSystem->addComponent(id, entComp->mPhysicData->mPhysic);
      mPhysicsSystem->addPhysicObject(id, entComp->mPhysicData->mShapeForm, entComp->mPhysicData->mShapeType,entComp->mPhysicData->mPhysicProperties);
    }
    if(entComp->mMovement != nullptr) {
      mMovementSystem->addComponent(id, entComp->mMovement);
    }
    if(entComp->mCameraData != nullptr) {
      mCameraSystem->addComponent(id, entComp->mCameraData->mCamera);
      mCameraSystem->initializeViewport(id);
      mCameraSystem->setFov(id, entComp->mCameraData->fov);
      mCameraSystem->setProjectionType(id, entComp->mCameraData->projection);

      if(entComp->mCameraData->nearDist != -1)
        mCameraSystem->setNearDist(id, entComp->mCameraData->nearDist);

      if(entComp->mCameraData->farDist != -1)
              mCameraSystem->setFarDist(id, entComp->mCameraData->farDist);
    }
  }
}

Para la interfaz dejamos de usar CEGUI, que está muy bien pero es muy dificil y poco manejable y utilizamos Noesis Engine. Noesis Engine es un framework que se puede integrar con diferentes motores para realizar todo lo referente a la interfaz de usuario. Los desarrolladores nos facilitaron unas librerías para linux y después de luchar un poco lo pudimos integrar al proyecto, la parte de diseño se realizaba en Blend de Microsoft y después se exportaba y se utilizaba en ECS.

Al cargar el .xml de Blender se creaba cada objeto como Entidad y se le añadían los diferentes Componentes como puede ser el de física, gráfico, etc… que más tarde procesarían los diferentes Sistemas, para seguir con el ejemplo componentes físicos se controlan con el sistema de físicas (OgreBullet) o componentes gráficos se controlan con Ogre3D. Decir que cada objeto creado en Blender tenía diferentes atributos como «ent» para decir que es entidad, «phy» para decir que es objeto físico… de esta forma luego se podía filtrar la creación de la entidad con los diferentes componentes.

En este proyecto todo la configuración está controlada mediante XML. Gracias a esto, y sin compilar de nuevo el juego, podemos modificar ciertos aspectos del juego como la cadencia de los cañones, munición y vidas, etc…