Files
2026-06-01 12:46:52 +02:00

475 lines
8.9 KiB
C++

#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<KSpritePrimitive*> 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); i<m_vtFrameAnimator.size(); ++i )
{
m_vtFrameAnimator[i]->SetAniTargetSize( width, height );
}
InvalidateWnd();
}