SubGameSceneShoot.h 6.91 KB
//
//  SubGameSceneTapNCatch.h
//  SteveAndMaggieGame
//
//  Created by Katarzyna Kalinowska-Górska on 07/05/2019.
//

#ifndef SubGameSceneShoot_h
#define SubGameSceneShoot_h

#include "SubGameScene.h"
#include <vector>
#include <map>
#include "TouchableSprite.h"
#include "SoundsRepo.h"
#include "MathUtils.h"

class SubGameSceneShoot : public SubGameScene {
    
public:
    
    struct LevelConfig {
        float levelTime;
        float trolleyTime;
    };
    
    struct SItem {
            int itemId;
            std::vector<std::string> picFilePaths;
            std::string groupPictureNodeName;
        std::string splodgePicFilePath;
                std::string soundRequest;
                std::string soundConf;
                std::string soundNo;
    };
    
    struct GameConfig {
        int lives;
        std::vector<LevelConfig> levelConfigs;
        std::map<int, SItem> shelfItems;
        cocos2d::Rect steveRect;
        cocos2d::Rect maggieRect;
        cocos2d::Rect trolleyRect;
        std::vector<cocos2d::Point> trolleyItemPoints;
    };

    enum ItemState {
        NONE,
        WAITING_TO_BE_LOADED,
        DRAGGING,
        LOADED,
        SHOT,
        SHOT_RELEASED,
        IN_TROLLEY
    };

    struct ShootGameState {
        std::vector<int> itemIdsOrder;
        std::vector<cocos2d::Node*> splashedItems;
        int currentItem;
        bool cartFlippedX;
        float currentTimeSeconds;
        int wrongItemsCount;
        ItemState itemState;
        bool itemFirstShot;
        int currentTutorialItem { 0};
        
        bool isAnimatingCart;
//        bool cartSineMovement {false};
//        float cartBaseY;
//        float cartBaseVelocity;
//        float cartVelocityModifier;
//        float cartSineAmpModifier;
//        float cartSineBreadth;
//        float cartSineShift;
//        cocos2d::Point cartStartPoint;
//        cocos2d::Point cartEndPoint;
    };
    
    static SubGameSceneShoot* create(int pGameId, std::string layoutFilePath, std::function<void(GameConfig&)> gameConfigParser);
    
    virtual void onEnter() override;
    virtual void update(float time) override;
    
protected:
    
    // tutorial
    cocos2d::Sprite* hintFingerSprite {nullptr};
    void tut_showItemDrag();
    void tut_showSlingDrag();
    void tut_showSlingDragAlongX();
    void tut_prepareFingerIfNeeded();
    // completion only for non-looped
    void tut_moveFinger(const cocos2d::Point& startPosition, const cocos2d::Point& endPosition, float moveTime, float pauseTime, bool loop = false, std::function<void()> completion = [](){});
    void tut_moveFingerBackAndForth(const cocos2d::Point& startPosition, const cocos2d::Point& endPosition, float moveTime, float pauseTime);
    void tut_hideFinger(bool remove = true);
    
    void tut_intro_start();
    void tut_intro_stop();
    void tut_intro_shootApple();
    void tut_intro_shootChocolate();
    void tut_intro_shootBanana();
    void tut_intro_shootItem(std::string groupNodeName, std::string singleItemFilePath, float moveAnimTime = 1);
    
    bool tutorialComplete();
    void saveTutorialComplete();
    /////
    
    std::string currentSteveHead;
    
    cocos2d::Node* _cart;
    cocos2d::Node* _cartFoodLayer;
    cocos2d::Node* _shelf;
    cocos2d::Layer* darkLayer;
    
    cocos2d::Label* _timeLabel;
    
    int currentlyDraggedObjectId;
    cocos2d::Sprite* _currentItem;
//    bool itemInSling;
    
