⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 roidscontainer.cpp

📁 rps game symbian os application development
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/*
* ============================================================================
*  Name     : CRoidsContainer from RoidsContainer.h
*  Part of  : roids
*  Created  : 05/12/2001 by Twm Davies
*  Implementation notes:
*     Initial content was generated by Nokia Series 60 AppWizard.
*  Version  :
*  Copyright: Twm Davies
* ============================================================================
*/

// INCLUDE FILES
#include "RoidsContainer.h"

#include <eiklabel.h>  // for example label control


#include <e32keys.h>
#include <coemain.h>
#include <eikenv.h>
#include <eikdef.h>
#include <roidsS60.rsg>
#include <nebula.mbg>
#include "roids.hrh"
#include "roidscontainer.h"
#include "polygon.h"
#include "casteroidpool.h"

#include <E32MATH.h>
#include "CGfxTimer.h"

const TInt KOneSecondInMicroSeconds = 1000000;
const TInt KFramesPerSecond = KOneSecondInMicroSeconds/35;
const TInt KScoreForAsteroidHit = 100;
const TInt KScoreForBonusLife = 6000;
const TInt KFrameTicksForGracePeriod = 50;
const TInt KFrameTicksTillReincarnation = 50;
const TInt KFragMentAgeIncrement = 10;
const TInt KFragmentAgeEndOfLife = 255;
const TInt KStarBurstRadiusIncrement =5;
const float KStarBurstRadiusMax = 255.0;
const TInt KStarBurstDensity = 1000;
		

_LIT(KRoidsLogoText, "-= R  O  I  D  S =- ");
_LIT(KRoidsAuthorLogo, "by TwmDesign");
_LIT(KLevelText, "Level");
_LIT(KGameOverText, "G A M E  O V E R");

	
void Panic(TInt aPanic)
	{
	User::Panic(_L("Roids App"),aPanic);
	}

// Class CRoidsContainer   


void CRoidsContainer::FocusChanged(TDrawNow aDrawNow)
	{
	SetPaused(!IsFocused());
	if(aDrawNow)
		DrawNow();
	}

void CRoidsContainer::SetPaused(TBool aState)
	{
	if(aState)
		iGfxTimer->Pause();
	else
		iGfxTimer->ReStart();
	}

/*
 * DrawBackgroundStars 
 * Fast pixel plot of starfild
 */
void CRoidsContainer::DrawBackgroundStars(CWsBitmap& aBitmap) const
	{
	TBitmapUtil bUtil(&aBitmap);	
	TDisplayMode display = iEikonEnv->DefaultDisplayMode();

	bUtil.Begin(TPoint(0,0));

	for(TInt i=0; i<EMaxStars; i++)
		{
		TPoint point(iStars[i].iX, iStars[i].iY);
		bUtil.SetPos(point);
			
		TInt gray = i%200 + 55;
		TRgb rgb(gray,gray,gray);
		switch(display)
			{
			case EColor64K: 
				bUtil.SetPixel(rgb._Color64K());
				break;	
			case EColor4K:
				bUtil.SetPixel(rgb._Color4K());
				break;	
		default:
			bUtil.SetPixel(rgb._Color16M());
			}		
		}
	bUtil.End();
	}
	
CWsBitmap* CRoidsContainer::LoadBitmapToFullScreenL(TRect aRect)
	{
	CWsBitmap* bitmap = new(ELeave)CWsBitmap(iCoeEnv->WsSession());
	CleanupStack::PushL(bitmap);
	User::LeaveIfError(bitmap->Create(Rect().Size(), iEikonEnv->DefaultDisplayMode()));


	CFbsBitmapDevice* bitmapDevice=CFbsBitmapDevice::NewL(bitmap);
	CleanupStack::PushL(bitmapDevice);
	
	CFbsBitGc* gc;	
	User::LeaveIfError(bitmapDevice->CreateContext(gc));
	CleanupStack::PushL(gc);

	CWsBitmap* neb =  iEikonEnv->CreateBitmapL(_L("\\resource\\apps\\nebula.mbm"), EMbmNebulaNebula );

	gc->Reset();
	gc->SetBrushColor(KRgbBlack);
	gc->Clear();

	TPoint offset = bitmap->SizeInPixels().AsPoint() - neb->SizeInPixels().AsPoint();
	gc->BitBlt(offset, neb);
	//gc->DrawBitmap(aRect,neb);
	
	delete neb;
	
	CleanupStack::PopAndDestroy(2,	bitmapDevice);
	CleanupStack::Pop(bitmap);	
	
	return bitmap;	
}

