Updates to osgcatch game to allow different types of falling objects

This commit is contained in:
Robert Osfield 2005-05-21 12:57:28 +00:00
parent ea9cfaf11e
commit 3d4e2fa4f3

View File

@ -31,13 +31,16 @@
#include <osgParticle/FireEffect> #include <osgParticle/FireEffect>
typedef std::vector<std::string> FileList; typedef std::vector<std::string> FileList;
typedef std::map<std::string, osg::ref_ptr<osg::Node> > ObjectMap;
static ObjectMap s_objectMap;
class Character : public osg::Referenced class Character : public osg::Referenced
{ {
public: public:
Character(); Character();
void setCharacter(const std::string& filename, const std::string& name, const osg::Vec3& orgin, const osg::Vec3& width, float positionRatio); void setCharacter(const std::string& filename, const std::string& name, const osg::Vec3& orgin, const osg::Vec3& width, const osg::Vec3& catchPos, float positionRatio);
void setLives(const std::string& filename, const osg::Vec3& orgin, const osg::Vec3& delta, unsigned int numLives); void setLives(const std::string& filename, const osg::Vec3& orgin, const osg::Vec3& delta, unsigned int numLives);
@ -85,7 +88,7 @@ Character::Character():
} }
void Character::setCharacter(const std::string& filename, const std::string& name, const osg::Vec3& origin, const osg::Vec3& width, float positionRatio) 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)
{ {
_origin = origin; _origin = origin;
_width = width; _width = width;
@ -117,8 +120,8 @@ void Character::setCharacter(const std::string& filename, const std::string& nam
moveTo(positionRatio); moveTo(positionRatio);
_centerBasket = width*0.2 + height*0.57 + pos; _centerBasket = width*catchPos.x() + height*catchPos.y() + pos;
_radiusBasket = width.length()*0.34; _radiusBasket = width.length()*catchPos.z();
} }
@ -276,6 +279,7 @@ class CatchableObject : public osg::Referenced
double _timeToRemove; double _timeToRemove;
static void setUpCatchablesMap(const FileList& fileList);
public: public:
@ -347,6 +351,7 @@ class CatchableObject : public osg::Referenced
float _viscosityCoefficient; float _viscosityCoefficient;
float _densityCoefficeint; float _densityCoefficeint;
}; };
CatchableObject::CatchableObject() CatchableObject::CatchableObject()
@ -358,6 +363,36 @@ CatchableObject::CatchableObject()
setFluidToAir(); setFluidToAir();
} }
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;
}
}
}
void CatchableObject::setObject(const std::string& filename, const std::string& name, const osg::Vec3& center, float characterSize, const osg::Vec3& velocity) 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; _radius = 0.5f*characterSize;
@ -367,28 +402,21 @@ void CatchableObject::setObject(const std::string& filename, const std::string&
_velocity = velocity; _velocity = velocity;
_mass = 1000.0*Volume; _mass = 1000.0*Volume;
osg::Image* image = osgDB::readImageFile(filename); if (s_objectMap.count(filename)!=0)
if (image)
{ {
osg::Vec3 width(characterSize*((float)image->s())/(float)(image->t()),0.0f,0.0); osg::PositionAttitudeTransform* scaleTransform = new osg::PositionAttitudeTransform;
osg::Vec3 height(0.0f,0.0f,characterSize); scaleTransform->setScale(osg::Vec3(characterSize,characterSize,characterSize));
osg::Vec3 pos = (width+height)*-0.5f; scaleTransform->addChild(s_objectMap[filename].get());
osg::Geometry* geometry = osg::createTexturedQuadGeometry(pos,width,height);
osg::StateSet* stateset = geometry->getOrCreateStateSet();
stateset->setTextureAttributeAndModes(0,new osg::Texture2D(image),osg::StateAttribute::ON);
stateset->setMode(GL_BLEND,osg::StateAttribute::ON);
stateset->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
osg::Geode* geode = new osg::Geode;
geode->addDrawable(geometry);
_object = new osg::PositionAttitudeTransform; _object = new osg::PositionAttitudeTransform;
_object->setName(name); _object->setName(name);
_object->addChild(geode);
_object->setPosition(center); _object->setPosition(center);
_object->addChild(scaleTransform);
}
else
{
osg::notify(osg::NOTICE)<<"CatchableObject::setObject("<<filename<<") not able to create catchable object."<<std::endl;
} }
} }
void CatchableObject::update(double dt) void CatchableObject::update(double dt)
@ -480,6 +508,58 @@ public:
void createNewCatchable(); void createNewCatchable();
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);
catchesPosition = _originBaseLine+osg::Vec3(200.0f,-0.5f,0.0f);
}
else
{
livesPosition = _originBaseLine+osg::Vec3(900.0f,-0.5f,000.0f);
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;
}
}
}
protected: protected:
~GameEventHandler() {} ~GameEventHandler() {}
@ -498,12 +578,15 @@ protected:
osg::ref_ptr<osg::Group> _group; osg::ref_ptr<osg::Group> _group;
Character _player1; unsigned int _numberOfPlayers;
Character _player2; Character _players[2];
typedef std::list< osg::ref_ptr<CatchableObject> > CatchableObjectList; typedef std::list< osg::ref_ptr<CatchableObject> > CatchableObjectList;
CatchableObjectList _catchableObjects; CatchableObjectList _catchableObjects;
FileList _backgroundFiles;
FileList _benignCatachables;
bool _leftKeyPressed; bool _leftKeyPressed;
bool _rightKeyPressed; bool _rightKeyPressed;
@ -521,10 +604,32 @@ GameEventHandler::GameEventHandler()
_originBaseLine = _origin+_width*0.5-_widthBaseLine*0.5f; _originBaseLine = _origin+_width*0.5-_widthBaseLine*0.5f;
_characterSize = _width.length()*0.2f; _characterSize = _width.length()*0.2f;
_backgroundImageFile = "Catch/sky1.JPG"; _backgroundImageFile = "Catch/farm.JPG";
_numberOfPlayers = 0;
_leftKeyPressed=false; _leftKeyPressed=false;
_rightKeyPressed=false; _rightKeyPressed=false;
_backgroundFiles.push_back("Catch/farm.JPG");
_backgroundFiles.push_back("Catch/sky1.JPG");
_backgroundFiles.push_back("Catch/sky2.JPG");
_backgroundFiles.push_back("Catch/sky3.JPG");
_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);
} }
bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&) bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionAdapter&)
@ -536,12 +641,12 @@ bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
// move characters // move characters
if (_leftKeyPressed) if (_leftKeyPressed)
{ {
_player2.moveLeft(); if (_numberOfPlayers>=2) _players[1].moveLeft();
} }
if (_rightKeyPressed) if (_rightKeyPressed)
{ {
_player2.moveRight(); if (_numberOfPlayers>=2) _players[1].moveRight();
} }
static double previous_time = ea.time(); static double previous_time = ea.time();
@ -557,35 +662,25 @@ bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
bool removeEntry = false; bool removeEntry = false;
if ((*itr)->dangerous()) for(unsigned int i=0;i<_numberOfPlayers;++i)
{ {
if ((*itr)->anyInside(_player1.getLowerLeft(),_player1.getUpperRight())) if ((*itr)->dangerous())
{ {
_player1.looseLife(); if ((*itr)->anyInside(_players[i].getLowerLeft(),_players[i].getUpperRight()))
removeEntry = true; {
_players[i].looseLife();
removeEntry = true;
}
} }
else
if ((*itr)->anyInside(_player2.getLowerLeft(),_player2.getUpperRight()))
{ {
_player2.looseLife(); if ((*itr)->centerInside(_players[i].getCurrentCenterOfBasket(),_players[i].getCurrentRadiusOfBasket()))
removeEntry = true; {
_players[i].addCatch();
removeEntry = true;
}
} }
} }
else
{
if ((*itr)->centerInside(_player1.getCurrentCenterOfBasket(),_player1.getCurrentRadiusOfBasket()))
{
_player1.addCatch();
removeEntry = true;
}
if ((*itr)->centerInside(_player2.getCurrentCenterOfBasket(),_player2.getCurrentRadiusOfBasket()))
{
_player2.addCatch();
removeEntry = true;
}
}
if (!(*itr)->anyInside(_origin, _origin+_width+_height) || if (!(*itr)->anyInside(_origin, _origin+_width+_height) ||
(*itr)->needToRemove(ea.time()) || (*itr)->needToRemove(ea.time()) ||
@ -631,22 +726,12 @@ bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
_rightKeyPressed=true; _rightKeyPressed=true;
return true; return true;
} }
else if (ea.getKey()=='1')
{
_player1.looseLife();
_player1.addCatch();
return true;
}
else if (ea.getKey()=='2')
{
_player2.looseLife();
_player2.addCatch();
return true;
}
else if (ea.getKey()==' ') else if (ea.getKey()==' ')
{ {
_player1.reset(); for(unsigned int i=0;i<_numberOfPlayers;++i)
_player2.reset(); {
_players[i].reset();
}
return true; return true;
} }
} }
@ -668,7 +753,7 @@ bool GameEventHandler::handle(const osgGA::GUIEventAdapter& ea,osgGA::GUIActionA
{ {
float px = (ea.getXnormalized()+1.0f)*0.5f; float px = (ea.getXnormalized()+1.0f)*0.5f;
_player1.moveTo(px); if (_numberOfPlayers>=1) _players[0].moveTo(px);
return true; return true;
} }
@ -697,23 +782,17 @@ osg::Node* GameEventHandler::createScene()
{ {
_group = new osg::Group; _group = new osg::Group;
std::string player_one = "Catch/girl.png"; if (_numberOfPlayers==0)
std::string player_two = "Catch/boy.png"; {
addPlayer(PLAYER_GIRL);
_player1.setCharacter(player_one,"girl", _originBaseLine + osg::Vec3(0.0f,-1.0f,0.0f), _widthBaseLine, 0.4f); }
_player1.setLives(player_one,_originBaseLine+osg::Vec3(0.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),3);
_player1.setCatches("Catch/broach.png",_originBaseLine+osg::Vec3(200.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10);
_group->addChild(_player1._character.get());
_group->addChild(_player1._livesSwitch.get());
_group->addChild(_player1._catchSwitch.get());
_player2.setCharacter(player_two,"boy", _originBaseLine + osg::Vec3(0.0f,-2.0f,0.0f), _widthBaseLine, 0.4f);
_player2.setLives(player_two,_originBaseLine+osg::Vec3(900.0f,-0.5f,000.0f), osg::Vec3(0.0f,0.0f,100.0f),3);
_player2.setCatches("Catch/broach.png",_originBaseLine+osg::Vec3(1100.0f,-0.5f,0.0f), osg::Vec3(0.0f,0.0f,100.0f),10);
_group->addChild(_player2._character.get());
_group->addChild(_player2._livesSwitch.get());
_group->addChild(_player2._catchSwitch.get());
for(unsigned int i=0;i<_numberOfPlayers;++i)
{
_group->addChild(_players[i]._character.get());
_group->addChild(_players[i]._livesSwitch.get());
_group->addChild(_players[i]._catchSwitch.get());
}
createNewCatchable(); createNewCatchable();
createNewCatchable(); createNewCatchable();
@ -742,6 +821,13 @@ osg::Node* GameEventHandler::createScene()
void GameEventHandler::createNewCatchable() void GameEventHandler::createNewCatchable()
{ {
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];
float ratio = ((float)rand() / (float)RAND_MAX); float ratio = ((float)rand() / (float)RAND_MAX);
float size = 100.0f*((float)rand() / (float)RAND_MAX); float size = 100.0f*((float)rand() / (float)RAND_MAX);
float angle = osg::PI*0.25f + 0.5f*osg::PI*((float)rand() / (float)RAND_MAX); float angle = osg::PI*0.25f + 0.5f*osg::PI*((float)rand() / (float)RAND_MAX);
@ -751,7 +837,7 @@ void GameEventHandler::createNewCatchable()
osg::Vec3 position = _origin+_height+_width*ratio + osg::Vec3(0.0f,-0.7f,0.0f); 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); osg::Vec3 velocity(-cosf(angle)*speed,0.0f,-sinf(angle)*speed);
//std::cout<<"angle = "<<angle<<" velocity="<<velocity<<std::endl; //std::cout<<"angle = "<<angle<<" velocity="<<velocity<<std::endl;
catchableObject->setObject("Catch/a.png","boy",position,size,velocity); catchableObject->setObject(filename,"boy",position,size,velocity);
_catchableObjects.push_back(catchableObject); _catchableObjects.push_back(catchableObject);
// catchableObject->explode(); // catchableObject->explode();
@ -792,6 +878,11 @@ int main( int argc, char **argv )
} }
while (arguments.read("--boy")) seh->addPlayer(GameEventHandler::PLAYER_BOY);
while (arguments.read("--girl")) seh->addPlayer(GameEventHandler::PLAYER_GIRL);
// get details on keyboard and mouse bindings used by the viewer. // get details on keyboard and mouse bindings used by the viewer.
viewer.getUsage(*arguments.getApplicationUsage()); viewer.getUsage(*arguments.getApplicationUsage());