Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

Last change on this file since 7884 was 7884, checked in by bensch, 19 years ago

orxonox/trunk: first Event gets dispached… but i see, that the interface is crappy… there has to be a much better solution for:

  1. Generating Signals (more variable)
  2. Bringing Variables onto the Signals
  3. Interface has to be way simpler:

at the moment the Interface looks like this:
===
OrxGui::GLGuiPushButton* rdnpb = new OrxGui::GLGuiPushButton("REALLY DO NOT PUSH ME");
rdnpb→connectSignal(OrxGui::Signal_release, this, createExecutor<SimpleGameMenu>(&SimpleGameMenu::quitMenu));
===
But it should be like the following:
OrxGui::GLGuiPushButton* pb = new OrxGui::GLGuiPushButton("Push this button, it is way better");
pb→connect(this, OrxGui::SIGNAL(released()), this, OrxGui::SLOT(quitMenu()));

man, this would be almost too much :)

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