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); 
			} 
		} 
	} ;  
}