CollisionDirection CollisionHandler::DetectCollisionWithObj(MovingObject& _obj, DisplayableObject& _ref) { if (_obj.GetID() == _ref.GetID()) return NO_COL; return DetectCollisionWithRect(_obj.GetCoordinates(), _ref.GetCoordinates()); }
CollisionDirection CollisionHandler::HandleCollisionWithRect(unsigned int _objId, sf::FloatRect _ref) { DisplayableObject *obj = m_gameEngine->GetForegroundItem(_objId); CollisionDirection direction = DetectCollisionWithRect(obj->GetCoordinates(), _ref); ReactToCollision(*obj, _ref, direction); return direction; }
void CollisionHandler::SendNewObjectPositionToGFX(DisplayableObject& _obj) { // Send information about the object that has been hit (for gfx to know about states changes) EngineEvent redisplayObject(INFO_POS_LVL); if (_obj.GetClass() == PLAYER || _obj.GetClass() == ENEMY) redisplayObject.set(INFO_POS_CHAR, _obj.GetInfoForDisplay()); else redisplayObject.set(INFO_POS_LVL, _obj.GetInfoForDisplay()); m_gameEngine->TransmitInfoToGFX(redisplayObject); }
void CollisionHandler::ReactToCollisionsWithObj(MovingObject& _obj, DisplayableObject& _ref, CollisionDirection _direction) { ReactToCollision(_obj, _ref.GetCoordinates(), _direction); _obj.UpdateAfterCollision(Util::OppositeCollisionDirection(_direction), _ref.GetClass()); // Updates the state of the object, not its coordinates _obj.SetPosition(m_gameEngine->GetCoordinatesOfForegroundItem(_obj.GetID())); _ref.UpdateAfterCollision(_direction, _obj.GetClass()); SendNewObjectPositionToGFX(_ref); }
void CollisionHandler::ReactToCollision(DisplayableObject& _obj, sf::FloatRect _refRect, CollisionDirection _direction) { sf::FloatRect objRect = _obj.GetCoordinates(); switch (_direction) { case TOP: objRect.top -= (objRect.top + objRect.height - _refRect.top); break; case BOTTOM: objRect.top += (_refRect.top + _refRect.height - objRect.top); break; case LEFT: objRect.left -= (objRect.left + objRect.width - _refRect.left); break; case RIGHT: objRect.left += (_refRect.left + _refRect.width - objRect.left); break; case NO_COL: default: break; } m_gameEngine->UpdateForegroundItem(_obj.GetID(), objRect); }
void nextFrame(void) { int actTime = glutGet(GLUT_ELAPSED_TIME); int interval = actTime - lastTime; lastTime = actTime; float knightStep = knightSpeed * interval / 1000.0; float ghostStep = ghostSpeed * interval / 1000.0; if (steps == 1) { ghostX = -1; ghostZ = 0; } if (steps == 500) { ghostX = 0; ghostZ = -1; } if (steps == 1000) { ghostX = 1; ghostZ = 0; } if (steps == 1500) { ghostX = 0; ghostZ = 1; } if (steps == 2000) { knightX *= -1; steps = 0; } knight.Move(vec3(knightX, 0, 0), knightStep); ghost.Move(vec3(ghostX, 0, ghostZ), ghostStep); steps++; glutPostRedisplay(); }
void Ball::DoUpdate( int iCurrentTime ) { DisplayableObject* pObject; for(int iObjectId = 0; (pObject = GetEngine()->GetDisplayableObject( iObjectId )) != NULL ; iObjectId++ ){ if ( pObject == this ) // This is us, skip it continue; PlayerWall* pWall = (PlayerWall*) pObject; // We have no other objects so no point checking if it's not a player wall, hence no dynamic cast int xx = pWall->GetXCentre() - (pWall->GetDrawWidth()/2); int xx1 = pWall->GetXCentre() + (pWall->GetDrawWidth()/2); int yy = pWall->GetYCentre() - (pWall->GetDrawHeight()/2); int yy1 = pWall->GetYCentre() + (pWall->GetDrawHeight()/2); int x = m_iCurrentScreenX + m_iStartDrawPosX + m_iDrawWidth/2; int x1 = m_iCurrentScreenX + m_iStartDrawPosX + m_iDrawWidth/2; int y = m_iCurrentScreenY + m_iStartDrawPosY + m_iDrawHeight/2; int y1 = m_iCurrentScreenY + m_iStartDrawPosY + m_iDrawHeight/2; if(collide(x, x1, y, y1, xx, xx1, yy, yy1)){ pWall->IncreaseScore(10); m_dSY = -m_dSY; float fDiff = (pObject->GetXCentre() - m_iCurrentScreenX)/400.0; // Bounce angle relative to hit position, lower denomenator means higher angle // Calculating the angle as above also allows a bounce to have a shallower angle than the angle it hit at depending where it hits the player. //m_dSY -= 0.04; // Increase speed m_dSY += pWall->GetPlayer() ? -0.04 : 0.04; m_dSX += -fDiff; // Change horizontal speed } } m_dX += m_dSX; m_dY += m_dSY; if ( (m_dX+m_iStartDrawPosX) < 0 ) { m_dX = - m_iStartDrawPosX; if ( m_dSX < 0 ) m_dSX = -m_dSX; } if ( (m_dX+m_iStartDrawPosX+m_iDrawWidth) > (GetEngine()->GetScreenWidth()-1) ) { m_dX = GetEngine()->GetScreenWidth() -1 - m_iStartDrawPosX - m_iDrawWidth; if ( m_dSX > 0 ) m_dSX = -m_dSX; } if ( (m_dY+m_iStartDrawPosY) < 0 ) { m_dY = -m_iStartDrawPosY; if ( m_dSY < 0 ) m_dSX = m_dSY = 0; // Game over, bot player wins m_pEngine->GameOver(true/*bot*/); } if ( (m_dY+m_iStartDrawPosY+m_iDrawHeight) > (GetEngine()->GetScreenHeight()-1) ) { m_dY = GetEngine()->GetScreenHeight() -1 - m_iStartDrawPosY - m_iDrawHeight; if ( m_dSY > 0 ){ m_dSX = m_dSY = 0; // Game over, top player wins m_pEngine->GameOver(false/*top*/); } } // Work out current position m_iCurrentScreenX = (int)(m_dX+0.5); m_iCurrentScreenY = (int)(m_dY+0.5); // Ensure that the object gets redrawn on the display, if something changed RedrawObjects(); }
void Demo4Object::DoUpdate( int iCurrentTime ) { m_iPreviousScreenX = m_iCurrentScreenX; m_iPreviousScreenY = m_iCurrentScreenY; /********** EXTRA ********/ // Iterate through the objects // We are looking for one which is too close to us DisplayableObject* pObject; for ( int iObjectId = 0 ; (pObject = m_pMainEngine->GetDisplayableObject( iObjectId ) ) != NULL ; iObjectId++ ) { if ( pObject == this ) // This is us, skip it continue; // If you need to cast to the sub-class type, you must use dynamic_cast, see lecture 19 // We are just using base class parts int iXDiff = pObject->GetXCentre() - m_iCurrentScreenX; int iYDiff = pObject->GetYCentre() - m_iCurrentScreenY; // Estimate the size - by re-calculating it int iTick = iCurrentTime/20; // 1 per 20ms int iFrame = iTick % 30; int iSize = 10 + iFrame; if ( iFrame > 15 ) iSize = 10 + (30-iFrame); int iSizeOther = iSize; // Assume both the same size // Pythagorus' theorum: if ( ((iXDiff*iXDiff)+(iYDiff*iYDiff)) < ((iSizeOther+iSize)*(iSizeOther+iSize)) ) { // Move us to 1,1 and set direction right m_iMapX = 1+rand()%13; m_iMapY = 1+(rand()%2)*8; m_iDir = 1; // Face right m_oMover.Setup( m_iMapX *50 + 25 + 25, //m_iCurrentScreenX, m_iMapY *50 + 25 + 40, //m_iCurrentScreenY, m_iMapX *50 + 25 + 25, m_iMapY *50 + 25 + 40, iCurrentTime, iCurrentTime+400+rand()%200 ); // Ask the mover where the object should be m_oMover.Calculate( iCurrentTime ); m_iCurrentScreenX = m_oMover.GetX(); m_iCurrentScreenY = m_oMover.GetY(); // Ensure that the object gets redrawn on the display, if something changed RedrawObjects(); return; } } /********** END EXTRA ********/ // If movement has finished if ( m_oMover.HasMovementFinished(iCurrentTime) ) { Demo4TileManager& tm = m_pMainEngine->GetTileManager(); // Handle any tile that we just moved onto switch ( tm.GetValue( m_iMapX, m_iMapY ) ) { case 2: case 3: case 4: case 5: case 6: case 7: tm.UpdateTile( m_pMainEngine, m_iMapX, m_iMapY, tm.GetValue( m_iMapX, m_iMapY ) + 1 ); break; case 8: tm.UpdateTile( m_pMainEngine, m_iMapX, m_iMapY, 0 ); break; } // Set off a new movement switch( rand() % 10 ) { case 0: // Increase dir by 1 m_iDir = ( m_iDir + 1 )%4; break; case 1: // Reduce dir by 1 m_iDir = ( m_iDir + 3 )%4; break; } // Allow some control over the object by the player if ( m_pMainEngine->IsKeyPressed( SDLK_UP ) ) m_iDir = 0; if ( m_pMainEngine->IsKeyPressed( SDLK_RIGHT ) ) m_iDir = 1; if ( m_pMainEngine->IsKeyPressed( SDLK_DOWN ) ) m_iDir = 2; if ( m_pMainEngine->IsKeyPressed( SDLK_LEFT ) ) m_iDir = 3; switch ( tm.GetValue( m_iMapX + GetXDiffForDirection(m_iDir), m_iMapY + GetYDiffForDirection(m_iDir) ) ) { case 0: // Passageway case 2: // Pellet case 3: // Pellet case 4: // Pellet case 5: // Pellet case 6: // Pellet case 7: // Pellet case 8: // Pellet // Allow move - set up new movement now m_iMapX += GetXDiffForDirection(m_iDir); m_iMapY += GetYDiffForDirection(m_iDir); m_oMover.Setup( m_iCurrentScreenX, m_iCurrentScreenY, m_iMapX *50 + 25 + 25, m_iMapY *50 + 25 + 40, iCurrentTime, iCurrentTime+400+rand()%200 ); break; case 1: // Wall m_iDir = rand()%4; // Rotate randomly break; } } // If making a move then do the move if ( !m_oMover.HasMovementFinished(iCurrentTime) ) { // Ask the mover where the object should be m_oMover.Calculate( iCurrentTime ); m_iCurrentScreenX = m_oMover.GetX(); m_iCurrentScreenY = m_oMover.GetY(); } // Ensure that the object gets redrawn on the display, if something changed RedrawObjects(); }
void DisplayObjects() { grass.Display(); castle.Display(); knight.Display(); wallpaper.Display(); roof.Display(); ceiling.Display(); armour.Display(); entrance.Display(); ghost.Display(); throne.Display(); table.Display(); }
void LoadObjects() { castle.LoadFromFile("castle.obj"); castle.LoadTexture("Stone.tga"); grass.LoadFromFile("ground.obj"); grass.LoadTexture("Earth.tga"); knight.LoadFromFile("Knight.obj"); knight.LoadTexture("Metal.tga"); roof.LoadFromFile("Roof.obj"); roof.LoadTexture("Stone.tga"); ceiling.LoadFromFile("Ceiling.obj"); ceiling.LoadTexture("Wood.tga"); armour.LoadFromFile("Armour.obj"); armour.LoadTexture("Metal.tga"); entrance.LoadFromFile("Entrance.obj"); entrance.LoadTexture("Stone.tga"); ghost.LoadFromFile("Ghost.obj"); ghost.LoadTexture("Bedsheet.tga"); throne.LoadFromFile("Throne.obj"); throne.LoadTexture("Gold.tga"); table.LoadFromFile("Table.obj"); table.LoadTexture("Table.tga"); wallpaper.LoadFromFile("wallpaper.obj"); wallpaper.LoadTexture("fleurdelis-tile.tga"); }
void Nxs13uEnemyObject::DoUpdate(int currentTime) { //keep the objects in the playing field //so the dimensions of the player field is (0,50), (600,50), (0,550), (600,550) int fieldXmin = 0; int fieldXmax = 600; int fieldYmin = 50; int fieldYmax = 550; if (id == 3){ //for start page, enemy must be able to travel anywhere fieldXmin = 0; fieldXmax = GetEngine()->GetScreenWidth(); fieldYmin = 0; fieldYmax = GetEngine()->GetScreenHeight(); } // Alter position for speed - this makes the ball appear to vibrate // remember that speed is basically pixels travelled per tick m_iCurrentScreenX += (speedX * rand() % (difficulty + 1)); m_iCurrentScreenY += (speedY * rand() % (difficulty + 1)); // Check for bounce off the edge if (m_iCurrentScreenX < fieldXmin + radius) { m_iCurrentScreenX = fieldXmin + radius; if (speedX < 0) speedX = -speedX; } if (m_iCurrentScreenX > fieldXmax - radius) { m_iCurrentScreenX = fieldXmax - radius; if (speedX > 0) speedX = -speedX; } if (m_iCurrentScreenY < fieldYmin + radius) { m_iCurrentScreenY = fieldYmin + radius; if (speedY < 0) speedY = -speedY; } if (m_iCurrentScreenY > fieldYmax - radius) { m_iCurrentScreenY = fieldYmax - radius; if (speedY > 0) speedY = -speedY; } // Set current position m_iCurrentScreenX = (int)(m_iCurrentScreenX + speedX); m_iCurrentScreenY = (int)(m_iCurrentScreenY + speedY); //dynamic cast DisplayableObject* playerObject; //COLLISIONS if (id == 2){ //FOR GAME MODE ENEMY (not start-up page enemy) for (int objectId = 0; (playerObject = m_pMainEngine->GetDisplayableObject(objectId)) != NULL; objectId++) { if (playerObject == this) // This is us, skip it continue; //get the difference between the player and the enemy int playerSize = 40; int xDifference = playerObject->GetXCentre() - m_iCurrentScreenX; int yDifference = playerObject->GetYCentre() - m_iCurrentScreenY; // Pythagorus' theorum, if the distance is smaller than the size (radius size of both objects), then it is a collission if (((xDifference*xDifference) + (yDifference*yDifference)) < ((playerSize + radius)*(playerSize + radius))) { //move 70 pixels away from user and go in opposite direction (prevents re-collision) speedX = -speedX; speedY = -speedY; if (speedX < 0 || m_iCurrentScreenX > 530) m_iCurrentScreenX = m_iCurrentScreenX - 70; else m_iCurrentScreenX = m_iCurrentScreenX + 70; if (speedY < 0 || m_iCurrentScreenY > 480) m_iCurrentScreenY = m_iCurrentScreenY - 70; else m_iCurrentScreenY = m_iCurrentScreenY + 70; collision = true; //check which player it collided with - lives are passed back to Nxs13uMain if (objectId == 0) player1lives--; else if (objectId == 1) player2lives--; } // end of collissions } } RedrawObjects(); }