// // 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 #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::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); }