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

📄 ski.cpp

📁 symbian 第二版 一个滑雪游戏的例子
💻 CPP
📖 第 1 页 / 共 5 页
字号:
*/
TSkierAttribs& CSkier::Attribs()
{
    return iAttribs;
}

/**
* Returns a flag to indicate whether or not the skier is currently jumping
* @retval ETrue the skier is jumping
* @retval EFalse the skier is not jumping
*/
TBool CSkier::Jumping() const
{
    return iJumping;
}

/**
* Sets a flag that indicates whether or not the skier is currently jumping
* @param the required jump state for the skier
*/
void CSkier::SetJumping(TBool aJump)
{
    iJumping = aJump;
}

/**
* Accesses the magnitude of the maximum velocity
* @return the maximum velocity
*/
TReal CSkier::MaxVel() const
{
    return iMaxVel;
}

/**
* Sets the magnitude of the maximum velocity
* @param the maximum velocity
*/
void CSkier::SetMaxVel(TReal aVel)
{
    iMaxVel = aVel;
}

/**
* Gets the force that the skier jumps with
* @return the jump force
*/
TInt CSkier::DefJumpForce() const
{
    return iDefJumpForce;
}

/**
* Sets the force that the skier jumps with
* @param the jump force
*/
void CSkier::SetDefJumpForce(TInt aForce)
{
    iDefJumpForce = aForce;
}

/**
* Gets the friction factor that opposes the skier's motion
* @param aCoeff the friction factor
*/
TReal CSkier::CoeffOfRestitution() const
{
    return iCoeff;
}

/**
* Set the friction factor opposing the skier's motion
* @param aCoeff the friction factor
*/
void CSkier::SetCoeffOfRestitution(TReal aCoeff)
{
    iCoeff = aCoeff;
}

/**
* Determine the skier's current acceleration from its direction
* @return the skier's acceleration
*/
TSkiVector CSkier::GetAccelFromState() const
{
    switch (iAttribs.State())
    {
        case TSkierAttribs::ESkier0 :
        case TSkierAttribs::ESkier180 :
            return TSkiVector(0.0f, 0.0f);

        case TSkierAttribs::ESkier30 :
            return TSkiVector(-KSkiingMaxXAccel, KSkiingMinYAccel);

        case TSkierAttribs::ESkier60 :
            return TSkiVector(-KSkiingMaxXAccel, KSkiingMaxYAccel);

        case TSkierAttribs::ESkier90 :
            return TSkiVector(0.0f, 1.0f);

        case TSkierAttribs::ESkier120 :
            return TSkiVector(KSkiingMaxXAccel, KSkiingMaxYAccel);

        case TSkierAttribs::ESkier150 :
            return TSkiVector(KSkiingMaxXAccel, KSkiingMinYAccel);

        default:
            break;
    }

    return TSkiVector();
}

/**
* Make sure that the skier doesn't exceed the maximum velocity
*/
void CSkier::LimitVelocity()
{
    TSkiVector vel = iAttribs.Vel();

    if (vel.Magnitude() > iMaxVel)
    {
        vel.Normalize();
        vel.iX *= iMaxVel;
        vel.iY *= iMaxVel;
    }

    //vel.iX *= iCoeff;
    //vel.iY *= iCoeff;

    // we don't want the skier to go backwards!
    if (vel.iY < 0.0f)
    {
        vel.iY = 0.0f;
    }

    iAttribs.SetVel(vel);
}

/**
* Update the attributes of the skier eg. increase velocity
* by acceleration
*/
void CSkier::Update()
{
    if (iJumping)
    {
        TInt elev = iAttribs.Elevation();
        TInt netForce = iAttribs.JumpForce() - iAttribs.Gravity();
        iAttribs.SetJumpForce(netForce);
        elev += netForce;

        if (elev < 0)
        {
            // reset
            elev = 0;
            iJumping = EFalse;
            iAttribs.SetJumpForce(iDefJumpForce);
        }

        iAttribs.SetElevation(elev);
    }

    // update velocity by acceleration
    iAttribs.SetAccel(GetAccelFromState());
    TSkiVector vel = iAttribs.Vel() + iAttribs.Accel();

    iAttribs.SetVel(vel);
    DoFriction();
    LimitVelocity();

    iAttribs.SetPosn(iAttribs.Posn() + vel);
}

