Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

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

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

gui: added definitions

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