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


#include "bounce.h"

Game game ;

INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR, INT )
{
return game.FrameworkRun ( hInst ) ;
}

CBasicSprite * Game::Sprites [ 12 ] ;
CBasicSprite * Game::BrickSprites [ 12 ] ;

Resource Game::Resources [ ] =
{
{ NewLevel , Resource::Sound , NULL , true , "powerup.wav" } ,
{ WallHit , Resource::Sound , NULL , true , "wallhit.wav" } ,
{ BrickHit , Resource::Sound , NULL , true , "brickhit.wav" } ,
{ NewBall , Resource::Sound , NULL , true , "newball.wav" } ,
{ GameOver , Resource::Sound , NULL , true , "gameover.wav" } ,
{ MidiMusic , Resource::Music , NULL , true , "onestop.mid" } ,
{ Flare , Resource::Texture , NULL , true , "ball.png" } ,
{ Brick , Resource::Texture , NULL , true , "brick.png" } ,
{ Anna1 , Resource::Texture , NULL , true , "anna1.jpg" } ,
{ Anna2 , Resource::Texture , NULL , true , "anna2.jpg" } ,
// Must end with a zero id
{ Null , Resource::Null , NULL , false , NULL } ,
} ;

void Game::OnStartup ( void )
{
FrameworkName ( TEXT ( "So Cool Bouncing Balls!" ) ) ;
FrameworkWindow ( 620 , 620 , false ) ;
Media.Table ( Resources ) ;
}

void Game::OnCreateGame ( void )
{
Timing.Speed ( 1.0f ) ; // game time is real time
Music.Play ( ( int ) MidiMusic ) ;
// Create 22 rendering objects
for ( int i = 0 ; i < 11 ; ++ i )
{
// define white blue, red, gold, green, etc colors for sprites, all with about 50> alpha
Color Colors [ 11 ] =
{
0x90FFFFFF ,
0x9000EECC , 0x9022EE00 , 0x90CC0033 , 0x90AA0099 , 0x90EEAA00 ,
0x9022AA77 , 0x90118833 , 0x90AA1111 , 0x90881166 , 0x90AA7711
} ;
// this tells SxDL to be ready to render objects of that kind.
// here SxDL will need to load a texture and create a VB
Sprites [ i ] =
// resource , color, tex offset, tex size
new CBasicSprite ( Flare , Colors [ i ] , 0 , 0 , 64 , 64 ) ;
BrickSprites [ i ] =
// resource , color, tex offset, tex size
new CBasicSprite ( Brick , Colors [ i ] , 0 , 0 , 64 , 64 ) ;
} ;
// create four walls
new CWall ( -310 , 0 , 20 , 620 ) ;
new CWall ( 310 , 0 , 20 , 620 ) ;
new CWall ( 0 , -310 , 620 , 20 ) ;
new CWall ( 0 , 310 , 620 , 20 ) ;
// create one pad
Pad = new CPad ( 0 , - 280 , 200 , 20 ) ;
// Hide the Pad until the game really starts
Pad->WillRenderLike ( NullRenderer ) ;
// create the colliders
Collider_BallsWalls = new CCollider ( Balls , Walls ) ;
Collider_BallsBalls = new CCollider ( Balls , Balls ) ;
Collider_BallsBricks = new CCollider ( Balls , Bricks ) ;
Collider_BallsGround = new CCollider ( Balls , Ground ) ;
Collider_BallsPads = new CCollider ( Balls , Pads ) ;
Collider_BricksGround = new CCollider ( Bricks , Ground ) ;
Collider_BricksPads = new CCollider ( Bricks , Pads ) ;
Collider_WallsPads = new CCollider ( Walls , Pads ) ;
// Start in game mode
GameMode = true ;
// Register the F2 key
Input.Register ( CInput::NewGame ) ;
// Create a font
Font = new CFont ( _T("Impact"), 24 , CFont::Bold ) ;
Backdrop = new CBackground ( Tools.Toss ( ) ? Anna1 : Anna2 , 0xFFffFFff ) ;
Backdrop->Enable ( ) ;
}

void Game::OnNewGame ( void )
{
// Set up scoring
Score = 0 ;
Level = 0 ;
// Delete all stray balls and bricks if any
Clean ( ( int ) Balls ) ;
Clean ( ( int ) Bricks ) ;
BricksInGame = 0 ;
// Move the pad down in the middle, stop it.
Pad->Position = Vector3 ( 0.0f , -260.0f , 0.0f ) ;
Pad->Velocity = Vector3 ( 0.0f , 0.0f , 0.0f ) ;
// assign its renderer to the pad
Pad->WillRenderLike ( BrickSprites [ 0 ] ) ;
// Run the colliders
Collider_BallsWalls ->Enable ( ) ;
Collider_BallsBalls ->Enable ( ) ;
Collider_BallsBricks ->Enable ( ) ;
Collider_BallsGround ->Enable ( ) ;
Collider_BallsPads ->Enable ( ) ;
Collider_BricksGround ->Enable ( ) ;
Collider_BricksPads ->Enable ( ) ;
Collider_WallsPads ->Enable ( ) ;
// restart time
Timing.SetTimer ( StartGame , 1.0f , true ) ; // one shot
// create the first level
OnNewLevel ( ) ;
// drop the bg pic
Backdrop->Enable ( false ) ;
// Run, baby, run
GameMode = true ;
}

