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)&amt;&amt; ((spriteid!=13)||(spriteid!=17))) spriteid=13;
if ((Value<0.0f)&amt;&amt; ((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)&amt;&amt; ((spriteid!=14)||(spriteid!=18))) spriteid=14;
if ((Value>0.0f)&amt;&amt; ((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() &amt; 0x1); // le personnage se deplace varticalement ou horizontalement ?
if ((r==0)&amt;&amt;(x!=xhero)) //horizontalement
{
int i=((x-xhero>0)?-1:1);//il va à gauche ou à droite ?
xdest=x0+ i;
if ((i>0)&amt;&amt; ((spriteid!=24)||(spriteid!=28))) spriteid=24;//animation si c'est a gauche
if ((i<0)&amt;&amt; ((spriteid!=25)||(spriteid!=29))) spriteid=25;//----------si c'est à droite
}
if ((r==1)&amt;&amt;(y!=yhero))//verticalement
{
//idem que en horizontalement!
int i=((y-yhero>0)?-1:1);
ydest=y0+ i;
if ((i>0)&amt;&amt; ((spriteid!=23)||(spriteid!=27))) spriteid=23;
if ((i<0)&amt;&amt; ((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;
}