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

📄 ski.cpp

📁 symbian 第二版 一个滑雪游戏的例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
    {
        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 + -