2007-06-12 22:20:16 +08:00
/* OpenSceneGraph example, osgcatch.
*
* Permission is hereby granted , free of charge , to any person obtaining a copy
* of this software and associated documentation files ( the " Software " ) , to deal
* in the Software without restriction , including without limitation the rights
* to use , copy , modify , merge , publish , distribute , sublicense , and / or sell
* copies of the Software , and to permit persons to whom the Software is
* furnished to do so , subject to the following conditions :
*
* THE SOFTWARE IS PROVIDED " AS IS " , WITHOUT WARRANTY OF ANY KIND , EXPRESS OR
* IMPLIED , INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY ,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT . IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM , DAMAGES OR OTHER
* LIABILITY , WHETHER IN AN ACTION OF CONTRACT , TORT OR OTHERWISE , ARISING FROM ,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE .
2005-04-07 04:54:36 +08:00
*/
# include <osgDB/ReadFile>
# include <osgDB/WriteFile>
2005-05-23 04:19:26 +08:00
2005-04-07 04:54:36 +08:00
# include <osgUtil/Optimizer>
2005-05-23 04:19:26 +08:00
# include <osgUtil/GLObjectsVisitor>
# include <osgText/Text>
2005-04-07 04:54:36 +08:00
# include <osg/Geode>
# include <osg/Notify>
# include <osg/MatrixTransform>
# include <osg/PositionAttitudeTransform>
# include <osg/Switch>
# include <osg/TexMat>
# include <osg/Texture2D>
2006-12-27 01:35:45 +08:00
# include <osg/Timer>
2005-04-11 05:25:37 +08:00
# include <osg/io_utils>
2006-12-27 01:35:45 +08:00
# include <osgGA/GUIEventHandler>
2005-04-11 05:25:37 +08:00
# include <osgParticle/ExplosionEffect>
2005-05-26 00:42:36 +08:00
# include <osgParticle/ExplosionDebrisEffect>
2005-04-11 05:25:37 +08:00
# include <osgParticle/SmokeEffect>
# include <osgParticle/FireEffect>
2005-04-07 04:54:36 +08:00
2007-01-29 01:12:57 +08:00
# include <osgViewer/Viewer>
# include <iostream>
2005-05-23 04:19:26 +08:00
# include <sstream>
2005-04-07 04:54:36 +08:00
typedef std : : vector < std : : string > FileList ;
2005-05-21 20:57:28 +08:00
typedef std : : map < std : : string , osg : : ref_ptr < osg : : Node > > ObjectMap ;
static ObjectMap s_objectMap ;
2005-04-07 04:54:36 +08:00
2005-04-11 05:25:37 +08:00
class Character : public osg : : Referenced
2005-04-07 04:54:36 +08:00
{
2005-04-11 05:25:37 +08:00
public :
2005-04-07 04:54:36 +08:00
Character ( ) ;
2005-05-21 20:57:28 +08:00
void setCharacter ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & orgin , const osg : : Vec3 & width , const osg : : Vec3 & catchPos , float positionRatio ) ;
2005-04-07 04:54:36 +08:00
void setLives ( const std : : string & filename , const osg : : Vec3 & orgin , const osg : : Vec3 & delta , unsigned int numLives ) ;
void setCatches ( const std : : string & filename , const osg : : Vec3 & orgin , const osg : : Vec3 & delta , unsigned int numLives ) ;
void moveLeft ( ) ;
void moveRight ( ) ;
void moveTo ( float positionRatio ) ;
void reset ( ) ;
2005-05-22 05:19:11 +08:00
void resetCatches ( ) ;
2005-04-07 04:54:36 +08:00
bool addCatch ( ) ;
2005-05-22 05:19:11 +08:00
2005-04-07 04:54:36 +08:00
bool looseLife ( ) ;
2005-04-11 05:25:37 +08:00
osg : : Vec3 getCurrentCenterOfBasket ( ) const { return _character - > getPosition ( ) + _centerBasket ; }
float getCurrentRadiusOfBasket ( ) const { return _radiusBasket ; }
osg : : Vec3 getLowerLeft ( ) const { return _character - > getPosition ( ) ; }
osg : : Vec3 getUpperRight ( ) const { return _character - > getPosition ( ) ; }
2005-04-07 04:54:36 +08:00
osg : : Vec3 _origin ;
osg : : Vec3 _width ;
float _positionRatio ;
osg : : ref_ptr < osg : : PositionAttitudeTransform > _character ;
unsigned int _numLives ;
osg : : ref_ptr < osg : : Switch > _livesSwitch ;
unsigned int _numCatches ;
osg : : ref_ptr < osg : : Switch > _catchSwitch ;
2005-04-11 05:25:37 +08:00
osg : : ref_ptr < osg : : Group > _objectsGroup ;
osg : : Vec3 _centerBasket ;
float _radiusBasket ;
2005-04-07 04:54:36 +08:00
} ;
Character : : Character ( ) :
_positionRatio ( 0.5f ) ,
_numLives ( 3 ) ,
_numCatches ( 0 )
{
}
2005-05-21 20:57:28 +08:00
void Character : : setCharacter ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & origin , const osg : : Vec3 & width , const osg : : Vec3 & catchPos , float positionRatio )
2005-04-07 04:54:36 +08:00
{
_origin = origin ;
_width = width ;
_positionRatio = positionRatio ;
_numLives = 3 ;
_numCatches = 0 ;
float _characterSize = _width . length ( ) * 0.2f ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
2005-04-11 05:25:37 +08:00
osg : : Vec3 pos ( - 0.5f * _characterSize , 0.0f , 0.0f ) ;
osg : : Vec3 width ( _characterSize * ( ( float ) image - > s ( ) ) / ( float ) ( image - > t ( ) ) , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , _characterSize ) ;
2005-04-07 04:54:36 +08:00
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
2005-04-11 05:25:37 +08:00
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
2005-04-07 04:54:36 +08:00
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_character = new osg : : PositionAttitudeTransform ;
_character - > setName ( name ) ;
_character - > addChild ( geode ) ;
moveTo ( positionRatio ) ;
2005-04-11 05:25:37 +08:00
2005-05-21 20:57:28 +08:00
_centerBasket = width * catchPos . x ( ) + height * catchPos . y ( ) + pos ;
_radiusBasket = width . length ( ) * catchPos . z ( ) ;
2005-04-11 05:25:37 +08:00
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
2005-04-07 04:54:36 +08:00
}
void Character : : setLives ( const std : : string & filename , const osg : : Vec3 & origin , const osg : : Vec3 & delta , unsigned int numLives )
{
float characterSize = delta . length ( ) ;
_numLives = numLives ;
_livesSwitch = new osg : : Switch ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
osg : : StateSet * stateset = _livesSwitch - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
2005-04-11 05:25:37 +08:00
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
2005-04-07 04:54:36 +08:00
for ( unsigned int i = 0 ; i < numLives ; + + i )
{
2005-04-11 05:25:37 +08:00
osg : : Vec3 pos = origin + delta * ( float ) i + osg : : Vec3 ( 0.0f , 0.0f , 0.0f ) ;
osg : : Vec3 width ( characterSize * ( ( float ) image - > s ( ) ) / ( float ) ( image - > t ( ) ) , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , characterSize ) ;
2005-04-07 04:54:36 +08:00
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_livesSwitch - > addChild ( geode , true ) ;
}
}
}
void Character : : setCatches ( const std : : string & filename , const osg : : Vec3 & origin , const osg : : Vec3 & delta , unsigned int numCatches )
{
float characterSize = delta . length ( ) ;
_numCatches = 0 ;
_catchSwitch = new osg : : Switch ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
osg : : StateSet * stateset = _catchSwitch - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
2005-04-11 05:25:37 +08:00
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
2005-04-07 04:54:36 +08:00
for ( unsigned int i = 0 ; i < numCatches ; + + i )
{
2005-04-11 05:25:37 +08:00
osg : : Vec3 pos = origin + delta * ( float ) i + osg : : Vec3 ( 0.0f , 0.0f , 0.0f ) ;
2005-04-07 04:54:36 +08:00
osg : : Vec3 width ( characterSize , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , characterSize * ( ( float ) image - > t ( ) ) / ( float ) ( image - > s ( ) ) ) ;
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
_catchSwitch - > addChild ( geode , false ) ;
}
}
}
void Character : : moveLeft ( )
{
moveTo ( _positionRatio - 0.01f ) ;
}
void Character : : moveRight ( )
{
moveTo ( _positionRatio + 0.01f ) ;
}
void Character : : moveTo ( float positionRatio )
{
if ( positionRatio < 0.0f ) positionRatio = 0.0f ;
if ( positionRatio > 1.0f ) positionRatio = 1.0f ;
_positionRatio = positionRatio ;
_character - > setPosition ( _origin + _width * + positionRatio ) ;
}
void Character : : reset ( )
{
_numCatches = 0 ;
_numLives = _livesSwitch - > getNumChildren ( ) ;
_livesSwitch - > setAllChildrenOn ( ) ;
_catchSwitch - > setAllChildrenOff ( ) ;
}
2005-05-22 05:19:11 +08:00
void Character : : resetCatches ( )
{
_numCatches = 0 ;
_catchSwitch - > setAllChildrenOff ( ) ;
}
2005-04-07 04:54:36 +08:00
bool Character : : addCatch ( )
{
if ( ! _catchSwitch | | _numCatches > = _catchSwitch - > getNumChildren ( ) ) return false ;
_catchSwitch - > setValue ( _numCatches , true ) ;
+ + _numCatches ;
return true ;
}
bool Character : : looseLife ( )
{
2005-05-22 05:19:11 +08:00
if ( ! _livesSwitch | | _numLives = = 0 ) return false ;
2005-04-07 04:54:36 +08:00
- - _numLives ;
_livesSwitch - > setValue ( _numLives , false ) ;
2005-05-22 05:19:11 +08:00
return ( _numLives ! = 0 ) ;
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
class CatchableObject : public osg : : Referenced
{
public :
CatchableObject ( ) ;
void setObject ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & center , float size , const osg : : Vec3 & direction ) ;
bool anyInside ( const osg : : Vec3 & lower_left , const osg : : Vec3 & top_right ) ;
bool centerInside ( const osg : : Vec3 & center , float radius ) ;
void explode ( ) ;
bool dangerous ( ) { return _dangerous ; }
void stop ( ) { _stopped = true ; }
bool stopped ( ) { return _stopped ; }
void setTimeToRemove ( double time ) { _timeToRemove = time ; }
double getTimeToRemove ( ) { return _timeToRemove ; }
bool needToRemove ( double time ) { return _timeToRemove > = 0.0 & & time > _timeToRemove ; }
osg : : ref_ptr < osg : : PositionAttitudeTransform > _object ;
osg : : Vec3 _velocity ;
float _mass ;
float _radius ;
bool _stopped ;
bool _dangerous ;
double _timeToRemove ;
2005-05-21 20:57:28 +08:00
static void setUpCatchablesMap ( const FileList & fileList ) ;
2005-04-11 05:25:37 +08:00
public :
// update position and velocity
void update ( double dt ) ;
/// Set the viscosity of the fluid.
inline void setFluidViscosity ( float v )
{
_viscosity = v ;
_viscosityCoefficient = 6 * osg : : PI * _viscosity ;
}
/// Get the viscosity of the fluid.
inline float getFluidViscosity ( ) const { return _viscosity ; }
/// Set the density of the fluid.
inline void setFluidDensity ( float d )
{
_density = d ;
_densityCoefficeint = 0.2f * osg : : PI * _density ;
}
/// Get the density of the fluid.
inline float getFluidDensity ( ) const { return _density ; }
/// Set the wind vector.
inline void setWind ( const osg : : Vec3 & wind ) { _wind = wind ; }
/// Get the wind vector.
inline const osg : : Vec3 & getWind ( ) const { return _wind ; }
/// Set the acceleration vector.
inline void setAcceleration ( const osg : : Vec3 & v ) { _acceleration = v ; }
/// Get the acceleration vector.
inline const osg : : Vec3 & getAcceleration ( ) const { return _acceleration ; }
/** Set the acceleration vector to the gravity on earth (0, 0, -9.81).
The acceleration will be multiplied by the < CODE > scale < / CODE > parameter .
*/
inline void setToGravity ( float scale = 1.0f ) { _acceleration . set ( 0 , 0 , - 9.81f * scale ) ; }
/// Set the fluid parameters as for air (20<32> C temperature).
inline void setFluidToAir ( )
{
setToGravity ( 1.0f ) ;
setFluidDensity ( 1.2929f ) ;
setFluidViscosity ( 1.8e-5 f ) ;
}
/// Set the fluid parameters as for pure water (20<32> C temperature).
inline void setFluidToWater ( )
{
setToGravity ( 1.0f ) ;
setFluidDensity ( 1.0f ) ;
setFluidViscosity ( 1.002e-3 f ) ;
}
protected :
osg : : Vec3 _acceleration ;
float _viscosity ;
float _density ;
osg : : Vec3 _wind ;
float _viscosityCoefficient ;
float _densityCoefficeint ;
2005-05-21 20:57:28 +08:00
2005-04-11 05:25:37 +08:00
} ;
CatchableObject : : CatchableObject ( )
{
_stopped = false ;
_dangerous = false ;
_timeToRemove = - 1.0 ; // do not remove.
setFluidToAir ( ) ;
}
2005-05-21 20:57:28 +08:00
void CatchableObject : : setUpCatchablesMap ( const FileList & fileList )
{
for ( FileList : : const_iterator itr = fileList . begin ( ) ;
itr ! = fileList . end ( ) ;
+ + itr )
{
const std : : string & filename = * itr ;
osg : : Image * image = osgDB : : readImageFile ( filename ) ;
if ( image )
{
osg : : ref_ptr < osg : : StateSet > stateset = new osg : : StateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
stateset - > setMode ( GL_BLEND , osg : : StateAttribute : : ON ) ;
stateset - > setRenderingHint ( osg : : StateSet : : TRANSPARENT_BIN ) ;
osg : : Vec3 width ( ( float ) ( image - > s ( ) ) / ( float ) ( image - > t ( ) ) , 0.0f , 0.0 ) ;
osg : : Vec3 height ( 0.0f , 0.0f , 1.0f ) ;
osg : : Vec3 pos = ( width + height ) * - 0.5f ;
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( pos , width , height ) ;
geometry - > setStateSet ( stateset . get ( ) ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
s_objectMap [ filename ] = geode ;
}
}
}
2005-04-11 05:25:37 +08:00
void CatchableObject : : setObject ( const std : : string & filename , const std : : string & name , const osg : : Vec3 & center , float characterSize , const osg : : Vec3 & velocity )
{
_radius = 0.5f * characterSize ;
float Area = osg : : PI * _radius * _radius ;
float Volume = Area * _radius * 4.0f / 3.0f ;
_velocity = velocity ;
_mass = 1000.0 * Volume ;
2005-05-21 20:57:28 +08:00
if ( s_objectMap . count ( filename ) ! = 0 )
2005-04-11 05:25:37 +08:00
{
2005-05-21 20:57:28 +08:00
osg : : PositionAttitudeTransform * scaleTransform = new osg : : PositionAttitudeTransform ;
scaleTransform - > setScale ( osg : : Vec3 ( characterSize , characterSize , characterSize ) ) ;
scaleTransform - > addChild ( s_objectMap [ filename ] . get ( ) ) ;
2005-04-11 05:25:37 +08:00
_object = new osg : : PositionAttitudeTransform ;
_object - > setName ( name ) ;
_object - > setPosition ( center ) ;
2005-05-21 20:57:28 +08:00
_object - > addChild ( scaleTransform ) ;
}
else
{
osg : : notify ( osg : : NOTICE ) < < " CatchableObject::setObject( " < < filename < < " ) not able to create catchable object. " < < std : : endl ;
2005-04-11 05:25:37 +08:00
}
}
void CatchableObject : : update ( double dt )
{
if ( _stopped ) return ;
float Area = osg : : PI * _radius * _radius ;
float Volume = Area * _radius * 4.0f / 3.0f ;
// compute force due to gravity + boyancy of displacing the fluid that the particle is emersed in.
osg : : Vec3 force = _acceleration * ( _mass - _density * Volume ) ;
// compute force due to friction
osg : : Vec3 relative_wind = _velocity - _wind ;
force - = relative_wind * Area * ( _viscosityCoefficient + _densityCoefficeint * relative_wind . length ( ) ) ;
// divide force by mass to get acceleration.
_velocity + = force * ( dt / _mass ) ;
_object - > setPosition ( _object - > getPosition ( ) + _velocity * dt ) ;
}
bool CatchableObject : : anyInside ( const osg : : Vec3 & lower_left , const osg : : Vec3 & upper_right )
{
osg : : Vec3 pos = _object - > getPosition ( ) ;
if ( pos . x ( ) + _radius < lower_left . x ( ) ) return false ;
if ( pos . x ( ) - _radius > upper_right . x ( ) ) return false ;
if ( pos . z ( ) + _radius < lower_left . z ( ) ) return false ;
if ( pos . z ( ) - _radius > upper_right . z ( ) ) return false ;
return true ;
}
bool CatchableObject : : centerInside ( const osg : : Vec3 & center , float radius )
{
osg : : Vec3 delta = _object - > getPosition ( ) - center ;
return ( delta . length ( ) < radius ) ;
}
void CatchableObject : : explode ( )
{
osg : : Vec3 position ( 0.0f , 0.0f , 0.0f ) ;
osgParticle : : ExplosionEffect * explosion = new osgParticle : : ExplosionEffect ( position , _radius ) ;
2005-05-26 00:42:36 +08:00
osgParticle : : ExplosionDebrisEffect * explosionDebri = new osgParticle : : ExplosionDebrisEffect ( position , _radius ) ;
2005-04-11 05:25:37 +08:00
osgParticle : : SmokeEffect * smoke = new osgParticle : : SmokeEffect ( position , _radius ) ;
osgParticle : : FireEffect * fire = new osgParticle : : FireEffect ( position , _radius ) ;
explosion - > setWind ( _wind ) ;
explosionDebri - > setWind ( _wind ) ;
smoke - > setWind ( _wind ) ;
fire - > setWind ( _wind ) ;
_object - > addChild ( explosion ) ;
_object - > addChild ( explosionDebri ) ;
_object - > addChild ( smoke ) ;
_object - > addChild ( fire ) ;
_dangerous = true ;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//
class GameEventHandler : public osgGA : : GUIEventHandler
2005-04-07 04:54:36 +08:00
{
public :
2005-04-11 05:25:37 +08:00
GameEventHandler ( ) ;
2005-04-07 04:54:36 +08:00
2005-04-11 05:25:37 +08:00
META_Object ( osgStereImageApp , GameEventHandler ) ;
2005-04-07 04:54:36 +08:00
virtual bool handle ( const osgGA : : GUIEventAdapter & ea , osgGA : : GUIActionAdapter & ) ;
virtual void getUsage ( osg : : ApplicationUsage & usage ) const ;
osg : : Matrix getCameraPosition ( ) ;
2005-05-23 04:19:26 +08:00
void compileGLObjects ( osg : : State & state )
{
osgUtil : : GLObjectsVisitor compile ;
compile . setState ( & state ) ;
for ( ObjectMap : : iterator itr = s_objectMap . begin ( ) ;
itr ! = s_objectMap . end ( ) ;
+ + itr )
{
itr - > second - > accept ( compile ) ;
}
}
2005-04-07 04:54:36 +08:00
osg : : Node * createScene ( ) ;
void setFOVY ( float fovy ) { _fovy = fovy ; }
float getFOVY ( ) const { return _fovy ; }
2005-04-11 05:25:37 +08:00
void createNewCatchable ( ) ;
2005-05-22 05:19:11 +08:00
2005-05-23 04:19:26 +08:00
void clearCatchables ( )
{
for ( CatchableObjectList : : iterator itr = _catchableObjects . begin ( ) ;
itr ! = _catchableObjects . end ( ) ;
+ + itr )
{
// need to remove
// remove child from parents.
osg : : ref_ptr < osg : : PositionAttitudeTransform > child = ( * itr ) - > _object ;
osg : : Node : : ParentList parents = child - > getParents ( ) ;
for ( osg : : Node : : ParentList : : iterator pitr = parents . begin ( ) ;
pitr ! = parents . end ( ) ;
+ + pitr )
{
( * pitr ) - > removeChild ( child . get ( ) ) ;
}
}
_catchableObjects . clear ( ) ;
}
2005-05-22 05:19:11 +08:00
void resetLevel ( )
{
_level = 0 ;
_levelSwitch - > setSingleChildOn ( _level ) ;
2005-05-23 04:19:26 +08:00
clearCatchables ( ) ;
updateLevelText ( ) ;
_levelStartTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2005-05-22 05:19:11 +08:00
}
void nextLevel ( )
{
+ + _level ;
if ( _level < _levelSwitch - > getNumChildren ( ) )
{
_levelSwitch - > setSingleChildOn ( _level ) ;
2005-05-23 04:19:26 +08:00
clearCatchables ( ) ;
2005-05-22 05:19:11 +08:00
}
2005-05-23 04:19:26 +08:00
updateLevelText ( ) ;
_levelStartTick = osg : : Timer : : instance ( ) - > tick ( ) ;
2005-05-22 05:19:11 +08:00
}
2005-05-23 04:19:26 +08:00
2005-05-22 05:19:11 +08:00
bool gameComplete ( )
{
return _level > = _levelSwitch - > getNumChildren ( ) ;
}
2005-04-07 04:54:36 +08:00
2005-05-23 04:19:26 +08:00
void resetGame ( )
{
_currentScore = 0 ;
updateTextWithScore ( ) ;
clearCatchables ( ) ;
resetLevel ( ) ;
for ( unsigned int i = 0 ; i < _numberOfPlayers ; + + i )
{
_players [ i ] . reset ( ) ;
}
}
2005-05-21 20:57:28 +08:00
enum Players
{
PLAYER_GIRL ,
PLAYER_BOY
} ;
void addPlayer ( Players player )
{
osg : : Vec3 livesPosition ;
osg : : Vec3 catchesPosition ;
if ( _numberOfPlayers = = 0 )
{
livesPosition = _originBaseLine + osg : : Vec3 ( 0.0f , - 0.5f , 0.0f ) ;
2005-05-23 04:19:26 +08:00
catchesPosition = _originBaseLine + osg : : Vec3 ( 100.0f , - 0.5f , 0.0f ) ;
2005-05-21 20:57:28 +08:00
}
else
{
2005-05-23 04:19:26 +08:00
livesPosition = _originBaseLine + osg : : Vec3 ( 1000.0f , - 0.5f , 000.0f ) ;
2005-05-21 20:57:28 +08:00
catchesPosition = _originBaseLine + osg : : Vec3 ( 1100.0f , - 0.5f , 0.0f ) ;
}
switch ( player )
{
case PLAYER_GIRL :
{
std : : string player_one = " Catch/girl.png " ;
osg : : Vec3 catchPos ( 0.2 , 0.57 , 0.34 ) ;
_players [ _numberOfPlayers ] . setCharacter ( player_one , " girl " , _originBaseLine + osg : : Vec3 ( 0.0f , - 1.0f , 0.0f ) , _widthBaseLine , catchPos , 0.5f ) ;
_players [ _numberOfPlayers ] . setLives ( player_one , livesPosition , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 3 ) ;
_players [ _numberOfPlayers ] . setCatches ( " Catch/broach.png " , catchesPosition , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 10 ) ;
+ + _numberOfPlayers ;
break ;
}
case PLAYER_BOY :
{
std : : string player_two = " Catch/boy.png " ;
osg : : Vec3 catchPos ( 0.8 , 0.57 , 0.34 ) ;
_players [ _numberOfPlayers ] . setCharacter ( player_two , " boy " , _originBaseLine + osg : : Vec3 ( 0.0f , - 2.0f , 0.0f ) , _widthBaseLine , catchPos , 0.5f ) ;
_players [ _numberOfPlayers ] . setLives ( player_two , livesPosition , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 3 ) ;
_players [ _numberOfPlayers ] . setCatches ( " Catch/broach.png " , catchesPosition , osg : : Vec3 ( 0.0f , 0.0f , 100.0f ) , 10 ) ;
+ + _numberOfPlayers ;
break ;
}
}
}
2005-05-23 04:19:26 +08:00
typedef std : : vector < osg : : ref_ptr < osgText : : Text > > TextList ;
void updateScoreWithCatch ( )
{
_currentScore + = 1 ;
updateTextWithScore ( ) ;
}
void updateScoreWithLevel ( )
{
osg : : Timer_t newTick = osg : : Timer : : instance ( ) - > tick ( ) ;
double timeForLevel = osg : : Timer : : instance ( ) - > delta_s ( _levelStartTick , newTick ) ;
// a ten second level gets you 10 points,
// a twenty second levels gets you 5 points.
_currentScore + = static_cast < unsigned int > ( 10000.0f / ( timeForLevel * timeForLevel ) ) ;
updateTextWithScore ( ) ;
}
void updateTextWithScore ( )
{
std : : ostringstream os ;
os < < " Score: " < < _currentScore ;
2005-05-21 20:57:28 +08:00
2005-05-23 04:19:26 +08:00
std : : string textString = os . str ( ) ;
for ( TextList : : iterator itr = _scoreTextList . begin ( ) ;
itr ! = _scoreTextList . end ( ) ;
+ + itr )
{
( * itr ) - > setText ( textString ) ;
}
}
void updateLevelText ( )
{
std : : ostringstream os ;
os < < " Level: " < < _level + 1 ;
_levelText - > setText ( os . str ( ) ) ;
}
2005-05-21 20:57:28 +08:00
2005-04-07 04:54:36 +08:00
protected :
2005-04-11 05:25:37 +08:00
~ GameEventHandler ( ) { }
GameEventHandler ( const GameEventHandler & , const osg : : CopyOp & ) { }
2005-04-07 04:54:36 +08:00
osg : : Vec3 _origin ;
osg : : Vec3 _width ;
osg : : Vec3 _height ;
osg : : Vec3 _originBaseLine ;
osg : : Vec3 _widthBaseLine ;
float _characterSize ;
float _fovy ;
2005-05-22 05:19:11 +08:00
unsigned _level ;
float _chanceOfExplodingAtStart ;
float _initialNumDropsPerSecond ;
2005-05-23 04:19:26 +08:00
osg : : ref_ptr < osg : : Switch > _gameSwitch ;
osg : : ref_ptr < osg : : Group > _gameGroup ;
osg : : ref_ptr < osg : : Switch > _levelSwitch ;
unsigned int _currentIndex ;
unsigned int _welcomeIndex ;
unsigned int _lostIndex ;
unsigned int _wonIndex ;
unsigned int _gameIndex ;
osg : : Timer_t _levelStartTick ;
unsigned int _currentScore ;
osg : : ref_ptr < osgText : : Text > _levelText ;
TextList _scoreTextList ;
2005-04-07 04:54:36 +08:00
2005-05-21 20:57:28 +08:00
unsigned int _numberOfPlayers ;
Character _players [ 2 ] ;
2005-04-07 04:54:36 +08:00
2005-04-11 05:25:37 +08:00
typedef std : : list < osg : : ref_ptr < CatchableObject > > CatchableObjectList ;
CatchableObjectList _catchableObjects ;
2005-05-21 20:57:28 +08:00
FileList _backgroundFiles ;
FileList _benignCatachables ;
2005-04-07 04:54:36 +08:00
bool _leftKeyPressed ;
2005-05-22 05:19:11 +08:00
bool _rightKeyPressed ;
2005-05-23 04:19:26 +08:00
osg : : ref_ptr < CatchableObject > _dummyCatchable ;
2005-04-07 04:54:36 +08:00
} ;
2005-04-11 05:25:37 +08:00
GameEventHandler : : GameEventHandler ( )
2005-04-07 04:54:36 +08:00
{
_origin . set ( 0.0f , 0.0f , 0.0f ) ;
_width . set ( 1280.0f , 0.0f , 0.0f ) ;
_height . set ( 0.0f , 0.0f , 1024.0f ) ;
_widthBaseLine = _width * 0.9f ;
_originBaseLine = _origin + _width * 0.5 - _widthBaseLine * 0.5f ;
_characterSize = _width . length ( ) * 0.2f ;
2005-05-21 20:57:28 +08:00
_numberOfPlayers = 0 ;
2005-05-22 05:19:11 +08:00
_level = 0 ;
_chanceOfExplodingAtStart = 0.1f ;
_initialNumDropsPerSecond = 1.0f ;
2005-04-07 04:54:36 +08:00
_leftKeyPressed = false ;
_rightKeyPressed = false ;
2005-05-21 20:57:28 +08:00
_backgroundFiles . push_back ( " Catch/sky1.JPG " ) ;
_backgroundFiles . push_back ( " Catch/sky3.JPG " ) ;
2005-05-23 04:19:26 +08:00
_backgroundFiles . push_back ( " Catch/sky2.JPG " ) ;
2005-05-22 05:19:11 +08:00
_backgroundFiles . push_back ( " Catch/farm.JPG " ) ;
2005-05-21 20:57:28 +08:00
_benignCatachables . push_back ( " Catch/a.png " ) ;
_benignCatachables . push_back ( " Catch/b.png " ) ;
_benignCatachables . push_back ( " Catch/c.png " ) ;
_benignCatachables . push_back ( " Catch/m.png " ) ;
_benignCatachables . push_back ( " Catch/n.png " ) ;
_benignCatachables . push_back ( " Catch/s.png " ) ;
_benignCatachables . push_back ( " Catch/t.png " ) ;
_benignCatachables . push_back ( " Catch/u.png " ) ;
_benignCatachables . push_back ( " Catch/ball.png " ) ;
CatchableObject : : setUpCatchablesMap ( _benignCatachables ) ;
2005-05-23 04:19:26 +08:00
_currentScore = 0 ;
2006-12-27 01:35:45 +08:00
setFOVY ( osg : : DegreesToRadians ( 60.0 ) ) ;
2005-05-21 20:57:28 +08:00
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
bool GameEventHandler : : handle ( const osgGA : : GUIEventAdapter & ea , osgGA : : GUIActionAdapter & )
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
if ( _currentIndex = = _welcomeIndex )
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
// welcome screen
switch ( ea . getEventType ( ) )
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
_currentIndex = _gameIndex ;
_gameSwitch - > setSingleChildOn ( _currentIndex ) ;
resetGame ( ) ;
return true ;
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
default :
return false ;
}
}
else if ( _currentIndex = = _lostIndex )
{
// lost screen
switch ( ea . getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
{
_currentIndex = _gameIndex ;
_gameSwitch - > setSingleChildOn ( _currentIndex ) ;
resetGame ( ) ;
return true ;
}
default :
return false ;
}
}
else if ( _currentIndex = = _wonIndex )
{
// won screen
switch ( ea . getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
_currentIndex = _gameIndex ;
_gameSwitch - > setSingleChildOn ( _currentIndex ) ;
resetGame ( ) ;
return true ;
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
default :
return false ;
}
}
else if ( _currentIndex = = _gameIndex )
{
// in game.
2005-04-11 05:25:37 +08:00
2005-05-23 04:19:26 +08:00
switch ( ea . getEventType ( ) )
{
case ( osgGA : : GUIEventAdapter : : FRAME ) :
2005-04-11 05:25:37 +08:00
{
2005-05-23 04:19:26 +08:00
// move characters
if ( _leftKeyPressed )
{
if ( _numberOfPlayers > = 2 ) _players [ 1 ] . moveLeft ( ) ;
}
2005-04-11 05:25:37 +08:00
2005-05-23 04:19:26 +08:00
if ( _rightKeyPressed )
2005-04-11 05:25:37 +08:00
{
2005-05-23 04:19:26 +08:00
if ( _numberOfPlayers > = 2 ) _players [ 1 ] . moveRight ( ) ;
}
2006-03-08 22:09:47 +08:00
static double previous_time = ea . getTime ( ) ;
double dt = ea . getTime ( ) - previous_time ;
previous_time = ea . getTime ( ) ;
2005-05-23 04:19:26 +08:00
// move objects
for ( CatchableObjectList : : iterator itr = _catchableObjects . begin ( ) ;
itr ! = _catchableObjects . end ( ) ;
+ + itr )
{
( * itr ) - > update ( dt ) ;
bool removeEntry = false ;
for ( unsigned int i = 0 ; i < _numberOfPlayers ; + + i )
2005-04-11 05:25:37 +08:00
{
2005-05-23 04:19:26 +08:00
bool inBasket = ( ( * itr ) - > centerInside ( _players [ i ] . getCurrentCenterOfBasket ( ) , _players [ i ] . getCurrentRadiusOfBasket ( ) ) ) ;
if ( ( * itr ) - > dangerous ( ) )
2005-05-21 20:57:28 +08:00
{
2005-05-23 04:19:26 +08:00
if ( ( * itr ) - > anyInside ( _players [ i ] . getLowerLeft ( ) , _players [ i ] . getUpperRight ( ) ) | | inBasket )
2005-05-22 05:19:11 +08:00
{
2005-05-23 04:19:26 +08:00
// player has hit or caught a dangerous object, must loose a life.
if ( ! _players [ i ] . looseLife ( ) )
{
_currentIndex = _lostIndex ;
_gameSwitch - > setSingleChildOn ( _currentIndex ) ;
return true ;
}
else
{
clearCatchables ( ) ;
return true ;
}
2005-05-22 05:19:11 +08:00
}
2005-05-21 20:57:28 +08:00
}
2005-05-23 04:19:26 +08:00
else if ( inBasket )
2005-05-21 20:57:28 +08:00
{
2005-05-23 04:19:26 +08:00
// player has caught a safe object.
updateScoreWithCatch ( ) ;
2005-05-22 05:19:11 +08:00
if ( ! _players [ i ] . addCatch ( ) )
{
_players [ i ] . resetCatches ( ) ;
2005-05-23 04:19:26 +08:00
updateScoreWithLevel ( ) ;
2005-05-22 05:19:11 +08:00
nextLevel ( ) ;
if ( gameComplete ( ) )
{
2005-05-23 04:19:26 +08:00
_currentIndex = _wonIndex ;
_gameSwitch - > setSingleChildOn ( _currentIndex ) ;
2005-05-22 05:19:11 +08:00
}
2005-05-23 04:19:26 +08:00
return true ;
2005-05-22 05:19:11 +08:00
}
2005-05-23 04:19:26 +08:00
2005-05-21 20:57:28 +08:00
removeEntry = true ;
}
2005-04-11 05:25:37 +08:00
}
2005-05-23 04:19:26 +08:00
if ( ! ( * itr ) - > anyInside ( _origin , _origin + _width + _height ) | |
2006-03-08 22:09:47 +08:00
( * itr ) - > needToRemove ( ea . getTime ( ) ) | |
2005-05-23 04:19:26 +08:00
removeEntry )
2005-04-11 05:25:37 +08:00
{
2005-05-23 04:19:26 +08:00
// need to remove
// remove child from parents.
osg : : ref_ptr < osg : : PositionAttitudeTransform > child = ( * itr ) - > _object ;
osg : : Node : : ParentList parents = child - > getParents ( ) ;
for ( osg : : Node : : ParentList : : iterator pitr = parents . begin ( ) ;
pitr ! = parents . end ( ) ;
+ + pitr )
{
( * pitr ) - > removeChild ( child . get ( ) ) ;
}
2005-04-11 05:25:37 +08:00
2005-05-23 04:19:26 +08:00
// remove child from catchable list
itr = _catchableObjects . erase ( itr ) ;
}
else if ( ( * itr ) - > anyInside ( _origin , _origin + _width ) & & ! ( * itr ) - > stopped ( ) )
{
// hit base line
( * itr ) - > explode ( ) ;
( * itr ) - > stop ( ) ;
2006-03-08 22:09:47 +08:00
( * itr ) - > setTimeToRemove ( ea . getTime ( ) + 3.0 ) ;
2005-05-23 04:19:26 +08:00
}
2005-04-11 05:25:37 +08:00
}
2005-05-22 05:19:11 +08:00
2005-05-23 04:19:26 +08:00
// create new catchable objects
2006-03-08 22:09:47 +08:00
static double previousTime = ea . getTime ( ) ;
double deltaTime = ea . getTime ( ) - previousTime ;
previousTime = ea . getTime ( ) ;
2005-05-23 04:19:26 +08:00
float numDropsPerSecond = _initialNumDropsPerSecond * ( _level + 1 ) ;
float r = ( float ) rand ( ) / ( float ) RAND_MAX ;
if ( r < deltaTime * numDropsPerSecond )
{
createNewCatchable ( ) ;
}
2005-05-22 05:19:11 +08:00
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
case ( osgGA : : GUIEventAdapter : : KEYDOWN ) :
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Left )
2005-05-21 20:57:28 +08:00
{
2005-05-23 04:19:26 +08:00
_leftKeyPressed = true ;
return true ;
}
else if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Right )
{
_rightKeyPressed = true ;
return true ;
2005-05-21 20:57:28 +08:00
}
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
case ( osgGA : : GUIEventAdapter : : KEYUP ) :
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Left )
{
_leftKeyPressed = false ;
return true ;
}
else if ( ea . getKey ( ) = = osgGA : : GUIEventAdapter : : KEY_Right )
{
_rightKeyPressed = false ;
return true ;
}
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
case ( osgGA : : GUIEventAdapter : : DRAG ) :
case ( osgGA : : GUIEventAdapter : : MOVE ) :
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
float px = ( ea . getXnormalized ( ) + 1.0f ) * 0.5f ;
if ( _numberOfPlayers > = 1 ) _players [ 0 ] . moveTo ( px ) ;
2005-04-07 04:54:36 +08:00
return true ;
}
2005-05-23 04:19:26 +08:00
default :
return false ;
2005-04-07 04:54:36 +08:00
}
}
2005-05-23 04:19:26 +08:00
return false ;
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
void GameEventHandler : : getUsage ( osg : : ApplicationUsage & ) const
2005-04-07 04:54:36 +08:00
{
}
2005-04-11 05:25:37 +08:00
osg : : Matrix GameEventHandler : : getCameraPosition ( )
2005-04-07 04:54:36 +08:00
{
osg : : Matrix cameraPosition ;
osg : : Vec3 center = _origin + ( _width + _height ) * 0.5f ;
float distance = _height . length ( ) / ( 2.0f * tanf ( _fovy * 0.5f ) ) ;
cameraPosition . makeLookAt ( center - osg : : Vec3 ( 0.0f , distance , 0.0f ) , center , osg : : Vec3 ( 0.0f , 0.0f , 1.0f ) ) ;
return cameraPosition ;
}
2005-04-11 05:25:37 +08:00
osg : : Node * GameEventHandler : : createScene ( )
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
_gameSwitch = new osg : : Switch ;
// create a dummy catchable to load all the particule textures to reduce
// latency later on..
_dummyCatchable = new CatchableObject ;
_dummyCatchable - > setObject ( " Catch/a.png " , " a " , osg : : Vec3 ( 0.0f , 0.0 , 0.0f ) , 1.0f , osg : : Vec3 ( 0.0f , 0.0 , 0.0f ) ) ;
_dummyCatchable - > explode ( ) ;
2005-04-13 03:28:37 +08:00
2005-05-23 04:19:26 +08:00
// set up welcome subgraph
2005-05-21 20:57:28 +08:00
{
2005-05-23 04:19:26 +08:00
osg : : Geode * geode = new osg : : Geode ;
// set up the background
2005-05-23 04:30:30 +08:00
osg : : Image * image = osgDB : : readImageFile ( " Catch/Welcome.jpg " ) ;
2005-05-23 04:19:26 +08:00
if ( image )
{
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( _origin , _width , _height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
geode - > addDrawable ( geometry ) ;
}
// set up the text
osg : : Vec3 textPosition = _origin + _width * 0.5f + _height * 0.8f - osg : : Vec3 ( 0.0f , 0.1f , 0.0f ) ;
{
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " osgcatch is a childrens catching game \n Move your character using the mouse to \n catch falling objects in your net \n but avoid burning objects - they kill!! " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.025f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
{
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Move mouse left and right to move character \n Catch ten objects to advance to next level \n Complete four levels to win. " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.025f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
{
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Game concept and artwork - Caitlin Osfield, aged 5! \n Software development - Robert Osfield " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.025f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
{
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Press any key to start game. \n Press Escape to exit game at any time. " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.025f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
_welcomeIndex = _gameSwitch - > getNumChildren ( ) ;
_gameSwitch - > addChild ( geode ) ;
2005-05-21 20:57:28 +08:00
}
2005-04-11 05:25:37 +08:00
2005-05-23 04:19:26 +08:00
// set up you've lost subgraph
2005-05-21 20:57:28 +08:00
{
2005-05-23 04:19:26 +08:00
osg : : Geode * geode = new osg : : Geode ;
2005-05-23 04:30:30 +08:00
osg : : Image * image = osgDB : : readImageFile ( " Catch/YouLost.jpg " ) ;
2005-05-23 04:19:26 +08:00
if ( image )
{
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( _origin , _width , _height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
geode - > addDrawable ( geometry ) ;
}
// set up the text
osg : : Vec3 textPosition = _origin + _width * 0.5f + _height * 0.75f - osg : : Vec3 ( 0.0f , 0.1f , 0.0f ) ;
{
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Game Over \n You lost all three lives " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.04f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
{
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Score: 0 " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.04f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
2007-02-13 19:32:28 +08:00
text - > setDataVariance ( osg : : Object : : DYNAMIC ) ;
2005-05-23 04:19:26 +08:00
geode - > addDrawable ( text ) ;
_scoreTextList . push_back ( text ) ;
}
{
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Press any key to have another game. \n Press Escape to exit game. " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.025f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
_lostIndex = _gameSwitch - > getNumChildren ( ) ;
_gameSwitch - > addChild ( geode ) ;
}
// set up you've won subgraph
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
osg : : Geode * geode = new osg : : Geode ;
2005-05-23 04:30:30 +08:00
osg : : Image * image = osgDB : : readImageFile ( " Catch/YouWon.jpg " ) ;
2005-05-23 04:19:26 +08:00
if ( image )
{
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( _origin , _width , _height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
geode - > addDrawable ( geometry ) ;
}
// set up the text
osg : : Vec3 textPosition = _origin + _width * 0.5f + _height * 0.75f - osg : : Vec3 ( 0.0f , 0.1f , 0.0f ) ;
{
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Well done!!! \n You completed all levels! " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.04f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
2005-05-22 05:19:11 +08:00
2005-04-07 04:54:36 +08:00
{
2005-05-23 04:19:26 +08:00
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Score: 0 " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.04f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
_scoreTextList . push_back ( text ) ;
}
{
textPosition - = _height * 0.25f ;
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Press any key to have another game. \n Press Escape to exit game. " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.025f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
text - > setAlignment ( osgText : : Text : : CENTER_CENTER ) ;
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( text ) ;
}
2005-04-07 04:54:36 +08:00
2005-05-23 04:19:26 +08:00
_wonIndex = _gameSwitch - > getNumChildren ( ) ;
_gameSwitch - > addChild ( geode ) ;
}
// set up game subgraph.
{
_gameGroup = new osg : : Group ;
if ( _numberOfPlayers = = 0 )
{
addPlayer ( PLAYER_GIRL ) ;
}
for ( unsigned int i = 0 ; i < _numberOfPlayers ; + + i )
{
_gameGroup - > addChild ( _players [ i ] . _character . get ( ) ) ;
_gameGroup - > addChild ( _players [ i ] . _livesSwitch . get ( ) ) ;
_gameGroup - > addChild ( _players [ i ] . _catchSwitch . get ( ) ) ;
}
// background
{
_levelSwitch = new osg : : Switch ;
for ( FileList : : const_iterator itr = _backgroundFiles . begin ( ) ;
itr ! = _backgroundFiles . end ( ) ;
+ + itr )
2005-05-22 05:19:11 +08:00
{
2005-05-23 04:19:26 +08:00
osg : : Image * image = osgDB : : readImageFile ( * itr ) ;
if ( image )
{
osg : : Geometry * geometry = osg : : createTexturedQuadGeometry ( _origin , _width , _height ) ;
osg : : StateSet * stateset = geometry - > getOrCreateStateSet ( ) ;
stateset - > setTextureAttributeAndModes ( 0 , new osg : : Texture2D ( image ) , osg : : StateAttribute : : ON ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( geometry ) ;
2005-05-22 05:19:11 +08:00
2005-05-23 04:19:26 +08:00
_levelSwitch - > addChild ( geode ) ;
}
2005-05-22 05:19:11 +08:00
}
2005-05-23 04:19:26 +08:00
_levelSwitch - > setSingleChildOn ( 0 ) ;
_gameGroup - > addChild ( _levelSwitch . get ( ) ) ;
}
_gameIndex = _gameSwitch - > getNumChildren ( ) ;
_gameSwitch - > addChild ( _gameGroup . get ( ) ) ;
// set up the text
osg : : Vec3 textPosition = _origin + _width * 0.05f + _height * 0.95f - osg : : Vec3 ( 0.0f , 0.1f , 0.0f ) ;
{
osgText : : Text * text = new osgText : : Text ;
text - > setText ( " Score : 0 " ) ;
text - > setFont ( " fonts/dirtydoz.ttf " ) ;
text - > setPosition ( textPosition ) ;
text - > setCharacterSize ( _width . length ( ) * 0.04f ) ;
text - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
2007-02-13 19:32:28 +08:00
text - > setDataVariance ( osg : : Object : : DYNAMIC ) ;
2005-05-23 04:19:26 +08:00
text - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
osg : : Geode * geode = new osg : : Geode ;
geode - > addDrawable ( text ) ;
_scoreTextList . push_back ( text ) ;
textPosition - = _height * 0.05f ;
_levelText = new osgText : : Text ;
_levelText - > setText ( " Level : 0 " ) ;
_levelText - > setFont ( " fonts/dirtydoz.ttf " ) ;
_levelText - > setPosition ( textPosition ) ;
_levelText - > setCharacterSize ( _width . length ( ) * 0.04f ) ;
_levelText - > setColor ( osg : : Vec4 ( 0.0f , 0.2f , 0.2f , 1.0f ) ) ;
2007-02-13 19:32:28 +08:00
_levelText - > setDataVariance ( osg : : Object : : DYNAMIC ) ;
2005-05-23 04:19:26 +08:00
_levelText - > setAxisAlignment ( osgText : : Text : : XZ_PLANE ) ;
geode - > addDrawable ( _levelText . get ( ) ) ;
_gameGroup - > addChild ( geode ) ;
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
2005-04-07 04:54:36 +08:00
}
2005-05-23 04:19:26 +08:00
_currentIndex = _welcomeIndex ;
_gameSwitch - > setSingleChildOn ( _currentIndex ) ;
2005-04-07 04:54:36 +08:00
2005-05-23 04:19:26 +08:00
return _gameSwitch . get ( ) ;
2005-04-07 04:54:36 +08:00
}
2005-04-11 05:25:37 +08:00
void GameEventHandler : : createNewCatchable ( )
{
2005-05-21 20:57:28 +08:00
if ( _benignCatachables . empty ( ) ) return ;
unsigned int catachableIndex = ( unsigned int ) ( ( float ) _benignCatachables . size ( ) * ( float ) rand ( ) / ( float ) RAND_MAX ) ;
if ( catachableIndex > = _benignCatachables . size ( ) ) catachableIndex = _benignCatachables . size ( ) - 1 ;
const std : : string & filename = _benignCatachables [ catachableIndex ] ;
2005-04-11 05:25:37 +08:00
float ratio = ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
2005-05-23 04:19:26 +08:00
float size = 20.0f + 100.0f * ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
2005-04-11 05:25:37 +08:00
float angle = osg : : PI * 0.25f + 0.5f * osg : : PI * ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
float speed = 200.0f * ( ( float ) rand ( ) / ( float ) RAND_MAX ) ;
CatchableObject * catchableObject = new CatchableObject ;
osg : : Vec3 position = _origin + _height + _width * ratio + osg : : Vec3 ( 0.0f , - 0.7f , 0.0f ) ;
osg : : Vec3 velocity ( - cosf ( angle ) * speed , 0.0f , - sinf ( angle ) * speed ) ;
//std::cout<<"angle = "<<angle<<" velocity="<<velocity<<std::endl;
2005-05-21 20:57:28 +08:00
catchableObject - > setObject ( filename , " boy " , position , size , velocity ) ;
2005-04-11 05:25:37 +08:00
_catchableObjects . push_back ( catchableObject ) ;
2005-05-22 05:19:11 +08:00
float r = ( float ) rand ( ) / ( float ) RAND_MAX ;
if ( r < _chanceOfExplodingAtStart )
{
catchableObject - > explode ( ) ;
}
2005-04-11 05:25:37 +08:00
2005-05-23 04:19:26 +08:00
_gameGroup - > addChild ( catchableObject - > _object . get ( ) ) ;
2005-04-11 05:25:37 +08:00
}
2005-04-07 04:54:36 +08:00
2007-02-03 06:30:36 +08:00
class CompileStateCallback : public osg : : Operation
2007-01-29 01:12:57 +08:00
{
public :
CompileStateCallback ( GameEventHandler * eh ) :
2007-02-03 06:30:36 +08:00
osg : : Operation ( " CompileStateCallback " , false ) ,
2007-01-29 01:12:57 +08:00
_gameEventHandler ( eh ) { }
2007-02-03 06:30:36 +08:00
virtual void operator ( ) ( osg : : Object * object )
{
osg : : GraphicsContext * context = dynamic_cast < osg : : GraphicsContext * > ( object ) ;
if ( ! context ) return ;
2005-05-23 04:19:26 +08:00
2007-01-29 01:12:57 +08:00
if ( _gameEventHandler )
{
2007-02-03 06:30:36 +08:00
_gameEventHandler - > compileGLObjects ( * ( context - > getState ( ) ) ) ;
2007-01-29 01:12:57 +08:00
}
}
OpenThreads : : Mutex _mutex ;
GameEventHandler * _gameEventHandler ;
} ;
2006-12-27 01:35:45 +08:00
int main ( int argc , char * * argv )
{
// use an ArgumentParser object to manage the program arguments.
osg : : ArgumentParser arguments ( & argc , argv ) ;
// set up the usage document, in case we need to print out how to use this program.
arguments . getApplicationUsage ( ) - > setDescription ( arguments . getApplicationName ( ) + " is the example which demonstrates use node masks to create stereo images. " ) ;
arguments . getApplicationUsage ( ) - > setCommandLineUsage ( arguments . getApplicationName ( ) + " [options] image_file_left_eye image_file_right_eye " ) ;
2007-12-11 01:30:18 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -d <float> " , " Time delay in seconds between the display of successive image pairs when in auto advance mode. " ) ;
2006-12-27 01:35:45 +08:00
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -a " , " Enter auto advance of image pairs on start up. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -x <float> " , " Horizontal offset of left and right images. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -y <float> " , " Vertical offset of left and right images. " ) ;
arguments . getApplicationUsage ( ) - > addCommandLineOption ( " -h or --help " , " Display this information " ) ;
// construct the viewer.
osgViewer : : Viewer viewer ;
2007-12-11 01:30:18 +08:00
// register the handler to add keyboard and mouse handling.
2006-12-27 01:35:45 +08:00
GameEventHandler * seh = new GameEventHandler ( ) ;
viewer . addEventHandler ( seh ) ;
while ( arguments . read ( " --boy " ) ) seh - > addPlayer ( GameEventHandler : : PLAYER_BOY ) ;
while ( arguments . read ( " --girl " ) ) seh - > addPlayer ( GameEventHandler : : PLAYER_GIRL ) ;
// if user request help write it out to cout.
if ( arguments . read ( " -h " ) | | arguments . read ( " --help " ) )
{
arguments . getApplicationUsage ( ) - > write ( std : : cout ) ;
return 1 ;
}
// any option left unread are converted into errors to write out later.
arguments . reportRemainingOptionsAsUnrecognized ( ) ;
2007-12-11 01:30:18 +08:00
// report any errors if they have occurred when parsing the program arguments.
2006-12-27 01:35:45 +08:00
if ( arguments . errors ( ) )
{
arguments . writeErrorMessages ( std : : cout ) ;
return 1 ;
}
// enable the image cache so we don't need to keep loading the particle files
osgDB : : ReaderWriter : : Options * options = new osgDB : : ReaderWriter : : Options ;
options - > setObjectCacheHint ( osgDB : : ReaderWriter : : Options : : CACHE_IMAGES ) ;
osgDB : : Registry : : instance ( ) - > setOptions ( options ) ;
// creat the scene from the file list.
osg : : ref_ptr < osg : : Node > rootNode = seh - > createScene ( ) ;
2007-01-02 20:19:26 +08:00
rootNode - > getOrCreateStateSet ( ) - > setMode ( GL_LIGHTING , osg : : StateAttribute : : OFF ) ;
2006-12-27 01:35:45 +08:00
//osgDB::writeNodeFile(*rootNode,"test.osg");
2009-10-17 01:22:20 +08:00
// for some reason osgcatch is hanging on exit inside the new TextureObject clean up code when the it's
// run as multi-threaded view, switching to SingleThreaded cures this.
viewer . setThreadingModel ( osgViewer : : Viewer : : SingleThreaded ) ;
2006-12-27 01:35:45 +08:00
// set the scene to render
viewer . setSceneData ( rootNode . get ( ) ) ;
2007-01-29 01:12:57 +08:00
viewer . setRealizeOperation ( new CompileStateCallback ( seh ) ) ;
2006-12-27 01:35:45 +08:00
double fovy , aspectRatio , zNear , zFar ;
viewer . getCamera ( ) - > getProjectionMatrixAsPerspective ( fovy , aspectRatio , zNear , zFar ) ;
seh - > setFOVY ( osg : : DegreesToRadians ( fovy ) ) ;
// todo for osgViewer - create default set up.
viewer . setUpViewAcrossAllScreens ( ) ;
viewer . realize ( ) ;
2007-01-02 20:50:57 +08:00
// switch off the cursor
osgViewer : : Viewer : : Windows windows ;
viewer . getWindows ( windows ) ;
for ( osgViewer : : Viewer : : Windows : : iterator itr = windows . begin ( ) ;
itr ! = windows . end ( ) ;
+ + itr )
{
( * itr ) - > useCursor ( false ) ;
}
2007-01-05 21:06:11 +08:00
// todo for osgViewer - implement warp pointer that can be done relative to different coordinate frames
2006-12-27 01:35:45 +08:00
// viewer.requestWarpPointer(0.5f,0.5f);
while ( ! viewer . done ( ) )
{
viewer . getCamera ( ) - > setViewMatrix ( seh - > getCameraPosition ( ) ) ;
// fire off the cull and draw traversals of the scene.
viewer . frame ( ) ;
}
return 0 ;
}