luskbo 24 Newbie Poster

Ok.
I've been working on a pacman game using C++, and OGRE. Things have been going good, but I have run across a problem with the collision detection of pacman hitting the walls.
Before I explaing, here is some of the source code.

PacpersonObj Class Header

// PacPersonObj.h
 // PacPersonObj class definition (represents a PacPersonObj in the game).
 #ifndef PacPersonObj_H
 #define PacPersonObj_H

 #include <Ogre.h> // Ogre class definition
 using namespace Ogre; // use the Ogre namespace


 const int RADIUS = 5; // the radius of the Pacperson



 class PacPersonObj
 {
 public:
    // constructor
    PacPersonObj( SceneManager *sceneManagerPtr );
    ~PacPersonObj(); // destructor
	void movePac( const Vector3 &direction ); // move a PacPersonObj
    void addToScene(); // add a PacPersonObj to the scene
	void movePac2( Real time ); // move the pacperson across the screen
	void setDirection(Vector3);


    

 private:
    SceneManager* sceneManagerPtr; // pointer to the SceneManager
    SceneNode *nodePtr; // pointer to a SceneNode                
    String name; // name of the PacPersonObj
    //int x;// x-coordinate of the PacPersonObj
//	int y;
	void reverseHorizontalDirection() ; // change horizontal direction
    void reverseVerticalDirection(); // change vertical direction
	int speed; // speed of the Pacperson
    Vector3 direction; // direction of the Pacperson



 }; // end of class PacPersonObj

 #endif // PacPersonObj_H

PacpersonObj Class .cpp

void PacPersonObj::setDirection(Vector3 newNirection)
 {
	 direction = newNirection;
 }

 void PacPersonObj::movePac2( Real time)
{
   nodePtr->translate( ( direction * ( speed * time ) ) ); // move pac 
   Vector3 position = nodePtr->getPosition(); // get pac'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 = 20; // the width of the walls

	
	// check if the Pac hit the left side
    if ( ( position.x - RADIUS ) <= leftPosition.x + ( WALL_WIDTH / 2 ) )
    {
       
       nodePtr->setPosition(0,0,0); // move pac 
	   
       Pacperson::waitTrueToggle();
     
    } // end if
    // check if the Pac hit the right side
    if (                                                           
       ( position.x + RADIUS ) >= rightPosition.x - ( WALL_WIDTH / 2 ) )
    {
       nodePtr->setPosition( (rightPosition.x - ( WALL_WIDTH / 2 ) - RADIUS ),                                   
           position.y , position.z );
	   
       Pacperson::updateScore( Players::PLAYER1 ); // update the score
     
    } // end else
    // check if the Pac hit the bottom wall
    else if (                                                             
       ( position.y - RADIUS ) <= bottomPosition.y + ( WALL_WIDTH / 2 ) &&
       direction.y < 0 )                                                  
    {
       // place the Pac on the bottom wall
       nodePtr->setPosition( position.x,                                   
          ( bottomPosition.y + ( WALL_WIDTH / 2 ) + RADIUS ), position.z );
      
    } // end else
    // check if the Pac hit the top wall
    else if (                                                          
      ( position.y + RADIUS ) >= topPosition.y - ( WALL_WIDTH / 2 ) &&
      direction.y > 0 )                                               
   {
      // place the Pac on the top wall
      nodePtr->setPosition( position.x,                                
         ( topPosition.y - ( WALL_WIDTH / 2 ) - RADIUS ), position.z );
      
   } // end else

 
 } // end function movePac


void PacPersonObj::reverseHorizontalDirection()
 {
    direction *= Vector3( -1, 1, 1 ); // reverse the horizontal direction
 } // end function reverseHorizontalDirection

 // reverse the Pacperson's vertical direction
 void PacPersonObj::reverseVerticalDirection()
 {
    direction *= Vector3( 1, -1, 1 ); // reverse the vertical direction
 } // end function reverseVerticalDirection

Class that implements ( relevent functions)