/**
* Limit the motion of the skier with friction
*/
void CSkier::DoFriction()
{
    TSkiVector vel = iAttribs.Vel();
    TSkiVector accel = iAttribs.Accel();
    vel.Normalize();
    accel.Normalize();

    // find proportion of velocity in direction of accel
    TReal dot = vel.DotProduct(accel);

    // find part of velocity not in direction of acceleration
    vel = iAttribs.Vel();
    TSkiVector velProjection(vel.iX * dot, vel.iY * dot);
    TSkiVector diff = vel - velProjection;

    // account for friction force opposing motion of skier not in direction
    // of skies
    diff.iX *= iCoeff;
    diff.iY *= iCoeff;

    vel = velProjection + diff;
    iAttribs.SetVel(vel);
}

/**
* Returns the skier to the default state
*/
void CSkier::Reset()
{
    iJumping = EFalse;
    iAttribs.SetElevation(0);
    iAttribs.SetAccel(TSkiVector(0.0f, 0.0f));
    iAttribs.SetVel(TSkiVector(0.0f, 0.0f));
}

/**
* Get's the skier's bounding rectangle
* @return the bounding rectangle
*/
TRect CSkier::GetRect() const
{
    // get skier position as a TPoint
    TSkiVector posVect = iAttribs.Posn();
    TPoint skierPosn(static_cast<TInt>(posVect.iX), static_cast<TInt>(posVect.iY));

     // from MMapPrimitiveToRectConverter::CreateRect
    TSize skierSize = iAttribs.SkierSize();
    TRect skierRect(skierPosn, skierSize);
    // map position is bottom centre of object
    skierRect.Move(-skierSize.iWidth / 2, -skierSize.iHeight);

    return skierRect;
}
//
// TSkiVector::
//

/**
* Default c++ constructor
*/
TSkiVector::TSkiVector():
 iX(0.0f),
 iY(0.0f)
{
}

/**
* c++ constructor
* @param aX the x direction of the vector
* @param aY the y direction of the vector
*/
TSkiVector::TSkiVector(TReal aX, TReal aY):
 iX(aX),
 iY(aY)
{
}

/**
* operator overload
*/
TSkiVector TSkiVector::operator+(const TSkiVector& aVector) const
{
    return TSkiVector(iX + aVector.iX, iY + aVector.iY);
}


/**
* operator overload
*/
TSkiVector TSkiVector::operator-(const TSkiVector& aVector) const
{
    return TSkiVector(iX - aVector.iX, iY - aVector.iY);
}

/**
* Find the dot product of this vector and another vector
* @param aVector the vector to dot his vector with
* @return the dot product
*/
TReal TSkiVector::DotProduct(const TSkiVector& aVector) const
{
    return (iX * aVector.iX) + (iY * aVector.iY);
}

/**
* Find the magnitude of this vector
* @return the magnitude
*/
TReal TSkiVector::Magnitude() const
{
    TReal magSqrd = (iX * iX) + (iY * iY);
    TReal mag;
    TInt err = Math::Sqrt(mag, magSqrd);

    return err == KErrNone ? mag : 0.0f;
}

/**
* Normalize this vector
*/
TInt TSkiVector::Normalize()
{
    TReal mag = Magnitude();

    if (mag == 0)
    {
        return KErrDivideByZero;
    }

    iX /= mag;
    iY /= mag;

    return KErrNone;
}

//
// TScrollDriver::
//

/**
* C++ constructor
* @param aAttribs screen attributes
* @param aMapLimits the size of the play area
* @param aScrollBox the size of an invisible box in the centre of the screen.  The game scrolls when
* the skier moves outside of this box
*/
TScrollDriver::TScrollDriver(TSkiScreenAttribs& aAttribs, TSize aMapLimits, TSize aScrollBox) :
 iAttribs(aAttribs),
 iLimits(aMapLimits),
 iScrollBox(aScrollBox)
{
}

/**
* C++ constructor
* @param aAttribs screen attributes
*/
TScrollDriver::TScrollDriver(TSkiScreenAttribs& aAttribs) :
 iAttribs(aAttribs)
{
}

