www.pudn.com > sxdl.zip > bomber.cpp


// BOMBER par Benamrouche abdel  
//		abdel_production@yahoo.fr  
//		abdel_production@multimania.com 
 
#include "bomber.h" 
 
Game game ; 
 
int Game::Map [ MapSize * MapSize ] ;  
//la carte :	0 = sol,  
//				1 = mur, 
//				2 = mur qui pourront etre detruits, 
//				3 = trou ou se cachent les méchants, 
//				5 = porte de sortie (inactif) 
int Game::InitialMap [ MapSize * MapSize ] =   
{ 
	1,1,3,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, 
	1,0,0,0,0,0,1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,2,2,2,2,0,2,2,2,2,1,2,2,2,0,0,0,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,2,0,0,0,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,2,0,0,0,1,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,2,0,0,2,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,2,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,0,0,1, 
	1,0,0,0,2,0,0,2,2,2,0,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,0,0,0,2,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,0,0,0,2,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,2,2,2,2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,2,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,1,2,2,2,2,0,0,1, 
	1,2,2,0,2,2,2,2,2,2,2,2,2,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,3, 
	1,0,2,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,0,2,2,0,0,0,0,0,0,0,2,2,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,2,0,0,1, 
	1,0,0,0,0,0,0,2,0,0,2,2,2,2,1,0,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,1, 
	1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,2,0,0,0,0,0,0,1,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,2,0,0,2,2,2,2,2,2,2,0,1,0,2,0,0,0,0,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,2,0,0,2,0,0,2,2,0,0,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	3,0,2,2,0,2,2,0,0,0,0,0,0,0,1,0,2,0,0,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,2,0,0,0,0,1, 
	1,2,2,2,2,2,2,2,2,2,2,0,2,2,1,0,2,2,2,2,2,2,2,2,2,2,0,0,0,2,2,2,2,2,2,0,0,0,2,1, 
	1,0,0,0,0,0,0,0,0,2,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,0,0,0,0,2,0,2,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,2,2,2,2,2,0,2,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,0,0,2,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1, 
	1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1 
} ; 
 
Resource Game::Resources [ ] =  
{ 
	{ Mp3Music  ,	Resource::Music   , NULL , true , "onestop.mid" } ,//une au hasard 
	{ RWall     ,   Resource::Texture , NULL , true , "wall.bmp" } ,   
	{ RWalld    ,   Resource::Texture , NULL , true , "walld.bmp" } ,  
	{ REmpty    ,   Resource::Texture , NULL , true , "empty.bmp" } ,  
	{ RWhole    ,   Resource::Texture , NULL , true , "whole.bmp" } ,  
	{ RDoor     ,   Resource::Texture , NULL , true , "door.bmp" } ,  
	{ RHero     ,   Resource::Texture , NULL , true , "benkouin.tga" } ,  
	{ RExplosion,   Resource::Texture , NULL , true , "explosion.PNG" } ,  
	// Doit se terminer avec un zéro 
	{ Null , Resource::Null , NULL , false , NULL } ,   
} ;  
 
CBasicSprite * Game::Sprites  [ 60 ] ;   
 
INT WINAPI WinMain ( HINSTANCE hInst, HINSTANCE, LPSTR, INT ) 
{ 
    return game.FrameworkRun ( hInst ) ; 
} 
 
void Game::OnEndAnimate ( float /* ElapsedTime */ , float /* AbsoluteTime */ )  
{ 
	ChangeSprites = false ;  
}  
 
void Game::OnStartup ( void )  
{ 
	FrameworkName ( TEXT ( "Bomberman" ) ) ;  
	FrameworkMode ( Window ) ;  
	FrameworkWindow ( 640, 480, false ) ; 
	Media.Table ( Resources ) ;  
} 
 
