Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: orxonox.OLD/branches/gui/src/story_entities/simple_game_menu.cc @ 7866

Last change on this file since 7866 was 7866, checked in by bensch, 18 years ago

Events are subscribed at the EventListener, and not the EventHandler

File size: 15.9 KB
RevLine 
[6501]1/*
2   orxonox - the future of 3D-vertical-scrollers
3
4   Copyright (C) 2004 orx
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11### File Specific:
12   main-programmer: Patrick Boenzli
13
14*/
15
16#define DEBUG_SPECIAL_MODULE DEBUG_MODULE_WORLD
17
18
19#include "simple_game_menu.h"
20
[7866]21#include "event_handler.h"
22
[6502]23#include "state.h"
24#include "class_list.h"
25
[7193]26#include "util/loading/load_param.h"
[6502]27#include "fast_factory.h"
[7193]28#include "util/loading/factory.h"
[6502]29
[6521]30#include "p_node.h"
[6502]31#include "world_entity.h"
[7016]32#include "elements/image_entity.h"
[6502]33#include "terrain.h"
[6521]34#include "camera.h"
[6502]35
[6524]36#include "graphics_engine.h"
[6841]37#include "object_manager.h"
[7318]38#include "sound_engine.h"
39#include "sound_source.h"
[6504]40
[6502]41#include "cd_engine.h"
42
43
[6501]44using namespace std;
45
46
[6502]47//! This creates a Factory to fabricate a SimpleGameMenu
48CREATE_FACTORY(SimpleGameMenu, CL_SIMPLE_GAME_MENU);
49
50
51
52SimpleGameMenu::SimpleGameMenu(const TiXmlElement* root)
[6989]53  : GameWorld()
[6502]54{
55  this->setClassID(CL_SIMPLE_GAME_MENU, "SimpleGameMenu");
56  this->setName("SimpleGameMenu uninitialized");
57
58  this->dataTank = new SimpleGameMenuData();
59
[6521]60  this->cameraVector = Vector(50.0, 0.0, 0.0);
[6991]61  this->menuLayers.push_back(MenuLayer());
62  this->menuLayers.push_back(MenuLayer());
[6862]63
[6837]64  this->layerIndex = 0;
[6862]65  this->menuSelectedIndex = 0;
[7318]66  this->selectorSource = NULL;
[6521]67
[7221]68  if (root != NULL)
69    this->loadParams(root);
[6878]70
[7032]71  State::setMenuID(this->getNextStoryID());
[6502]72}
73
74
[6501]75/**
[7221]76 *  @brief remove the SimpleGameMenu from memory
[6502]77 *
78 *  delete everything explicitly, that isn't contained in the parenting tree!
79 *  things contained in the tree are deleted automaticaly
[6501]80 */
[6502]81SimpleGameMenu::~SimpleGameMenu ()
82{
83  PRINTF(3)("SimpleGameMenu::~SimpleGameMenu() - deleting current world\n");
[7287]84
85  if( this->dataTank)
86    delete this->dataTank;
[6502]87}
[6501]88
[6502]89
90/**
[7221]91 * @brief loads the parameters of a SimpleGameMenu from an XML-element
[6502]92 * @param root the XML-element to load from
[6501]93 */
[6502]94void SimpleGameMenu::loadParams(const TiXmlElement* root)
95{
96  /* skip the GameWorld, since it does not define any useful loadParams for this class */
[6696]97  //static_cast<GameWorld*>(this)->loadParams(root);
98  GameWorld::loadParams(root);
[6501]99
[6502]100  PRINTF(4)("Loaded SimpleGameMenu specific stuff\n");
101}
[6501]102
[6502]103
[6501]104/**
[7221]105 * @brief this is executed just before load
[6504]106 *
107 * since the load function sometimes needs data, that has been initialized
108 * before the load and after the proceeding storyentity has finished
109 */
110ErrorMessage SimpleGameMenu::init()
111{
112  /* call underlying init funciton */
113  GameWorld::init();
114
[7866]115  this->subscribeEvent(ES_MENU, SDLK_UP);
116  this->subscribeEvent(ES_MENU, SDLK_DOWN);
117  this->subscribeEvent(ES_MENU, SDLK_RETURN);
118  this->subscribeEvent(ES_MENU, SDLK_SPACE);
119  this->subscribeEvent(ES_MENU, SDLK_ESCAPE);
[6521]120
121  this->dataTank->localCamera->setRelCoor(this->cameraVector);
[6524]122
123  GraphicsEngine::getInstance()->displayFPS(false);
[6862]124
125  this->layerIndex = 0;
126  this->menuSelectedIndex = 0;
[6504]127}
128
129
[6524]130/**
[7221]131 * @brief load the data
[6524]132 */
[6521]133ErrorMessage SimpleGameMenu::loadData()
[6504]134{
[6521]135  GameWorld::loadData();
[6504]136
[6845]137  if (this->dataXML != NULL)
138  {
[7318]139    LoadParam(dataXML, "selector-sound", this, SimpleGameMenu, setSelectorSound);
140
[6845]141    TiXmlElement* element = this->dataXML->FirstChildElement("Elements");
142
[7318]143
[6845]144    if( element == NULL)
145    {
146      PRINTF(1)("SimpleGameMenu is missing 'Elements'\n");
147    }
148    else
149    {
150      element = element->FirstChildElement();
151    // load Players/Objects/Whatever
152      PRINTF(4)("Loading Elements\n");
153      while( element != NULL)
154      {
155        BaseObject* created = Factory::fabricate(element);
156        if( created != NULL )
[6852]157        {
158          PRINTF(4)("Created a %s::%s\n", created->getClassName(), created->getName());
159          if (!created->isA(CL_ELEMENT_2D))
160            PRINTF(2)("Error the Created Entity is not an Element2D but an %s::%s\n", created->getClassName(), created->getName());
161        }
[6851]162        element = element->NextSiblingElement();
[6845]163      }
164      PRINTF(4)("Done loading Elements\n");
165    }
166  }
167
[6520]168  /* get the menu list */
169  const std::list<BaseObject*>* imageEntityList = ClassList::getList(CL_IMAGE_ENTITY);
170  std::list<BaseObject*>::const_iterator entity;
171  for (entity = imageEntityList->begin(); entity != imageEntityList->end(); entity++)
172  {
173
174    if( !strcmp("Selector_Menu", (*entity)->getName()))
175    {
176      this->menuSelector = dynamic_cast<ImageEntity*>(*entity);
[6878]177      this->menuSelector->setBindNode((const PNode*)NULL);
[6520]178    }
[7019]179  }
180
181  imageEntityList = ClassList::getList(CL_TEXT_ELEMENT);
182  for (entity = imageEntityList->begin(); entity != imageEntityList->end(); entity++)
183  {
184    if( !strcmp( "StartGame_Menu", (*entity)->getName()))
[6520]185    {
[7019]186      this->menuStartGame = dynamic_cast<TextElement*>(*entity);
[6878]187      this->menuStartGame->setBindNode((const PNode*)NULL);
[6883]188      this->menuStartGame->setRelCoor2D(State::getResX() / 2.0f,
[7316]189                                        State::getResY() / 2.0f - 60.0f);
[7019]190      this->menuLayers[0].menuList.push_back(dynamic_cast<TextElement*>(*entity));
[6835]191
[6520]192    }
193    else if( !strcmp( "Multiplayer_Menu", (*entity)->getName()))
194    {
[7019]195      this->menuStartMultiplayerGame = dynamic_cast<TextElement*>(*entity);
[6878]196      this->menuStartMultiplayerGame->setBindNode((const PNode*)NULL);
[6883]197      this->menuStartMultiplayerGame->setRelCoor2D(State::getResX() / 2.0f,
[7316]198                                                   State::getResY() / 2.0f + ((this->menuLayers[0].menuList.size() -1 ) * 60.0f));
[7019]199      this->menuLayers[0].menuList.push_back(dynamic_cast<TextElement*>(*entity));
[6520]200    }
201    else if( !strcmp( "Quit_Menu", (*entity)->getName()))
202    {
[7019]203      this->menuQuitGame = dynamic_cast<TextElement*>(*entity);
[6878]204      this->menuQuitGame->setBindNode((const PNode*)NULL);
[6883]205      this->menuQuitGame->setRelCoor2D(State::getResX() / 2.0f,
[7316]206                                       State::getResY() / 2.0f + ((this->menuLayers[0].menuList.size() -1 )* 60.0f));
[7019]207      this->menuLayers[0].menuList.push_back(dynamic_cast<TextElement*>(*entity));
[6520]208    }
209  }
[6980]210  this->menuSelected->getNullElement()->update2D(0.1f);
[6520]211  this->menuSelectedIndex = 0;
[6991]212  this->menuSelected = this->menuLayers[0].menuList[this->menuSelectedIndex];
[7063]213  this->sliderTo(this->menuSelected, 0.0f);
[6839]214
215
216  // loading the storyentities submenu (singleplayer)
217  const std::list<BaseObject*>* storyEntities = ClassList::getList(CL_STORY_ENTITY);
218  std::list<BaseObject*>::const_iterator it;
219  for( it = storyEntities->begin(); it != storyEntities->end(); it++)
220  {
221    StoryEntity* se = dynamic_cast<StoryEntity*>(*it);
222    if( se->isContainedInMenu())
223    {
[6991]224      this->menuLayers[1].storyList.push_back(se);
[6874]225
226      // generating menu item
[7019]227      TextElement* te = new TextElement();
228      te->setVisibility(false);
229      te->setText(se->getName());
[7316]230      te->setRelCoor2D(State::getResX() / 2.0f - 200.0f, State::getResY() / 2.0f + ((this->menuLayers[1].menuList.size() - 2.0f) * 60.0f));
[7019]231      this->menuLayers[1].menuList.push_back(te);
232
233      // generating screenshoot item
[6841]234      ImageEntity* ie = new ImageEntity();
[6848]235      ie->setVisibility(false);
[6878]236      ie->setBindNode((const PNode*)NULL);
237      ie->setTexture(se->getMenuScreenshoot());
[7316]238      ie->setRelCoor2D(State::getResX() / 2.0f + 250.0f, State::getResY() / 2.0f);
[6884]239      ie->setSize2D(140.0f, 105.0f);
[6991]240      this->menuLayers[1].screenshootList.push_back(ie);
[6839]241    }
242  }
[6521]243}
[6520]244
[7318]245/**
246 * @brief set the Sound to play when switching menu entry.
247 * @param selectorSound the sound to load.
248 */
249void SimpleGameMenu::setSelectorSound(const std::string& selectorSound)
250{
[7460]251  this->selectorSource = OrxSound::SoundEngine::getInstance()->createSource(selectorSound, NULL);
[7318]252}
[6521]253
[6862]254ErrorMessage SimpleGameMenu::unloadData()
255{
[7866]256  this->unsubscribeEvents(ES_MENU);
[6862]257
[6991]258  std::vector<MenuLayer>::iterator mit;
259  for(mit = this->menuLayers.begin(); mit != this->menuLayers.end(); mit++)
[6862]260  {
[7019]261    while(!(*mit).menuList.empty())
262    {
263      delete (*mit).menuList.back();
264      (*mit).menuList.pop_back();
265    }
266
267    (*mit).menuList.clear();
268    (*mit).storyList.clear();
[6991]269    (*mit).screenshootList.clear();
[6862]270  }
[7029]271
[7318]272  // delete the SoundSource.
273  if (this->selectorSource != NULL)
274    delete this->selectorSource;
275  this->selectorSource = NULL;
[7029]276
277  GameWorld::unloadData();
[6862]278}
279
280
[6524]281/**
[7221]282 * @brief start the menu
[6524]283 */
[6521]284bool SimpleGameMenu::start()
285{
286  EventHandler::getInstance()->pushState(ES_MENU);
287
[6504]288  /* now call the underlying*/
289  GameWorld::start();
290}
291
292
293
[6524]294/**
295 * stop the menu
296 */
[6504]297bool SimpleGameMenu::stop()
298{
299  EventHandler::getInstance()->popState();
300
301  /* now call the underlying*/
302  GameWorld::stop();
303}
304
305
[6521]306/**
307 *  override the standard tick for more functionality
308 */
309void SimpleGameMenu::tick()
310{
311  GameWorld::tick();
[6504]312
[7131]313  this->animateScene(this->dtS);
[6521]314}
315
316
[6504]317/**
[7370]318 * @brief no collision detection in the menu
[6501]319 */
[6502]320void SimpleGameMenu::collide()
[6521]321{
322//   this->dataTank->localCamera->
323}
[6501]324
325
[6504]326/**
[7370]327 * @brief animate the scene
[6521]328 */
329void SimpleGameMenu::animateScene(float dt)
330{
[7131]331  Quaternion q(/*0.00005*/ dt * .1, Vector(0.0, 1.0, 0.0));
[6521]332  this->cameraVector = q.apply(this->cameraVector);
333  this->dataTank->localCamera->setRelCoor(this->cameraVector);
334  this->dataTank->localCamera->getTarget()->setRelCoorSoft(0,0,0);
335}
336
337
338/**
[7370]339 * @brief event dispatcher funciton
[6504]340 * @param event the incoming event
341 */
342void SimpleGameMenu::process(const Event &event)
343{
[6839]344  /* ----------------- LAYER 1 ---------------*/
[6837]345  if( this->layerIndex == 0)
[6504]346  {
[6837]347    if( event.type == SDLK_RETURN && event.bPressed == true)
[6520]348    {
[6837]349      if( this->menuSelected == this->menuQuitGame)
350      {
351        this->setNextStoryID(WORLD_ID_GAMEEND);
352        this->stop();
353      }
354      if( this->menuSelected == this->menuStartGame)
355      {
356        // switch to first submenu
[6991]357        if( this->menuLayers[1].menuList.size() == 0)
[6837]358        {
[6839]359          PRINTF(1)("Haven't got any StoryEntities to play!\n");
[6837]360          return;
361        }
362
363        this->switchMenuLayer(this->layerIndex, 1);
364      }
[6520]365    }
[6854]366    if( event.type == SDLK_ESCAPE && event.bPressed == true)
367    {
368      this->setNextStoryID(WORLD_ID_GAMEEND);
369      this->stop();
370    }
[6839]371  }  /* ----------------- LAYER 2 ---------------*/
[6837]372  else if( this->layerIndex == 1)
[6520]373  {
[6848]374    if( event.type == SDLK_RETURN && event.bPressed == true)
375    {
[6991]376      this->setNextStoryID( this->menuLayers[1].storyList[this->menuSelectedIndex]->getStoryID());
[6848]377      this->stop();
378    }
[6854]379    if( event.type == SDLK_ESCAPE && event.bPressed == true)
380    {
381      this->switchMenuLayer(this->layerIndex, 0);
382    }
[6520]383  }
[6853]384
385
386
387  // The menu selction cursor
388  if( event.type == SDLK_DOWN && event.bPressed == true)
389  {
[6991]390    if(this->menuSelectedIndex < (this->menuLayers[this->layerIndex].menuList.size() - 1))
[6853]391    {
[6991]392      this->menuSelected = this->menuLayers[this->layerIndex].menuList[++this->menuSelectedIndex];
[7063]393      this->sliderTo(this->menuSelected, 5.0f);
[7318]394      if (this->selectorSource != NULL)
395        this->selectorSource->play();
[6883]396
397      if( this->layerIndex == 1)
398      {
[6991]399        this->menuLayers[1].screenshootList[this->menuSelectedIndex]->setVisibility(true);
400        this->menuLayers[1].screenshootList[this->menuSelectedIndex-1]->setVisibility(false);
[6883]401      }
[6853]402    }
403  }
404  else if( event.type == SDLK_UP && event.bPressed == true)
405  {
406    if(this->menuSelectedIndex > 0)
407    {
[6991]408      this->menuSelected = this->menuLayers[this->layerIndex].menuList[--this->menuSelectedIndex];
[7063]409      this->sliderTo(this->menuSelected, 5.0f);
[7318]410      if (this->selectorSource != NULL)
411        this->selectorSource->play();
[6883]412
413      if( this->layerIndex == 1)
414      {
[6991]415        this->menuLayers[1].screenshootList[this->menuSelectedIndex]->setVisibility(true);
416        this->menuLayers[1].screenshootList[this->menuSelectedIndex+1]->setVisibility(false);
[6883]417      }
[6853]418    }
419  }
[6504]420}
[6502]421
422
[6837]423/**
[7317]424 * @brief switches to from one meny layer to an other
[6837]425 * @param layer1 from layer
426 * @param layer2 to layer
427 */
428void SimpleGameMenu::switchMenuLayer(int layer1, int layer2)
429{
430  // wrong sizes
[6991]431  if(layer1 >= this->menuLayers.size() || layer2 >= this->menuLayers.size())
[6837]432    return;
[6502]433
434
[6837]435  PRINTF(0)("Removing layer %i\n", layer1);
[7019]436  std::vector<TextElement*>::iterator te;
[6837]437  // fade old menu
[7019]438  for( te = this->menuLayers[layer1].menuList.begin(); te != this->menuLayers[layer1].menuList.end(); te++)
[6837]439  {
[7019]440    (*te)->setVisibility(false);
[6837]441  }
[7019]442
443  std::vector<ImageEntity*>::iterator it;
444
[6878]445  //also fade the screenshots if in level choosement mode
[6991]446  for( it = this->menuLayers[layer1].screenshootList.begin(); it != this->menuLayers[layer1].screenshootList.end(); it++)
[6878]447  {
448    (*it)->setVisibility(false);
449  }
[6502]450
451
[6837]452  PRINTF(0)("Showing layer %i\n", layer1);
453  // beam here the new menu
[7019]454  for( te = this->menuLayers[layer2].menuList.begin(); te != this->menuLayers[layer2].menuList.end(); te++ )
[6848]455  {
[7019]456    (*te)->setVisibility(true);
[6848]457  }
[6837]458
[6878]459
[6837]460  this->layerIndex = layer2;
[6991]461  this->menuSelected = this->menuLayers[layer2].menuList[0];
[7765]462  this->menuSelector->setAbsCoor2D(this->menuSelected->getAbsCoor2D() + Vector2D(0, this->menuSelected->getSizeY2D() *.5));
463  this->menuSelector->setSize2D(this->menuSelected->getSizeX2D()*.7, this->menuSelected->getSizeY2D());
[6855]464  this->menuSelectedIndex = 0;
[6883]465
466  if( layer2 == 1)
[6991]467    this->menuLayers[layer2].screenshootList[0]->setVisibility(true);
[6837]468}
469
[7063]470void SimpleGameMenu::sliderTo(const Element2D* element, float bias)
471{
472  if (bias > 0.0)
473  {
[7316]474    this->menuSelector->setAbsCoorSoft2D(element->getAbsCoor2D() + Vector2D(0, element->getSizeY2D() *.5), bias);
[7764]475    this->menuSelector->setSizeSoft2D(element->getSizeX2D()*.7, element->getSizeY2D(), bias);
[7063]476  }
477  else
478  {
[7316]479    this->menuSelector->setAbsCoor2D(element->getAbsCoor2D() + Vector2D(0, element->getSizeY2D() *.5));
[7764]480    this->menuSelector->setSize2D(element->getSizeX2D()*.7, element->getSizeY2D());
[7063]481  }
482}
[6837]483
484
485
[6502]486/**********************************************************************************************
487    SimpleGameMenuData
488 **********************************************************************************************/
489
490
[6501]491/**
[6502]492 * SimpleGameMenuData constructor
[6501]493 */
[6502]494SimpleGameMenuData::SimpleGameMenuData()
[6501]495{}
496
497/**
[6502]498 * SimpleGameMenuData decontructor
[6501]499 */
[6502]500SimpleGameMenuData::~SimpleGameMenuData()
[6501]501{}
502
503
504/**
[6502]505 *  initialize the GameWorldDataData
[6501]506 */
[6502]507ErrorMessage SimpleGameMenuData::init()
508{
509  /* call underlying function */
510  GameWorldData::init();
511}
[6501]512
513
514/**
[6502]515 *  loads the GUI data
516 * @param root reference to the xml root element
[6501]517 */
[7370]518ErrorMessage SimpleGameMenuData::loadGUI(const TiXmlElement* root)
[6502]519{
520  /* call underlying function */
521  GameWorldData::loadGUI(root);
522}
[6501]523
524
525/**
[6502]526 *  unloads the GUI data
[6501]527 */
[6502]528ErrorMessage SimpleGameMenuData::unloadGUI()
529{
530  /* call underlying function */
531  GameWorldData::unloadGUI();
532}
533
534
535/**
536 *  overloads the GameWorld::loadWorldEntities(...) class since the menu WorldEntity loading is different (less loading stuff)
537 * @param root reference to the xml root parameter
538 */
[7370]539ErrorMessage SimpleGameMenuData::loadWorldEntities(const TiXmlElement* root)
[6502]540{
[7370]541  GameWorldData::loadWorldEntities(root);
542  /*
543  const TiXmlElement* element = root->FirstChildElement("WorldEntities");
[6502]544
545  if( element != NULL)
546  {
547    element = element->FirstChildElement();
548    PRINTF(4)("Loading WorldEntities\n");
[7370]549    while(element != NULL)
[6502]550    {
551      BaseObject* created = Factory::fabricate(element);
552      if( created != NULL )
553        printf("Created a %s: %s\n", created->getClassName(), created->getName());
554
[7370]555      if( element->Value() == "SkyBox")
[6502]556        this->sky = dynamic_cast<WorldEntity*>(created);
[7370]557      if( element->Value() == "Terrain")
[6502]558        this->terrain = dynamic_cast<Terrain*>(created);
559      element = element->NextSiblingElement();
560    }
[7370]561
[6502]562    PRINTF(4)("Done loading WorldEntities\n");
563  }
564
[7370]565  // init the pnode tree
[6502]566  PNode::getNullParent()->init();
[7370]567  */
[6502]568}
569
570
571/**
572 *  unloads the world entities from the xml file
573 */
574ErrorMessage SimpleGameMenuData::unloadWorldEntities()
575{
576  /* call underlying function */
577  GameWorldData::unloadWorldEntities();
578}
579
580
581/**
582 *  loads the scene data
583 * @param root reference to the xml root element
584 */
[7370]585ErrorMessage SimpleGameMenuData::loadScene(const TiXmlElement* root)
[6502]586{
587  /* call underlying function */
588  GameWorldData::loadScene(root);
589}
590
591
592/**
593 *  unloads the scene data
594 */
595ErrorMessage SimpleGameMenuData::unloadScene()
596{
597  /* call underlying function */
598  GameWorldData::unloadScene();
599}
600
601
602
Note: See TracBrowser for help on using the repository browser.