void CRoidsContainer::ConstructL(const TRect& aRect)
	{
	CreateWindowL();
	SetBlank();
	SetRect(aRect);

	iBackupBitmap = new(ELeave)CWsBitmap(iCoeEnv->WsSession());
	iBackupBitmap->Create(Rect().Size(), iEikonEnv->DefaultDisplayMode());

	iBitmapDevice=CFbsBitmapDevice::NewL(iBackupBitmap);
	User::LeaveIfError(iBitmapDevice->CreateContext(iBitmapGc));

	// Start the game heartbeat
	iGfxTimer = new(ELeave)CGfxTimer(*this, NULL);
	iGfxTimer->ConstructL();
	iGfxTimer->StartPulse(KFramesPerSecond); 
	
	iAsteroidPool = new(ELeave) CAsteroidPool();
	iCapsulePool = new(ELeave) CCapsulePool();
	iProjectilePool = new(ELeave) CProjectilePool();
	
	ResetGame();
	iInvinsibleTicker = 0;
	iLineWidth =1;

	// Pregenerate background stars
	for(TInt i=0; i< EMaxStars; i++)
		{
		iStars[i].iX = Math::Random()%Size().iWidth;
		iStars[i].iY = Math::Random()%Size().iHeight;
		}

	// Construct lives indicator Shape
	iLivesShape[0] = TPoint(0, -6);
	iLivesShape[1] = TPoint(+3, +6);
	iLivesShape[2] = TPoint(-3, +6);

	iGameState = EIntro;
	ResetRoids(4);

	TRAPD(err, iNebula= LoadBitmapToFullScreenL(aRect));
		
	ActivateL();
	}

CRoidsContainer::~CRoidsContainer()
	{
	delete iAsteroidPool;
	delete iCapsulePool;
	delete iProjectilePool;
	delete iBackupBitmap;
	delete iGfxTimer;
	delete iBitmapDevice;
	delete iBitmapGc;
	delete iNebula;
	}

void CRoidsContainer::SizeChanged()
	{
	}

TInt CRoidsContainer::CountComponentControls() const
	{
	return 0;
	}

CCoeControl* CRoidsContainer::ComponentControl(TInt /*aIndex*/) const
	{
	return NULL;
	}

void CRoidsContainer::Draw(const TRect& aRect) const
	{
	CWindowGc& gc=SystemGc();
	gc.BitBlt(aRect.iTl, iBackupBitmap, aRect);				
	}

void CRoidsContainer::UpdateFromKeyStates()
	{		
	if( (iShip.State()==TShip::EAlive) ||
		(iShip.State()==TShip::EInvinsible))
		{
		if(KeyDown(EKeyRotateLeft))
			iShip.DecAngle();	

		if(KeyDown(EKeyRotateRight))
			iShip.IncAngle();	

		if(KeyDown(EKeyThrust))
			iShip.Accelerate();

		if(KeyDown(EKeyFireGun))
			{
			ClearKeyDown(EKeyFireGun); // We don't want any repeats for fire;
			LaunchProjectile();
			}
		}
	}
							
void  CRoidsContainer::HandleShipHitAsteroid(TAsteroid& /*aAsteroid*/)
	{
	if(iShip.State() == TShip::EExploding)
		return;
	SplitShip();
	iShip.SetState(TShip::EExploding);
	iDeadTicker =0;
	iLives--;
	if(iLives==0)
		{
		iGameState = EGameOver;
		}
	}

void CRoidsContainer::ResetGame()
	{
	iGameState = EPlaying;
	ResetShip();
	iLives=3;
	iLevel=1;
	iScore=0;
	iNextLevelTicker = -1;
	iInvinsibleTicker = 0;

	
	HandleNextLevel(0);
	
	iProjectilePool->Reset();
		
	}

void CRoidsContainer::ResetShip()
	{
	iShip.Construct();
	iShip.SetState(TShip::EInvinsible);
	// Center point
	iShip.SetWorldPoint(TPoint(Size().iWidth/2, Size().iHeight/2));
	iShip.SetSpeedAndDirection(0,0.0);
	}


void CRoidsContainer::DrawExplosionParticle(CGraphicsContext& aGc, const TExplosionFragment& aFragment) const
	{
	const MPolygon& shape = aFragment.DrawableShape();

	TInt gray = 255-aFragment.Age();
	aGc.SetPenColor(TRgb(gray, gray, gray));
	aGc.DrawLine(shape.PolyPoint(0), shape.PolyPoint(1) );
	}

