Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

orxonox/trunk: fixed a bug in the EventHandler, that resulted from multiple inputs or so…

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