#include "stdafx.h" #include "KViewport.h" #include "KUIWndManager.h" #include "KUIControlQuickEffect.h" #include "KResourceManager.h" class KSpriteAnimator { public: enum ANI_TYPE { NORMAL = 1 << 0, LAST_PAGE = 1 << 1, REVERSE = 1 << 2, REPEAT = 1 << 3, PING_PONG = 1 << 4, }; public: KSpriteAnimator() { m_isPlay = false; m_startTime = 0; m_aniType = NORMAL; m_curTime = 0; m_frameTime = 0; } ~KSpriteAnimator() { for(size_t i = 0 ; i < m_vtSpriteFrame.size(); ++i) delete m_vtSpriteFrame[i]; m_vtSpriteFrame.clear(); } void AddRes(KResSprite* pRes) { KSpritePrimitive *pSpr = new KSpritePrimitive; pSpr->SetRes(pRes); m_vtSpriteFrame.push_back(pSpr); } void StartAnimation(DWORD curTime, int aniType, DWORD frameTime) { m_isPlay = true; m_startTime = curTime; m_aniType = aniType; m_frameTime = frameTime; } void StopAnimation() { m_isPlay = false; } bool IsPlay() { return m_isPlay; } KSpritePrimitive* Process(DWORD time) { m_curTime = time; if(m_isPlay == false) return NULL; DWORD timeDiff = m_curTime - m_startTime; if(m_frameTime == 0) assert(false); const size_t totalFrame = m_vtSpriteFrame.size(); if(totalFrame == 0) assert(false ); DWORD frameIdx = timeDiff / m_frameTime; if( frameIdx >= totalFrame) { if(m_aniType & PING_PONG) { // PING if( (frameIdx / totalFrame) % 2 == 0) { frameIdx %= totalFrame; } else { frameIdx %= totalFrame; frameIdx = totalFrame - 1 - frameIdx; } } else if(m_aniType & REPEAT) { frameIdx %= totalFrame; } else if(m_aniType & LAST_PAGE) { frameIdx = totalFrame - 1; } else { m_isPlay = false; frameIdx = 0; return NULL; } } if(m_aniType & REVERSE) { frameIdx = totalFrame - 1 - frameIdx; } return m_vtSpriteFrame.at(frameIdx); } void SetPosition(int x, int y, int z) { for(size_t i = 0 ; i < m_vtSpriteFrame.size(); ++i) m_vtSpriteFrame.at(i)->SetPosition(x,y,z); } void SetAddPosition(int x, int y) { for(size_t i = 0 ; i < m_vtSpriteFrame.size(); ++i) m_vtSpriteFrame.at(i)->SetAddPosition(x,y,0); } void SetVisibility(float fVisi) { for(size_t i = 0 ; i < m_vtSpriteFrame.size(); ++i) m_vtSpriteFrame.at(i)->SetVisibility(fVisi); } void SetAniTargetSize( float width, float height ) { for(size_t i = 0 ; i < m_vtSpriteFrame.size(); ++i) m_vtSpriteFrame.at(i)->SetTargetSize( width, height ); } private: bool m_isPlay; int m_aniType; DWORD m_startTime; DWORD m_curTime; DWORD m_frameTime; std::vector m_vtSpriteFrame; }; namespace { KUIWnd* QuickEffectCreator() { return new KUIControlQuickEffect; } const bool bRegister = KUIFactory::GetInstance()->RegisterCreator( QuickEffectCreator, "quick_effect"); enum { STATE_NONE = 0, STATE_WAIT, STATE_CAST, STATE_USE, STATE_TOGGLE, STATE_COOL_TIME_OFF, }; enum ANI_NAME_INDEX { ANI_WAIT = 0, ANI_CAST_START, ANI_CAST, ANI_USE, ANI_TOGGLE, ANI_TOGGLE_LINE, ANI_COOL_TIME, TOTAL_ANI_NAME, }; LPCSTR ANI_NAME[TOTAL_ANI_NAME] = { "static_quickslot_wait", "static_quickslot_caststart", "static_quickslot_cast", "static_quickslot_start", "static_quickslot_toggle", "static_quickslot_toggle01_", "static_quickslot_cooltime", }; int FRAME_COUNT[TOTAL_ANI_NAME] = { 10, 9, 9, 11, 9, 16, 10, }; const DWORD FRAME_TIME = 100; } KUIControlQuickEffect::KUIControlQuickEffect() { for(size_t i = 0; i < TOTAL_ANI_NAME; ++i) { m_vtFrameAnimator.push_back(new KSpriteAnimator); } m_isNextUseQuickSlot = false; m_isNextToggleOn = false; m_castTime = 0; m_toggleTime = 0; m_coolTime = 0; m_curTime = 0; m_bIsPrevToggleOn = false; } KUIControlQuickEffect::~KUIControlQuickEffect() { SAFE_DELETE_VECTOR(m_vtFrameAnimator); } void KUIControlQuickEffect::OnPosChangeNofity(int XOffset, int YOffset) { for(size_t i = 0; i < m_vtFrameAnimator.size(); ++i) { m_vtFrameAnimator.at(i)->SetAddPosition(XOffset, YOffset); } } void KUIControlQuickEffect::OnAlphaChangeNotify(float fAlpha) { for(size_t i = 0; i < m_vtFrameAnimator.size(); ++i) { m_vtFrameAnimator.at(i)->SetVisibility( fAlpha); } } void KUIControlQuickEffect::Process(DWORD time) { m_curTime = time; DWORD timeDiff = m_curTime - m_stateStartTime; switch(m_state) { case STATE_NONE: case STATE_WAIT: break; case STATE_CAST: { if(timeDiff > m_castTime && m_castTime != 0) { if(m_isNextUseQuickSlot) { m_isNextUseQuickSlot = false; UseQuickSlot(m_coolTime,m_isNextToggleOn,m_toggleTime); } else { Cancel(); } } #ifdef _KUI_INVALIDATION // { [sonador] InvalidateWnd(); // } #endif } break; case STATE_USE: if(false == m_vtFrameAnimator.at(ANI_USE)->IsPlay() ) { if(m_isNextToggleOn) { m_isNextToggleOn = false; ToggleOn(true, m_toggleTime); } else { Cancel(); } } break; case STATE_TOGGLE: { if(m_toggleTime != 0 && timeDiff > m_toggleTime) { Cancel(); } } break; case STATE_COOL_TIME_OFF: { if(false == m_vtFrameAnimator.at(ANI_COOL_TIME)->IsPlay() ) Cancel(); #ifdef _KUI_INVALIDATION InvalidateWnd(); #endif } break; } if(m_coolTime != 0 && timeDiff > m_coolTime) { CoolTimeOff(); } } void KUIControlQuickEffect::Render(KViewportObject * pViewport, bool isFront /* = false */) { if(false == m_bShowFlag) return; for(size_t i = 0 ; i < m_vtFrameAnimator.size(); ++i) { KSpritePrimitive* pPrimitive = m_vtFrameAnimator.at(i)->Process(m_curTime); if(pPrimitive) { pViewport->Register(pPrimitive); } } } void KUIControlQuickEffect::Wait() { _SetState(STATE_WAIT); _StopAllAnimation(); _StartAnimation(ANI_WAIT, KSpriteAnimator::REPEAT); } void KUIControlQuickEffect::Cast(DWORD castTime, bool isUseQuickSlot, DWORD coolTime, bool isToggleOn, DWORD toggleTime) { _StopAllAnimation(); _SetState(STATE_CAST); m_castTime = castTime; _StartAnimation(ANI_CAST_START, KSpriteAnimator::NORMAL); _StartAnimation(ANI_CAST, KSpriteAnimator::REPEAT); m_isNextUseQuickSlot = isUseQuickSlot; m_coolTime = coolTime; m_isNextToggleOn = isToggleOn; m_toggleTime = toggleTime; } void KUIControlQuickEffect::UseQuickSlot(DWORD coolTime, bool isToggleOn, DWORD toggleTime) { _StopAllAnimation(); _SetState(STATE_USE); m_coolTimeStartTime = m_curTime; m_coolTime = coolTime; m_isNextToggleOn = isToggleOn; m_toggleTime = toggleTime; _StartAnimation(ANI_USE, KSpriteAnimator::NORMAL); } void KUIControlQuickEffect::ToggleOn(bool isToggleOn, DWORD toggleTime) { _StopAllAnimation(); m_toggleTime = toggleTime; if( m_state == STATE_TOGGLE) { if(false == isToggleOn) { _SetState(STATE_NONE); m_bIsPrevToggleOn = false; } } else if(isToggleOn) { _SetState(STATE_TOGGLE); _StartAnimation(ANI_TOGGLE, KSpriteAnimator::REPEAT); _StartAnimation(ANI_TOGGLE_LINE, KSpriteAnimator::PING_PONG); m_bIsPrevToggleOn = true; } else { m_bIsPrevToggleOn = false; } } const bool KUIControlQuickEffect::IsToggleOn() { return m_state == STATE_TOGGLE; } void KUIControlQuickEffect::CoolTimeOff() { m_coolTime = 0; _StopAllAnimation(); _SetState(STATE_COOL_TIME_OFF); _StartAnimation(ANI_COOL_TIME, KSpriteAnimator::NORMAL); } void KUIControlQuickEffect::Cancel() { _StopAllAnimation(); _SetState(STATE_NONE); } void KUIControlQuickEffect::_initControl() { //처음에 다 로드를 하자? for(int i = 0 ; i < TOTAL_ANI_NAME; ++i) { KSpriteAnimator* pAnimator = m_vtFrameAnimator.at(i); char buff[_MAX_PATH]; for(int k = 0; k < FRAME_COUNT[i]; ++k) { _snprintf_s(buff, _MAX_PATH, _MAX_PATH-1, k >= 10 ? "%d" : "0%d", k); std::string aniName = ANI_NAME[i]; aniName += buff; KResSprite* pRes = _getSpriteSet()->GetSpriteRes(aniName.c_str(), 0); pAnimator->AddRes(pRes); if(i == 0 && k == 0) { m_rcRegion.right = m_rcRegion.left + pRes->GetSizeX(); m_rcRegion.bottom = m_rcRegion.top+ pRes->GetSizeY(); } } pAnimator->SetPosition(m_rcRegion.left, m_rcRegion.top, m_fZPos); } } void KUIControlQuickEffect::_SetState(int state) { m_state = state; m_stateStartTime = m_curTime; InvalidateWnd(); } void KUIControlQuickEffect::_StartAnimation(int type, int aniType) { m_vtFrameAnimator.at(type)->StartAnimation(m_curTime, aniType, FRAME_TIME); InvalidateWnd(); } void KUIControlQuickEffect::_StopAnimation(int type) { m_vtFrameAnimator.at(type)->StopAnimation(); InvalidateWnd(); } void KUIControlQuickEffect::_StopAllAnimation() { std::for_each(m_vtFrameAnimator.begin(), m_vtFrameAnimator.end(), std::mem_fun(&KSpriteAnimator::StopAnimation) ); InvalidateWnd(); } void KUIControlQuickEffect::SetAniTargetSize( float width, float height ) { m_rcRegion.right = m_rcRegion.left + width; m_rcRegion.bottom = m_rcRegion.top + height; for( int i(0); iSetAniTargetSize( width, height ); } InvalidateWnd(); }