void Game::OnEndGame ( void )
{
// stop creating new balls
Timing.KillTimer ( CreateNewBall ) ;
// Disable the collision manager
Collider_BallsWalls ->Enable ( false ) ;
Collider_BallsBalls ->Enable ( false ) ;
Collider_BallsBricks ->Enable ( false ) ;
Collider_BallsGround ->Enable ( false ) ;
Collider_BallsPads ->Enable ( false ) ;
Collider_BricksGround ->Enable ( false ) ;
Collider_BricksPads ->Enable ( false ) ;
Collider_WallsPads ->Enable ( false ) ;
}

void Game::OnNewLevel ( void )
{
Level ++ ;
CreateBricks ( ) ;
Timing.SetTimer ( CreateNewBall , ( float ) Level / 4.0f + 1.75f , false ) ; // periodic
}

inline void Game::CreateBricks ( void )
{
// create rows of 13 bricks each
int Rows = 5 + Level ;
const int Cols = 15 ;
for ( int row = 0 ; row < Rows ; ++ row )
{
const int cx = 40 ;
const int cy = 20 ;
// Game was too hard with the sidemost columns
for ( int col = 1 ; col < Cols - 1 ; ++ col )
{
int x = -300 + col * cx + cx / 2 ;
int y = 100 + row * cy + cy / 2 ;
new CBrick ( row > 5 , BrickSprites [ 1 + row > 5 ] , x , y , cx - 2 , cy - 2 ) ;
}
} ;
BricksInGame = Rows * ( Cols - 2 ) ;
}

inline void Game::CreateBall ( void )
{
int SpriteIndex = ( int ) Tools.randf ( 1.01f , 9.99f ) ;
int x = ( int ) Tools.randf ( -50.0f , 50.0f ) ;
int y = ( int ) Tools.randf ( 50.0f , 250.0f ) ;
CBall * ball = new CBall ( Sprites [ SpriteIndex ] , x , y , 25 , 25 ) ;
float s = Tools.randf ( 180.0f , 220.0f ) ;
Vector3 V = s * Tools.randv ( ) ;
V.z = 0.0f ;
ball->Velocity = V ;
}

void Game::OnTimer ( int TimerId )
{
switch ( TimerId )
{
case StartGame :
Timing.SetTimer ( CreateNewBall , 2.0f , false ) ; // periodic
break ;

case CreateNewBall :
Sound.Play ( NewBall ) ;
CreateBall ( ) ;
break ;
} ;
}

CWall::CWall ( int x , int y , int cx , int cy )
{
Family = ( int ) Game::Walls ;
if ( y < 0 )
Family = ( int ) Game::Ground ;
Mass = 0.0f ;
Position = Vector3 ( ( float ) x , ( float ) y , 0.0f ) ;
Normal = - Position ;
SxDLVec3Normalize ( Normal ) ;
Scale = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;
WillRenderLike ( Game::BrickSprites [ 1 ] ) ;
DoWorldMatrix ( ) ;
Activate ( true , true ) ;
}

void CWall::OnCollide ( CEntity * CollidingEntity )
{
if ( CollidingEntity->Family == Game::Pads )
{
CPad * pad = ( CPad * ) CollidingEntity ;
pad->Velocity = Vector3 ( 0.0f , 0.0f , 0.0f ) ;
pad->Position += 2.0f * Normal ;
} ;
}

CBrick::CBrick ( int Hits , CBasicSprite * Sprite , int x , int y , int cx , int cy )
{
HitPoints = ( float ) Hits ;
Family = ( int ) Game::Bricks ;
Mass = 0.14f ;
Position = Vector3 ( ( float ) x , ( float ) y , 0.0f ) ;
Scale = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;
WillRenderLike ( Sprite ) ;
Activate ( ) ;
}

void CBrick::OnDying ( )
{
game.BrickDying ( ) ;
}

inline void Game::BrickDying ( void )
{
-- BricksInGame ;
Score += Level ;
if ( BricksInGame == 0 )
{
Score += 50 * Level ;
Sound.Play ( NewLevel ) ;
OnNewLevel ( ) ;
} ;
}

inline void Game::OnGameOver ( void )
{
Sound.Play ( GameOver ) ;
OnEndGame ( ) ;
UserInterface.RunMenu ( UserInterface.GameOverLost ) ;
}

void CBrick::OnCollide ( CEntity * CollidingEntity )
{
if ( ( CollidingEntity->Family == Game::Ground ) ||
( CollidingEntity->Family == Game::Pads ) )
{
// Game over !
game.OnGameOver ( ) ;
} ;
}


