AniLevelView.cpp 8.04 KB
//
//  AniLevelView.cpp
//  HalloweenSpaceInvaders-mobile
//
//  Created by Katarzyna Kalinowska-Górska on 27/09/2019.
//

#include "AniLevelView.h"
#include <stdio.h>
#include <string>
#include "AniScalingUtils.h"
#include "AniMathUtils.h"
#include "AniMiscUtils.h"

static const float InactivePicScale = 0.8f;
static const int InactivePicOpacity = 100;
static const int FloatActionTag = 10;

AniLevelView* AniLevelView::create(std::string levelImagePath){
    AniLevelView * view = new (std::nothrow) AniLevelView();
    if(view && view->init(levelImagePath))
    {
        view->autorelease();
        return view;
    }
    CC_SAFE_DELETE(view);
    return nullptr;
}

AniLevelView* AniLevelView::create(std::string levelImagePath, std::string levelName){
    AniLevelView * view = new (std::nothrow) AniLevelView();
    if(view && view->init(levelImagePath, levelName))
    {
        view->autorelease();
        return view;
    }
    CC_SAFE_DELETE(view);
    return nullptr;
}

bool AniLevelView::init(std::string levelImagePath){
    if(!cocos2d::Node::init()){
        return false;
    }
    
    _bgNode = cocos2d::Sprite::create("graphics/level_halo.png");
    _pic = cocos2d::Sprite::create(levelImagePath);
    
    addChild(_bgNode);
    addChild(_pic);
    
    setContentSize(_pic->getBoundingBox().size);
    
    auto contentWidth = getContentSize().width;
    auto contentHeight = getContentSize().height;
    _bgNode->setPosition(contentWidth/2, contentHeight/2);
    _pic->setPosition(contentWidth/2, contentHeight/2);

    setAnchorPoint(cocos2d::Vec2(0.5,0.5));

    _isChosen = true;
    setChosen(false, false);
    
    return true;
}

bool AniLevelView::init(std::string levelImagePath, std::string levelName){
    if(!init(levelImagePath)){
        return false;
    }
    
    _label = cocos2d::Label::createWithTTF(levelName, "fonts/ComicSansMSBold.ttf", 100*AniScalingUtils::getScaleForFont()); //magic number
    addChild(_label);
    float padding = 50*AniScalingUtils::scaleAspectFillToDesignIpadProSize(); //TODO magic number
    setContentSize(cocos2d::Size(getContentSize().width, getContentSize().height+padding+_label->getBoundingBox().size.height));
    _pic->setPosition(getContentSize().width/2, getContentSize().height - _pic->getBoundingBox().size.height/2 - padding);
    _bgNode->setPosition(_pic->getPosition());
    _label->setPosition(_pic->getPositionX(), _pic->getBoundingBox().getMinY() - padding - _label->getBoundingBox().size.height/2);
    
//    auto bg = cocos2d::LayerColor::create(cocos2d::Color4B(100,100,255, 255));
//    bg->setContentSize(getContentSize());
//    addChild(bg);
//    bg->_setLocalZOrder(-10);
    
    _isChosen = true;
    setChosen(false, false);
    
    return true;
}

void AniLevelView::setChosen(bool chosen, bool animated){
    static cocos2d::Color3B FontColorChosen = cocos2d::Color3B(255, 255, 255);
    static cocos2d::Color3B FontColorDimmed = cocos2d::Color3B(128, 128, 128);
    static float FontScaleChosen = 1.f;
    static float FontScaleSmaller = 0.9f;
    
    if(chosen != _isChosen){
        _bgNode->stopAllActions();
        auto newBgNodeOpacity = 255.f;
        auto newPicScale = 1.f;
        auto newPicOpacity = 255;
        if(!chosen){
            newBgNodeOpacity = 0;
            newPicScale = InactivePicScale;
            newPicOpacity = InactivePicOpacity;
        }
        
        if(animated){
//            _bgNode->runAction(cocos2d::FadeTo::create(AniMiscUtils::StandardAnimationTime, newBgNodeOpacity));
            _pic->runAction(cocos2d::Spawn::create(cocos2d::ScaleTo::create(AniMiscUtils::StandardAnimationTime, newPicScale),
                                                   cocos2d::FadeTo::create(AniMiscUtils::StandardAnimationTime, newPicOpacity), nullptr));
            _bgNode->runAction(cocos2d::FadeTo::create(AniMiscUtils::StandardAnimationTime, newBgNodeOpacity));
            if(_label != nullptr){
                _label->runAction(cocos2d::TintTo::create(AniMiscUtils::StandardAnimationTime, (chosen? FontColorChosen : FontColorDimmed)));
                _label->runAction(cocos2d::ScaleTo::create(AniMiscUtils::StandardAnimationTime, (chosen? FontScaleChosen : FontScaleSmaller)));
            }
            
        } else {
            _bgNode->setOpacity(newBgNodeOpacity);
            _pic->setScale(newPicScale, newPicScale);
            _pic->setOpacity(newPicOpacity);
            if(_label != nullptr){
                _label->setColor(chosen? FontColorChosen : FontColorDimmed);
                _label->setScale(chosen ? FontScaleChosen : FontScaleSmaller);
            }
        }
        _isChosen = chosen;
    }
}

