AniSubGameScene.cpp 10.5 KB
//
//  AniSubGameScene.cpp
//  SteveAndMaggieGame-mobile
//
//  Created by Katarzyna Kalinowska-Górska on 07/05/2019.
//

#include "AniSubGameScene.h"
#include "AniSoundUtils.h"
#include "AniSimpleButton.h"
#include "AniMathUtils.h"
#include "AniMiscUtils.h"
#include "ui/CocosGUI.h"
#include "AniScalingUtils.h"
#include "AniLevelPickerView.h"
#include <vector>
#include "AniLevelPickerLayer.h"
#include "cocos2d.h"
#include "AniTOSAcceptPopupView.h"
#include "AniSoundsRepo.h"

static float SOUND_EFFECTS_VOLUME = 0.75;

AniSubGameScene* AniSubGameScene::createPlain(std::string layoutFilePath){
    AniSubGameScene * scene = new (std::nothrow) AniSubGameScene();
    if(scene && scene->initWithConfiguration(layoutFilePath))
    {
        scene->autorelease();
        return scene;
    }
    CC_SAFE_DELETE(scene);
    return nullptr;
}

bool AniSubGameScene::initWithConfiguration(std::string layoutFilePath)
{
    if(!AniParentScene::initWithConfigurationFiles(layoutFilePath)){
        return false;
    }
    
    gameState = createGameState();
    
    auto backgroundLayer = cocos2d::LayerColor::create(cocos2d::Color4B(255,255,255,255));
    this->addChild(backgroundLayer);

    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
        addBackButtonListener();
    #endif
    
    return true;
}

AniSubGameScene::~AniSubGameScene(){
    removeGameState();
}

AniSubGameScene::GameState* AniSubGameScene::createGameState(){
    return new AniSubGameScene::GameState();
}

void AniSubGameScene::clearGameState(){
    clearAllItems();
    gameState->playState = AniSubGameScene::PlayState::INIT;
    gameState->currentItemTypeIndex = -1;
    gameState->itemVanishingMode = false;
    gameState->timeCount = 0;
    gameState->lossTimeCount = 0;
    gameState->lossHalfTime = 0;
    gameState->wrongItemCount = 0;
    gameState->currentLevel = -1;
    gameState->itemTypeOrder.clear();
    gameState->itemTypeOrder.push_back(ItemType::ONE);
    gameState->itemTypeOrder.push_back(ItemType::TWO);
    gameState->itemTypeOrder.push_back(ItemType::THREE);
    gameState->itemTypeOrder.push_back(ItemType::FOUR);
//    std::random_shuffle ( gameState->itemTypeOrder.begin(), gameState->itemTypeOrder.end() );
}


void AniSubGameScene::removeGameState(){
    if(gameState != nullptr){
        clearAllItems();
//        for(auto it = gameState->items.begin(); it != gameState->items.end(); ++it){
//            delete it->second;
//        }
        delete gameState;
        gameState = nullptr;
    }
}

void AniSubGameScene::onEnter()
{
    AniParentScene::onEnter();
    loadLayout(false);
    prepareSettingsMenu();
//#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
//    auto keyboardListener = cocos2d::EventListenerKeyboard::create();
//    keyboardListener->onKeyReleased = [&](cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event){
//        if(keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK) {
////            AniParentScene::touchHandlerForWidget("backButton",
////                                               cocos2d::ui::Widget::TouchEventType::ENDED);
//        }
//    };
//    _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
//#endif
}

//void AniSubGameScene::onExit(){
//    AniParentScene::onEnter();
//    
//}

bool AniSubGameScene::touchHandlerForWidget(std::string objectName, cocos2d::ui::Widget::TouchEventType touchEventType)
{
    if(objectName == "pauseButton" && touchEventType == cocos2d::ui::Widget::TouchEventType::ENDED){
//        scheduleOnce([&](float){
        presentGameResumeLayer();
        return true;
//        }, 0.05f, "presentGameResumeLayer");
    } else if(objectName == "prevButton" && touchEventType == cocos2d::ui::Widget::TouchEventType::ENDED){
        if(this->onPrevLevelButtonClicked()){
            return true;
        }
    } else if(objectName == "replayButton" && touchEventType == cocos2d::ui::Widget::TouchEventType::ENDED){

        return this->onReplayButtonClicked();

    }
    else if(objectName == "nextButton" && touchEventType == cocos2d::ui::Widget::TouchEventType::ENDED){

        return this->onNextLevelButtonClicked();
    }
    else if(objectName == "fastForwardButton" && touchEventType == cocos2d::ui::Widget::TouchEventType::ENDED){

        return this->onFastForwardButtonClicked();
    }

    return AniParentScene::touchHandlerForWidget(objectName, touchEventType);
}

bool AniSubGameScene::onPrevLevelButtonClicked()
{
    return true;
}

bool AniSubGameScene::onReplayButtonClicked()
{
//    lifeIndicatorView->reset();
    resetGame();
    return true;
}

bool AniSubGameScene::onNextLevelButtonClicked()
{
    return true;
}

bool AniSubGameScene::onFastForwardButtonClicked()
{
    disableButton("fastForwardButton");
    clearAllItems();
    return AniSubGameScene::onReplayButtonClicked();
}

void AniSubGameScene::resetGame(){
    stopAllActions();
    clearGameState();
    startGame(false);
}

void AniSubGameScene::clearAllItems(){
    std::map<int, Item*>::iterator it = gameState->items.begin();
    while(it != gameState->items.end()){
        delete it->second;
        ++it;
    }
    gameState->items.clear();
}

void AniSubGameScene::gameWon(){
    gameState->playState = PlayState::WON;
}

