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


#include "Ball.h" 
#include "Game.h" 
 
extern Game game ; 
 
 
CBall::CBall ( CBasicSprite * Sprite, CBall * Parent, int x, int y, int counter, int cx , int cy, float size)  
{  
// Masse pour la gravité	 
	Mass     = 190 ;  
	 
// une balle de plus !!!	 
	++ game.BallCount;  
	 
	_Sprite = Sprite; 
	Family   = ( int ) Game::FBall ; 
	 
// Si on crée une balle	qui provient d'une qui s'est divisé en deux (ou des residus) 
	if (Parent != NULL) 
	{ 
		// elle prend la position de sa mere 
		Position = Parent->Position ;  
		//  La taille est diisé par deux 
		SizeRatio = Parent->SizeRatio /2 ; ; 
		InitialScale = Parent->InitialScale; 
		Scale = SizeRatio * InitialScale ; 
		// on garde la trajectoire de la mere 
		Velocity = Parent->Velocity; 
		// pour l'une des deux on l'envoi dans l'autre sens (une à gauche et une à droite) 
		if (counter == 1) 
			Velocity.x *= -1; 
 
		// Si le compteur est > 2, on crée des residu de balle du à l'explosion/separation d'une d'entre elle 
		if (counter > 2) 
		{ 
			// On ralenti les residus mais il garde la trajectoire d'origine de leur mere 
			Velocity.x *= 0.5f; 
			Velocity.y *= 0.5f; 
			// Pas de gravité (en plus utilisé pour reconaitre un vrai balle d'un residu) 
			Mass = 0; 
			// les residus disparaissent avec le temps 
			LifeTime = 0.4f + game.Tools.randf ( -0.1f , 0.1f ) ; 
			SizeRatio = size; 
			Scale = SizeRatio * InitialScale ; 
		} 
 
		// On met une peu de hasard pour pas avoir des balles toutes identiques 
		Velocity.x += game.Tools.randf ( -15.0f , 15.0f ) ; 
		Velocity.y += game.Tools.randf ( -15.0f , 15.0f ) ; 
	} 
// Si on crée un balle toute neuve	 
	else 
	{ 
		// Position en parametre 
		Position = Vector3 ( ( float )  x , ( float )  y , 0.0f ) ;  
		// taille standard ou celle passé en parametre 
		if (size == 0) 
			SizeRatio = 1.2f ; 
		else 
			SizeRatio = size; 
		InitialScale = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;  
		Scale = SizeRatio * InitialScale ;  
		 
		//trajesctoire au hasard  pour pas avoir des balles toutes identiques 
		float s = game.Tools.randf ( 100.0f , 150.0f ) ;  
		Vector3 V = s * game.Tools.randv ( ) ;  
		V.z = 0.0f ;  
		V.y = 0.0f ;  
		Velocity = V ; 
	} ; 
	 
	NoCollide = false; 
	 
	WillRenderLike ( Sprite ) ;  
	Activate ( ) ;  
} ;	 
	 
 
bool CBall::OnAnimate ( float ElapsedTime , float AbsoluteTime )   
{	 
// Pour revenir à la taille normal aprés une collision 
	//Scale = SizeRatio * InitialScale ;  
	 
	if (Position.x < -310 || Position.x > 310 || Position.y < -310 || Position.y > 310) 
		LifeTime = 0.0f; 
 
	if (LifeTime > 0.0f) 
		Scale = InitialScale * SizeRatio * ( 1.0f - (Age/LifeTime) ); 
 
	return true ;  
}  
 
 
void CBall::OnCollide ( CEntity *  CollidingEntity )  
{ 
// Si la balle touche un mur	 
	if ( CollidingEntity->Family == Game::FWall && NoCollide == false)  
	{ 
		CWall * Wall = ( CWall * ) CollidingEntity ;  
	// rebond		 
		DoBounce(Wall->Normal);  
		NoCollide = true; 
		Time = Age; 
	 
	// Si collision sur le sol, on compresse la balle		 
		if (Wall->Normal.y > 0) 
		{ 
			int Wy = (int) (Wall->Position.y + Wall->Scale.y/2); 
			int By = (int) (Position.y - Scale.y/2); 
			if (By < Wy) 
			{ 
				//Scale.y -= 2*(Wy-By);	 
				Position.y += Wy-By; 
			} 
		} 
 
 
		int Wx; 
		int Bx; 
	// Si collision sur le mur gauche, on compresse la balle 
		if (Wall->Normal.x > 0) 
		{		 
			Wx = (int) (Wall->Position.x + Wall->Scale.x/2); 
			Bx = (int) (Position.x - Scale.x/2); 
			if (Bx < Wx) 
			{ 
				//Scale.x -= 2*(Wx-Bx);	 
				Position.x += Wx-Bx; 
			}		 
		} 
		 
	// Si collision sur le mur droit, on compresse la balle		 
		if (Wall->Normal.x < 0) 
		{		 
			Wx = (int) (Wall->Position.x - Wall->Scale.x/2); 
			Bx = (int) (Position.x + Scale.x/2); 
			if (Wx < Bx) 
			{ 
				//Scale.x -= 2*(Bx-Wx);	 
				Position.x += Bx-Wx; 
			}		 
		} 
	}  
	else if ( NoCollide == true && (Time+0.2f) >= Age) 
		NoCollide = false; 
} 	 
 
 
void CBall::OnDying ( )  
{ 
// Et une balle de moins, une !!	 
	-- game.BallCount; 
	 
	// Si elle est assez "grosse" 
	if (SizeRatio > 0.4f && Mass > 0) 
	{ 
		// on en creé 2 plus petite 
		new CBall( _Sprite, this , 0, 0, 1, 0, 0, 0.0f); 
		new CBall( _Sprite, this , 0, 0, 2, 0, 0, 0.0f); 
		// Creation de residus pour faire beau 
		for(int i=3;i<8;i++) 
			new CBall( _Sprite, this , 0, 0, i, 0, 0, 0.15f); 
	}  
// Si c'est une balle on crée des residus pour faire beau 
	else if (Mass > 0) 
	{ 
		// Creation de residus 
		for(int i=3;i<23;i++) 
			new CBall( _Sprite, this , 0, 0, i, 0, 0, 0.15f); 
	} ; 
 
// Si ya plus de balle on a gagné !		 
	if ( game.BallCount == 0 )  
	{ 
	// C'est bien t'es doué, on te donne une vie comme recompense !! 
		if (game.Player1->HitPoints < 15) 
		{ 
			game.Player1->Life[(int)game.Player1->HitPoints] = new CLife ( game.LifeSprites, -350 , -320+40*((int)game.Player1->HitPoints+1), 32 , 32 ) ; 
			game.Player1->HitPoints++; 
		} 
 
		// Si 2 joueurs 
		if (game.PlayerNb > 1 && game.Player2->HitPoints < 15) 
		{ 
			game.Player2->Life[(int)game.Player2->HitPoints] = new CLife ( game.LifeSprites,  350 , -320+40*((int)game.Player2->HitPoints+1), 32 , 32 ) ; 
			game.Player2->HitPoints++; 
		} 
 
	// Niveau suivant 
		game.OnNewLevel ( ) ;  
	} ;  
	 
// bonus seulement pour les vrais balles	 
	if (Mass > 0) 
	{ 
		if ( (int)game.Tools.randf ( 0.0f , 25.9f )  == 0 ) 
		//if (true) 
		{ 
			int tmp = (int)game.Tools.randf ( 0.0f , 1.9f ); 
			new CBonus ( game.BonusSprites[tmp], (int)Position.x , (int)Position.y , 16 , 16 ,tmp); 
		} 
		 
	} 
} 
 
 
 
/////////////////////////// 
 
 
CBonus::CBonus ( CMovieSprite * Sprite, int x , int y , int cx , int cy , int BonusType)  
{ 
	Family   = ( int ) Game::FBonus ; 
	Mass     = 100.0f + float(BonusType);  
	Position = Vector3 ( ( float )  x , ( float )  y , 0.0f ) ;  
	Scale    = Vector3 ( ( float ) cx , ( float ) cy , 0.0f ) ;  
	HitPoints = 5.0f; 
	InitialScale  = Scale;  
	WillRenderLike ( Sprite , 0.08f) ;  
	//DoWorldMatrix ( ) ;  
	Activate ()  ;  
}  
 
 
bool CBonus::OnAnimate ( float ElapsedTime , float AbsoluteTime )  
{ 
	HitPoints -= ElapsedTime; 
	if (Position.y < -280) 
	{ 
		Position.y = -280; 
		//Mass = 0; 
	} 
	 
	if (HitPoints < 1.0f) 
		Scale = InitialScale * (HitPoints) ; 
	 
	return (true); 
}