www.pudn.com > sxdl.zip > cBoomBastic.cpp
#include "cBoomBastic.h"
#include "cAITank.h"
#define ONE_PLAYER 1
#define TWO_PLAYERS 2
#define NO_WINNER -1
#define DRAW 4
#define TIME_OUT 5
//Instance globale du jeu
cBoomBastic g_BoomBastic;
#ifdef WIN32
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR, INT)
{
//On lance le jeu
return g_BoomBastic.FrameworkRun(hInst);
}
#else
int main(int argc, char *argv[])
{
//On lance le jeu
return g_BoomBastic.FrameworkRun();
}
#endif
CResource cBoomBastic::m_Resources[] =
{
{ TANK_TEXTURE, CResource::Texture, NULL, true, "Tank.png" },
{ SPRITE_TEXTURE, CResource::Texture, NULL, true, "BoomBasticSprites.tga" },
{ MENU_BG, CResource::Texture, NULL, true, "BgMenu.png" },
{ GAME_BG, CResource::Texture, NULL, true, "BgGame.png" },
{ EXPLODE_SOUND, CResource::Sound, NULL, true, "explode.wav" },
{ CANNON_SOUND, CResource::Sound, NULL, true, "cannon.wav" },
{ BONUS_SOUND, CResource::Sound, NULL, true, "bonus.wav" },
{ REMAINS_MUSIC, CResource::Music, NULL, true, "Remains.mp3" },
{ NULL_RESOURCE, CResource::Null, NULL, false, "" }
};
cBoomBastic::cBoomBastic()
{
m_NbPlayers = 1;
}
void cBoomBastic::OnStartup()
{
//On cree la fenetre
FrameworkName(TEXT("BoomBastic"));
#ifdef _DEBUG
FrameworkMode( Window ) ;
#else
FrameworkMode( FullScreen ) ;
#endif
FrameworkWindow ( 800, 600, false );
//Les ressources sont chargees
Media.Table(m_Resources);
}
void cBoomBastic::OnCreateGame()
{
//On cree les sprites du jeu
int i, j; // for VC 6
for ( i = 0 ; i < 8 ; ++ i )
{
EntitySprites [ i ] = NULL ;
} ;
//Sprite des rochers
EntitySprites[ROCK_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 129, 0, 63, 64 ) ;
//Sprites des bonus
EntitySprites[BOMB_BONUS_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 128, 192, 64, 64 ) ;
EntitySprites[SPEED_BONUS_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 0, 192, 64, 64 ) ;
EntitySprites[ROCKET_BONUS_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 64, 192, 64, 64 ) ;
//Sprites des bombes
EntitySprites[BOMB_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 0, 137, 48, 47 ) ;
//Sprite des missiles
EntitySprites[ROCKET_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 128, 128, 26, 26 ) ;
//Sprite des explosions
EntitySprites[FIRE_SPRITE] = new CBasicSprite(SPRITE_TEXTURE, 0xFFFFFFFF, 64, 129, 64, 63 ) ;
// All sprites will have alpha inv src alpha in the Impostors layer
for ( i = 0 ; i < 8 ; ++ i )
{
if ( NULL != EntitySprites [ i ] )
EntitySprites [ i ]->Layer = SxDL::Impostors ;
} ;
//Sprites pour les tanks
for (i = 0; i < 4; i++)
{
for (j = 0; j < 4; j++)
{
TankSprites[i][j] = new CBasicSprite(TANK_TEXTURE, 0xFFFFFFFF, j * 64, i * 64, 64, 64 ) ;
TankSprites[i][j]->Layer = SxDL::Impostors ;
}
}
// Particules are blended and live in the foreground ( default )
Particles[ROCKET_PARTICLE] = new CLerpingSprite(SPRITE_TEXTURE, CLerpingSprite::Red, 192, 64, 64, 64);
Particles[BONUS_PARTICLE] = new CLerpingSprite(SPRITE_TEXTURE, CLerpingSprite::Blue, 192, 64, 64, 64);
Particles[TANK_PARTICLE] = new CLerpingSprite(SPRITE_TEXTURE, CLerpingSprite::Green, 192, 64, 64, 64);
Particles[EXPLO_PARTICLE] = new CLerpingSprite(SPRITE_TEXTURE, CLerpingSprite::Red, 192, 64, 64, 64);
//On cree la map
Tilemap = new cMap(SPRITE_TEXTURE);
Tilemap->Enable(false);
//On cree les backgrounds
m_MenuBackground = new CBackground(MENU_BG, 0xFFFFFFFF);
m_MenuBackground->Enable();
m_GameBackground = new CBackground(GAME_BG, 0xFFFFFFFF);
m_GameBackground->Enable(false);
//On cree les colliders
m_TankBonusCollider = new CCollider(TANK_ID, BONUS_ID);
m_TankRocketCollider = new CCollider(TANK_ID, ROCKET_ID);
//On lit la musique
Music.Play(REMAINS_MUSIC);
//On initialise les scores a 0
m_Score[0] = m_Score[1] = m_Score[2] = m_Score[3] = 0;
//On cree un nouveau menu
CMenu *NewGameMenu = new CMenu("New Game", CUserInterface::DoMenu, "One or two players?");
NewGameMenu->Add(new CMenu("One player", ONE_PLAYER, ""));
NewGameMenu->Add(new CMenu("Two players", TWO_PLAYERS, ""));
NewGameMenu->Add(new CMenu("-|-", CUserInterface::Nothing, ""));
NewGameMenu->Add(new CMenu("Back to Main Menu", CUserInterface::GoBack, "Returns to main menu options"));
UserInterface.Main->Add(NewGameMenu, 1);
Input.SetMode ( CInput::TwoPlayers ) ;
//On affiche le menu principal
UserInterface.RunMenu(UserInterface.Main);
}
void cBoomBastic::OnMenuItemSelected(int ActionID, float ElapsedTime, float AbsoluteTime)
{
//Si le joueur a demande de creer une nouvelle partie a un ou deux joueurs
if (ActionID == ONE_PLAYER || ActionID == TWO_PLAYERS)
{
m_NbPlayers = ActionID;
//On fait disparaitre le menu
UserInterface.DismissMenu();
//et on quitte la partie actuelle (s'il y en a une) puis on en lance une nouvelle
OnEndGame();
OnNewGame();
}
}
void cBoomBastic::OnNewGame()
{
//On affiche le background du jeu
m_MenuBackground->Enable(false);
m_GameBackground->Enable();
//On active les colliders
m_TankBonusCollider->Enable();
m_TankRocketCollider->Enable();
//On construit la map
Tilemap->Build();
Tilemap->CreateRocks();
Tilemap->Enable();
//On cree les tanks
if (m_NbPlayers == ONE_PLAYER)
{
// Input.SetMode(CInput::SinglePlayer);
Tanks[0] = new cTank(TankSprites[0], 0, 0, 0, 1);
Tanks[1] = new cAITank(TankSprites[1], MAP_WIDTH - 1, 0, 1);
Tanks[2] = new cTank(TankSprites[2], 0, MAP_HEIGHT - 1, 2, 0);
Tanks[3] = new cAITank(TankSprites[3], MAP_WIDTH - 1, MAP_HEIGHT - 1, 3);
}
else
{
// Input.SetMode(CInput::TwoPlayers);
Tanks[0] = new cTank(TankSprites[0], 0, 0, 0, 1);
Tanks[1] = new cAITank(TankSprites[1], MAP_WIDTH - 1, 0, 1);
Tanks[2] = new cAITank(TankSprites[2], 0, MAP_HEIGHT - 1, 2);
Tanks[3] = new cTank(TankSprites[3], MAP_WIDTH - 1, MAP_HEIGHT - 1, 3, 2);
}
//Au debut tous les tanks sont vivants
IsStillAlive[0] = IsStillAlive[1] = IsStillAlive[2] = IsStillAlive[3] = true;
m_WinnerTank = NO_WINNER;
m_GameIsRunning = true;
Timing.Speed(1.0f);
m_StartTime = Timing.GetAbsolute();
m_RemainingTime = 180.0f;
}
void cBoomBastic::OnEndGame()
{
//On affiche le background du menu
m_MenuBackground->Enable();
m_GameBackground->Enable(false);
//On desactive la map
Tilemap->Enable(false);
//On detruit les entites creees
Clean(TANK_ID);
Clean(EXPLOSIVEDEVICE_ID);
Clean(BOMB_ID);
Clean(ROCKET_ID);
Clean(FIRE_ID);
Clean(BONUS_ID);
Clean(ROCK_ID);
Clean(PARTICLE_ID);
//On desactive les colliders
m_TankBonusCollider->Enable(false);
m_TankRocketCollider->Enable(false);
m_GameIsRunning = false;
}
void cBoomBastic::OnAnimate(float ElapsedTime, float AbsoluteTime)
{
//Si le jeu n'est pas en cours, on ne fait rien
if (!m_GameIsRunning)
return;
//Si on a pas determine de vainqueur
if (m_WinnerTank == NO_WINNER)
{
//On calcule le temps restant
m_RemainingTime = 180.0f - (AbsoluteTime - m_StartTime);
//on calcule le nombre de tanks restant en jeu
int i;
int NbTanksAlive = 0;
for (i = 0; i < 4; i++)
{
if (IsStillAlive[i])
NbTanksAlive++;
}
//Si il ne reste plus qu'un tank ou moins...
if (NbTanksAlive <= 1 || m_RemainingTime <= 0.0f)
{
//On pause le jeu
Timing.Speed(0.0f);
//Si il reste un tank...
if (NbTanksAlive == 1)
{
//On cherche le tank qui a gagne
int WinnerTankID = 0;
for (i = 0; i < 4; i++)
{
if (IsStillAlive[i])
WinnerTankID = i;
}
//On augmente le score de ce tank
m_Score[WinnerTankID]++;
m_WinnerTank = WinnerTankID;
}
//S'il ne reste plus de tank, c'est un match nul
else if (NbTanksAlive == 0)
m_WinnerTank = DRAW;
//Sinon, tout le temps est ecoule
else
m_WinnerTank = TIME_OUT;
}
}
}
void cBoomBastic::OnRenderText(float ElapsedTime, float AbsoluteTime)
{
//Si le jeu n'est pas en cours, on ne fait rien
if (!m_GameIsRunning)
return;
#ifdef WIN32
#define snprintf _snprintf
#endif
//On affiche le temps restant, s'il en reste
if (m_WinnerTank != TIME_OUT)
{
int Min, Sec;
Min = ((int)m_RemainingTime) / 60;
Sec = ((int)m_RemainingTime) % 60;
char strRemainingTime[5];
if (Sec < 10)
snprintf(strRemainingTime, 5, TEXT("%d:0%d"), Min, Sec);
else
snprintf(strRemainingTime, 5, TEXT("%d:%d"), Min, Sec);
MenuFont->DrawTextScaled(0.0f, 1.0f, 0.1f, 0.1f, 0xFFFFFFFF, strRemainingTime, CFont::Centered_X);
}
//On affiche le nombre de rockets et le score de chacun des tanks
int i;
char String[5];
for (i = 0; i < 4; i++)
{
if (IsStillAlive[i])
{
snprintf(String, 5, TEXT("%d"), Tanks[i]->NbRockets);
if (Tanks[i]->NbRockets < 10)
SystemFont->DrawTextScaled(-0.96f, 0.53f - i * 0.44f, 0.05f, 0.05f, 0xFFFFFFFF, String);
else
SystemFont->DrawTextScaled(-0.98f, 0.53f - i * 0.44f, 0.05f, 0.05f, 0xFFFFFFFF, String);
}
else
SystemFont->DrawTextScaled(-0.96f, 0.53f - i * 0.44f, 0.05f, 0.05f, 0xFFFFFFFF, "X");
snprintf(String, 5, TEXT("%d"), m_Score[i]);
if (m_Score[i] < 10)
SystemFont->DrawTextScaled(0.93f, 0.53f - i * 0.44f, 0.05f, 0.05f, 0xFFFFFFFF, String);
else
SystemFont->DrawTextScaled(0.91f, 0.53f - i * 0.44f, 0.05f, 0.05f, 0xFFFFFFFF, String);
}
//Si le jeu vient de se terminer, on affiche le nom du vainqueur, DRAW ou TIME OUT
// but only if there is no menu on top of it
if ( GameMode )
{
if (m_WinnerTank != NO_WINNER)
{
if (m_WinnerTank == DRAW)
MenuFont->DrawTextScaled(0.0f, 0.0f, 0.20f, 0.20f, 0xFFF89B00, "DRAW", CFont::Centered_X | CFont::Centered_Y);
else if (m_WinnerTank == TIME_OUT)
MenuFont->DrawTextScaled(0.0f, 0.0f, 0.20f, 0.20f, 0xFFF89B00, "TIME OUT", CFont::Centered_X | CFont::Centered_Y);
else
{
char strWinnerIs[20];
snprintf(strWinnerIs, 20, TEXT("Player %d wins"), m_WinnerTank + 1);
MenuFont->DrawTextScaled(0.0f, 0.0f, 0.20f, 0.20f, 0xFFF89B00, strWinnerIs, CFont::Centered_X | CFont::Centered_Y);
}
}
} ;
}