void Game::OnCreateGame ( void )  
{ 
	Timing.Speed ( 1.0f ) ; // game time is real time 
	Music.Play ( ( int ) Mp3Music ) ; //un peu de musique 
	// colors  
	Color White  = D3DCOLOR_ARGB ( 255,255,255,255 ) ;  
	Color Red    = D3DCOLOR_ARGB ( 255,255,20,50 ); 
	// creation des sprites composant le decor 
	Sprites[0]=new CBasicSprite(REmpty,D3DCOLOR_ARGB(255,0,0,0 ),0,0,32,32);//si on met Colors, ca devient hyper moche 
	Sprites[1]=new CBasicSprite(RWall,White ,0,0,32,32); 
	Sprites[2]=new CBasicSprite(RWalld,White ,0,0,32,32); 
	Sprites[3]=new CBasicSprite(RWhole,White ,0,0,32,32); 
	Sprites[4]=new CBasicSprite(RDoor,White ,0,0,32,32); 
	// sprites composant le hero 
	for (int i=0;i<2;i++) 
	{ 
		Sprites[12+4*i]=new CBasicSprite(RHero,White ,64*i,0,32,32); 
		Sprites[13+4*i]=new CBasicSprite(RHero,White ,32+64*i,0,32,32); 
		Sprites[14+4*i]=new CBasicSprite(RHero,White ,64*i,32,32,32); 
		Sprites[15+4*i]=new CBasicSprite(RHero,White ,32+64*i,32,32,32); 
	} ;  
	// sprites composant les vilains 
	for ( int j=0; j<2; j++) 
	{ 
		Sprites[22+4*j]=new CBasicSprite(RHero,Red, 64*j,0,32,32); 
		Sprites[23+4*j]=new CBasicSprite(RHero,Red, 32+64*j,0,32,32); 
		Sprites[24+4*j]=new CBasicSprite(RHero,Red, 64*j,32,32,32); 
		Sprites[25+4*j]=new CBasicSprite(RHero,Red, 32+64*j,32,32,32); 
	} ;  
	// sprites de l'explosion 
	float a = 150.0f ;  
	float r = 255.0f ;  
	float g = 150.0f ;  
	float b = 100.0f ;  
	for( int k=0 ; k < 30 ; k++ ) 
	{ 
		Color FadingColor = D3DCOLOR_ARGB ( ( int ) a , ( int ) r , ( int ) g , ( int ) b ) ; 
		Sprites[30+k]=new CBasicSprite(RExplosion, FadingColor , 0,0,64,64 ) ; 
		a *= 0.95f ;  
		r *= 0.95f ;  
		g *= 0.80f ;  
		b *= 0.70f ;  
	} ;  
 
	Timing.SetTimer ( Start , 0.1f , true ) ; // one shot  
	Timing.SetTimer ( ChangeSprite , 0.4f , false ) ; // pour les deplacemets des personnages 
	Timing.SetTimer ( CreateEnemyTimer , 6.0f , false ) ; // periodiquement créer des enemies  
 
	Hero = NULL ;  
} 
 
void Game::OnTimer ( int TimerId )  
{ 
	switch ( TimerId )  
	{ 
		case Start : //debut de jeu 
			OnNewGame ( ) ;  
			break ;  
 
		case ChangeSprite : //deplacement des personnages 
			ChangeSprites = true ;  
			break ;  
 
		case CreateEnemyTimer : // periodiquement créer des enemies  
			if (map(2,1)==0)   new CBadguy(Sprites[22],2,1); 
			if (map(1,33)==0)  new CBadguy(Sprites[22],1,33); 
			if (map(38,24)==0) new CBadguy(Sprites[22],38,24); 
			break ;  
	} ;  
}  
 
void Game::OnNewGame ( void )  
{ 
	// on est en vue de haut, donc pas besoin d'effet de poids !!  
	World.GravitationField =Vector3 ( 0.0f , 0.0f , 0.0f ) ;  
	// Clean up  
	Clean ( (int) Heroes ) ;  
	Clean ( (int) Badguys ) ;  
	Clean ( (int) Walls ) ;  
	//création du hero 
	Hero = new CHero( Sprites[12]); 
	// reload the map  
	for ( int x = 0 ; x < MapSize ; x++ )  
		for (int y = 0 ; y < MapSize ; y++ ) 
			Map [ x + y * MapSize ] = InitialMap [ x + y * MapSize ] ;  
	// Creation des murs du labyrinthe  
	for ( x = 0 ; x < MapSize ; x++ )  
	{  
		for ( int y = 0 ; y < MapSize ; y++ ) 
			new CBloc ( Sprites [ Map [ x + y * MapSize ] ] , x, y ) ;  
	} ;  
	// disable mouse and joystick axis input  
	Input.EnableMouseAxis ( false ) ;  
	Input.EnableJoystickAxis ( false ) ;  
 
	ChangeSprites = false ;  
} 
 
void Game::GameWin() 
{ 
	OnEndGame ( ) ;   
	UserInterface.RunMenu ( UserInterface.GameOverWon ) ;  
} 
 
void Game::GameLose() 
{ 
	OnEndGame ( ) ;   
	UserInterface.RunMenu ( UserInterface.GameOverLost ) ;  
} 
 
CBloc::CBloc ( CBasicSprite * _Sprite  ,int _x,int _y )  
{  
	Family = Game::Walls ;  
	x=_x; 
	y=_y; 
	Position.x = x * 32.0f; 
	Position.y = y * 32.0f; 
 
	WillRenderLike ( _Sprite ) ;  
	Scale = Vector3 ( 32.0f , 32.0f , 0.0f ) ;  
	Activate ( ) ;  
} 
 