void AniSubGameScene::gameLost(){
    gameState->playState = PlayState::LOST;
}

static int ResumeLayerTag = 123;

void AniSubGameScene::presentGameResumeLayer(){
    if(this->getChildByTag(ResumeLayerTag) == nullptr && !gameState->settingsMenuShown && (gameState->playState == PlayState::PLAYING || gameState->playState == PlayState::PRE_PLAYING || gameState->playState == PlayState::CHANGING_LEVEL)){
        gameState->resumeLayerShown = true;
        pauseGame();
        //TODO constant for all the layers that have semi-transparent dark bg
        auto resumeLayer = cocos2d::LayerColor::create(cocos2d::Color4B(0,0,0,220),getBoundingBox().size.width, getBoundingBox().size.height);
        resumeLayer->setCascadeOpacityEnabled(true);
        addTouchBlockingLayer(resumeLayer);
        resumeLayer->setLocalZOrder(400);
        resumeLayer->setTag(ResumeLayerTag);
        // add the resume button
        auto buttonResume = AniSimpleButton::create();
        buttonResume->setCascadeOpacityEnabled(true);
        auto buttonTexturePath = "buttons/graphics/dark_green.png";
        buttonResume->loadTextures(buttonTexturePath, buttonTexturePath, buttonTexturePath);
        auto buttonBg = cocos2d::Sprite::create("buttons/graphics/button_repeat.png");
        buttonResume->addChild(buttonBg);
        buttonBg->setPosition(cocos2d::Vec2(buttonResume->getContentSize().width/2,buttonResume->getContentSize().height/2));
        resumeLayer->addChild(buttonResume);
        buttonResume->setPosition(cocos2d::Vec2(resumeLayer->getContentSize().width/2, resumeLayer->getContentSize().height/2));
        buttonResume->setOnTouchEndedCallback(std::bind([&](std::string name, cocos2d::ui::Widget::TouchEventType eventType, cocos2d::Node* n){
            resumeGame();
            AniMiscUtils::hideAndRemoveView(n, true);
            gameState->resumeLayerShown = false;
        }, std::placeholders::_1, std::placeholders::_2, resumeLayer));
        resumeLayer->setOpacity(0);
        AniMiscUtils::showView(resumeLayer, true, 220.f);
    }
}

void AniSubGameScene::prepareSettingsMenu(){
    if(m_settingsMenu == nullptr){
        auto screenSize = cocos2d::Director::getInstance()->getWinSize();
            m_settingsMenu = AniSettingsLayer::create(screenSize.width, screenSize.height, CC_CALLBACK_0(AniSubGameScene::hideSettingsMenuWithLevelReset, this), CC_CALLBACK_0(AniSubGameScene::hideSettingsMenuWithTutorialReset, this));
        //    addChild(settingsMenu);
            addTouchBlockingLayer(m_settingsMenu);
            m_settingsMenu->setLocalZOrder(200);
            moveSettingsButtonToFront(210);
            hideSettingsMenu(false);
            
            m_settingsMenu->setPosition(cocos2d::Vec2(0, 0));
            m_settingsMenu->setCascadeOpacityEnabled(true);

        #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
            auto keyboardListener = cocos2d::EventListenerKeyboard::create();
            keyboardListener->onKeyReleased = std::bind([&](cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event* event, cocos2d::Node* n){
                if(keyCode == cocos2d::EventKeyboard::KeyCode::KEY_BACK){
                    if(AniMiscUtils::isNodeVisible(n)) {
                        if (m_settingsMenu->isShowingParentalGate()) {
                            m_settingsMenu->hideParentalGate();
                        } else {
                            resumeGame();
                            hideSettingsMenu(true);
                        }
                    }
                }
            }, std::placeholders::_1, std::placeholders::_2, m_settingsMenu);
            _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, m_settingsMenu);
        #endif
    }
}

void AniSubGameScene::showSettingsMenu(bool animated){
    gameState->settingsMenuShown = true;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    _keyboardListener->setEnabled(false);
#endif
    m_settingsMenu->prepareForShowing();
    if(animated){
        m_settingsMenu->stopAllActions();
        m_settingsMenu->setVisible(true);
        m_settingsMenu->setOpacity(0);
        m_settingsMenu->runAction(cocos2d::FadeTo::create(AniMiscUtils::StandardAnimationTime, 240)); //TODO magic number
    } else {
        m_settingsMenu->setOpacity(255);
    }
}

void AniSubGameScene::hideSettingsMenu(bool animated){
    gameState->settingsMenuShown = false;
    if(animated){
        m_settingsMenu->stopAllActions();
        m_settingsMenu->runAction(cocos2d::Sequence::create(cocos2d::FadeOut::create(AniMiscUtils::StandardAnimationTime),
                                                          cocos2d::CallFunc::create([&](){
            m_settingsMenu->setVisible(false);
        }), nullptr));
    } else {
        m_settingsMenu->setOpacity(0);
        m_settingsMenu->setVisible(false);
    }
    #if (CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID)
    m_settingsMenu->runAction(cocos2d::CallFunc::create([&](){
            _keyboardListener->setEnabled(true);
        }));
    #endif
}

void AniSubGameScene::reloadLayoutClean()
{
    AniParentScene::reloadLayoutClean();
    m_settingsMenu = nullptr;
    prepareSettingsMenu();
}

void AniSubGameScene::moveSettingsButtonToFront(int localZOrder){
    auto settingsButton = _objects["settingsButton"];
    settingsButton->removeFromParent(); //remove from the object layer, which it is originally in, as specified in the scene_layout file
    addChild(settingsButton);
    settingsButton->setLocalZOrder(localZOrder);
}