/creathemup_sdl/src/CLevelRenderer.cpp
C++ | 1166 lines | 693 code | 241 blank | 232 comment | 115 complexity | 5eb0465fda530d9c82e58d52469c707c MD5 | raw file
- #include "../include/CLevelRenderer.h"
- #include "../include/CSDLManager.h"
- #include "../include/CRenderBackground.h"
- #include "../include/CRenderPlayer.h"
- #include "../include/CRenderEnemy.h"
- #include "../include/CPlayerBehaviour.h"
- #include "../include/CDefaultEnemyBehaviour.h"
- #include "../include/CDiagonalEnemyBehaviour.h"
- #include "../include/CHorizontalEnemyBehaviour.h"
- #include "../include/CBoatEnemyBehaviour.h"
- #include "../include/CDefaultPowerUpBehaviour.h"
- #include "../include/CShotPowerUpBehaviour.h"
- #include <SDL/SDL.h>
- #include <SDL/SDL_image.h>
- #include <SDL/SDL_ttf.h>
- #include <assert.h>
- #include <math.h>
- //**************************
- //Description : Constructor
- //Parameters : None
- //Note : Private because a single instance is needed
- //**************************
- CLevelRenderer::CLevelRenderer()
- : m_sNbPlayers(0),
- m_sCurrentPlayer(0),
- m_sNbEnemies(0)
- {
- }
- //**************************
- //Description : Constructor
- //Parameters : None
- //Note : Private because a single instance is needed
- //**************************
- CLevelRenderer::~CLevelRenderer()
- {
- }
-
- //**************************
- //Description : Init the instance
- //Parameters : None
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::Init()
- {
- m_SDLManager = CSDLManager::GetInstancePtr();
- m_sCurrentLevel = NULL;
- m_Background = NULL;
- m_vPlayers = NULL;
- m_vEnemies = NULL;
- m_Highscores = m_SDLManager->GetHighscoreGameSurfaces();
- m_Lives = m_SDLManager->GetLivesSurfaces();
- m_Numbers = m_SDLManager->GetNumbersSurfaces();
- LoadHighScore();
- }
-
- //**************************
- //Description : DeInit the instance
- //Parameters : None
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::DeInit()
- {
- if ( m_sCurrentLevel != NULL )
- delete[] m_sCurrentLevel;
- if ( m_Background != NULL )
- delete m_Background;
- if ( m_vPlayers != NULL )
- delete[] m_vPlayers;
- if ( m_vEnemies != NULL )
- delete[] m_vEnemies;
- }
- //**************************
- //Description : Load the level _szLevel
- //Parameters : Pointer toward the current level configuration file
- //Return Value : true if success, otherwise false
- //Note : Have to be called after the SDL initialisation because we need a screen
- //**************************
- bool CLevelRenderer::LoadLevel(const char * _szLevelDir)
- {
- char szBuffer[255]; //buffer of a line
- char szBackgroundName[255]; //name of the background bind to ther level
- int iTypeEnemy, // type of the enemy
- iX, // value of the abscissa
- iY, // value of the ordinary
- iSpeedX, // value of the m_sCurrentLevelspeed on the abscissa
- iSpeedY, // value of the speed on the ordinary
- iPowerUp, // 0 if no powerup, 1 if a powerup
- iTypePowerUp, // type of the power up
- iTypeShotPowerUp, // if it's a shot power up, we have to know the type of shot that is changed
- iBackgroundSpeed; //speed of the scrolling
- long lEnemyAppearance; //time before the appearance of an enemy
- SDL_Surface * Screen = m_SDLManager->GetScreen();
- FILE *fFile; //pointer on the file
- fFile = fopen(_szLevelDir, "r");
- //test on the opening
- assert ( fFile != NULL );
- //get the first line
- fgets(szBuffer, 255, fFile);
- //scan the background
- sscanf(szBuffer, "BACKGROUND: %s %d", szBackgroundName, &iBackgroundSpeed);
- //We create the animation
- CSpriteAnimation BackAnim(szBackgroundName);
- //we create the CRenderBackground
- m_Background = new CRenderBackground(Screen, &BackAnim, iBackgroundSpeed);
- //get the second line
- fgets(szBuffer, 255, fFile);
- //scan the number of enemies
- sscanf(szBuffer, "ENNEMIES: %hd", &m_sNbEnemies);
- m_vEnemies = new CRenderEnemy[m_sNbEnemies]();
- short sCount = 0;
- while ( !feof(fFile) && sCount < m_sNbEnemies )
- {
- //get a line
- fgets(szBuffer, 255, fFile);
- //check wether it's useful or not (comment line, blank, or nothing)
- if (szBuffer[0] != '#' && szBuffer[0] != '\r' && szBuffer[0] != '\0'
- && szBuffer[0] != '\n' && strlen(szBuffer) != 0)
- {
- //get info of the ennemy
- sscanf(szBuffer, "%d %d %d %d %d %d %d %d %ld", &iTypeEnemy,
- &iX, &iY,
- &iSpeedX, &iSpeedY,
- &iPowerUp, &iTypePowerUp, &iTypeShotPowerUp,
- &lEnemyAppearance);
- CDefaultEnemyBehaviour * Enemy;
- //create the enemy
- switch (iTypeEnemy)
- {
- case DEFAULTENEMY:
- {
- CDefaultEnemyBehaviour * DefaultEnemy = new CDefaultEnemyBehaviour(iX, iY, iSpeedX, iBackgroundSpeed+iSpeedY);
- Enemy = DefaultEnemy;
- break;
- }
- case DIAGONALENEMY:
- {
- CDiagonalEnemyBehaviour * DiagonalEnemy = new CDiagonalEnemyBehaviour(iX, iY, iSpeedX, iBackgroundSpeed+iSpeedY);
- Enemy = DiagonalEnemy;
- break;
- }
- case HORIZONTALENEMY:
- {
- CHorizontalEnemyBehaviour * HorizontalEnemy = new CHorizontalEnemyBehaviour(iX, iY, iSpeedX, iBackgroundSpeed+iSpeedY);
- Enemy = HorizontalEnemy;
- break;
- }
- case BOATENEMY:
- {
- CBoatEnemyBehaviour * BoatEnemy = new CBoatEnemyBehaviour(iX, iY, iSpeedX, iBackgroundSpeed+iSpeedY);
- Enemy = BoatEnemy;
- break;
- }
- }
- m_vEnemies[sCount].SetRender(Screen,
- Enemy,
- lEnemyAppearance,
- m_SDLManager->GetEnemyAnimations(iTypeEnemy),
- m_SDLManager->GetEnemyShotsAnimation(iTypeEnemy));
- //if there is a powerup
- if ( iPowerUp == 1 )
- {
- //create the powerup
- switch (iTypePowerUp)
- {
- case DEFAULTPOWERUP:
- {
- CDefaultPowerUpBehaviour * DefaultPowerUp = new CDefaultPowerUpBehaviour();
- m_vEnemies[sCount].SetPowerUpBehaviour(DefaultPowerUp, m_SDLManager->GetPowerUpAnimations(iTypePowerUp) );
- break;
- }
- case SHOTPOWERUP:
- {
- CShotPowerUpBehaviour * ShotPowerUp = new CShotPowerUpBehaviour();
- ShotPowerUp->SetTypeShotBonus(iTypeShotPowerUp);
- m_vEnemies[sCount].SetPowerUpBehaviour(ShotPowerUp, m_SDLManager->GetPowerUpAnimations(iTypePowerUp) );
- break;
- }
- }
- }
- sCount++;
- }
- }
- fclose(fFile);
- return true;
- }
- //**************************
- //Description : Load the last game saved
- //Parameters : The path to the game
- //Return Value : true if success, otherwise false
- //Note : Have to be called after the SDL initialisation because we need a screen
- //**************************
- bool CLevelRenderer::LoadGame(const char * _szLoad)
- {
- FILE *fLoadGame;
- short sCurrentLevel; //current level of a player
- int iLives, //number of lives of a player
- iEnemiesKilled; //number of ennemies that a player killed
- long lCurrentTime, //time spent from the begining of the current level
- lPoints; //points of the player
- int iNbShots[2]; //number of shot for each type of shot of the player
- SDL_Surface * Screen = m_SDLManager->GetScreen();
- fLoadGame = fopen(_szLoad, "rb");
- assert( fLoadGame != NULL );
- //we load the number of players
- fread(&m_sNbPlayers, sizeof(short), 1, fLoadGame);
- //we load the time from the begining of the level
- fread(&lCurrentTime, sizeof(long), 1, fLoadGame);
- //we load the number of the player who is currently playing
- fread(&m_sCurrentPlayer, sizeof(short), 1, fLoadGame);
- //we create necessary variables
- m_vPlayers = new CRenderPlayer[m_sNbPlayers]();
- m_sCurrentLevel = new short[m_sNbPlayers]();
- //we load the two players
- for (int i = 0; i < m_sNbPlayers; i++)
- {
- CPlayerBehaviour * Player = new CPlayerBehaviour();
- //we store its lives, its points and the number of enemies that he killed
- fread(&sCurrentLevel, sizeof(short), 1, fLoadGame);
- fread(&iLives, sizeof(int), 1, fLoadGame);
- fread(&lPoints, sizeof(long), 1, fLoadGame);
- fread(&iEnemiesKilled, sizeof(int), 1, fLoadGame);
-
- //we go until we have the TWO shots (primary and secondary)
- for (int j = 0; j < 2; j++)
- {
- fread(&iNbShots[j], sizeof(int), 1, fLoadGame);
- }
- //we set the current level
- m_sCurrentLevel[i] = sCurrentLevel;
- //we set the lives
- Player->AddLife(iLives - Player->HasLives());
- //we set its points
- Player->AddPoints(lPoints);
- //we set its number of enemies killed
- Player->AddEnemiesKilled(iEnemiesKilled);
- //we set the number of shots
- Player->SetNbShots(iNbShots);
- m_vPlayers[i].SetRender(Screen,
- Player,
- m_SDLManager->GetPlayerAnimations(i),
- m_SDLManager->GetPlayerShotsAnimation(i));
- Player = NULL;
- }
- //we load the current level
- char szCurrentLevel[2];
- sprintf(szCurrentLevel, "%hd", m_sCurrentLevel[m_sCurrentPlayer]);
- std::string szStringCurrentLevel;
- szStringCurrentLevel += szLevelsDir;
- szStringCurrentLevel += "Level";
- szStringCurrentLevel += szCurrentLevel;
- LoadLevel( szStringCurrentLevel.c_str() );
- //we record the beginning of the level
- m_lBeginLevel = SDL_GetTicks() - lCurrentTime;
- m_lPauseTime = 0;
- fclose(fLoadGame);
- //we make the enemies that have an appearance lowest than the time of the game disappear (we make their y be after the height of the window)
- int i = 0;
- while ( i < m_sNbEnemies && m_vEnemies[i].GetAppearance() < lCurrentTime )
- {
- m_vEnemies[i].GetEnemyBehaviour()->SetY(GAME_WINDOW_HEIGHT*2);
- i++;
- }
- return true;
- }
- //**************************
- //Description : Save the current game
- //Parameters : The path to the save
- //Return Value : true if success, otherwise false
- //Note : Have to be called after the SDL initialisation because we need a screen
- //**************************
- bool CLevelRenderer::SaveGame(const char * _szSave)
- {
- FILE *fSaveGame;
- short sCurrentLevel; //current level of a player
- int iLives, //number of lives of a player
- iEnemiesKilled; //number of ennemies that a player killed
- long lCurrentTime, //time spent from the begining of the current level
- lPoints; //points of the player
- int * iNbShots; //number of shot for each type of shot of the player
- fSaveGame = fopen(_szSave, "wb");
- assert( fSaveGame != NULL );
- //we get the time from the beginning of the level
- lCurrentTime = SDL_GetTicks() - m_lBeginLevel - m_lPauseTime;
- //we save the number of players
- fwrite(&m_sNbPlayers, sizeof(short), 1, fSaveGame);
- //we save this value
- fwrite(&lCurrentTime, sizeof(long), 1, fSaveGame);
- //we save the player who is currently playing
- fwrite(&m_sCurrentPlayer, sizeof(short), 1, fSaveGame);
- //we save the two players
- for (int i = 0; i < m_sNbPlayers; i++)
- {
- CPlayerBehaviour * Player = m_vPlayers[i].GetPlayerBehaviour();
- //we save info from the player
- sCurrentLevel = m_sCurrentLevel[i];
- iLives = Player->HasLives();
- lPoints = Player->GetPoints();
- iEnemiesKilled = Player->GetEnemiesKilled();
- iNbShots = Player->GetNbShots();
- //we store its current level, itslives, its points and the number of enemies that he killed
- fwrite(&sCurrentLevel, sizeof(short), 1, fSaveGame);
- fwrite(&iLives, sizeof(int), 1, fSaveGame);
- fwrite(&lPoints, sizeof(long), 1, fSaveGame);
- fwrite(&iEnemiesKilled, sizeof(int), 1, fSaveGame);
-
- //we go until we have the TWO shots (primary and secondary)
- for (int j = 0; j < 2; j++)
- {
- fwrite(&iNbShots[j], sizeof(int), 1, fSaveGame);
- }
- }
- fclose(fSaveGame);
- return true;
- }
- //**************************
- //Description : Restart the current level
- //Parameters : None
- //Return Value : None
- //Note : RestartLevel is called when a player die, because we can't restart a level when we want
- //**************************
- void CLevelRenderer::RestartLevel()
- {
- //we delete the background
- if ( m_Background != NULL )
- delete m_Background;
- //We delete the ennemies
- if ( m_vEnemies != NULL )
- delete[] m_vEnemies;
- //we reinitialise the current player and set the second (if any)
- m_vPlayers[m_sCurrentPlayer].InitRender();
- m_sCurrentPlayer++;
- if (m_sCurrentPlayer >= m_sNbPlayers)
- m_sCurrentPlayer = 0;
- //we init the current player in order to make it blink
- m_vPlayers[m_sCurrentPlayer].InitRender();
- //we load the level for the player
- char szCurrentLevel[2];
- sprintf(szCurrentLevel, "%hd", m_sCurrentLevel[m_sCurrentPlayer]);
- std::string szStringCurrentLevel;
- szStringCurrentLevel += szLevelsDir;
- szStringCurrentLevel += "Level";
- szStringCurrentLevel += szCurrentLevel;
- LoadLevel( szStringCurrentLevel.c_str() );
- //we save the begining of the level
- m_lBeginLevel = SDL_GetTicks();
- m_lPauseTime = 0;
- }
- //**************************
- //Description : Load the highscore of the game
- //Parameters : None
- //Return Value : true if success, otherwise false
- //Note : None
- //**************************
- bool CLevelRenderer::LoadHighScore()
- {
- FILE * fFile;
- fFile = fopen( szHighScoreDir.c_str() , "rb" );
- //test on the opening
- assert ( fFile != NULL );
- do
- {
- fread(&m_lHighScore, sizeof(long), 1, fFile);
- }
- while ( !feof(fFile) );
- fclose(fFile);
- return true;
- }
- //**************************
- //Description : Save the highscore of the game
- //Parameters : None
- //Return Value : true if success, otherwise false
- //Note : None
- //**************************
- bool CLevelRenderer::SaveHighScore()
- {
- FILE * fFile;
- fFile = fopen( szHighScoreDir.c_str(), "wb" );
- //test on the opening
- assert ( fFile != NULL );
- fwrite(&m_lHighScore, sizeof(long), 1, fFile);
- fclose(fFile);
- return true;
- }
- //**************************
- //Description : Return the highscore of the game
- //Parameters : None
- //Return Value : The high score of the game
- //Note : have to be called after LoadHighScore
- //**************************
- long CLevelRenderer::GetHighScore()
- {
- return m_lHighScore;
- }
- //**************************
- //Description : Start the game from the beginning with _sNbPLayers
- //Parameters : The number of players
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::StartGame(short _sNbPlayers)
- {
- //we test if can start the game
- if ( _sNbPlayers > 0 && _sNbPlayers <= MAX_PLAYERS )
- {
- //we initialise
- m_sCurrentLevel = new short[_sNbPlayers]();
- m_sNbPlayers = _sNbPlayers;
- m_sCurrentPlayer = 0;
- //we initialise each player
- m_vPlayers = new CRenderPlayer[m_sNbPlayers]();
- CPlayerBehaviour * Players = NULL;
- SDL_Surface * Screen = m_SDLManager->GetScreen();
- for (int i = 0; i < m_sNbPlayers; i++)
- {
- Players = new CPlayerBehaviour();
- m_vPlayers[i].SetRender(Screen,
- Players,
- m_SDLManager->GetPlayerAnimations(i),
- m_SDLManager->GetPlayerShotsAnimation(i));
- m_sCurrentLevel[i] = 0;
- Players = NULL;
- }
- //we load the current level
- char szCurrentLevel[2];
- sprintf(szCurrentLevel, "%hd", m_sCurrentLevel[m_sCurrentPlayer]);
- std::string szStringCurrentLevel;
- szStringCurrentLevel += szLevelsDir;
- szStringCurrentLevel += "Level";
- szStringCurrentLevel += szCurrentLevel;
- LoadLevel( szStringCurrentLevel.c_str() );
- //we record the beginning of the level
- m_lBeginLevel = SDL_GetTicks();
- m_lPauseTime = 0;
- //we launch the game
- Game();
- }
- }
- //**************************
- //Description : Start the game from a save file
- //Parameters : The save configuration file
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::StartGame(const char * _szLoadLevel)
- {
- if ( LoadGame(_szLoadLevel) )
- {
- //we test if can start the game by loading the save
- if ( m_sNbPlayers > 0 && m_sNbPlayers <= MAX_PLAYERS )
- {
- //we launch the game
- Game();
- }
- }
- }
- //**************************
- //Description : Test if the game is over or not
- //Parameters : None
- //Return Value : True if the game is over, false if not
- //Note : The game is over whan all players don't have life anymore or if one player has finished the game
- //**************************
- bool CLevelRenderer::GameOver()
- {
- bool bGameOver = true;
- int i = 0;
- if ( m_vPlayers != NULL )
- {
- //we search partially, because if only one players is alive, the game isn't over
- while (i < m_sNbPlayers && bGameOver)
- {
- bGameOver = (m_vPlayers[i].GetPlayerBehaviour()->IsDead() || (m_sCurrentLevel[i] >= NUMBER_LEVELS) );
- i++;
- }
- //we can declare the end of the game after the animation of death of the current player has ended
- if ( bGameOver )
- bGameOver = m_vPlayers[m_sCurrentPlayer].IsPlayerDead();
- }
- return bGameOver;
- }
- //**************************
- //Description : Test if the current level is over or not
- //Parameters : None
- //Return Value : True if the lvel is over, false if not
- //Note : The level is over when all ennemies went out of the screen (y > GAME_WINDOW_HEIGHT) or are dead
- //**************************
- bool CLevelRenderer::LevelOver()
- {
- //if the current player is dead, we have to restart the level
- if ( m_vPlayers != NULL && (m_vPlayers[m_sCurrentPlayer].IsExploding() || m_vPlayers[m_sCurrentPlayer].IsPlayerExplosed()) )
- return false;
- bool bLevelOver = true;
- //we test if there are enemies
- if ( m_vEnemies != NULL )
- {
- //we test the appearance of the last enemy and we add some time in order to let him move
- long lCurrentTime = SDL_GetTicks();
- int iNumEnemy = 0;
- while (iNumEnemy < m_sNbEnemies && bLevelOver)
- {
- //if the enemy has appeared
- if ( (m_vEnemies[iNumEnemy].GetAppearance() + 2000) < (lCurrentTime - m_lBeginLevel - m_lPauseTime) )
- {
- //we test if the enemy is dead OR if he is out of the screen (he has passed the height of the screen
- bLevelOver = ( m_vEnemies[iNumEnemy].IsEnemyDead()
- || (m_vEnemies[iNumEnemy].GetEnemyBehaviour()->GetY() - m_vEnemies[iNumEnemy].GetEnemyBehaviour()->GetHeight()/2) > GAME_WINDOW_HEIGHT );
- }
- else
- bLevelOver = false;
- iNumEnemy++;
- }
- }
- return bLevelOver;
- }
- //**************************
- //Description : Manage collision between all rendering entities
- //Parameters : None
- //Return Value : True if the players collide with an enemy or a shot, otherwise false
- //Note : None
- //**************************
- bool CLevelRenderer::Collision()
- {
- bool bCollision = false;
- //we get the current time
- long lCurrentTime = SDL_GetTicks();
- for (int i = 0; i < m_sNbEnemies; i++)
- {
- //we test the time of appearance
- if ( m_vEnemies[i].GetAppearance() < (lCurrentTime - m_lBeginLevel - m_lPauseTime) )
- {
- if ( m_vPlayers[m_sCurrentPlayer].CollideWithEnemy(&m_vEnemies[i]) )
- bCollision = true;
- m_vEnemies[i].CollideWithPlayer(&m_vPlayers[m_sCurrentPlayer]);
- }
- //else ennemies after this one don't appear because their appearance time is higher
- else
- i = m_sNbEnemies;
- }
- return bCollision;
- }
- //**************************
- //Description : Draw the statistics of the given player at the end of a level, of the game or when it's game over
- //Parameters : The number of the player we want to draw the statistics
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::DrawPlayerStatistics(int _iNumPlayer)
- {
- std::string szText;
- char szPlayer[100];
- long lHigh = 0; //highscore of the player
- int iNum; //number to draw
- int iPow = 1; //result of pow
- SDL_Color White = { 255, 255, 255 };
- SDL_Color Green = { 0, 255, 0 };
- SDL_Color Red = { 255, 0, 0 };
- SDL_Rect Dest;
- SDL_Surface * Screen = m_SDLManager->GetScreen(), *Text;
- //we get the font
- TTF_Font * BigGameFont = m_SDLManager->GetBigGameFont();
- TTF_Font * LittleGameFont = m_SDLManager->GetLittleGameFont();
- szText.clear();
- sprintf(szPlayer, "%d", _iNumPlayer);
- szText = "Player ";
- szText += szPlayer;
- Text = TTF_RenderText_Blended(LittleGameFont, szText.c_str(), Green);
- Dest.x = 50;
- Dest.y = 150 + (_iNumPlayer-1) * 200;
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- //if the player is dead, we show it
- if ( m_vPlayers[_iNumPlayer-1].GetPlayerBehaviour()->IsDead() )
- {
- Dest.x = 60 + Text->w;
- Dest.y = 150 + (_iNumPlayer-1) * 200;
- szText.clear();
- szText = "DEAD";
- Text = TTF_RenderText_Blended(LittleGameFont, szText.c_str(), Red);
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- }
- szText.clear();
- szText = "Highscore :";
- Text = TTF_RenderText_Blended(LittleGameFont, szText.c_str(), White);
- Dest.x = 70;
- Dest.y = 190 + (_iNumPlayer-1) * 200;
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- lHigh = m_vPlayers[_iNumPlayer-1].GetPlayerBehaviour()->GetPoints();
- //we draw that we have a new highscore
- if ( lHigh > m_lHighScore )
- {
- szText.clear();
- szText = "NEW HIGHSCORE !";
- Text = TTF_RenderText_Blended(LittleGameFont, szText.c_str(), Red);
- Dest.y = 190 + (_iNumPlayer-1) * 200;
- Dest.x = 9 * 40;
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- }
- //we draw the value of the highscore
- for (int j = 0; j < 9; j++)
- {
- for (int a = 0; a < (8-j); a++)
- iPow *= 10;
- iNum = lHigh / iPow;
- lHigh -= iNum * iPow;
- sprintf(szPlayer, "%d", iNum);
- Text = TTF_RenderText_Blended(LittleGameFont, szPlayer, White);
- Dest.y = 230 + (_iNumPlayer-1) * 200;
- Dest.x = 100 + j * 40;
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- iPow = 1;
- }
- szText.clear();
- szText = "Enemies killed :";
- Text = TTF_RenderText_Blended(LittleGameFont, szText.c_str(), White);
- Dest.x = 70;
- Dest.y = 270 + (_iNumPlayer-1) * 200;
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- sprintf(szPlayer, "%d", m_vPlayers[_iNumPlayer-1].GetPlayerBehaviour()->GetEnemiesKilled());
- Text = TTF_RenderText_Blended(LittleGameFont, szPlayer, White);
- Dest.x = 100;
- Dest.y = 310 + (_iNumPlayer-1) * 200;
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- }
- //**************************
- //Description : Draw the statistics on the screen at the end of the level or at the end of the game
- //Parameters : None
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::DrawEndStatistics()
- {
- SDL_Rect Dest;
- SDL_Surface * Screen = m_SDLManager->GetScreen();
- // We first fill the entire screen with black
- SDL_FillRect(Screen, NULL, SDL_MapRGB(Screen->format, 0, 0, 0));
- //we get the background of the menu and apply it here
- SDL_Surface * Background = m_SDLManager->GetBackgroundMenu();
- Dest.x = 0;
- Dest.y = 0;
- SDL_BlitSurface(Background, NULL, Screen, &Dest);
- //we get the font
- TTF_Font * BigGameFont = m_SDLManager->GetBigGameFont();
- TTF_Font * LittleGameFont = m_SDLManager->GetLittleGameFont();
- SDL_Color White = { 255, 255, 255 };
- SDL_Color Green = { 0, 255, 0 };
- SDL_Color Red = { 255, 0, 0 };
- SDL_Surface * Text;
- //we are either at the end of a level, or at the end of the game when this function is called
- if ( LevelOver() )
- {
- if ( m_sCurrentLevel[m_sCurrentPlayer] >= (NUMBER_LEVELS-1) )
- Text = TTF_RenderText_Blended(BigGameFont, "Game Finished !", Green);
- else
- Text = TTF_RenderText_Blended(BigGameFont, "Level Clear !", Green);
- Dest.y = 20;
- Dest.x = (WINDOW_WIDTH / 2) - (Text->w / 2);
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- //we draw the statistics only for the current player
- DrawPlayerStatistics(m_sCurrentPlayer+1);
- }
- else
- {
- Text = TTF_RenderText_Blended(BigGameFont, "Game Statistics :", Green);
- Dest.y = 20;
- Dest.x = (WINDOW_WIDTH / 2) - (Text->w / 2);
- SDL_BlitSurface(Text, NULL, Screen, &Dest);
- //we draw the statistics of the two players
- for (int i = 1; i <= m_sNbPlayers; i++)
- DrawPlayerStatistics(i);
- }
- //We flip the screen
- m_SDLManager->Flip();
- SDL_Delay(4000);
- }
- //**************************
- //Description : Draw the statistics on the screen
- //Parameters : None
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::DrawStatistics()
- {
- SDL_Surface * Screen = m_SDLManager->GetScreen();
- SDL_Rect Dest;
- long lHigh = 0; //highscore of the player
- int iNum; //number to draw
- int iPow = 1; //result of pow
- //we draw the highscores to the left off the screen
- for (int i = 0; i < m_sNbPlayers; i++)
- {
- Dest.y = i * (2 * m_Highscores[i+1]->h);
- Dest.x = 0;
- SDL_BlitSurface(m_Highscores[i+1], NULL, Screen, &Dest);
- lHigh = m_vPlayers[i].GetPlayerBehaviour()->GetPoints();
- //we draw the value of the highscore
- for (int j = 0; j < 9; j++)
- {
- Dest.y = i * (2 * m_Highscores[i+1]->h) + m_Highscores[i+1]->h;
- Dest.x = j * m_Numbers[j]->w;
- for (int a = 0; a < (8-j); a++)
- iPow *= 10;
- iNum = lHigh / iPow;
- lHigh -= iNum * iPow;
- SDL_BlitSurface(m_Numbers[iNum], NULL, Screen, &Dest);
- iPow = 1;
- }
- }
- //the highscore of the game is drawn to the bottom left
- Dest.y = WINDOW_HEIGHT - (2 * m_Highscores[0]->h);
- Dest.x = 0;
- SDL_BlitSurface(m_Highscores[0], NULL, Screen, &Dest);
- lHigh = m_lHighScore;
- //we draw the value of the highscore
- for (int j = 0; j < 9; j++)
- {
- Dest.y = WINDOW_HEIGHT - m_Highscores[0]->h;
- Dest.x = j * m_Numbers[j]->w;
- for (int a = 0; a < (8-j); a++)
- iPow *= 10;
- iNum = lHigh / iPow;
- lHigh -= iNum * iPow;
- SDL_BlitSurface(m_Numbers[iNum], NULL, Screen, &Dest);
- iPow = 1;
- }
- int iLives; //number of lives of a player
- //the lives are drawn to the right of the screen
- for (int i = 0; i < m_sNbPlayers; i++)
- {
- Dest.y = i * (2 * m_Lives[i]->h);
- Dest.x = GAME_WINDOW_X + GAME_WINDOW_WIDTH;
- SDL_BlitSurface(m_Lives[i], NULL, Screen, &Dest);
- //we draw the number of lives
- Dest.y = i * (2 * m_Lives[i]->h) + m_Lives[i]->h;
- Dest.x = GAME_WINDOW_X + GAME_WINDOW_WIDTH;
- iLives = m_vPlayers[i].GetPlayerBehaviour()->HasLives();
- SDL_BlitSurface(m_Numbers[iLives], NULL, Screen, &Dest);
- }
- }
- //**************************
- //Description : Draw the screen
- //Parameters : None
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::DrawScene()
- {
- SDL_Surface * Screen = m_SDLManager->GetScreen();
- // We first fill the entire screen with black
- SDL_FillRect(Screen, NULL, SDL_MapRGB(Screen->format, 0, 0, 0));
- //we draw the statistics
- DrawStatistics();
- //we render the background
- m_Background->Render();
- //we get the current time
- long lCurrentTime = SDL_GetTicks();
- //we render the enemies if they have to appear
- for (int i = 0; i < m_sNbEnemies; i++)
- {
- //we test the time of appearance
- if ( m_vEnemies[i].GetAppearance() < (lCurrentTime - m_lBeginLevel - m_lPauseTime) )
- m_vEnemies[i].Render();
- //else ennemies after this one don't appear because their appearance time is higher
- else
- i = m_sNbEnemies;
- }
-
- //we render the player
- m_vPlayers[m_sCurrentPlayer].Render();
- //We flip the screen
- m_SDLManager->Flip();
- }
-
- //**************************
- //Description : Manage events in the game
- //Parameters : a boolean, to know if the player quit the game, a boolean to know if we are in pause or not
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::ManageEvents(bool & _bEndGame, bool & _bPauseGame)
- {
- SDL_Event event;
-
- while ( SDL_PollEvent(&event) )
- {
- if ( event.type == SDL_QUIT )
- _bEndGame = true;
-
- if ( event.type == SDL_KEYDOWN )
- {
- if ( event.key.keysym.sym == SDLK_ESCAPE )
- _bEndGame = true;
-
- if ( event.key.keysym.sym == SDLK_p )
- {
- _bPauseGame = !_bPauseGame;
-
- if (_bPauseGame)
- m_lBeginPause = SDL_GetTicks();
- else
- m_lPauseTime += SDL_GetTicks() - m_lBeginPause;
- }
- //save the game
- if ( event.key.keysym.sym == SDLK_F5 )
- {
- SaveGame( szSaveGameDir.c_str() );
- }
- }
- }
- }
- //**************************
- //Description : Manage the game
- //Parameters : None
- //Return Value : None
- //Note : None
- //**************************
- void CLevelRenderer::Game()
- {
- bool bPlayerExploded = false; //allows us to show the animation of the death of the player before switching player
- bool bEndGame = false; //if escape or sdl_quit is called we return to the menu
- bool bPauseGame = false; //if P is pressed, Pause is set/unset
- long lCurrentTime, lFormerTime = SDL_GetTicks();
- while ( !bEndGame && !GameOver() )
- {
- lCurrentTime = SDL_GetTicks();
- if ( (lCurrentTime - lFormerTime) > DELAY )
- {
- ManageEvents(bEndGame, bPauseGame);
- if ( !bPauseGame )
- {
- if ( !LevelOver() )
- {
- if ( !bPlayerExploded )
- //we test the collision
- bPlayerExploded = Collision();
- else
- {
- //if the animation of the death of the current player has finished, we switch player and restart the level
- if ( m_vPlayers[m_sCurrentPlayer].IsPlayerExplosed() )
- {
- //we search the first player who don't have finished the game
- do
- {
- m_sCurrentPlayer++;
- if ( m_sCurrentPlayer >= m_sNbPlayers )
- m_sCurrentPlayer = 0;
- }
- while ( m_sCurrentLevel[m_sCurrentPlayer] >= NUMBER_LEVELS );
- m_sCurrentPlayer--;
- if ( m_sCurrentPlayer < 0 )
- m_sCurrentPlayer = m_sNbPlayers - 1;
- RestartLevel();
- bPlayerExploded = false;
- }
- }
- //we render the screen
- DrawScene();
- }
- else
- {
- //show the current statistics
- DrawEndStatistics();
- //Delete current enemies and background
- delete m_Background;
- m_Background = NULL;
- delete[] m_vEnemies;
- m_vEnemies = NULL;
- //we reinitialise the player for the next level
- m_vPlayers[m_sCurrentPlayer].InitRender();
- //next level
- m_sCurrentLevel[m_sCurrentPlayer]++;
- //if we are ate the end of the game
- if ( m_sCurrentLevel[m_sCurrentPlayer] < NUMBER_LEVELS )
- {
- //load the next level
- char szCurrentLevel[2];
- sprintf(szCurrentLevel, "%hd", m_sCurrentLevel[m_sCurrentPlayer]);
- std::string szStringCurrentLevel;
- szStringCurrentLevel += szLevelsDir;
- szStringCurrentLevel += "Level";
- szStringCurrentLevel += szCurrentLevel;
- LoadLevel( szStringCurrentLevel.c_str() );
- m_lBeginLevel = SDL_GetTicks();
- m_lPauseTime = 0;
- }
- else
- {
- bEndGame = true;
- //the game is finished for this player but maybe not for the others
- int i = 0;
- while ( i < m_sNbPlayers && bEndGame )
- {
- if ( m_sCurrentLevel[i] < NUMBER_LEVELS )
- bEndGame = false;
- i++;
- }
- //if the game is not ended, we get to the player before the first who do not have finished the game and restart the level
- if ( !bEndGame )
- {
- while ( m_sCurrentLevel[m_sCurrentPlayer] >= NUMBER_LEVELS )
- {
- m_sCurrentPlayer++;
- if ( m_sCurrentPlayer >= m_sNbPlayers )
- m_sCurrentPlayer = 0;
- }
- m_sCurrentPlayer--;
- if ( m_sCurrentPlayer < 0 )
- m_sCurrentPlayer = m_sNbPlayers - 1;
- RestartLevel();
- }
- }
- }
- }
- lFormerTime = SDL_GetTicks();
- }
- else
- SDL_Delay(DELAY - (lCurrentTime - lFormerTime));
- }
- DrawEndStatistics();
- long lPlayer;
- for ( int i = 0; i < m_sNbPlayers; i++)
- {
- lPlayer = m_vPlayers[i].GetPlayerBehaviour()->GetPoints();
- if ( lPlayer > m_lHighScore )
- {
- m_lHighScore = lPlayer;
- SaveHighScore();
- }
- }
- //we delete the players for further instances
- if ( m_vPlayers != NULL )
- {
- delete[] m_vPlayers;
- m_vPlayers = NULL;
- }
- }