bool CBloc::OnAnimate ( float ElapsedTime , float AbsoluteTime )   
{ 
	if ( game.map( x, y, -1, 0 ) )  
		HitPoints = -1.0f ; // variable de sxdl: sxdl se chargera de le detruire ! 
	return true; 
} 
 
CHero::CHero ( CBasicSprite * _Sprite )  
{  
	Family = Game::Heroes ;   
	x=2; 
	y=38; 
	Position.x = x*32.0f ;  
	Position.y = y*32.0f ; 
 
	x0=x; 
	y0=y; 
 
	spriteid=12; 
	AnimationIndex = 0 ;  
	Sprite = _Sprite ;  
	WillRenderLike ( Sprite ) ;  
	Scale = Vector3 ( 32.0f , 32.0f , 0.0f ) ;  
	Activate ( ) ; 
	game.Input.Register ( this , CInput::UpDown ) ;  
	game.Input.Register ( this , CInput::LeftRight ) ;  
} 
 
bool CHero::OnAnimate ( float ElapsedTime , float AbsoluteTime )   
{ 
	if (game.map(x0,y0)==-1)  
		game.GameLose() ; 
 
	//le deplacement d'une case du hero est une animation deplacant le hero pixel par pixel 
	// et ceci 32 fois (taille d'une case) : i varie alors de 1 à 32 
	if ( AnimationIndex==33) 
	{    
		// fin de l'animation 
		game.map(x,y,0);   // on efface son ancienne trace sur la carte 
		game.map(x0,y0,2); // on active sa nouvelle  ------------- 
		x=x0 ;  
		y=y0 ;  
		AnimationIndex = 0 ;  
	} 
	else  
	{ 
		++ AnimationIndex ;  
	}  
 
	//mise a jour de la position du hero 
	Position.x= x*32.0f + (x0-x) * AnimationIndex; 
	Position.y= y*32.0f + (y0-y) * AnimationIndex; 
 
	//la camera suit le personnage  
	game.Camera.MoveTo ( Vector3 ( Position.x , Position.y , 0.0f ) ) ;  
 
	if ( game.ChangeSprites ) //il est temps de changer de sprite 
	{ 
		spriteid=((spriteid-12)+4)%8+12;//calcul de l'id de sprite suivante 
		Sprite = Game::Sprites [spriteid]; 
		WillRenderLike ( Sprite ) ; 
	} ; 
	return true ; 
} 
 
// les 3 fonctions suivantes pour la gestion du clavier 
inline void CHero::OnUserInput ( CInput::VirtualKeys VirtualKey , float ElapsedTime , float Value )  
{ 
	game.ChangeSprites = true; 
	if ( VirtualKey == CInput::UpDown )    OnUpDown    ( ElapsedTime , Value ) ;  
	if ( VirtualKey == CInput::LeftRight ) OnLeftRight ( ElapsedTime , Value ) ;  
}  
 
void CHero::OnUpDown    ( float ElapsedTime , float Value )  
{ 
	if ( game.map ( x0, y + ( int ) Value ) == 0 ) y0 = y + ( int ) Value; 
	if ( game.map ( x0, y + ( int ) Value ) == 4 ) game.GameWin(); 
 
	if ((Value>0.0f)&& ((spriteid!=13)||(spriteid!=17))) spriteid=13; 
	if ((Value<0.0f)&& ((spriteid!=12)||(spriteid!=16))) spriteid=12; 
}  
 
void CHero::OnLeftRight ( float ElapsedTime , float Value )  
{ 
	if ( game.map ( x - ( int ) Value, y0 ) == 0 ) x0 = x - ( int ) Value; 
	if ( game.map ( x - ( int ) Value, y0 ) == 4 ) game.GameWin(); 
	if ((Value<0.0f)&& ((spriteid!=14)||(spriteid!=18))) spriteid=14; 
	if ((Value>0.0f)&& ((spriteid!=15)||(spriteid!=19))) spriteid=15; 
}  
 
//c'est pareil que CHero::CHero 
CBadguy::CBadguy ( CBasicSprite * _Sprite,int _x,int _y )  
{  
	Family = Game::Badguys ;  
	x=_x; 
	y=_y; 
	Position.x = x * 32.0f ; 
	Position.y = y * 32.0f ; 
 
	AnimationIndex = 0 ; //pour l animation 
 
	x0=x; 
	y0=y; 
 
	spriteid=22; 
 
	LifeTime =game.Tools.randf ( 40.0f , + 170.0f ) ;  
 
	Sprite = _Sprite ;  
	WillRenderLike ( Sprite ) ;  
	Scale = Vector3 ( 32.0f , 32.0f , 0.0f ) ;  
	Activate ( ) ; 
} 
 