#include <sstream>
  using std::ostringstream;

  #include <stdexcept>
  using std::runtime_error;

  #include <Ogre.h> // Ogre class definition
  using namespace Ogre; // use the Ogre namespace

  #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 "powerUp.h"
  #include "PacPersonObj.h"
  #include "newTut.h"

  int Pacperson::player1Score = 0; // initialize player 1's score to 0
  int Pacperson::player2Score = 0; // initialize player 2's score to 0
  bool Pacperson::wait = false; // initialize wait to false

	// directions to move the Paddles
  const Vector3 PACPERSON_DOWN = Vector3( 0, -1, 0 );
  const Vector3 PACPERSON_UP = Vector3( 0, 1, 0 );   
  const Vector3 PACPERSON_LEFT = Vector3( -1, 0, 0 );
  const Vector3 PACPERSON_RIGHT = Vector3( 1, 0, 0 );  



  
//////////////ommitted objects///////////////



PacPersonObjPtr = new PacPersonObj( sceneManagerPtr ); // make the PacPerson
    PacPersonObjPtr->addToScene(); // add the PacPersonObj to the scene


// update the score
 void Pacperson::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 Pacperson
    updateScoreText(); // update the score text on the screen
 } // end function updateScore

 // update the score text
 void Pacperson::updateScoreText()
 {
    ostringstream scoreText; // text to be displayed

    scoreText << "Player 2 Score: " << 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 << "Player 1 Score: " << 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 Pacperson::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 Pacpersonup
         PacPersonObjPtr->setDirection(PACPERSON_UP);
		 wait = false;
          break;
     case OIS::KC_DOWN: // down-arrow key hit: move the right Pacpersondown
          PacPersonObjPtr->setDirection( PACPERSON_DOWN );
		  wait = false;
          break;
	   case OIS::KC_LEFT: // up-arrow key hit: move the right Pacpersonup
          PacPersonObjPtr->setDirection( PACPERSON_LEFT );
		  wait = false;
          break;
       case OIS::KC_RIGHT: // down-arrow key hit: move the right Pacpersondown
          PacPersonObjPtr->setDirection( PACPERSON_RIGHT );
		  wait = false;
          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 Pacperson::keyReleased( const OIS::KeyEvent &keyEventRef )
 {
    return true;
 } // end function keyReleased

 // return true if the program should render the next frame
 bool Pacperson::frameEnded( const FrameEvent &frameEvent )
 {
    return !quit; // quit = false if the user hasn't quit yet
 } // end function frameEnded

 bool Pacperson::frameStarted( const FrameEvent &frameEvent )
 {

	 keyboardPtr->capture(); // get keyboard events

	 if ( !wait && !pause )
    {
       // move the Pacperson
       PacPersonObjPtr->movePac2( frameEvent.timeSinceLastFrame);
    } // end if
    // don't move the Pacperson 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 Pacperson 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

// sets wait to true
 void Pacperson::waitTrueToggle()
 {
	 wait = true;
 }

OK now for the explanation.
In the PacpersonObj Class .cpp source, I define the function.

void PacPersonObj::movePac2( Real time)

This function recieves a time parameter from the class that implements its.
It uses that time to to move the object using .

nodePtr->translate( ( direction * ( speed * time ) ) ); 
   Vector3 position = nodePtr->getPosition();

I sets the location of the walls and uses if/ else statements to check for collisions with the walls .

The directions is set by the

void PacPersonObj::setDirection(Vector3 newNirection)

This direction is sent to it by the from the class that implements its.

Specifically the keyPressed function , and the frameStarted functions.

???????????????????
My Problem!
???????????????????

When ever I run the game. the ball dissapears. I have tried many diffrent things to fix this, and have discovered something that I don't understand.


When the code is like this :

if ( ( position.x - RADIUS ) <= leftPosition.x + ( WALL_WIDTH / 2 ) )
    {
       
       nodePtr->setPosition(0,0,0); // move pac 
	   
       Pacperson::waitTrueToggle();
     
}

The ball appears, and the collision detection works, except for this first part of the if/else statements. I can set the " nodePtr->setPosition(0,0,0); " to anywhere , and it will go back to that point after it hits the wall, but it also starts there when the game starts.

I just want it to stop at the wall like my other if else's do , but if I change the code like the other if/else statements, the ball dissapears as soon as it starts.

My though is that is is reading my fist if statement too early.

any ideas??

Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.