Platform game written for the GHI/OutrageousCircuits RETRO game device. Navigate the caves collecting all the pickups and avoiding the creatures and haunted mine carts that patrol the caves. Oh and remember to watch out for the poisonous plants... This game demonstrates the ability to have multiple animated sprites where the sprites can overlap the background environment. See how the player moves past the fence and climbs the wall in the 3rd screen.

Dependencies:   mbed

Player.h

Committer:
taylorza
Date:
2015-02-16
Revision:
16:f9227904afc4
Parent:
11:9ae9a88a1da8

File content as of revision 16:f9227904afc4:

class Player : public GameObject
{
public:
    enum State { Stopped, Walking, Jumping, Falling, OnLadder, Dying };
    
    Player() : 
        _state(Stopped),
        _jumpY(0),
        _jumpX(0),
        _introMode(false),
        _forceLeaveLadder(false)
    {
        setCollisionRect(2, 0, 11, 16);
    }

    void alignX()
    {
        Point &position = getPosition();
        if (position.X % 8 != 0)
        {
            int8_t dx = getLastXDirection();
            if (dx < 0) moveLeft();
            else if (dx > 0) moveRight();
        }        
    }
    
    void setIntroMode(bool flag)
    {
        _introMode = flag;
        if (_introMode) 
            setSpriteId(1);
        else
            setSpriteId(0);
    }
    
    virtual void update()
    {   
        static int counter = 0;
        
        counter++;
        if (_introMode)
        {
            static bool shuffleRight = true;
            
            if (shuffleRight)
            {
                if (!moveRight()) shuffleRight = false;
            }
            else
            {
                if (!moveLeft()) shuffleRight = true;
            }
            animate();
        }
        else if (_state == Dying)
        {
            animate();
            if (counter == 4) 
            {
                Game::Instance->die();
                _state = Stopped;
            }
        }
        else
        {
            if (_forceLeaveLadder && !isLadderAbove() && !isOverLadder() && _state != Stopped) _forceLeaveLadder = false; 
            
            if (_state == OnLadder && !isLadderBelow()) _state = Stopped;
            if (_state == OnLadder || (isLadderAbove() && isOpenBelow())) setSpriteId(1);
            else setSpriteId(0);
            
            if (_state != Jumping && _state != Falling)
            {
                if (_state != OnLadder || isLadderAbove())
                {
                    if (GameInput::isLeftPressed()) 
                    {                             
                        if (_state != OnLadder || isLadderLeft())
                        {                
                            _state = moveLeft() ? Walking : Stopped;                     
                            animate();
                        }
                    }
                    else if (GameInput::isRightPressed()) 
                    { 
                        if (_state != OnLadder || isLadderRight())
                        {
                            _state = moveRight() ? Walking : Stopped;                
                            animate(); 
                        }
                    }
                }
                
                if (GameInput::isCirclePressed()) 
                { 
                    if (GameInput::isLeftPressed()) _jumpX = -1;
                    else if (GameInput::isRightPressed()) _jumpX = 1;
                    else _jumpX = 0;
                    
                    if (_state == OnLadder || isLadderAbove())
                    {
                        _forceLeaveLadder = true;
                    }
                    
                    if (_state != OnLadder || _jumpX != 0 || _forceLeaveLadder)
                    {
                        _state = Jumping;
                        PLAY_EFFECT(0, Sound_PlayerJumping);
                        _jumpY = 0;   
                    }            
                }
                
                if (GameInput::isUpPressed())
                {
                    if (_state == OnLadder || isLadderAbove())
                    {
                        if(moveUp())
                        {
                            _state = OnLadder;                              
                            animate();              
                        }
                        else
                        {
                            _state = Stopped;
                        }
                    }
                }
                else if (GameInput::isDownPressed())
                {
                    if (_state == OnLadder || isLadderBelow())
                    {                    
                        if(moveDown())
                        {
                            _state = OnLadder;                        
                            animate();
                        } 
                        else
                        {
                            _state = Stopped;
                        }
                    }
                    else if (isLadderAbove() && isOpenBelow())
                    {
                        _forceLeaveLadder = true;
                    }
                }        
            }
            
            if (_state != Jumping && _state != OnLadder)
            {                 
                if (isLadderAbove() && !_forceLeaveLadder)
                {
                    _state = OnLadder;
                }
                else if (fall())
                {                
                    _state = Falling; 
                    alignX();                            
                }
                else
                {
                    _state = Stopped;                                               
                }                      
            }
            
            if (_state == Jumping)
            {            
                if (isLadderAbove() && !_forceLeaveLadder)
                {
                    _state = Stopped;
                    _jumpY = 0;
                }            
                else if (_jumpY < 10)
                {            
                    if (moveUp())
                        ++_jumpY;
                    else
                        _jumpY = 10;
                }                                    
                else if (!moveDown())
                {                
                    _state = Stopped;
                    _jumpY = 0;
                }
                
                if (_state == Jumping)
                {
                    if (_jumpX < 0) 
                    { 
                        if (!moveLeft()) _jumpX = 0;
                        //moveLeft();
                    }
                    else if (_jumpX > 0) 
                    { 
                        if (!moveRight()) _jumpX = 0;
                        //moveRight();
                    }
                    animate();
                }
            }   
            
            const Block *obj = detectBlock();
            if (obj != NULL && obj->getType() == Block::Pickup)
            {
                if (pickupObject())
                {
                    if (obj->getData() == 1)
                    {
                        Game::Instance->addScore(25);
                        PLAY_EFFECT(0, Sound_NewScreen);
                        Game::Instance->completeScreen();
                    }
                    else
                    {
                        Game::Instance->addScore(10);
                        PLAY_EFFECT(0, Sound_PickupItem); 
                    }
                }
            }
            
            if (detectCollision() != NULL || detectBlock()->getType() == Block::Deadly)
            {
                _state = Dying;
                counter = 0;
                if (Game::Instance->getLives() > 1) PLAY_EFFECT(1, Sound_PlayerDying);
            }
        }
    }
    
    virtual void draw()
    {
        GameObject::draw();                
    }
    
private:
    State   _state;
    int8_t  _jumpY;     
    int8_t  _jumpX;
    bool    _introMode;
    bool    _forceLeaveLadder;
    
};