Show
Ignore:
Timestamp:
05/22/05 22:19:26 (9 years ago)
Author:
robert
Message:

Added scoring, welcome page, you've lost and you've won pages.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • OpenSceneGraph/trunk/examples/osgcatch/osgcatch.cpp

    r4281 r4282  
    1515#include <osgDB/ReadFile> 
    1616#include <osgDB/WriteFile> 
     17 
    1718#include <osgUtil/Optimizer> 
     19#include <osgUtil/GLObjectsVisitor> 
     20 
     21#include <osgText/Text> 
    1822 
    1923#include <osg/Geode> 
     
    3135#include <osgParticle/FireEffect> 
    3236 
     37#include <sstream> 
     38 
    3339typedef std::vector<std::string> FileList; 
    3440typedef std::map<std::string, osg::ref_ptr<osg::Node> >  ObjectMap; 
     
    509515    osg::Matrix getCameraPosition(); 
    510516     
     517    void compileGLObjects(osg::State& state) 
     518    { 
     519        osgUtil::GLObjectsVisitor compile; 
     520        compile.setState(&state); 
     521     
     522        for(ObjectMap::iterator itr = s_objectMap.begin(); 
     523            itr != s_objectMap.end(); 
     524            ++itr) 
     525        { 
     526            itr->second->accept(compile); 
     527        } 
     528    } 
     529     
    511530    osg::Node* createScene(); 
    512531     
     
    516535    void createNewCatchable(); 
    517536     
     537    void clearCatchables() 
     538    { 
     539        for(CatchableObjectList::iterator itr=_catchableObjects.begin(); 
     540            itr!=_catchableObjects.end(); 
     541            ++itr) 
     542        { 
     543            // need to remove 
     544            // remove child from parents. 
     545            osg::ref_ptr<osg::PositionAttitudeTransform> child = (*itr)->_object; 
     546            osg::Node::ParentList parents = child->getParents(); 
     547            for(osg::Node::ParentList::iterator pitr=parents.begin(); 
     548                pitr!=parents.end(); 
     549                ++pitr) 
     550            { 
     551                (*pitr)->removeChild(child.get()); 
     552            } 
     553        } 
     554 
     555        _catchableObjects.clear(); 
     556    } 
     557     
    518558    void resetLevel() 
    519559    { 
    520560        _level = 0; 
    521561        _levelSwitch->setSingleChildOn(_level); 
     562        clearCatchables(); 
     563 
     564        updateLevelText(); 
     565 
     566        _levelStartTick = osg::Timer::instance()->tick(); 
    522567    } 
    523568     
     
    528573        { 
    529574            _levelSwitch->setSingleChildOn(_level); 
    530         } 
    531     } 
    532      
     575            clearCatchables(); 
     576        } 
     577 
     578        updateLevelText(); 
     579 
     580        _levelStartTick = osg::Timer::instance()->tick(); 
     581    } 
     582 
    533583    bool gameComplete() 
    534584    { 
    535585        return _level >= _levelSwitch->getNumChildren(); 
    536586    } 
     587 
     588    void resetGame() 
     589    { 
     590        _currentScore = 0; 
     591         
     592        updateTextWithScore(); 
     593 
     594        clearCatchables(); 
     595        resetLevel(); 
     596         
     597        for(unsigned int i=0;i<_numberOfPlayers;++i) 
     598        { 
     599            _players[i].reset(); 
     600        } 
     601    } 
     602 
    537603 
    538604    enum Players 
     
    549615        { 
    550616            livesPosition = _originBaseLine+osg::Vec3(0.0f,-0.5f,0.0f); 
    551             catchesPosition = _originBaseLine+osg::Vec3(200.0f,-0.5f,0.0f); 
     617            catchesPosition = _originBaseLine+osg::Vec3(100.0f,-0.5f,0.0f); 
    552618        } 
    553619        else 
    554620        { 
    555             livesPosition = _originBaseLine+osg::Vec3(900.0f,-0.5f,000.0f); 
     621            livesPosition = _originBaseLine+osg::Vec3(1000.0f,-0.5f,000.0f); 
    556622            catchesPosition = _originBaseLine+osg::Vec3(1100.0f,-0.5f,0.0f); 
    557623        } 
     
    585651        }                 
    586652    } 
    587          
     653     
     654     
     655    typedef std::vector< osg::ref_ptr<osgText::Text> > TextList; 
     656 
     657    void updateScoreWithCatch() 
     658    { 
     659        _currentScore += 1; 
     660        updateTextWithScore(); 
     661    } 
     662 
     663    void updateScoreWithLevel() 
     664    { 
     665        osg::Timer_t newTick = osg::Timer::instance()->tick(); 
     666        double timeForLevel = osg::Timer::instance()->delta_s(_levelStartTick, newTick); 
     667 
     668        // a ten second level gets you 10 points,  
     669        // a twenty second levels gets you 5 points.         
     670        _currentScore += static_cast<unsigned int>(10000.0f/(timeForLevel*timeForLevel)); 
     671 
     672        updateTextWithScore(); 
     673 
     674    } 
     675 
     676    void updateTextWithScore() 
     677    { 
     678        std::ostringstream os; 
     679        os<<"Score: "<<_currentScore; 
     680         
     681        std::string textString = os.str(); 
     682     
     683        for(TextList::iterator itr = _scoreTextList.begin(); 
     684            itr != _scoreTextList.end(); 
     685            ++itr) 
     686        { 
     687            (*itr)->setText(textString); 
     688        } 
     689    }         
     690     
     691    void updateLevelText() 
     692    { 
     693        std::ostringstream os; 
     694        os<<"Level: "<<_level+1; 
     695        _levelText->setText(os.str()); 
     696    } 
    588697         
    589698 
     
    607716    float _initialNumDropsPerSecond; 
    608717     
    609     osg::ref_ptr<osg::Group> _group; 
    610     osg::ref_ptr<osg::Switch> _levelSwitch; 
     718    osg::ref_ptr<osg::Switch>   _gameSwitch; 
     719    osg::ref_ptr<osg::Group>    _gameGroup; 
     720    osg::ref_ptr<osg::Switch>   _levelSwitch; 
     721     
     722    unsigned int                _currentIndex; 
     723    unsigned int                _welcomeIndex; 
     724    unsigned int                _lostIndex; 
     725    unsigned int                _wonIndex; 
     726    unsigned int                _gameIndex; 
     727     
     728    osg::Timer_t                _levelStartTick; 
     729    unsigned int                _currentScore; 
     730     
     731    osg::ref_ptr<osgText::Text> _levelText; 
     732    TextList                    _scoreTextList; 
    611733     
    612734    unsigned int _numberOfPlayers; 
     
    621743    bool _leftKeyPressed; 
    622744    bool _rightKeyPressed; 
     745     
     746    osg::ref_ptr<CatchableObject> _dummyCatchable; 
    623747     
    624748         
     
    647771 
    648772    _backgroundFiles.push_back("Catch/sky1.JPG"); 
     773    _backgroundFiles.push_back("Catch/sky3.JPG"); 
    649774    _backgroundFiles.push_back("Catch/sky2.JPG"); 
    650     _backgroundFiles.push_back("Catch/sky3.JPG"); 
    651775    _backgroundFiles.push_back("Catch/farm.JPG"); 
    652776 
     
    663787    CatchableObject::setUpCatchablesMap(_benignCatachables); 
    664788     
    665      
     789    _currentScore = 0; 
    666790 
    667791} 
     
    669793bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) 
    670794{ 
    671     switch(ea.getEventType()) 
    672     { 
    673         case(osgGA::GUIEventAdapter::FRAME): 
    674         { 
    675             // move characters 
    676             if (_leftKeyPressed) 
     795    if (_currentIndex==_welcomeIndex) 
     796    { 
     797        // welcome screen 
     798        switch(ea.getEventType()) 
     799        { 
     800            case(osgGA::GUIEventAdapter::KEYDOWN): 
    677801            { 
    678                 if (_numberOfPlayers>=2) _players[1].moveLeft(); 
     802                _currentIndex = _gameIndex; 
     803                _gameSwitch->setSingleChildOn(_currentIndex); 
     804                resetGame(); 
     805                return true; 
    679806            } 
    680              
    681             if (_rightKeyPressed) 
     807            default: 
     808                return false; 
     809        } 
     810         
     811    } 
     812    else if (_currentIndex==_lostIndex) 
     813    { 
     814        // lost screen 
     815        switch(ea.getEventType()) 
     816        { 
     817            case(osgGA::GUIEventAdapter::KEYDOWN): 
    682818            { 
    683                 if (_numberOfPlayers>=2) _players[1].moveRight(); 
     819                _currentIndex = _gameIndex; 
     820                _gameSwitch->setSingleChildOn(_currentIndex); 
     821                resetGame(); 
     822                return true; 
    684823            } 
    685  
    686             static double previous_time = ea.time(); 
    687             double dt = ea.time()-previous_time; 
    688             previous_time = ea.time(); 
    689              
    690             // move objects 
    691             for(CatchableObjectList::iterator itr=_catchableObjects.begin(); 
    692                 itr!=_catchableObjects.end(); 
    693                 ++itr) 
     824            default: 
     825                return false; 
     826        } 
     827         
     828    } 
     829    else if (_currentIndex==_wonIndex) 
     830    { 
     831        // won screen 
     832        switch(ea.getEventType()) 
     833        { 
     834            case(osgGA::GUIEventAdapter::KEYDOWN): 
    694835            { 
    695                 (*itr)->update(dt); 
    696                  
    697                 bool removeEntry = false; 
    698  
    699                 for(unsigned int i=0;i<_numberOfPlayers;++i) 
     836                _currentIndex = _gameIndex; 
     837                _gameSwitch->setSingleChildOn(_currentIndex); 
     838                resetGame(); 
     839                return true; 
     840            } 
     841            default: 
     842                return false; 
     843        } 
     844         
     845    } 
     846    else if (_currentIndex==_gameIndex) 
     847    { 
     848        // in game. 
     849 
     850        switch(ea.getEventType()) 
     851        { 
     852            case(osgGA::GUIEventAdapter::FRAME): 
     853            { 
     854                // move characters 
     855                if (_leftKeyPressed) 
    700856                { 
    701                     if ((*itr)->dangerous()) 
     857                    if (_numberOfPlayers>=2) _players[1].moveLeft(); 
     858                } 
     859 
     860                if (_rightKeyPressed) 
     861                { 
     862                    if (_numberOfPlayers>=2) _players[1].moveRight(); 
     863                } 
     864 
     865                static double previous_time = ea.time(); 
     866                double dt = ea.time()-previous_time; 
     867                previous_time = ea.time(); 
     868 
     869                // move objects 
     870                for(CatchableObjectList::iterator itr=_catchableObjects.begin(); 
     871                    itr!=_catchableObjects.end(); 
     872                    ++itr) 
     873                { 
     874                    (*itr)->update(dt); 
     875 
     876                    bool removeEntry = false; 
     877 
     878                    for(unsigned int i=0;i<_numberOfPlayers;++i) 
    702879                    { 
    703                         if ((*itr)->anyInside(_players[i].getLowerLeft(),_players[i].getUpperRight())) 
     880                        bool inBasket = ((*itr)->centerInside(_players[i].getCurrentCenterOfBasket(),_players[i].getCurrentRadiusOfBasket())); 
     881                     
     882                        if ((*itr)->dangerous()) 
    704883                        { 
    705                             if (!_players[i].looseLife()) 
     884                            if ((*itr)->anyInside(_players[i].getLowerLeft(),_players[i].getUpperRight()) || inBasket) 
    706885                            { 
    707                                 std::cout<<"Ouch you lost all your lives, Game Over!!"<<std::endl; 
    708                                 exit(0); 
     886                                // player has hit or caught a dangerous object, must loose a life. 
     887                                if (!_players[i].looseLife()) 
     888                                { 
     889                                    _currentIndex = _lostIndex; 
     890                                    _gameSwitch->setSingleChildOn(_currentIndex); 
     891 
     892                                    return true; 
     893                                } 
     894                                else 
     895                                { 
     896                                    clearCatchables(); 
     897                                    return true; 
     898                                } 
    709899                            } 
     900                        } 
     901                        else if (inBasket) 
     902                        { 
     903                            // player has caught a safe object. 
     904                            updateScoreWithCatch(); 
     905                             
     906                            if (!_players[i].addCatch()) 
     907                            { 
     908                                _players[i].resetCatches(); 
     909                                updateScoreWithLevel(); 
     910                                nextLevel(); 
     911                                if (gameComplete()) 
     912                                { 
     913                                    _currentIndex = _wonIndex; 
     914                                    _gameSwitch->setSingleChildOn(_currentIndex); 
     915                                } 
     916                                return true; 
     917                            } 
     918 
    710919                            removeEntry = true; 
    711920                        } 
    712921                    } 
    713                     else 
     922 
     923                    if (!(*itr)->anyInside(_origin, _origin+_width+_height) ||  
     924                        (*itr)->needToRemove(ea.time()) || 
     925                        removeEntry) 
    714926                    { 
    715                         if ((*itr)->centerInside(_players[i].getCurrentCenterOfBasket(),_players[i].getCurrentRadiusOfBasket())) 
     927                        // need to remove 
     928                        // remove child from parents. 
     929                        osg::ref_ptr<osg::PositionAttitudeTransform> child = (*itr)->_object; 
     930                        osg::Node::ParentList parents = child->getParents(); 
     931                        for(osg::Node::ParentList::iterator pitr=parents.begin(); 
     932                            pitr!=parents.end(); 
     933                            ++pitr) 
    716934                        { 
    717                             if (!_players[i].addCatch()) 
    718                             { 
    719                                 _players[i].resetCatches(); 
    720                                 nextLevel(); 
    721                                 if (gameComplete()) 
    722                                 { 
    723                                     std::cout<<"Congratulations you've completed the game!!"<<std::endl; 
    724                                     exit(0); 
    725                                 } 
    726                             } 
    727                              
    728                              
    729                             removeEntry = true; 
     935                            (*pitr)->removeChild(child.get()); 
    730936                        } 
     937 
     938                        // remove child from catchable list 
     939                        itr = _catchableObjects.erase(itr); 
     940 
    731941                    } 
     942                    else if ((*itr)->anyInside(_origin, _origin+_width) && !(*itr)->stopped()) 
     943                    { 
     944                        // hit base line 
     945                        (*itr)->explode(); 
     946                        (*itr)->stop(); 
     947                        (*itr)->setTimeToRemove(ea.time()+3.0); 
     948                    } 
     949 
    732950                } 
    733951 
    734                 if (!(*itr)->anyInside(_origin, _origin+_width+_height) ||  
    735                     (*itr)->needToRemove(ea.time()) || 
    736                     removeEntry) 
     952 
     953                // create new catchable objects 
     954                static double previousTime = ea.time(); 
     955                double deltaTime = ea.time()-previousTime; 
     956                previousTime = ea.time(); 
     957 
     958                float numDropsPerSecond = _initialNumDropsPerSecond * (_level+1); 
     959                float r = (float)rand()/(float)RAND_MAX; 
     960                if (r < deltaTime*numDropsPerSecond) 
     961                {  
     962                    createNewCatchable(); 
     963                } 
     964 
     965 
     966 
     967            } 
     968            case(osgGA::GUIEventAdapter::KEYDOWN): 
     969            { 
     970                if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left) 
    737971                { 
    738                     // need to remove 
    739                     // remove child from parents. 
    740                     osg::ref_ptr<osg::PositionAttitudeTransform> child = (*itr)->_object; 
    741                     osg::Node::ParentList parents = child->getParents(); 
    742                     for(osg::Node::ParentList::iterator pitr=parents.begin(); 
    743                         pitr!=parents.end(); 
    744                         ++pitr) 
    745                     { 
    746                         (*pitr)->removeChild(child.get()); 
    747                     } 
    748  
    749                     // remove child from catchable list 
    750                     itr = _catchableObjects.erase(itr); 
    751  
     972                    _leftKeyPressed=true; 
     973                    return true; 
    752974                } 
    753                 else if ((*itr)->anyInside(_origin, _origin+_width) && !(*itr)->stopped()) 
     975                else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right) 
    754976                { 
    755                     // hit base line 
    756                     (*itr)->explode(); 
    757                     (*itr)->stop(); 
    758                     (*itr)->setTimeToRemove(ea.time()+3.0); 
     977                    _rightKeyPressed=true; 
     978                    return true; 
    759979                } 
    760                  
    761980            } 
    762               
    763  
    764             // create new catchable objects 
    765             static double previousTime = ea.time(); 
    766             double deltaTime = ea.time()-previousTime; 
    767             previousTime = ea.time(); 
    768              
    769             float numDropsPerSecond = _initialNumDropsPerSecond * (_level+1); 
    770             float r = (float)rand()/(float)RAND_MAX; 
    771             if (r < deltaTime*numDropsPerSecond) 
    772             {  
    773                 createNewCatchable(); 
     981            case(osgGA::GUIEventAdapter::KEYUP): 
     982            { 
     983                if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left) 
     984                { 
     985                    _leftKeyPressed=false; 
     986                    return true; 
     987                } 
     988                else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right) 
     989                { 
     990                    _rightKeyPressed=false; 
     991                    return true; 
     992                } 
    774993            } 
    775  
    776  
    777  
    778         } 
    779         case(osgGA::GUIEventAdapter::KEYDOWN): 
    780         { 
    781             if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left) 
     994            case(osgGA::GUIEventAdapter::DRAG): 
     995            case(osgGA::GUIEventAdapter::MOVE): 
    782996            { 
    783                 _leftKeyPressed=true; 
     997                float px = (ea.getXnormalized()+1.0f)*0.5f; 
     998 
     999                if (_numberOfPlayers>=1) _players[0].moveTo(px); 
     1000 
    7841001                return true; 
    7851002            } 
    786             else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right) 
    787             { 
    788                 _rightKeyPressed=true; 
    789                 return true; 
    790             } 
    791             else if (ea.getKey()==' ') 
    792             { 
    793                 for(unsigned int i=0;i<_numberOfPlayers;++i) 
    794                 { 
    795                     _players[i].reset(); 
    796                 } 
    797                 return true; 
    798             } 
    799         } 
    800         case(osgGA::GUIEventAdapter::KEYUP): 
    801         { 
    802             if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Left) 
    803             { 
    804                 _leftKeyPressed=false; 
    805                 return true; 
    806             } 
    807             else if (ea.getKey()==osgGA::GUIEventAdapter::KEY_Right) 
    808             { 
    809                 _rightKeyPressed=false; 
    810                 return true; 
    811             } 
    812         } 
    813         case(osgGA::GUIEventAdapter::DRAG): 
    814         case(osgGA::GUIEventAdapter::MOVE): 
    815         { 
    816             float px = (ea.getXnormalized()+1.0f)*0.5f; 
    817  
    818             if (_numberOfPlayers>=1) _players[0].moveTo(px); 
    819  
    820             return true; 
    821         } 
    822  
    823         default: 
    824             return false; 
    825     } 
     1003 
     1004            default: 
     1005                return false; 
     1006        } 
     1007    } 
     1008    return false;     
    8261009} 
    8271010 
     
    8431026osg::Node* GameEventHandler::createScene() 
    8441027{ 
    845     _group = new osg::Group; 
    846  
    847     if (_numberOfPlayers==0) 
    848     { 
    849         addPlayer(PLAYER_GIRL); 
    850     } 
    851  
    852     for(unsigned int i=0;i<_numberOfPlayers;++i) 
    853     { 
    854         _group->addChild(_players[i]._character.get()); 
    855         _group->addChild(_players[i]._livesSwitch.get()); 
    856         _group->addChild(_players[i]._catchSwitch.get()); 
    857     }     
    858      
    859     // background 
    860     { 
    861         _levelSwitch = new osg::Switch; 
    862          
    863         for(FileList::const_iterator itr = _backgroundFiles.begin(); 
    864             itr != _backgroundFiles.end(); 
    865             ++itr) 
    866         { 
    867  
    868             osg::Image* image = osgDB::readImageFile(*itr); 
    869             if (image) 
     1028    _gameSwitch = new osg::Switch; 
     1029     
     1030    // create a dummy catchable to load all the particule textures to reduce  
     1031    // latency later on.. 
     1032    _dummyCatchable = new CatchableObject; 
     1033    _dummyCatchable->setObject("Catch/a.png","a",osg::Vec3(0.0f,0.0,0.0f),1.0f,osg::Vec3(0.0f,0.0,0.0f)); 
     1034    _dummyCatchable->explode(); 
     1035 
     1036    // set up welcome subgraph 
     1037    { 
     1038        osg::Geode* geode = new osg::Geode; 
     1039 
     1040        // set up the background 
     1041        osg::Image* image = osgDB::readImageFile("Catch/Welcome.png"); 
     1042        if (image) 
     1043        { 
     1044            osg::Geometry* geometry = osg::createTexturedQuadGeometry(_origin,_width,_height); 
     1045            osg::StateSet* stateset = geometry->getOrCreateStateSet(); 
     1046            stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON); 
     1047 
     1048            geode->addDrawable(geometry); 
     1049        } 
     1050         
     1051        // set up the text 
     1052        osg::Vec3 textPosition = _origin+_width*0.5f+_height*0.8f -osg::Vec3(0.0f,0.1f,0.0f); 
     1053        { 
     1054            osgText::Text* text = new osgText::Text; 
     1055            text->setText("osgcatch is a childrens catching game\nMove your character using the mouse to\ncatch falling objects in your net\nbut avoid burning objects - they kill!!"); 
     1056            text->setFont("fonts/dirtydoz.ttf"); 
     1057            text->setPosition(textPosition); 
     1058            text->setCharacterSize(_width.length()*0.025f); 
     1059            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1060            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1061            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1062 
     1063            geode->addDrawable(text); 
     1064        } 
     1065         
     1066        { 
     1067            textPosition -= _height*0.25f; 
     1068            osgText::Text* text = new osgText::Text; 
     1069            text->setText("Move mouse left and right to move character\nCatch ten objects to advance to next level\nComplete four levels to win."); 
     1070            text->setFont("fonts/dirtydoz.ttf"); 
     1071            text->setPosition(textPosition); 
     1072            text->setCharacterSize(_width.length()*0.025f); 
     1073            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1074            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1075            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1076 
     1077            geode->addDrawable(text); 
     1078        } 
     1079 
     1080        { 
     1081            textPosition -= _height*0.25f; 
     1082            osgText::Text* text = new osgText::Text; 
     1083            text->setText("Game concept and artwork - Caitlin Osfield, aged 5!\nSoftware development - Robert Osfield"); 
     1084            text->setFont("fonts/dirtydoz.ttf"); 
     1085            text->setPosition(textPosition); 
     1086            text->setCharacterSize(_width.length()*0.025f); 
     1087            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1088            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1089            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1090 
     1091            geode->addDrawable(text); 
     1092        } 
     1093 
     1094        { 
     1095            textPosition -= _height*0.25f; 
     1096            osgText::Text* text = new osgText::Text; 
     1097            text->setText("Press any key to start game.\nPress Escape to exit game at any time."); 
     1098            text->setFont("fonts/dirtydoz.ttf"); 
     1099            text->setPosition(textPosition); 
     1100            text->setCharacterSize(_width.length()*0.025f); 
     1101            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1102            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1103            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1104 
     1105            geode->addDrawable(text); 
     1106        } 
     1107 
     1108        _welcomeIndex = _gameSwitch->getNumChildren(); 
     1109        _gameSwitch->addChild(geode); 
     1110    } 
     1111 
     1112    // set up you've lost subgraph 
     1113    { 
     1114        osg::Geode* geode = new osg::Geode; 
     1115 
     1116        osg::Image* image = osgDB::readImageFile("Catch/YouLost.png"); 
     1117        if (image) 
     1118        { 
     1119            osg::Geometry* geometry = osg::createTexturedQuadGeometry(_origin,_width,_height); 
     1120            osg::StateSet* stateset = geometry->getOrCreateStateSet(); 
     1121            stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON); 
     1122 
     1123            geode->addDrawable(geometry); 
     1124        } 
     1125         
     1126        // set up the text 
     1127        osg::Vec3 textPosition = _origin+_width*0.5f+_height*0.75f -osg::Vec3(0.0f,0.1f,0.0f); 
     1128        { 
     1129            osgText::Text* text = new osgText::Text; 
     1130            text->setText("Game Over\nYou lost all three lives"); 
     1131            text->setFont("fonts/dirtydoz.ttf"); 
     1132            text->setPosition(textPosition); 
     1133            text->setCharacterSize(_width.length()*0.04f); 
     1134            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1135            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1136            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1137 
     1138            geode->addDrawable(text); 
     1139        } 
     1140         
     1141        { 
     1142            textPosition -= _height*0.25f; 
     1143            osgText::Text* text = new osgText::Text; 
     1144            text->setText("Score: 0"); 
     1145            text->setFont("fonts/dirtydoz.ttf"); 
     1146            text->setPosition(textPosition); 
     1147            text->setCharacterSize(_width.length()*0.04f); 
     1148            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1149            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1150            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1151 
     1152            geode->addDrawable(text); 
     1153            _scoreTextList.push_back(text); 
     1154        } 
     1155 
     1156        { 
     1157            textPosition -= _height*0.25f; 
     1158            osgText::Text* text = new osgText::Text; 
     1159            text->setText("Press any key to have another game.\nPress Escape to exit game."); 
     1160            text->setFont("fonts/dirtydoz.ttf"); 
     1161            text->setPosition(textPosition); 
     1162            text->setCharacterSize(_width.length()*0.025f); 
     1163            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1164            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1165            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1166 
     1167            geode->addDrawable(text); 
     1168        } 
     1169 
     1170        _lostIndex = _gameSwitch->getNumChildren(); 
     1171        _gameSwitch->addChild(geode); 
     1172    } 
     1173 
     1174    // set up you've won subgraph 
     1175    { 
     1176        osg::Geode* geode = new osg::Geode; 
     1177 
     1178        osg::Image* image = osgDB::readImageFile("Catch/YouWon.png"); 
     1179        if (image) 
     1180        { 
     1181            osg::Geometry* geometry = osg::createTexturedQuadGeometry(_origin,_width,_height); 
     1182            osg::StateSet* stateset = geometry->getOrCreateStateSet(); 
     1183            stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON); 
     1184 
     1185            geode->addDrawable(geometry); 
     1186        } 
     1187         
     1188        // set up the text 
     1189        osg::Vec3 textPosition = _origin+_width*0.5f+_height*0.75f -osg::Vec3(0.0f,0.1f,0.0f); 
     1190        { 
     1191            osgText::Text* text = new osgText::Text; 
     1192            text->setText("Well done!!!\nYou completed all levels!"); 
     1193            text->setFont("fonts/dirtydoz.ttf"); 
     1194            text->setPosition(textPosition); 
     1195            text->setCharacterSize(_width.length()*0.04f); 
     1196            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1197            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1198            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1199 
     1200            geode->addDrawable(text); 
     1201        } 
     1202         
     1203        { 
     1204            textPosition -= _height*0.25f; 
     1205            osgText::Text* text = new osgText::Text; 
     1206            text->setText("Score: 0"); 
     1207            text->setFont("fonts/dirtydoz.ttf"); 
     1208            text->setPosition(textPosition); 
     1209            text->setCharacterSize(_width.length()*0.04f); 
     1210            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1211            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1212            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1213 
     1214            geode->addDrawable(text); 
     1215            _scoreTextList.push_back(text); 
     1216        } 
     1217 
     1218        { 
     1219            textPosition -= _height*0.25f; 
     1220            osgText::Text* text = new osgText::Text; 
     1221            text->setText("Press any key to have another game.\nPress Escape to exit game."); 
     1222            text->setFont("fonts/dirtydoz.ttf"); 
     1223            text->setPosition(textPosition); 
     1224            text->setCharacterSize(_width.length()*0.025f); 
     1225            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1226            text->setAlignment(osgText::Text::CENTER_CENTER); 
     1227            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1228 
     1229            geode->addDrawable(text); 
     1230        } 
     1231 
     1232        _wonIndex = _gameSwitch->getNumChildren(); 
     1233        _gameSwitch->addChild(geode); 
     1234    } 
     1235 
     1236    // set up game subgraph. 
     1237    { 
     1238        _gameGroup = new osg::Group; 
     1239 
     1240        if (_numberOfPlayers==0) 
     1241        { 
     1242            addPlayer(PLAYER_GIRL); 
     1243        } 
     1244 
     1245        for(unsigned int i=0;i<_numberOfPlayers;++i) 
     1246        { 
     1247            _gameGroup->addChild(_players[i]._character.get()); 
     1248            _gameGroup->addChild(_players[i]._livesSwitch.get()); 
     1249            _gameGroup->addChild(_players[i]._catchSwitch.get()); 
     1250        }     
     1251 
     1252        // background 
     1253        { 
     1254            _levelSwitch = new osg::Switch; 
     1255 
     1256            for(FileList::const_iterator itr = _backgroundFiles.begin(); 
     1257                itr != _backgroundFiles.end(); 
     1258                ++itr) 
    8701259            { 
    871                 osg::Geometry* geometry = osg::createTexturedQuadGeometry(_origin,_width,_height); 
    872                 osg::StateSet* stateset = geometry->getOrCreateStateSet(); 
    873                 stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON); 
    874  
    875                 osg::Geode* geode = new osg::Geode; 
    876                 geode->addDrawable(geometry); 
    877  
    878                 _levelSwitch->addChild(geode); 
     1260 
     1261                osg::Image* image = osgDB::readImageFile(*itr); 
     1262                if (image) 
     1263                { 
     1264                    osg::Geometry* geometry = osg::createTexturedQuadGeometry(_origin,_width,_height); 
     1265                    osg::StateSet* stateset = geometry->getOrCreateStateSet(); 
     1266                    stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON); 
     1267 
     1268                    osg::Geode* geode = new osg::Geode; 
     1269                    geode->addDrawable(geometry); 
     1270 
     1271                    _levelSwitch->addChild(geode); 
     1272                } 
    8791273            } 
    880         } 
    881         _levelSwitch->setSingleChildOn(0); 
    882         _group->addChild(_levelSwitch.get()); 
    883     } 
    884  
    885     return _group.get(); 
     1274            _levelSwitch->setSingleChildOn(0); 
     1275            _gameGroup->addChild(_levelSwitch.get()); 
     1276        } 
     1277 
     1278 
     1279        _gameIndex = _gameSwitch->getNumChildren(); 
     1280        _gameSwitch->addChild(_gameGroup.get()); 
     1281 
     1282        // set up the text 
     1283        osg::Vec3 textPosition = _origin+_width*0.05f+_height*0.95f-osg::Vec3(0.0f,0.1f,0.0f); 
     1284        { 
     1285            osgText::Text* text = new osgText::Text; 
     1286            text->setText("Score : 0"); 
     1287            text->setFont("fonts/dirtydoz.ttf"); 
     1288            text->setPosition(textPosition); 
     1289            text->setCharacterSize(_width.length()*0.04f); 
     1290            text->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1291            text->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1292 
     1293            osg::Geode* geode = new osg::Geode; 
     1294            geode->addDrawable(text); 
     1295            _scoreTextList.push_back(text); 
     1296             
     1297            textPosition -= _height*0.05f; 
     1298            _levelText = new osgText::Text; 
     1299            _levelText->setText("Level : 0"); 
     1300            _levelText->setFont("fonts/dirtydoz.ttf"); 
     1301            _levelText->setPosition(textPosition); 
     1302            _levelText->setCharacterSize(_width.length()*0.04f); 
     1303            _levelText->setColor(osg::Vec4(0.0f,0.2f,0.2f,1.0f)); 
     1304            _levelText->setAxisAlignment(osgText::Text::XZ_PLANE); 
     1305 
     1306            geode->addDrawable(_levelText.get()); 
     1307             
     1308 
     1309 
     1310            _gameGroup->addChild(geode); 
     1311        } 
     1312 
     1313 
     1314    } 
     1315     
     1316    _currentIndex = _welcomeIndex; 
     1317    _gameSwitch->setSingleChildOn(_currentIndex); 
     1318 
     1319    return _gameSwitch.get(); 
    8861320} 
    8871321 
     
    8961330 
    8971331    float ratio = ((float)rand() / (float)RAND_MAX); 
    898     float size = 100.0f*((float)rand() / (float)RAND_MAX); 
     1332    float size = 20.0f+100.0f*((float)rand() / (float)RAND_MAX); 
    8991333    float angle = osg::PI*0.25f + 0.5f*osg::PI*((float)rand() / (float)RAND_MAX); 
    9001334    float speed = 200.0f*((float)rand() / (float)RAND_MAX); 
     
    9131347    } 
    9141348 
    915     _group->addChild(catchableObject->_object.get()); 
    916 } 
     1349    _gameGroup->addChild(catchableObject->_object.get()); 
     1350} 
     1351 
     1352 
     1353class CompileStateCallback : public osgProducer::OsgCameraGroup::RealizeCallback 
     1354{ 
     1355    public: 
     1356        CompileStateCallback(GameEventHandler* eh):_gameEventHandler(eh) {} 
     1357         
     1358        virtual void operator()( osgProducer::OsgCameraGroup&, osgProducer::OsgSceneHandler& sh, const Producer::RenderSurface& ) 
     1359        {  
     1360            // now safe to construct 
     1361            sh.init(); 
     1362                         
     1363            if (_gameEventHandler) 
     1364            { 
     1365                _gameEventHandler->compileGLObjects(*(sh.getSceneView()->getState())); 
     1366            } 
     1367        } 
     1368         
     1369         
     1370        GameEventHandler*  _gameEventHandler; 
     1371         
     1372}; 
    9171373 
    9181374int main( int argc, char **argv ) 
     
    9801436    seh->setFOVY(fovy); 
    9811437     
     1438    // enable the image cache so we don't need to keep loading the particle files 
     1439    osgDB::ReaderWriter::Options* options = new osgDB::ReaderWriter::Options; 
     1440    options->setObjectCacheHint(osgDB::ReaderWriter::Options::CACHE_IMAGES); 
     1441    osgDB::Registry::instance()->setOptions(options); 
     1442 
     1443 
    9821444    // creat the scene from the file list. 
    9831445    osg::ref_ptr<osg::Node> rootNode = seh->createScene(); 
     
    9871449    // set the scene to render 
    9881450    viewer.setSceneData(rootNode.get()); 
     1451 
     1452    viewer.setRealizeCallback(new CompileStateCallback(seh)); 
    9891453 
    9901454    // create the windows and run the threads. 
     
    10101474    } 
    10111475     
    1012     // wait for all cull and draw threads to complete before exit. 
     1476    // run a clean up frame to delete all OpenGL objects. 
     1477    viewer.cleanup_frame(); 
     1478 
     1479    // wait for all the clean up frame to complete. 
    10131480    viewer.sync(); 
    10141481