void AniLevelView::loadPropertiesFromJSON(const rapidjson::Value& jsonValue, AniLayoutViewInterface* scene, const std::string resFolder, const std::string altResFolder)
{
    this->loadCommonPropertiesFromJSON(jsonValue);
    if(jsonValue.HasMember("opacity")){
        auto opacity = jsonValue["opacity"].GetInt();
        _pic->setOpacity(opacity);
    }
}

void AniLevelView::startFloating(){
    _isFloating = true;
    _circleMidPoint = getPosition();
    _floatDirection = 1;
    doFloat(true);
}

void AniLevelView::stopFloating(){
    if(_isFloating){
        _isFloating = false;
        stopActionByTag(FloatActionTag);
    }
}

void AniLevelView::doFloat(bool start){
    float radiusX = getContentSize().height/100;
    float radiusY = getContentSize().height/16;
    float newX = _circleMidPoint.x + AniMathUtils::getRandom(-radiusX, radiusX);
    float newY = _circleMidPoint.y + radiusY*_floatDirection;
    auto animationTime = start ? 0.8 : 1.6f;
    auto floatAction = cocos2d::Sequence::create(cocos2d::EaseInOut::create(cocos2d::MoveTo::create(animationTime, cocos2d::Vec2(newX, newY)), 2), cocos2d::CallFunc::create([&](){
        doFloat();
    }), nullptr);
    floatAction->setTag(FloatActionTag);
    runAction(floatAction);
    _floatDirection *= -1;
}

//void AniLevelView::flash(){
//    auto halfDuration = AniMiscUtils::StandardAnimationTime*2;
//    if(_bgNode != nullptr){
//        auto flashAction = cocos2d::Sequence::create(cocos2d::EaseInOut::create(cocos2d::FadeIn::create(halfDuration),2),
//                                                     cocos2d::EaseInOut::create(cocos2d::FadeOut::create(halfDuration),2),nullptr);
//        _bgNode->runAction(flashAction);
//    }
//    if(_pic != nullptr){
//        auto lastOpacity = _pic->getOpacity();
//        _pic->runAction(cocos2d::Sequence::create(cocos2d::EaseInOut::create(cocos2d::FadeIn::create(halfDuration), 2),
//                                                  cocos2d::EaseInOut::create(cocos2d::FadeTo::create(halfDuration, lastOpacity), 2), nullptr));
//    }
//}

void AniLevelView::startAnimatingLevelPicture(){
    auto jumpAction = cocos2d::RepeatForever::create(cocos2d::Sequence::create(cocos2d::JumpTo::create(0.4f, _pic->getPosition(), _pic->getBoundingBox().size.height/10, 1), cocos2d::DelayTime::create(0.f), nullptr));
    _pic->runAction(jumpAction);
    _bgNode->runAction(jumpAction->clone());
}

void AniLevelView::changePicture(std::string newPicturePath){
    auto oldOpacity = _pic->getOpacity();
    _pic->removeFromParent();
    _pic = cocos2d::Sprite::create(newPicturePath);
    addChild(_pic);
    setContentSize(_pic->getBoundingBox().size);
    
    auto contentWidth = getContentSize().width;
    auto contentHeight = getContentSize().height;
    _bgNode->setPosition(contentWidth/2, contentHeight/2);
    _pic->setPosition(contentWidth/2, contentHeight/2);
    
    if(_label != nullptr){
        float padding = 50*AniScalingUtils::scaleAspectFillToDesignIpadProSize(); //TODO magic number
        setContentSize(cocos2d::Size(getContentSize().width, getContentSize().height+padding+_label->getBoundingBox().size.height));
        _pic->setPosition(getContentSize().width/2, getContentSize().height - _pic->getBoundingBox().size.height/2 - padding);
        _bgNode->setPosition(_pic->getPosition());
        _label->setPosition(_pic->getPositionX(), _pic->getBoundingBox().getMinY() - padding - _label->getBoundingBox().size.height/2);
    }
    
    setChosen(_isChosen, false);
    _pic->setOpacity(oldOpacity);
    
}