// presque pareil que CHero 
bool CBadguy::OnAnimate ( float ElapsedTime , float AbsoluteTime )   
{ 
	if ( AnimationIndex == 33 ) 
	{ 
		game.map(x,y,0); 
		game.map(x0,y0,1); 
		x = x0 ;  
		y = y0 ;  
		ia() ;  
		AnimationIndex = 0 ;  
	}  
	else 
	{ 
		++ AnimationIndex ;  
	}  
 
	Position.x = x * 32.0f + (x0-x) * AnimationIndex ; 
	Position.y = y * 32.0f + (y0-y) * AnimationIndex ; 
 
	if ( game.ChangeSprites )  
	{ 
		spriteid= ( ( spriteid - 22 ) + 4 ) % 8 + 22; 
		Sprite = Game::Sprites [ spriteid ] ;  
		WillRenderLike ( Sprite ) ; 
	} 
	return true ; 
} 
 
//une ia extrenement simple : les vilains sont attirés stupidement par le hero  
void CBadguy::ia() 
{ 
	int xhero= game.Hero->x ; //coordonnées du hero 
	int yhero= game.Hero->y ;  
	 
	int xdest=x;//valeurs tampon, contiendra les coordonnees de la destinantion du vilain 
	int ydest=y; 
 
	x0=x;  
	y0=y; //destination du vilain 
 
	int r=(int)( rand() & 0x1); // le personnage se deplace varticalement ou horizontalement ? 
	if ((r==0)&&(x!=xhero))     //horizontalement 
	{ 
		int i=((x-xhero>0)?-1:1);//il va à gauche ou à droite ? 
		xdest=x0+ i; 
		if ((i>0)&& ((spriteid!=24)||(spriteid!=28))) spriteid=24;//animation si c'est a gauche 
		if ((i<0)&& ((spriteid!=25)||(spriteid!=29))) spriteid=25;//----------si c'est à droite 
	} 
	if ((r==1)&&(y!=yhero))//verticalement 
	{	 
		//idem que en horizontalement! 
		int i=((y-yhero>0)?-1:1); 
		ydest=y0+ i; 
		if ((i>0)&& ((spriteid!=23)||(spriteid!=27))) spriteid=23; 
		if ((i<0)&& ((spriteid!=22)||(spriteid!=26))) spriteid=22; 
	} 
 
	if (game.map (xdest,ydest) == 0 ) 
	{ 
		//ok le vilain peut y aller 
		x0 = xdest; 
		y0 = ydest; 
	} 
	if ( game.map ( xdest,ydest ) == 2 ) //dans ce cas il explose 
		HitPoints = -1.0f;  
} 
 
void CBadguy::OnDying() 
{ 
	game.map(x,y,0);//on le fait disparaitre de la carte 
 
	// creation d'une explosion 
	for ( int i=0; i < 60 ; i++ ) 
		new CExplosion(game.Sprites[30],x,y); //les vilains ! en mourrant ils explosent ! 
 
	// mise a jour de la carte indiquant les murs qui devront etre detruits 
	game.map ( x-1, y, 2, -1 ); 
	game.map ( x+1, y, 2, -1 ); 
	for ( int  j =-1 ; j < 2 ; j ++ ) 
	{ 
		game.map ( x+j , y-1 , 2, -1 ); 
		game.map ( x+j , y+1 , 2, -1 ); 
	} 
} 
 
CExplosion::CExplosion ( CBasicSprite * Sprite , int x, int y )  
{ 
	Position.x = x * 32.0f ; 
	Position.y = y * 32.0f ; 
	// au bout de 2 a 4 s l'entité meurt 
	LifeTime = 3.0f + game.Tools.randf ( -1.0f , + 1.0f ) ;  
	//la velocité de l'entité est un vecteur aléatoire 
	Velocity = game.Tools.randv ( ) ;  
	Velocity *= 12.0f ;  
	Velocity.z = 0.0f ;  
	WillRenderLike ( Sprite ) ;  
	// taille de l explosion 
	InitialScale = Scale =  
		Vector3 (  
			20.0f + game.Tools.randf ( -10.0f , + 10.0f ) , 
			20.0f + game.Tools.randf ( -10.0f , + 10.0f ) ,  
			0.0f ) ;  
	Activate ( ) ;  
} 
 
bool CExplosion::OnAnimate ( float ElapsedTime , float AbsoluteTime )   
{ 
	// change sprite de l explosion 
	WillRenderLike ( game.Sprites[ ( int ) ( 30 + Alive ( ) * 29 ) ] ) ; 
	Scale = ( 0.2f + Fade ( ) ) * InitialScale ;  
	// Accept default processing 
	return true; 
}