/**
* Updates the screen offset with respect to the new position and the scrollbox size
* @param aPosn the new position
*/
void TScrollDriver::Move(TPoint aPosn)
{
    TRect scrRect = iAttribs.Rect();
    TRect scrBox = GetScrollBox();

    // If the map co-ordinate aPosn is outside of the scroll box, update
    // the screen offset.  The screen offset is the top left hand corner of the
    // screen rectangle.  Changing this causes the scrolling.
    //

    if (!scrBox.Contains(aPosn))
    {
        TPoint oldOffset = iAttribs.Offset();
        TPoint newOffset = oldOffset;

        if (aPosn.iX < scrBox.iTl.iX)
        {
            newOffset.iX += aPosn.iX - scrBox.iTl.iX;
        }
        else if (aPosn.iX > scrBox.iBr.iX)
        {
            newOffset.iX += aPosn.iX - scrBox.iBr.iX;
        }

        if (aPosn.iY < scrBox.iTl.iY)
        {
            newOffset.iY += aPosn.iY - scrBox.iTl.iY;
        }
        else if (aPosn.iY > scrBox.iBr.iY)
        {
            newOffset.iY += aPosn.iY - scrBox.iBr.iY;
        }

        iAttribs.SetOffset(newOffset);

        if (KeptOffsetInMap(newOffset, oldOffset))
        {
            iAttribs.SetOffset(newOffset);
        }
        else
        {
            TPoint oldTopRight(scrRect.iBr.iX, scrRect.iTl.iY);
            scrRect = iAttribs.Rect();
            TPoint newTopRight(scrRect.iBr.iX, scrRect.iTl.iY);

            if (KeptOffsetInMap(newTopRight, oldTopRight))
            {
                newTopRight.iX -= scrRect.Size().iWidth;
                iAttribs.SetOffset(newTopRight);
            }
        }
    }
}

/**
 * Returns the scroll box
 * @return the scroll box
 */
TRect TScrollDriver::GetScrollBox() const
{
    // The screen rectangle is in terms of map co-ordinates, not screen
    // co-ordinates.  By shrinking and shifting a copy of the screen
    // rectangle, we can create the scrollbox in terms of map co-ordinates

    TRect scrRect = iAttribs.Rect();
    TSize scrRectSize = scrRect.Size();

    TInt xShrink = (scrRectSize.iWidth - iScrollBox.iWidth) / 2;
    TInt yShrink = (scrRectSize.iHeight - iScrollBox.iHeight) / 2;
    scrRect.Shrink(xShrink, yShrink);
    scrRect.Move(iOffset);  // scrRect is now the scroll box

    return scrRect;
}

/**
* Method to ensure that the offset value (the coordinate of the top left of the screen)
* stays in the map
* @param aOffset the offset
* @param the previous position
* @return a boolean flag to indicate if aOffset has been changed
*/
TBool TScrollDriver::KeptOffsetInMap(TPoint& aOffset, TPoint aPrevious)
{
    TPoint tempOffset = aOffset;
    TRect map(iLimits);
    TBool retVal = !map.Contains(aOffset);

    if (retVal)
    {
        // could be just the x or y coordinate responsible for
        // entering here, so need to try both combinations of
        // possible offset value
        tempOffset.iX = aPrevious.iX;

        if (!map.Contains(tempOffset))
        {
            tempOffset = aOffset;
            tempOffset.iY = aPrevious.iY;

            if (!map.Contains(tempOffset))
                tempOffset = aPrevious;
        }
    }

    aOffset = tempOffset;
    return retVal;
}

/**
* Gets the size of the map limits
* @return the size of the map
*/
TSize TScrollDriver::Limits() const
{
    return iLimits;
}

/**
* Sets the size of the map limits
* @param the new size of the map
*/
void TScrollDriver::SetLimits(TSize aSize)
{
    iLimits = aSize;
}

/**
* Gets the size of the scroll box
* @return the size of the scroll box
*/
TSize TScrollDriver::ScrollBox() const
{
    return iScrollBox;
}

/**
* Sets the size of the scroll box
* @param the size of the scroll box
*/
void TScrollDriver::SetScrollBox(TSize aSize)
{
    iScrollBox = aSize;
}

/**
* Returns the offset of the scrollbox
* @return the offset
*/
TPoint TScrollDriver::Offset() const
{
    return iOffset;
}

/**
* Sets the offset of the scrollbox
* @param the offset
*/
void TScrollDriver::SetOffset(TPoint aPosn)
{
    iOffset = aPosn;
}

//
// TSkierCollisionResponse::
//

/**
* C++ constructor
* @param aAttribs the skier's attributes
*/
TSkierCollisionResponse::TSkierCollisionResponse(TSkierAttribs& aAttribs) :
    iAttribs(aAttribs)
{
}

/**
* Caches the fall position and updates the skier's state
* @param aResartPosn The restart position to be cached
*/
void TSkierCollisionResponse::Fall(const TPoint aRestartPosn)
{
    iRestartPosn = aRestartPosn;
    iFallTick = iAttribs.FallTickCount();
    iAttribs.SetState(TSkierAttribs::ESkierFall);
}

/**
* Decrements a fall counter.  When this expires, the skier is updated so that it stands
* @return a boolean flag to indicate whether or not the skier is standing
*/
TBool TSkierCollisionResponse::SkierStanding()
{
    if (--iFallTick <= 0)

⌨️ 快捷键说明

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