// Translates and draws the shape
void CRoidsContainer::DrawShape(CGraphicsContext& aGc, const MPolygon& aPolygon, TRgb aColor) const
	{
	if(iShowBoundinBox)
		{
		aGc.Reset();	
		aGc.SetPenColor(KRgbGreen);	
		TRect bound;
		aPolygon.GetBoundingRect(bound);
		aGc.DrawRect(bound);
		}
			
	aGc.Reset();
	aGc.SetPenColor(aColor);
	aGc.SetPenSize(TSize(iLineWidth,iLineWidth));

	for(TInt i=0; i<aPolygon.PolyLineCount(); i++)
		{
		TPoint start;
		TPoint end;
		aPolygon.GetPolyLine(i, start, end);
		aGc.DrawLine(start, end);
		}
	}

void CRoidsContainer::DrawLivesAndScoreIndicator(CGraphicsContext& aGc) const
	{
	TPoint center(Size().iWidth-12, Size().iHeight-12);
	TFixedPolygon<3> shapeBuffer;
	for(TInt i=0; i<iLives;i++)
		{
		iLivesShape.Offset(center, shapeBuffer);
		DrawShape(aGc, shapeBuffer, KRgbGreen);
		center+=TPoint(-18,0);
		}
		
	aGc.UseFont(iEikonEnv->NormalFont());

	TBuf<20> text;
	text.Num(iScore);

	aGc.DrawText(text,TPoint(Size().iWidth-iEikonEnv->NormalFont()->TextWidthInPixels(text)-6, Size().iHeight-23) );
	aGc.DiscardFont();
	};

void CRoidsContainer::DrawGameOver(CGraphicsContext& aGc) const
	{
	aGc.UseFont(iEikonEnv->TitleFont());
	
	aGc.DrawText(KGameOverText,
		TPoint(Size().iWidth/2 - (iEikonEnv->TitleFont()->TextWidthInPixels(KGameOverText)/2),
		Size().iHeight/2) );
	aGc.DiscardFont();
	}

void CRoidsContainer::DrawIntro(CGraphicsContext& aGc) const
	{
	aGc.SetPenColor(KRgbGreen);

	aGc.UseFont(iEikonEnv->TitleFont());
	aGc.SetPenColor(KRgbBlack);
	aGc.DrawText(KRoidsLogoText,
	TPoint(Size().iWidth/2 - (iEikonEnv->TitleFont()->TextWidthInPixels(KRoidsLogoText)/2)+2,
	Size().iHeight/2-18) );
			
	aGc.SetPenColor(TRgb(0,150,0) );
	aGc.DrawText(KRoidsLogoText,
	TPoint(Size().iWidth/2 - (iEikonEnv->TitleFont()->TextWidthInPixels(KRoidsLogoText)/2),
	Size().iHeight/2-20) );

	aGc.SetPenColor(KRgbGreen);
	aGc.DrawText(KRoidsAuthorLogo,
		TPoint(Size().iWidth/2 - (iEikonEnv->TitleFont()->TextWidthInPixels(KRoidsAuthorLogo)/2),
		Size().iHeight/2+30) );

	aGc.DiscardFont();
	}

void CRoidsContainer::DrawLevelIndicator(CGraphicsContext& aGc) const
	{
	aGc.UseFont(iEikonEnv->TitleFont());

	TInt green =	(iNextLevelTicker%8)*32 -1;
	aGc.SetPenColor(TRgb(0x0,green,0x0));				

	TBuf<20> text(KLevelText);
	text.AppendNum(iLevel);
		
	aGc.DrawText(text,TPoint(Size().iWidth/2 - (iEikonEnv->TitleFont()->TextWidthInPixels(text)/2), Size().iHeight/2) );
	aGc.DiscardFont();
	}

void CRoidsContainer::DrawAsteroids(CBitmapContext& aGc) const
	{
	TRgb color;

	TAsteroidIterator iterator(iAsteroidPool->Iterator());
	
	TAsteroid* a(iterator.First());
	while(a)
		{
		DrawShape(aGc, a->DrawableShape(), a->Color());		
		a = iterator.Next();
		};
	}


void CRoidsContainer::DrawProjectiles(CBitmapContext& aGc) const
	{
	TProjectileIterator iterator= iProjectilePool->Iterator();
	TProjectile* proj(iterator.First());
	while(proj)
		{
		if(proj->IsActive())
			{
			aGc.Reset();
			aGc.SetPenColor(KRgbYellow);
			aGc.SetBrushStyle(CGraphicsContext::ESolidBrush);
			TPoint pointCenter = proj->WorldPointAsPoint();
			TRect rect(pointCenter-TPoint(1,1), pointCenter+TPoint(1,1));
			aGc.DrawRect(rect);
			}
			proj=iterator.Next();	
		}		

	}

