📄 ski.cpp
字号:
{
iAttribs.SetPosn(TSkiVector(iRestartPosn.iX, iRestartPosn.iY));
iAttribs.SetState(TSkierAttribs::ESkier0);
return ETrue;
}
return EFalse;
}
//
// CSkiCollisionDetection::
//
/**
* Standard Symbian OS 2-phase construction
* @param aMap The map
* @param aSkier The skier
*/
CSkiCollisionDetection* CSkiCollisionDetection::NewL(CSkiMap& aMap, CSkier& aSkier)
{
CSkiCollisionDetection* self = NewLC(aMap, aSkier);
CleanupStack::Pop(self);
return self;
}
/**
* Standard Symbian OS 2-phase construction. The object is left on the cleanup stack
* @param aMap The map
* @param aSkier The skier
*/
CSkiCollisionDetection* CSkiCollisionDetection::NewLC(CSkiMap& aMap, CSkier& aSkier)
{
CSkiCollisionDetection* self = new (ELeave) CSkiCollisionDetection(aMap, aSkier);
CleanupStack::PushL(self);
self->ConstructL();
return self;
}
/**
* Tests for a collision
*/
void CSkiCollisionDetection::UpdateL()
{
TSkierAttribs& attribs = iSkier.Attribs();
// make sure that skier and solid rects are in sync
iSolidRects->SetElevation(attribs.Elevation());
if (!iCollision)
{
CSkiMap* collisionMap = iMap.IntersectsLC(iSkier.GetRect(), *iSolidRects);
if (collisionMap->PrimitiveArray().Count() > 0)
{
iSkier.Reset();
iCollision = ETrue;
TMapPrimitive primitive = collisionMap->PrimitiveArray().At(0);
TPoint newPosn = primitive.Posn();
newPosn.iY+= attribs.SkierSize().iHeight + iSolidRects->SizeL(primitive.Type()).iHeight;
iResponse.Fall(newPosn);
}
CleanupStack::PopAndDestroy(collisionMap);
}
else
{
iCollision = ! (iResponse.SkierStanding());
}
}
/**
* Returns a flag that indicates if there's a collision
* @param a boolean flag that indicates if there's a collision
*/
TBool CSkiCollisionDetection::Collision() const
{
return iCollision;
}
/**
* Standard Symbian OS 2nd phase construction
*/
void CSkiCollisionDetection::ConstructL()
{
iSolidRects = CMapPrimitiveBoundingRects::NewL();
iSolidRects->AddSizeL(TSize(KSkiTreeWidth,KSkiTreeHeight), 38, TMapPrimitive::ETree);
iSolidRects->AddSizeL(TSize(KSkiLogWidth,KSkiLogHeight), 6, TMapPrimitive::ELog);
}
/**
* Standard C++ constructor
* @param aMap The map
* @param aSkier The skier
*/
CSkiCollisionDetection::CSkiCollisionDetection(CSkiMap& aMap, CSkier& aSkier) :
iMap(aMap),
iSkier(aSkier),
iResponse(aSkier.Attribs())
{
}
/**
* Destructor
*/
CSkiCollisionDetection::~CSkiCollisionDetection()
{
delete iSolidRects;
}
//
// CSkiEngine::
//
/**
* C++ constructor
*/
CSkiEngine::CSkiEngine() :
iScrollDriver(iScrAttribs)
{
}
/**
* Standard Symbian OS 2 phase construction
* @param aRect The size of the screen
*/
CSkiEngine* CSkiEngine::NewL(TRect aRect)
{
CSkiEngine* self = NewLC(aRect);
CleanupStack::Pop(self);
return self;
}
/**
* Standard Symbian OS 2 phase construction. The object is left on the cleanup stack
* @param aRect The size of the screen
*/
CSkiEngine* CSkiEngine::NewLC(TRect aRect)
{
CSkiEngine* self = new (ELeave) CSkiEngine();
CleanupStack::PushL(self);
self->ConstructL(aRect);
return self;
}
/**
* destructor
*/
CSkiEngine::~CSkiEngine()
{
delete iColDetect;
delete iSkier;
delete iMap;
delete iMapGallery;
}
/**
* Standard Symbian OS 2nd phase constructor
* @param aRect The size of the screen
*/
void CSkiEngine::ConstructL(TRect aRect)
{
LoadMapL();
LoadSkierL();
LoadMapGalleryL();
iColDetect = CSkiCollisionDetection::NewL(*iMap, *iSkier);
iScrAttribs.Rect() = aRect;
iScrollDriver.SetLimits(iMap->MapLimits());
iScrollDriver.SetScrollBox(TSize(KSkiScrollBoxWidth, KSkiScrollBoxHeight));
iScrollDriver.SetOffset(TPoint(KSkiScrollBoxXPos, KSkiScrollBoxYPos));
}
/**
* Loads the skier
*/
void CSkiEngine::LoadSkierL()
{
iSkier = CSkier::NewL();
SkiBitmapLoader::AddSkierSpritesToGalleryL(iSkier->Gallery());
//
// initialise the skier with some sensible values
//
TSkierAttribs& attribs = iSkier->Attribs();
attribs.SetPosn(TSkiVector(80.0f, 100.0f));
attribs.SetGravity(1);
attribs.SetState(TSkierAttribs::ESkier0);
attribs.SetJumpForce(6);
attribs.SetFallTickCount(30);
attribs.SetSkierSize(TSize(15,15));
iSkier->SetMaxVel(8.0f);
iSkier->SetDefJumpForce(6);
iSkier->SetCoeffOfRestitution(0.7f);
}
/**
* Loads the map
*/
void CSkiEngine::LoadMapL()
{
iMap = CSkiMap::NewL();
//Objects of the same type are added in order of y position.
//This is because the y position specifies the draw order of objects of the same type
//
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(90, 550));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(110, 50));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(90, 150));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(20, 50));
LoadMapElementL(TMapPrimitive::EBump, TPoint(110, 270));
LoadMapElementL(TMapPrimitive::ETree, TPoint(10, 200));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(90, 350));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(20, 450));
LoadMapElementL(TMapPrimitive::ETree, TPoint(30, 210));
LoadMapElementL(TMapPrimitive::ELog, TPoint(50, 510));
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 300));
LoadMapElementL(TMapPrimitive::EBump, TPoint(150, 50));
LoadMapElementL(TMapPrimitive::EBump, TPoint(50, 450));
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 490));
LoadMapElementL(TMapPrimitive::EBump, TPoint(10, 50));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 90));
LoadMapElementL(TMapPrimitive::EBump, TPoint(0, 550));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 530));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 480));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 330));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 280));
LoadMapElementL(TMapPrimitive::ETree, TPoint(200, 350));
LoadMapElementL(TMapPrimitive::ETree, TPoint(180, 380));
LoadMapElementL(TMapPrimitive::ETree, TPoint(120, 480));
LoadMapElementL(TMapPrimitive::ETree, TPoint(170, 550));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 580));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 630));
LoadMapElementL(TMapPrimitive::ETree, TPoint(40, 750));
LoadMapElementL(TMapPrimitive::ETree, TPoint(80, 770));
LoadMapElementL(TMapPrimitive::ETree, TPoint(60, 850));
LoadMapElementL(TMapPrimitive::ETree, TPoint(20, 890));
LoadMapElementL(TMapPrimitive::ETree, TPoint(70, 880));
LoadMapElementL(TMapPrimitive::ETree, TPoint(50, 930));
LoadMapElementL(TMapPrimitive::ETree, TPoint(80, 1000));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 1000));
LoadMapElementL(TMapPrimitive::ETree, TPoint(20, 1100));
LoadMapElementL(TMapPrimitive::ETree, TPoint(80, 1200));
LoadMapElementL(TMapPrimitive::ETree, TPoint(120, 1230));
LoadMapElementL(TMapPrimitive::ETree, TPoint(70, 1150));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 1150));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 1030));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 280));
LoadMapElementL(TMapPrimitive::ETree, TPoint(200, 350));
LoadMapElementL(TMapPrimitive::ETree, TPoint(180, 380));
LoadMapElementL(TMapPrimitive::ETree, TPoint(120, 480));
LoadMapElementL(TMapPrimitive::ETree, TPoint(170, 550));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 580));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 630));
LoadMapElementL(TMapPrimitive::ETree, TPoint(60, 1350));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 1420));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 1480));
LoadMapElementL(TMapPrimitive::ETree, TPoint(80, 1520));
LoadMapElementL(TMapPrimitive::ETree, TPoint(60, 1570));
LoadMapElementL(TMapPrimitive::ETree, TPoint(180, 1650));
LoadMapElementL(TMapPrimitive::ETree, TPoint(80, 1700));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 1980));
LoadMapElementL(TMapPrimitive::ETree, TPoint(40, 1950));
LoadMapElementL(TMapPrimitive::ETree, TPoint(70, 2080));
LoadMapElementL(TMapPrimitive::ETree, TPoint(60, 2180));
LoadMapElementL(TMapPrimitive::ETree, TPoint(40, 2250));
LoadMapElementL(TMapPrimitive::ETree, TPoint(10, 2300));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 2330));
LoadMapElementL(TMapPrimitive::ETree, TPoint(150, 1780));
LoadMapElementL(TMapPrimitive::ETree, TPoint(200, 1850));
LoadMapElementL(TMapPrimitive::ETree, TPoint(180, 1980));
LoadMapElementL(TMapPrimitive::ETree, TPoint(160, 2080));
LoadMapElementL(TMapPrimitive::ETree, TPoint(140, 2150));
LoadMapElementL(TMapPrimitive::ETree, TPoint(120, 2280));
LoadMapElementL(TMapPrimitive::ETree, TPoint(100, 2330));
// bumps
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 580));
LoadMapElementL(TMapPrimitive::EBump, TPoint(150, 650));
LoadMapElementL(TMapPrimitive::EBump, TPoint(50, 750));
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 690));
LoadMapElementL(TMapPrimitive::EBump, TPoint(10, 850));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 890));
LoadMapElementL(TMapPrimitive::EBump, TPoint(0, 950));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 930));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 1080));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 1130));
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 1580));
LoadMapElementL(TMapPrimitive::EBump, TPoint(150, 1650));
LoadMapElementL(TMapPrimitive::EBump, TPoint(50, 1750));
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 1690));
LoadMapElementL(TMapPrimitive::EBump, TPoint(10, 1850));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 1490));
LoadMapElementL(TMapPrimitive::EBump, TPoint(0, 1950));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 1330));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 1980));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 1330));
LoadMapElementL(TMapPrimitive::EBump, TPoint(90, 2080));
LoadMapElementL(TMapPrimitive::EBump, TPoint(150, 2050));
LoadMapElementL(TMapPrimitive::EBump, TPoint(150, 2150));
LoadMapElementL(TMapPrimitive::EBump, TPoint(190, 2290));
LoadMapElementL(TMapPrimitive::EBump, TPoint(110, 2250));
LoadMapElementL(TMapPrimitive::EBump, TPoint(130, 2390));
LoadMapElementL(TMapPrimitive::EBump, TPoint(120, 2550));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 2630));
LoadMapElementL(TMapPrimitive::EBump, TPoint(30, 2480));
LoadMapElementL(TMapPrimitive::EBump, TPoint(180, 2130));
// logs
LoadMapElementL(TMapPrimitive::ELog, TPoint(220, 1110));
LoadMapElementL(TMapPrimitive::ELog, TPoint(180, 2210));
//flags
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(50, 700));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(150, 800));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(200, 850));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(110, 900));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(200, 1250));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(90, 1290));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(170, 1350));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(50, 1600));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(10, 1700));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(100, 1790));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(90, 1850));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(170, 2120));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(230, 2170));
LoadMapElementL(TMapPrimitive::ELeftFlag, TPoint(110, 2450));
LoadMapElementL(TMapPrimitive::ERightFlag, TPoint(20, 2450));
// set map limits
iMap->SetMapLimits(TSize(250, 2500));
}
/**
* Adds a map element in order to the map
* @param aType the type of map element
* @param aPosn the position of the element being added
*/
void CSkiEngine::LoadMapElementL(TMapPrimitive::TMapObjectType aType, TPoint aPosn)
{
//
// HAVE TO MAKE SURE THAT THESE ARE ADDED IN Y-ORDER, OR ELSE
// IT MESSES UP THE DRAW ORDER!
//
TKeyArrayFix key(_FOFF(TMapPrimitive, Posn().iY), ECmpTInt);
// allow duplicates so that more than one object can have the same y coordinate
iMap->PrimitiveArray().InsertIsqAllowDuplicatesL(TMapPrimitive(aPosn, aType), key);
}
/**
* Loads the galery of map elements
*/
void CSkiEngine::LoadMapGalleryL()
{
iMapGallery = CMapGallery::NewL();
SkiBitmapLoader::AddMapSpritesToGalleryL(*iMapGallery);
}
/**
* Performs collision detection, scrolling and updates the skier's attributes
*/
void CSkiEngine::UpdateEngineL()
{
TBool collision = iColDetect->Collision();
if (!collision)
{
ProcessUserInput();
}
iColDetect->UpdateL();
KeepSkierWithinMapLimits();
//
// drive scrolling here
//
// scrolldriver updates screen attributes for us
TSkierAttribs& attribs = iSkier->Attribs();
// get skier position as a TPoint
TSkiVector posVect = attribs.Posn();
TPoint skierPosn(static_cast<TInt>(posVect.iX), static_cast<TInt>(posVect.iY));
iScrollDriver.Move(skierPosn);
//
// update skier attribs here
//
if (!collision)
{
iSkier->Update(); // TODO: because skier state gets updated by collision detection (TSkierCollisionResponse). design flaw
}
}
/**
* Updates the skier's attributes according to the state of the key handler
*/
void CSkiEngine::ProcessUserInput()
{
TSkierAttribs& attribs = iSkier->Attribs();
//
// process user input here
//
TInt state = iKeyHandler.State();
if (state & TKeyHandler::ELeft)
{
attribs.RotateClockwise();
}
if (state & TKeyHandler::ERight)
{
attribs.RotateAntiClockwise();
}
TBool jump = state & TKeyHandler::EFire;
if (!iSkier->Jumping())
{
iSkier->SetJumping(jump);
}
}
/**
* Keeps the skier in the map
*/
void CSkiEngine::KeepSkierWithinMapLimits()
{
TSkierAttribs& attribs = iSkier->Attribs();
// IF THE SKIER GOES OUTSIDE OF THE MAP HAVE IT CYCLE
// THROUGH TO THE OTHER SIDE
//
TRect mapRect(iMap->MapLimits());
// get skier position as a TPoint
TSkiVector posVect = attribs.Posn();
TPoint skierPosn(static_cast<TInt>(posVect.iX), static_cast<TInt>(posVect.iY));
if (!mapRect.Contains(skierPosn))
{
if (skierPosn.iX < mapRect.iTl.iX || skierPosn.iX > mapRect.iBr.iX)
{
TSkiVector vel = attribs.Vel();
vel.iX = -vel.iX;
attribs.SetVel(vel);
}
if (skierPosn.iY < mapRect.iTl.iY)
{
skierPosn.iY = mapRect.iBr.iY - 1;
}
else if (skierPosn.iY > mapRect.iBr.iY)
{
skierPosn.iY = mapRect.iTl.iY + 1;
iScrAttribs.SetOffset(TPoint(0,0));
}
attribs.SetPosn(TSkiVector(skierPosn.iX, skierPosn.iY));
}
}
/**
* Map accessor
* @return the map
*/
CSkiMap& CSkiEngine::Map()
{
return *iMap;
}
/**
* Map accessor
* @return the map
*/
const CSkiMap& CSkiEngine::Map() const
{
return *iMap;
}
/**
* skier accessor
* @return the skier
*/
CSkier& CSkiEngine::Skier()
{
return *iSkier;
}
/**
* skier accessor
* @return the map gallery
*/
const CSkier& CSkiEngine::Skier() const
{
return *iSkier;
}
/**
* Map gallery accessor
* @return the map gallery
*/
CMapGallery& CSkiEngine::MapGallery()
{
return *iMapGallery;
}
/**
* Map gallery accessor
* @return the map gallery
*/
const CMapGallery& CSkiEngine::MapGallery() const
{
return *iMapGallery;
}
/**
* Screen attributes acessor
* @return the screen attributes
*/
TSkiScreenAttribs& CSkiEngine::ScreenAttribs()
{
return iScrAttribs;
}
/**
* Screen attributes acessor
* @return the screen attributes
*/
const TSkiScreenAttribs& CSkiEngine::ScreenAttribs() const
{
return iScrAttribs;
}
/**
* Key handler accessor
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -