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

#include "ToySubGameScene.h"
#include "ToySoundUtils.h"
#include "ToySimpleButton.h"
#include "ToyMathUtils.h"
#include "ToyMiscUtils.h"
#include "ui/CocosGUI.h"
#include "ToyScalingUtils.h"
#include "ToyLevelPickerView.h"
#include <vector>
#include "ToyLevelPickerLayer.h"
#include "cocos2d.h"
#include "ToyTOSAcceptPopupView.h"
#include "ToySoundsRepo.h"

static float SOUND_EFFECTS_VOLUME = 0.75;

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

//    soundEngine = CocosDenshion::SimpleAudioEngine::getInstance();

    this->commonConfig = std::move(commonConfig);
    ToySoundsRepo::preloadAllLoadedSoundEffects();

    return true;
}

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

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

void ToySubGameScene::clearGameState(){
    clearAllItems();
    gameState->playState = ToySubGameScene::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 ToySubGameScene::removeGameState(){
    if(gameState != nullptr){
        clearAllItems();
//        for(auto it = gameState->items.begin(); it != gameState->items.end(); ++it){
//            delete it->second;
//        }
        delete gameState;
        gameState = nullptr;
    }
}

void ToySubGameScene::onEnter()
{
    ToyParentScene::onEnter();
    loadLayout(false);
    addLivesIndicatorView();
#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) {
            ToyParentScene::touchHandlerForWidget("backButton",
                                               cocos2d::ui::Widget::TouchEventType::ENDED);
        }
    };
    _eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
#endif
}

void ToySubGameScene::addLivesIndicatorView(){
    lifeIndicatorView = ToyGameLifeIndicatorView::create("graphics/g_life_indicator_ok.png", "graphics/g_life_indicator_dead.png", commonConfig.lives);
    addChild(lifeIndicatorView);
    auto winSize = cocos2d::Director::getInstance()->getWinSize();
    auto paddingTop = lifeIndicatorView->getPaddingX()/2;
    lifeIndicatorView->setPosition(winSize.width - lifeIndicatorView->getBoundingBox().size.width, winSize.height - lifeIndicatorView->getBoundingBox().size.height - paddingTop);
    lifeIndicatorView->setLocalZOrder(100);
    lifeIndicatorView->setCascadeOpacityEnabled(true);
}

bool ToySubGameScene::generateItemTypeAndId(ItemType& itemType, int& itemId, std::string& itemPicturePath, ItemType preferredType){
    static int staticItemId = 0;
    staticItemId = (staticItemId%(commonConfig.maxItemsAtATime*10))+1;
//    printf("generated item with id: %d\n",staticItemId);
    itemId = staticItemId;

    if(commonConfig.itemPicturePaths.empty()){
        return false;
    }

    int itemNumber = 0;
    if(preferredType == ItemType::NONE){
        itemNumber = ToyMathUtils::getRandomInt(0, (int)commonConfig.itemPicturePaths.size()-1);
    } else {
        itemNumber = ToyMathUtils::getRandomInt(0, (int)((commonConfig.itemPicturePaths.size()-1)*1.5f));
    }
    //there are always 4 types of items
    static int nItemTypes = 4;
    int step = (int)commonConfig.itemPicturePaths.size()/nItemTypes;
    auto type = ItemType::ONE;
    if(itemNumber >= step*nItemTypes){
        type = preferredType;
        itemNumber = step*((int)preferredType)-ToyMathUtils::getRandomInt(1, 3);
    } else {
        for(int i = 1; i <= nItemTypes; ++i){
            if(itemNumber < step*i){
                type = ItemType(i);
                break;
            }
        }
    }
    itemType = type;
    

    itemPicturePath = commonConfig.itemPicturePaths[itemNumber];

    return true;
}

std::string ToySubGameScene::generateItemPicPathForType(ItemType itemType){

    if(commonConfig.itemPicturePaths.empty()){
        return "";
    }

    //there are always 4 types of items
    static int nItemTypes = 4;
    int itemNumber = ToyMathUtils::getRandomInt(0, nItemTypes-1);
    itemNumber = nItemTypes*((int)itemType-1) + itemNumber;

    return commonConfig.itemPicturePaths[itemNumber];
}

bool ToySubGameScene::touchHandlerForWidget(std::string objectName, cocos2d::ui::Widget::TouchEventType touchEventType)
{
    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 ToyParentScene::touchHandlerForWidget(objectName, touchEventType);
}

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

bool ToySubGameScene::onReplayButtonClicked()
{
    resetGame();
    return true;
}

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

bool ToySubGameScene::onFastForwardButtonClicked()
{
    clearAllItems();
    return ToySubGameScene::onReplayButtonClicked();
}

void ToySubGameScene::resetGame(){
    stopAllActions();
    clearGameState();
    lifeIndicatorView->reset();
    startGame(false);
}

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

void ToySubGameScene::gameWon(){
    gameState->playState = PlayState::WON;
//    playSound(gameFinishedSound().filePath);
}

void ToySubGameScene::gameLost(){
    gameState->playState = PlayState::LOST;
//    playSound(gameLostSound().filePath);
}

static int ResumeLayerTag = 123;

void ToySubGameScene::presentGameResumeLayer(){
    if(this->getChildByTag(ResumeLayerTag) == nullptr && !gameState->settingsMenuShown && (gameState->playState == PlayState::PLAYING || gameState->playState == PlayState::PRE_PLAYING || gameState->playState == PlayState::CHANGING_LEVEL)){
        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 = ToySimpleButton::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();
            ToyMiscUtils::hideAndRemoveView(n, true);
        }, std::placeholders::_1, std::placeholders::_2, resumeLayer));
        resumeLayer->setOpacity(0);
        ToyMiscUtils::showView(resumeLayer, true, 220.f);
    }
}