304 lines
11 KiB
C++
304 lines
11 KiB
C++
// Pong.cpp
|
|
// Pong class member-function definitions.
|
|
#include <sstream>
|
|
#include <stdexcept>
|
|
#include <Ogre.h> // Ogre class definition
|
|
using namespace Ogre; // use the Ogre namespace
|
|
using namespace std; // use the Standard C namespace
|
|
|
|
#include <OgreAL.h> // OgreAL class definition
|
|
#include <OgreStringConverter.h> // OgreStringConverter class definition
|
|
#include <OIS/OISEvents.h> // OISEvents class definition
|
|
#include <OIS/OISInputManager.h> // OISInputManager class definition
|
|
#include <OIS/OISKeyboard.h> // OISKeyboard class definition
|
|
#include "Ball.h" // Ball class definition
|
|
#include "Paddle.h" // Paddle class definition
|
|
#include "Pong.h" // Pong class definition
|
|
|
|
int Pong::player1Score = 0; // initialize player 1's score to 0
|
|
int Pong::player2Score = 0; // initialize player 2's score to 0
|
|
bool Pong::wait = false; // initialize wait to false
|
|
|
|
// directions to move the Paddles
|
|
const Vector3 PADDLE_DOWN = Vector3( 0, -15, 0 );
|
|
const Vector3 PADDLE_UP = Vector3( 0, 15, 0 );
|
|
|
|
// constructor
|
|
Pong::Pong()
|
|
{
|
|
|
|
#ifdef _DEBUG
|
|
rootPtr = new Root("Plugins_d.cfg"); // initialize Root object
|
|
#else
|
|
rootPtr = new Root("Plugins.cfg"); // initialize Root object
|
|
#endif
|
|
|
|
// use the Ogre Config Dialog Box to choose the settings
|
|
if ( !( rootPtr->showConfigDialog() ) ) // user canceled the dialog box
|
|
throw runtime_error( "User Canceled Ogre Setup Dialog Box." );
|
|
|
|
// get a pointer to the RenderWindow
|
|
windowPtr = rootPtr->initialise( true, "Pong" );
|
|
|
|
// create the SceneManager
|
|
sceneManagerPtr = rootPtr->createSceneManager( ST_GENERIC );
|
|
|
|
// create the Camera
|
|
cameraPtr = sceneManagerPtr->createCamera( "PongCamera" );
|
|
cameraPtr->setPosition( Vector3( 0, 0, 200 ) ); // set Camera position
|
|
cameraPtr->lookAt( Vector3( 0, 0, 0 ) ); // set where Camera looks
|
|
cameraPtr->setNearClipDistance( 5 ); // near distance Camera can see
|
|
cameraPtr->setFarClipDistance( 1000 ); // far distance Camera can see
|
|
|
|
// create the Viewport
|
|
viewportPtr = windowPtr->addViewport( cameraPtr );
|
|
viewportPtr->setBackgroundColour( ColourValue( 0, 0, 0 ) );
|
|
|
|
// set the Camera's aspect ratio
|
|
cameraPtr->setAspectRatio( Real( viewportPtr->getActualWidth() ) /
|
|
( viewportPtr->getActualHeight() ) );
|
|
|
|
// set the scene's ambient light
|
|
sceneManagerPtr->setAmbientLight( ColourValue( 0.75, 0.75, 0.75 ) );
|
|
|
|
// create the Light
|
|
Light *lightPtr = sceneManagerPtr->createLight( "Light" ); // a Light
|
|
lightPtr->setPosition( 0, 0, 50 ); // set the Light's position
|
|
|
|
unsigned long hWnd; // variable to hold the window handle
|
|
windowPtr->getCustomAttribute( "WINDOW", &hWnd ); // get window handle
|
|
OIS::ParamList paramList; // create an OIS ParamList
|
|
|
|
// add the window to the ParamList
|
|
paramList.insert( OIS::ParamList::value_type( "WINDOW",
|
|
Ogre::StringConverter::toString( hWnd ) ) );
|
|
|
|
// create the InputManager
|
|
inputManagerPtr = OIS::InputManager::createInputSystem( paramList );
|
|
keyboardPtr = static_cast< OIS::Keyboard* >( inputManagerPtr->
|
|
createInputObject( OIS::OISKeyboard, true ) ); // create a Keyboard
|
|
keyboardPtr->setEventCallback( this ); // add a KeyListener
|
|
|
|
rootPtr->addFrameListener( this ); // add this Pong as a FrameListener
|
|
|
|
// load resources for Pong
|
|
ResourceGroupManager::getSingleton().addResourceLocation(
|
|
"resources", "FileSystem", "Pong" );
|
|
ResourceGroupManager::getSingleton().initialiseAllResourceGroups();
|
|
|
|
quit = pause = false; // player has not quit or paused the game
|
|
time = 0; // initialize the time since Ball was reset to 0
|
|
} // end Pong constructor
|
|
|
|
// Pong destructor erases objects contained in a Pong object
|
|
Pong::~Pong()
|
|
{
|
|
// free dynamically allocated memory for Keyboard
|
|
inputManagerPtr->destroyInputObject( keyboardPtr );
|
|
OIS::InputManager::destroyInputSystem( inputManagerPtr );
|
|
|
|
// free dynamically allocated memory for Root
|
|
delete rootPtr; // release memory pointer points to
|
|
rootPtr = 0; // point pointer at 0
|
|
|
|
// free dynamically allocated memory for Ball
|
|
delete ballPtr; // release memory pointer points to
|
|
ballPtr = 0; // point pointer at 0
|
|
|
|
// free dynamically allocated memory for Paddle
|
|
delete leftPaddlePtr; // release memory pointer points to
|
|
leftPaddlePtr = 0; // point pointer at 0
|
|
|
|
// free dynamically allocated memory for Paddle
|
|
delete rightPaddlePtr; // release memory pointer points to
|
|
rightPaddlePtr = 0; // point pointer at 0
|
|
} // end Pong destructor
|
|
|
|
// create the scene to be displayed
|
|
void Pong::createScene()
|
|
{
|
|
// get a pointer to the Score Overlay
|
|
Overlay *scoreOverlayPtr =
|
|
OverlayManager::getSingleton().getByName( "Score" );
|
|
scoreOverlayPtr->show(); // show the Overlay
|
|
|
|
// make the game objects
|
|
ballPtr = new Ball( sceneManagerPtr ); // make the Ball
|
|
ballPtr->addToScene(); // add the Ball to the scene
|
|
rightPaddlePtr = new Paddle( sceneManagerPtr, "RightPaddle", 90 );
|
|
rightPaddlePtr->addToScene(); // add a Paddle to the scene
|
|
leftPaddlePtr = new Paddle( sceneManagerPtr, "LeftPaddle", -90 );
|
|
leftPaddlePtr->addToScene(); // add a Paddle to the scene
|
|
|
|
// create the walls
|
|
Entity *entityPtr = sceneManagerPtr->
|
|
createEntity( "WallLeft", "cube.mesh" ); // create the left wall
|
|
entityPtr->setMaterialName( "wall" ); // set material for left wall
|
|
entityPtr->setNormaliseNormals( true ); // fix the normals when scaled
|
|
|
|
// create the SceneNode for the left wall
|
|
SceneNode *nodePtr = sceneManagerPtr->getRootSceneNode()->
|
|
createChildSceneNode( "WallLeft" );
|
|
nodePtr->attachObject( entityPtr ); // attach left wall to SceneNode
|
|
nodePtr->setPosition( -95, 0, 0 ); // set the left wall's position
|
|
nodePtr->setScale( .05, 1.45, .1 ); // set the left wall's size
|
|
entityPtr = sceneManagerPtr->createEntity( "WallRight", "cube.mesh" );
|
|
entityPtr->setMaterialName( "wall" ); // set material for right wall
|
|
entityPtr->setNormaliseNormals( true ); // fix the normals when scaled
|
|
|
|
// create the SceneNode for the right wall
|
|
nodePtr = sceneManagerPtr->getRootSceneNode()->
|
|
createChildSceneNode( "WallRight" );
|
|
nodePtr->attachObject( entityPtr ); // attach right wall to SceneNode
|
|
nodePtr->setPosition( 95, 0, 0 ); // set the right wall's position
|
|
nodePtr->setScale( .05, 1.45, .1 ); // set the right wall's size
|
|
entityPtr = sceneManagerPtr->createEntity( "WallBottom", "cube.mesh" );
|
|
entityPtr->setMaterialName( "wall" ); // set material for bottom wall
|
|
entityPtr->setNormaliseNormals( true ); // fix the normals when scaled
|
|
|
|
// create the SceneNode for the bottom wall
|
|
nodePtr = sceneManagerPtr->getRootSceneNode()->
|
|
createChildSceneNode( "WallBottom" );
|
|
nodePtr->attachObject( entityPtr ); // attach bottom wall to SceneNode
|
|
nodePtr->setPosition( 0, -70, 0 ); // set the bottom wall's position
|
|
nodePtr->setScale( 1.95, .05, .1 ); // set bottom wall's size
|
|
entityPtr = sceneManagerPtr->createEntity( "WallTop", "cube.mesh" );
|
|
entityPtr->setMaterialName( "wall" ); // set the material for wall
|
|
entityPtr->setNormaliseNormals( true ); // fix the normals when scaled
|
|
|
|
// create the SceneNode for the top wall
|
|
nodePtr = sceneManagerPtr->getRootSceneNode()->
|
|
createChildSceneNode( "WallTop" );
|
|
nodePtr->attachObject( entityPtr ); // attach top wall to SceneNode
|
|
nodePtr->setPosition( 0, 70, 0 ); // set the top wall's position
|
|
nodePtr->setScale( 1.95, .05, .1 ); // set the top wall's size
|
|
} // end function createScene
|
|
|
|
// start a game of Pong
|
|
void Pong::run()
|
|
{
|
|
createScene(); // create the scene
|
|
rootPtr->startRendering(); // start rendering frames
|
|
} // end function run
|
|
|
|
// update the score
|
|
void Pong::updateScore( Players player )
|
|
{
|
|
// increase the correct player's score
|
|
if ( player == Players::PLAYER1 )
|
|
player1Score++;
|
|
else
|
|
player2Score++;
|
|
|
|
wait = true; // the game should wait to restart the Ball
|
|
updateScoreText(); // update the score text on the screen
|
|
} // end function updateScore
|
|
|
|
// update the score text
|
|
void Pong::updateScoreText()
|
|
{
|
|
ostringstream scoreText; // text to be displayed
|
|
|
|
scoreText << "P2: " << player2Score; // make the text
|
|
|
|
// get the right player's TextArea
|
|
OverlayElement *textElementPtr =
|
|
OverlayManager::getSingletonPtr()->getOverlayElement( "right" );
|
|
textElementPtr->setCaption( scoreText.str() ); // set the text
|
|
|
|
scoreText.str( "" ); // reset the text in scoreText
|
|
scoreText << "P1: " << player1Score; // make the text
|
|
|
|
// get the left player's TextArea
|
|
textElementPtr =
|
|
OverlayManager::getSingletonPtr()->getOverlayElement( "left" );
|
|
textElementPtr->setCaption( scoreText.str() ); // set the text
|
|
} // end function updateScoreText
|
|
|
|
// respond to user keyboard input
|
|
bool Pong::keyPressed( const OIS::KeyEvent &keyEventRef )
|
|
{
|
|
// if the game is not paused
|
|
if ( !pause )
|
|
{
|
|
// process KeyEvents that apply when the game is not paused
|
|
switch ( keyEventRef.key )
|
|
{
|
|
case OIS::KC_ESCAPE: // escape key hit: quit
|
|
quit = true;
|
|
break;
|
|
case OIS::KC_UP: // up-arrow key hit: move the right Paddle up
|
|
rightPaddlePtr->movePaddle( PADDLE_UP );
|
|
break;
|
|
case OIS::KC_DOWN: // down-arrow key hit: move the right Paddle down
|
|
rightPaddlePtr->movePaddle( PADDLE_DOWN );
|
|
break;
|
|
case OIS::KC_A: // A key hit: move left Paddle up
|
|
leftPaddlePtr->movePaddle( PADDLE_UP );
|
|
break;
|
|
case OIS::KC_Z: // Z key hit: move left Paddle down
|
|
leftPaddlePtr->movePaddle( PADDLE_DOWN );
|
|
break;
|
|
case OIS::KC_P: // P key hit: pause the game
|
|
pause = true; // set pause to true when the user pauses the game
|
|
Overlay *pauseOverlayPtr =
|
|
OverlayManager::getSingleton().getByName( "PauseOverlay" );
|
|
pauseOverlayPtr->show(); // show the pause Overlay
|
|
break;
|
|
} // end switch
|
|
} // end if
|
|
else // game is paused
|
|
{
|
|
// user hit 'R' on the keyboard
|
|
if ( keyEventRef.key == OIS::KC_R )
|
|
{
|
|
pause = false; // set pause to false when user resumes the game
|
|
Overlay *pauseOverlayPtr =
|
|
OverlayManager::getSingleton().getByName( "PauseOverlay" );
|
|
pauseOverlayPtr->hide(); // hide the pause Overlay
|
|
} // end if
|
|
} // end else
|
|
return true;
|
|
} // end function keyPressed
|
|
|
|
// process key released events
|
|
bool Pong::keyReleased( const OIS::KeyEvent &keyEventRef )
|
|
{
|
|
return true;
|
|
} // end function keyReleased
|
|
|
|
// return true if the program should render the next frame
|
|
bool Pong::frameEnded( const FrameEvent &frameEvent )
|
|
{
|
|
return !quit; // quit = false if the user hasn't quit yet
|
|
} // end function frameEnded
|
|
|
|
// process game logic, return true if the next frame should be rendered
|
|
bool Pong::frameStarted( const FrameEvent &frameEvent )
|
|
{
|
|
keyboardPtr->capture(); // get keyboard events
|
|
// the game is not paused and the Ball should move
|
|
if ( !wait && !pause )
|
|
{
|
|
// move the Ball
|
|
ballPtr->moveBall( frameEvent.timeSinceLastFrame );
|
|
} // end if
|
|
// don't move the Ball if wait is true
|
|
else if ( wait )
|
|
{
|
|
// increase time if it is less than 4 seconds
|
|
if ( time < 4 )
|
|
// add the seconds since the last frame
|
|
time += frameEvent.timeSinceLastFrame;
|
|
else
|
|
{
|
|
wait = false; // shouldn't wait to move the Ball any more
|
|
time = 0; // reset the control variable to 0
|
|
} // end else
|
|
} // end else
|
|
|
|
return !quit; // quit = false if the user hasn't quit yet
|
|
} // end function frameStarted
|
|
|
|
|