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();
}
Exemple #7
0
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();
	
}
Exemple #8
0
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();
}