CPad::CPad ( int x , int y , int cx , int cy )
{
Family = ( int ) Game::Pads ;
Mass = 0.0 ;
Position = Vector3 ( ( float ) x , ( float ) y , 0.0f ) ;
Scale = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;
WillRenderLike ( Game::BrickSprites [ 0 ] ) ;
Activate ( ) ;
game.Input.Register ( this , CInput::UpDown ) ;
game.Input.Register ( this , CInput::LeftRight ) ;
}

inline void CPad::OnUserInput ( CInput::VirtualKeys VirtualKey , float ElapsedTime , float Value )
{
if ( VirtualKey == CInput::UpDown ) OnUpDown ( ElapsedTime , Value ) ;
if ( VirtualKey == CInput::LeftRight ) OnLeftRight ( ElapsedTime , Value ) ;
}

void CPad::OnUpDown ( float ElapsedTime , float Value )
{
Position += Vector3 ( 0.0f , 200.0f * Value * ElapsedTime , 0.0f ) ;
const float MaxY = - 280.0f ;
if ( Position.y < MaxY )
{
Position.y = MaxY ;
return ;
} ;
if ( Position.y > - MaxY )
{ Position.y = - MaxY ;
return ;
} ;
}

void CPad::OnLeftRight ( float ElapsedTime , float Value )
{
Position -= Vector3 ( 1000.0f * Value * ElapsedTime , 0.0f , 0.0f ) ;
}

CBall::CBall ( CBasicSprite * _Sprite , int x , int y , int cx , int cy )
{
Sprite = _Sprite ;
Family = ( int ) Game::Balls ;
Mass = 190.0f ;
Position = Vector3 ( ( float ) x , ( float ) y , 0.0f ) ;
SizeRatio = 1.2f ;
InitialScale = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;
Scale = SizeRatio * InitialScale ;
Velocity = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;
WillRenderLike ( Sprite ) ;
Activate ( ) ;
}

void CBall::OnCollide ( CEntity * CollidingEntity )
{
if ( CollidingEntity->Family == Game::Walls )
{
game.Sound.Play ( Game::WallHit ) ;
CWall * wall = ( CWall * ) CollidingEntity ;
DoBounce ( wall->Normal ) ;
} ;
if ( CollidingEntity->Family == Game::Ground )
{
CWall * wall = ( CWall * ) CollidingEntity ;
SizeRatio -= 0.15f ;
if ( SizeRatio < 0.3f )
LifeTime = 0.1f ;
else
{
Scale = SizeRatio * InitialScale ;
DoBounce ( wall->Normal ) ;
} ;
} ;
if ( CollidingEntity->Family == Game::Balls )
{
CBall * ball = ( CBall * ) CollidingEntity ;
if ( Sprite == ball->Sprite )
{
LifeTime = 0.1f ;
Vector3 V = 500.0f * game.Tools.randv ( ) ;
V.z = 0.0f ;
CBall * ball = new CBall ( Game::Sprites [ 0 ] , 0 , 0 , 5 , 5 ) ;
ball->Velocity = V ;
ball->Position = Position ;
ball->Family = 0 ;
ball->LifeTime = 0.1f ;
} ;
} ;
if ( CollidingEntity->Family == Game::Bricks )
{
game.Sound.Play ( Game::BrickHit ) ;
CBrick * brick = ( CBrick * ) CollidingEntity ;
brick->HitPoints -= 1.0f ;
Vector3 Normal = Position - brick->Position ;
DoBounce ( Normal ) ;
} ;
if ( CollidingEntity->Family == Game::Pads )
{
CPad * pad = ( CPad * ) CollidingEntity ;
Vector3 Normal = Vector3 ( 0.0f , pad->Scale.y , 0.0f ) ;
DoBounce ( Normal ) ;
} ;
}

void Game::OnRenderText ( float ElapsedTime , float AbsoluteTime )
{
D3DCOLOR fontColor = D3DCOLOR_ARGB(200,128,255,200 );
float a = 150.0f + 100.0f * cosf ( AbsoluteTime * 7.0f ) ;
float r = 150.0f + 100.0f * cosf ( AbsoluteTime * 5.0f ) ;
float g = 150.0f + 100.0f * cosf ( AbsoluteTime * 11.0f ) ;
float b = 150.0f + 100.0f * cosf ( AbsoluteTime * 3.0f ) ;
Color FadingColor = D3DCOLOR_ARGB ( ( int ) a , ( int ) r , ( int ) g , ( int ) b ) ;

if ( Level > 0 )
{
TCHAR szMsg[MAX_PATH] ;
_sntprintf( szMsg, MAX_PATH, _T("Level: >d - Score: >d"), Level , Score ) ;
Font->DrawTextScaled ( -0.2f , 0.95f , 0.07f , 0.07f , fontColor, szMsg );
}
else
{
if ( GameMode )
{
Font->DrawTextScaled ( 0.0f , 0.4f , 0.10f , 0.10f , FadingColor, "SxDL ~ Bouncing Balls" , CFont::Centered_X );
Font->DrawTextScaled ( 0.0f , 0.2f , 0.05f , 0.05f , fontColor, "Press F2 to start the game!" , CFont::Centered_X );
} ;
}
}