void CRoidsContainer::DrawShip(CBitmapContext& aGc) const
	{
	if(iGameState == EPlaying)
		{
		if( (iShip.State()==TShip::EAlive) ||
			(iShip.State()==TShip::EInvinsible))
			{
			TRgb color(KRgbWhite);
			if(iShip.State()==TShip::EInvinsible)
				{
				TInt gray =	(iInvinsibleTicker%8)*32 -1;
				color = TRgb(gray,gray,gray);
				}
			
			DrawShape(aGc, iShip.DrawableShape(), color);
			}
		}
	}

void CRoidsContainer::DrawFragments(CBitmapContext& aGc) const
	{
		// Draw fragments behind the action.
	for(TInt i=0; i<KMaxExplosionFragments; i++)
		{
		if(iExplosionFragments[i].IsActive())
			DrawExplosionParticle(aGc, iExplosionFragments[i]);
		}
	}

void CRoidsContainer::DrawGame(CBitmapContext& aGc) const
	{
	// Clear offscreen bitmap to Nebula pattern
	// or if that failed to load (due to OMM) then draw some background stars.
	if(iNebula)
		{
		aGc.BitBlt(TPoint(0,0),iNebula, iNebula->SizeInPixels());	
		}
	else
		{
		aGc.SetBrushColor(KRgbBlack);
		aGc.Clear();
		DrawBackgroundStars(*iBackupBitmap);
		}

	// Z order for drawing starting from backmost objects
	if(iDrawStarbust)
		DrawStarBust();

	DrawFragments(aGc);
	DrawProjectiles(aGc);
	DrawAsteroids(aGc);
	DrawLivesAndScoreIndicator(aGc);
		
	if(iGameState == EGameOver)
		DrawGameOver(aGc);
	else
	if(iGameState == EIntro)
		DrawIntro(aGc);

	if(iNextLevelTicker!=-1)		
			DrawLevelIndicator(aGc);
	
	DrawShip(aGc);
	DrawCapsule(aGc);	
	}

void CRoidsContainer::DrawCapsule(CBitmapContext& aGc) const
	{
	TCapsuleIterator iterator(iCapsulePool->Iterator());
	TCapsule* cap(iterator.First());
	while(cap)
		{
		if(cap->IsActive())
			{
			DrawShape(aGc, cap->DrawableShape(), KRgbBlue);	
			}			
		cap = iterator.Next();
		}

	}


/*
 * ClipObject - Apply mobius strip 
 */
void CRoidsContainer::ClipObject(TWorldObject &aObject)
	{
	// Translate to screen point;
	TWorldPoint wp = aObject.WorldPoint();
	
	if(wp.X()<= -1 )
		wp.SetX(Size().iWidth);
	else
	if(wp.X()> Size().iWidth)
		wp.SetX(1);
		
	if(wp.Y()> Size().iHeight)
		wp.SetY(1);
	else
	if(wp.Y()<= -1)
		wp.SetY(Size().iHeight);

	aObject.SetWorldPoint(wp);
	}

/* CalculateProjectileCollisions
 * Returns true if any of the active projectiles have collided with a given asteroid
 */
TBool CRoidsContainer::CalculateProjectileCollisions(TAsteroid& aRoid, const TRect& aBoundingRect)
	{
		
	TProjectileIterator iterator= iProjectilePool->Iterator();
	TProjectile* proj(iterator.First());
	while(proj)
		{
		if(proj->IsActive())
			{
			TPoint point(proj->WorldPointAsPoint());
			TPoint lastPoint(proj->LastPointAsPoint());

			// Do rough calculation first
			if( aBoundingRect.Contains(point) || aBoundingRect.Contains(lastPoint) )
				{
				// If asteroid is small, treat it as a square otherwise point in polygon
				if( (aRoid.MaxRadius()<5) ||
					(aRoid.Intersects(point, lastPoint)))
					{
					proj->SetActive(EFalse);
					iProjectilePool->FreeObject(proj); 
					return ETrue;
					}					
				}
			}
		proj=iterator.Next();
		}
	return EFalse;
	}

void CRoidsContainer::HandleShipHitCapsule(TCapsule& aCapsule)
	{
	iCapsulePool->FreeObject(&aCapsule);
	iScore+=500;	
	}

void CRoidsContainer::CalculateCapsuleCollisions(const TRect& aBoundingRect)
	{
	TCapsuleIterator iterator(iCapsulePool->Iterator());
	TCapsule* cap(iterator.First());
	while(cap)	
		{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -