ToySubGameSceneTapNCatch.h 6.37 KB
//
//  ToySubGameSceneTapNCatch.h
//  SteveAndMaggieGame
//
//  Created by Katarzyna Kalinowska-Górska on 07/05/2019.
//

#ifndef ToySubGameSceneTapNCatch_h
#define ToySubGameSceneTapNCatch_h

#include "ToySubGameScene.h"
#include <vector>
#include <map>
#include "ToyTouchableSprite.h"
#include "ToySoundsRepo.h"
#include "ToyMathUtils.h"

class ToySubGameSceneTapNCatch : public ToySubGameScene {
    
public:
    
    struct LevelConfig {
        float updateTimeInterval;
        float maxItemsFrac;
        float itemDisappearProbLim;
    };
    
    struct GameConfig {
        int levelsPerLevel;
        std::vector<LevelConfig> levelConfigs;
//        std::vector<cocos2d::Rect> obstacles;
        int staticItems;
        float additionalPaddingW;
        float additionalPaddingH;
        float levelTimeSeconds;
    };
    
    enum class MoveInPhase {
           NONE,
           PHASE_LINEAR,
           PHASE_BIG_CIRCLE,
           PHASE_SMALL_CIRCLE
       };
       
       struct EntryRotationParams {
           float currentMaggieDPhi;
           float maggieMoveInTotalTime;
           float totalDisplacement;
           float linearVelocity;
           float bigCircleRadius;
           cocos2d::Point midPoint;
       };
    
    struct TapNCatchGameState {
        bool isAnimatingSilent;
        int score;
        float updateTimeCount;
        MoveInPhase maggieMoveInPhase;
        EntryRotationParams entryRotationParams;
    };
    
    static ToySubGameSceneTapNCatch* create(int pGameId, std::string layoutFilePath, CommonConfig commonConfig, std::function<void(GameConfig&)> gameConfigParser);
    
    virtual void onEnter() override;
    virtual void update(float time) override;
    
protected:
    
    int gameId;
    
    class TapNCatchItem : public Item {
        public:
            cocos2d::Rect targetBBRect; // with full scale
            bool appearing;
            float disappearingInTime;
            bool disappearing;
            bool touchedAlready;
        virtual ~TapNCatchItem(){
//            Item::~Item();
        }
    };
    
    class FloatingCharacter : public cocos2d::Node {
        public:
            static FloatingCharacter* create(std::string spritePath){
                FloatingCharacter * character = new (std::nothrow) FloatingCharacter();
                if(character && character->init(spritePath))
                {
                    character->autorelease();
                    return character;
                }
                CC_SAFE_DELETE(character);
                return nullptr;
            }
            
            virtual void startCirclingAround(){
                isCirclingAround = true;
                circleMidPoint = getPosition();
                previousDirection = 1;
                circleAround();
            }
            
            virtual void stopCirclingAround(){
                if(isCirclingAround){
                    isCirclingAround = false;
                    stopAllActions(); //TODO by tag
                }
            }
            
            virtual void circleAround(){
                float radiusX = getBoundingBox().size.height/100;
                float radiusY = getBoundingBox().size.height/16;
                float newX = circleMidPoint.x + ToyMathUtils::getRandom(-radiusX, radiusX);
                float newY = circleMidPoint.y + radiusY*previousDirection;
                auto animationTime = 0.6;//*(dX*dX+dY*dY)/(radiusX*radiusX+radiusY*radiusY);
                auto floatAction = cocos2d::Sequence::create(cocos2d::EaseInOut::create(cocos2d::MoveTo::create(animationTime, cocos2d::Vec2(newX, newY)), 2), cocos2d::CallFunc::create([&](){
                    circleAround();
                }), nullptr);
                runAction(floatAction);
                previousDirection *= -1;
            }
            
        protected:
            
            cocos2d::Point circleMidPoint;
            int previousDirection;
            bool isCirclingAround;
            
            virtual bool init(std::string spritePath){
                if(!cocos2d::Node::init()){
                    return false;
                }
                
                setAnchorPoint(cocos2d::Vec2(0.5,0.5));
                auto mainSprite = cocos2d::Sprite::create(spritePath);
                addChild(mainSprite);
                setContentSize(cocos2d::Size(mainSprite->getBoundingBox().size.width,mainSprite->getBoundingBox().size.height));
                mainSprite->setPosition(getContentSize().width/2,getContentSize().height/2);
                mainSprite->setGlobalZOrder(100);
                isCirclingAround = false;
                return true;
            }
        };
    
    GameConfig gameConfig;
    TapNCatchGameState tapNCatchGameState;
    cocos2d::Label* scoreLabel;
    cocos2d::Sprite* scoreStar;
    FloatingCharacter* maggie;
    cocos2d::Sprite* steve;
    cocos2d::Sprite* maggiesRandomItem;
    
    virtual bool initWithConfiguration(int pGameId, std::string layoutFilePath, CommonConfig commonConfig, std::function<void(GameConfig&)> gameConfigParse);
    virtual void setupPauseButton();
    virtual void clearGameState() override;
    virtual void generateStaticItems(int nItems);
    virtual void generateItem(float delay, bool animated = true);
    virtual cocos2d::Rect generateValidRect(float rectW, float rectH);
    virtual void animateCorrectItem(Item& item);
    virtual void animateIncorrectItem(Item& item);
    virtual void flagRemoveAllItemsRapidly();
    virtual void changeType();
    virtual void changeTypeInternal();
    virtual void changeLevel();
    virtual void changeLevelInternal();
    virtual void reenableItemTouch();
    virtual void addScoreLabel();
    virtual void updateScoreLabel();
    
    virtual void startGame(bool playIntro = true) override;
    virtual void finishGame(ToySoundsRepo::SoundInfo sound);
    virtual void showScoreAndReplay();
    virtual void hideScoreAndReplay();
    
    virtual void updatePhaseCheckTime(float dt);
    virtual void updatePhaseRemoveScheduledItems(float dt);
    virtual void updatePhaseScheduleRemoveItems(float dt);
    virtual void updatePhaseGenerateNewItems(float dt);
    virtual void updatePhaseMoveInMaggie(float dt);
    
    void prepareMaggieEntryRotation(float animationTotalTime);
    
    virtual bool onReplayButtonClicked() override;
    
    virtual void pauseGame() override;
    virtual void resumeGame() override;
    
};

#endif /* ToySubGameSceneTapNCatch_h */