    cocos2d::Sprite* _slingGumLeft;
    cocos2d::Sprite* _slingGumRight;
    cocos2d::Sprite* _movingSling;
    cocos2d::Sprite* _slingStick;
    cocos2d::Node* _slingHand;
    cocos2d::Node* _slingSubHand;
    cocos2d::Point _slingLeftAttachmentPoint;
    cocos2d::Point _slingRightAttachmentPoint;
    float _slingLeftStartLength;
    float _slingRightStartLength;
    bool _isDraggingSling;
    
    bool _isSlingReturning;
    
    float _baseSpringOmegaZero;
    float _baseSpringDXForOmegaZero;
    float _springOmegaZero;
    float _springDampCoeff;
    float _slingAmplitude;
    float _totalReturningTime;
    cocos2d::Point _slingDragStartLocation;
    cocos2d::Point _movingSlingOriginalPosition;
    cocos2d::Point _handOriginalPosition;
    cocos2d::Vec2 _slingOriginalDeltaAnchorPoint;
    cocos2d::Point _slingDragTotalDelta;
    cocos2d::Point _oscMidPoint;
    float _slingGumLeftShootRotation;
    float _slingGumRightShootRotation;
    float _slingReturnAnimTotalTime;
    float prevCosVal;
//    bool itemShot;
//    bool itemReachedTarget;
    float slingHeight;
    float itemFlyTime;
    float itemFlyTimeElapsed;
    float itemV;
    float baseItemV;
    float slingAmpForBaseItemV;


    void itemFollowsTheSling();
    void gumsFollowTheSling(bool switchRotation);
    
    int gameId;
    
    GameConfig gameConfig;
    ShootGameState shootGameState;

    void cleanupSplashedItems();
    
    void startTimer();
    void setStartTimeAndLabel();
    void onSecondElapsed(float dt);
    
    virtual bool initWithConfiguration(int pGameId, std::string layoutFilePath, std::function<void(GameConfig&)> gameConfigParse);
    virtual void clearGameState() override;
    
    void maggieOpenBeak();
    void maggieCloseBeak();
    
    void prepareCartPosition();
    void prepareCartPositionOutside();
    void runCartAnimations(bool faster = false);
    void flipCart();
    
    void moveSlingToTheWorld();
    void moveSlingBackToTheHand();
    void placeItemInSling(cocos2d::Sprite* _item);
    void removeItemFromSling();
    void cancelItemDrag();
    
    // scroll the items on the shelf so that the given index is visible (two pages)
    void scrollShelf(cocos2d::Node* pageForNode, std::function<void()> completion = [](){});
    bool checkRectHidesBehindSling(cocos2d::Rect rectWorldCoord);
    SItem currentItem(){ return gameConfig.shelfItems[shootGameState.itemIdsOrder[shootGameState.currentItem]];}
    void nextItem();
    cocos2d::Sprite* splashItem(cocos2d::Node* where, cocos2d::Vec2 pos, float forHowLong = -1, int zOrder = 100);
    void switchSteveHead(std::string headName);
    
    virtual TouchHandlerFunction prepareTouchBeganHandler();
    virtual TouchHandlerFunction prepareTouchMovedHandler();
    virtual TouchHandlerFunction prepareTouchEndedHandler();
    virtual bool touchHandlerForWidget(std::string objectName, cocos2d::ui::Widget::TouchEventType touchEventType) override;

    void tryShoot();
    void shoot();
    void cancelSlingDrag(bool onlyOnStateDragging = true);
    
    void emptyTrolley();
    
    virtual void startGame(bool playIntro = true) override;

    void loseLife();
    virtual void gameLost() override;
    virtual bool onReplayButtonClicked() override;
    virtual bool onFastForwardButtonClicked() override;
//
    virtual void pauseGame() override;
    virtual void resumeGame() override;
    virtual void hideSettingsMenuWithLevelReset() override;
    
    void switchMenuToReplayButton();
    void fadeDarkLayer(bool fadeIn);
    
    void showWellDoneAndReplay();
    void hideWellDoneAndReplay();
};

#endif /* SubGameSceneShoot_h */