166 lines
6.6 KiB
C++
166 lines
6.6 KiB
C++
// Ball.cpp
|
|
// Ball class member-function definitions.
|
|
#include <Ogre.h> // Ogre class definition
|
|
using namespace Ogre; // use the Ogre namespace
|
|
|
|
#include <OgreAL.h> // OgreAL class definition
|
|
#include "Ball.h" // Ball class definition
|
|
#include "Paddle.h" // Paddle class definition
|
|
#include "Pong.h" // Pong class definition
|
|
|
|
// Ball constructor
|
|
Ball::Ball( SceneManager *ptr )
|
|
{
|
|
sceneManagerPtr = ptr; // set pointer to the SceneManager
|
|
soundManagerPtr = new OgreAL::SoundManager(); // create SoundManager
|
|
speed = 100; // speed of the Ball
|
|
direction = Vector3( 1, -1, 0 ); // direction of the Ball
|
|
} // end Ball constructor
|
|
|
|
// Ball destructor
|
|
Ball::~Ball()
|
|
{
|
|
// empty body
|
|
} // end Ball destructor
|
|
|
|
// add the Ball to the scene
|
|
void Ball::addToScene()
|
|
{
|
|
// create Entity and attach it to a node in the scene
|
|
Entity *entityPtr =
|
|
sceneManagerPtr->createEntity( "Ball", "cube.mesh" );
|
|
entityPtr->setMaterialName( "ball" ); // set material for the Ball
|
|
entityPtr->setNormaliseNormals( true ); // fix the normals when scaled
|
|
nodePtr = sceneManagerPtr->getRootSceneNode()->createChildSceneNode( "Ball" ); // create a SceneNode
|
|
nodePtr->attachObject( entityPtr ); // attach the Entity to SceneNode
|
|
nodePtr->setScale( .05, .05, .05 ); // scale SceneNode
|
|
|
|
// attach sounds to Ball so they will play from where Ball is
|
|
wallSoundPtr = soundManagerPtr->createSound( "wallSound", "wallSound.wav", false );
|
|
nodePtr->attachObject( wallSoundPtr ); // attach a sound to SceneNode
|
|
paddleSoundPtr = soundManagerPtr->createSound( "paddleSound", "paddleSound.wav", false );
|
|
nodePtr->attachObject( paddleSoundPtr ); // attach sound to SceneNode
|
|
scoreSoundPtr = soundManagerPtr->createSound( "cheer", "cheer.wav", false ); // create a Sound
|
|
|
|
// attach the score sound to its own node centered at ( 0, 0, 0 )
|
|
sceneManagerPtr->getRootSceneNode()->createChildSceneNode( "score" )->attachObject( scoreSoundPtr );
|
|
} // end function addToScene
|
|
|
|
// move the Ball across the screen
|
|
void Ball::moveBall( Real time )
|
|
{
|
|
nodePtr->translate( ( direction * ( speed * time ) ) ); // move Ball
|
|
Vector3 position = nodePtr->getPosition(); // get Ball's new position
|
|
|
|
// get the positions of the four walls
|
|
Vector3 topPosition = sceneManagerPtr->getSceneNode( "WallTop" )->getPosition();
|
|
Vector3 bottomPosition = sceneManagerPtr->getSceneNode( "WallBottom" )->getPosition();
|
|
Vector3 leftPosition = sceneManagerPtr->getSceneNode( "WallLeft" )->getPosition();
|
|
Vector3 rightPosition = sceneManagerPtr->getSceneNode( "WallRight" )->getPosition();
|
|
|
|
const int WALL_WIDTH = 5; // the width of the walls
|
|
|
|
// check if the Ball hit the left side
|
|
if ( ( position.x - RADIUS ) <= leftPosition.x + ( WALL_WIDTH / 2 ) )
|
|
{
|
|
nodePtr->setPosition( 0, 0, 0 ); // place Ball in center of screen
|
|
Pong::updateScore( Players::PLAYER2 ); // update the score
|
|
scoreSoundPtr->play(); // play a sound when player 2 scores
|
|
} // end if
|
|
// check if the Ball hit the right side
|
|
else if (
|
|
( position.x + RADIUS ) >= rightPosition.x - ( WALL_WIDTH / 2 ) )
|
|
{
|
|
nodePtr->setPosition( 0, 0, 0 ); // place Ball in center of screen
|
|
Pong::updateScore( Players::PLAYER1 ); // update the score
|
|
scoreSoundPtr->play(); // play a sound when player 1 scores
|
|
} // end else
|
|
// check if the Ball hit the bottom wall
|
|
else if (
|
|
( position.y - RADIUS ) <= bottomPosition.y + ( WALL_WIDTH / 2 ) &&
|
|
direction.y < 0 )
|
|
{
|
|
// place the Ball on the bottom wall
|
|
nodePtr->setPosition( position.x,
|
|
( bottomPosition.y + ( WALL_WIDTH / 2 ) + RADIUS ), position.z );
|
|
reverseVerticalDirection(); // make the Ball start moving up
|
|
} // end else
|
|
// check if the Ball hit the top wall
|
|
else if (
|
|
( position.y + RADIUS ) >= topPosition.y - ( WALL_WIDTH / 2 ) &&
|
|
direction.y > 0 )
|
|
{
|
|
// place the Ball on the top wall
|
|
nodePtr->setPosition( position.x,
|
|
( topPosition.y - ( WALL_WIDTH / 2 ) - RADIUS ), position.z );
|
|
reverseVerticalDirection(); // make the Ball start moving down
|
|
} // end else
|
|
|
|
hitPaddle(); // check if the Ball hit a Paddle
|
|
} // end function moveBall
|
|
|
|
// reverse the Ball's horizontal direction
|
|
void Ball::reverseHorizontalDirection()
|
|
{
|
|
direction *= Vector3( -1, 1, 1 ); // reverse the horizontal direction
|
|
paddleSoundPtr->play(); // play the "paddleSound" sound effect
|
|
} // end function reverseHorizontalDirection
|
|
|
|
// reverse the Ball's vertical direction
|
|
void Ball::reverseVerticalDirection()
|
|
{
|
|
direction *= Vector3( 1, -1, 1 ); // reverse the vertical direction
|
|
wallSoundPtr->play(); // play the "wallSound" sound effect
|
|
} // end function reverseVerticalDirection
|
|
|
|
// control the Ball colliding with the Paddle
|
|
void Ball::hitPaddle()
|
|
{
|
|
// get the position of the Paddles and the Ball
|
|
Vector3 leftPaddlePosition = sceneManagerPtr->
|
|
getSceneNode( "LeftPaddle" )->getPosition(); // left Paddle
|
|
Vector3 rightPaddlePosition = sceneManagerPtr->
|
|
getSceneNode( "RightPaddle" )->getPosition(); // right Paddle
|
|
Vector3 ballPosition = nodePtr->getPosition(); // the Ball's position
|
|
|
|
const int PADDLE_WIDTH = 2; // width of the Paddle
|
|
const int PADDLE_HEIGHT = 30; // height of the Paddle
|
|
|
|
// is the Ball in range of the left Paddle?
|
|
if ( ( ballPosition.x - RADIUS ) <
|
|
( leftPaddlePosition.x + ( PADDLE_WIDTH / 2 ) ) )
|
|
{
|
|
// check for collision with left Paddle
|
|
if ( ( ballPosition.y - RADIUS ) <
|
|
( leftPaddlePosition.y + ( PADDLE_HEIGHT / 2 ) ) &&
|
|
( ballPosition.y + RADIUS ) >
|
|
( leftPaddlePosition.y - ( PADDLE_HEIGHT / 2 ) ) )
|
|
{
|
|
reverseHorizontalDirection(); // reverse the Ball's direction
|
|
|
|
// place the Ball at the edge of the Paddle
|
|
nodePtr->setPosition(
|
|
( leftPaddlePosition.x + ( PADDLE_WIDTH / 2 ) + RADIUS ),
|
|
ballPosition.y, ballPosition.z );
|
|
} // end if
|
|
} // end if
|
|
// is the Ball in range of the right Paddle?
|
|
else if ( ( ballPosition.x + RADIUS ) >
|
|
( rightPaddlePosition.x - ( PADDLE_WIDTH / 2 ) ) )
|
|
{
|
|
// check for collision with right Paddle
|
|
if ( ( ballPosition.y - RADIUS ) <
|
|
( rightPaddlePosition.y + ( PADDLE_HEIGHT / 2 ) ) &&
|
|
( ballPosition.y + RADIUS ) >
|
|
( rightPaddlePosition.y - ( PADDLE_HEIGHT / 2 ) ) )
|
|
{
|
|
reverseHorizontalDirection(); // reverse the Ball's direction
|
|
|
|
// place the Ball at the edge of the Paddle
|
|
nodePtr->setPosition(
|
|
( rightPaddlePosition.x - ( PADDLE_WIDTH / 2 ) - RADIUS ),
|
|
ballPosition.y, ballPosition.z );
|
|
} // end if
|
|
} // end else
|
|
} // end function hitPaddle
|