#include "stdafx.h" #ifdef _COUNTRY_ME_ #include "KUIWndManager.h" #include "KUIControlEffectText_ME.h" #include "KResourceManager.h" #define _EFFECT_TEST ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControlEffectText Implement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace CONTROL_EFFECT_TEXT { const int MAX_WIDTH = 500; const int MAX_HEIGHT = 60; KUIWnd* EffectTextCreator() { return new KUIControlEffectText; } const bool bRegister = KUIFactory::GetInstance()->RegisterCreator( EffectTextCreator, "effect_text"); KUIControlEffectText* CreateEffectText(KUIWndManager* pManager, KUIWnd* pParent, LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, int x, int y, bool scaleDown) { KUIWND_CREATE_ARG arg; arg.lpszClassName = "effect_text"; arg.lpszSprName = "ui_frame.spr"; arg.pParent = pParent; arg.rcRect = KRect(x,y,x + MAX_WIDTH,y + MAX_HEIGHT); arg.lpszID = "_effect_text_id"; arg.lpszID += name; KUIControlEffectText* pEffect = static_cast( pManager->CreateControl(arg) ); pEffect->SetEffectInfo(name, type, scaleDown); return pEffect; } enum { STATE_MOVE = 0, STATE_WAIT, STATE_POPDOWN, // 점점 사라짐. TOTAL_STATE, }; const DWORD MOVE_TIME = 400; const DWORD LINE_MOVE_TIME_DELAY = 200; const DWORD CAPTION_MOVE_TIME_DELAY = 400; const int CAPTION_Y_OFFSET = -20; const int CAPTION_X_OFFSET = -50; const int LINE_Y_OFFSET = 28; const int LINE_X_OFFSET = 110; const DWORD STATE_TIME[TOTAL_STATE] = { CAPTION_MOVE_TIME_DELAY + MOVE_TIME, 300, 1000, }; const int LEFT_OFFEST = -400; enum COLLISION_STATE { CS_NONE = 0, // 부딪히지 않았음. CS_MOVE_RIGHT, // 부딛혀서 오른쪽으로 밀려남 CS_MOVE_LEFT_DOWN, // 좌측 대각선 아래로 내려감 CS_MOVE_DOWN, TOTAL_CS, }; const DWORD RIGHT_TIME = 100; const DWORD RIGHT_OFFSET = 40; // 1초당 얼만큼 움직일 것인가.. const float DOWN_SPEED = 500.f / 1000; const int DOWN_OFFSET = 35; LPCSTR TYPE_TO_COLOR[KUIControlEffectText::TOTAL_EFFECT_COUNT] = { "<#090101>", "<#ffffff>", }; LPCSTR TYPE_TO_BACK_NAME[KUIControlEffectText::TOTAL_EFFECT_COUNT] = { "static_playerview_conditionback_bad", "static_playerview_conditionback_good", }; LPCSTR TYPE_TO_LINE_NAME[KUIControlEffectText::TOTAL_EFFECT_COUNT] = { "static_playerview_conditionline_bad", "static_playerview_conditionline_good", }; } KUIControlEffectText::KUIControlEffectText() { using namespace CONTROL_EFFECT_TEXT; m_state = STATE_MOVE; m_collisionState = COLLISION_STATE::CS_NONE; m_collisionEffectStartTime = m_effectStartTime = m_curTime = 0; m_remainDownOffest = m_downOffest = 0; m_realRect = KRect(0,0,0,0); m_curCaptionAlpha = 1.f; m_curPrimitiveAlpha = 1.f; } KUIControlEffectText::~KUIControlEffectText() { } void KUIControlEffectText::Process(DWORD time) { using namespace CONTROL_EFFECT_TEXT; m_curTime = time; if(m_effectStartTime == 0) { m_effectStartTime = m_curTime; m_state = STATE_MOVE; return; } DWORD timeDiff = m_curTime - m_effectStartTime; switch(m_state) { case STATE_MOVE: { if(timeDiff > CAPTION_MOVE_TIME_DELAY) { DWORD newTimeDiff = timeDiff - CAPTION_MOVE_TIME_DELAY; // 최종적으로 caption이 위치해야할 곳 int captionLeft = m_rcRegion.left + m_backWidth - m_captionWidth; int left_offset = m_scaleDown ? LEFT_OFFEST * 0.7f : LEFT_OFFEST; int left = captionLeft + left_offset * (1.0f - getClampRatioSqrt(newTimeDiff,MOVE_TIME ) ); int y_offset = CAPTION_Y_OFFSET; if(m_scaleDown) { left += 100; y_offset = CAPTION_Y_OFFSET + 5; } m_curCaptionAlpha = 1.f; m_pCaptionPhrase->SetPosition( (left + CAPTION_X_OFFSET) , m_rcRegion.top + y_offset, m_fZPos); m_pCaptionPhrase->SetVisibility(m_curCaptionAlpha); } if(timeDiff > LINE_MOVE_TIME_DELAY) { DWORD newTimeDiff = timeDiff - LINE_MOVE_TIME_DELAY; int lineLeft = m_rcRegion.left; int left = lineLeft + LEFT_OFFEST * (1.0f - getClampRatioSqrt(newTimeDiff,MOVE_TIME) ); m_BackLine.SetRenderEnable(true); m_BackLine.SetPosition(left + LINE_X_OFFSET,m_rcRegion.top + LINE_Y_OFFSET,m_fZPos); } int backLeft = m_rcRegion.left; int left = backLeft + LEFT_OFFEST * (1.0f - getClampRatioSqrt(timeDiff,MOVE_TIME) ); m_Back.SetRenderEnable(true); m_Back.SetPosition(left,m_rcRegion.top,m_fZPos); } break; case STATE_WAIT: break; case STATE_POPDOWN: _ChangeCurAlpha(1.0f - getClampRatio(timeDiff, STATE_TIME[m_state]) ); break; } // 끝났3 if(m_state == TOTAL_STATE) { SetDestroy(true); } else if(false == IsDestroy() && timeDiff >= STATE_TIME[m_state] ) { m_state++; m_effectStartTime = m_curTime; } // 이 부분부턴 충돌해서 밀리는 부분.. DWORD csTimeDiff = m_curTime - m_collisionEffectStartTime; switch(m_collisionState) { case COLLISION_STATE::CS_NONE: // 난데모 나이 -_- m_collisionEffectStartTime = m_curTime; break; case COLLISION_STATE::CS_MOVE_RIGHT: { // 존내 밀려남 float ratio = getClampRatioSqrt(csTimeDiff, RIGHT_TIME); int width = (m_rcRegion.GetWidth() + RIGHT_OFFSET) * ratio; m_pCaptionPhrase->SetPosition(m_rcRegion.left + width, m_rcRegion.top, m_fZPos); m_realRect = m_rcRegion + KRect(width, 0, width, 0); if(ratio == 1.0f) { m_collisionState = COLLISION_STATE::CS_MOVE_LEFT_DOWN; m_collisionEffectStartTime = m_curTime; } } break; case COLLISION_STATE::CS_MOVE_LEFT_DOWN: { float ratioSub = 1.f - getClampRatioPow(csTimeDiff, RIGHT_TIME); int width = (m_rcRegion.GetWidth() + RIGHT_OFFSET) * ratioSub; _CalDownOffset(csTimeDiff); m_pCaptionPhrase->SetPosition(m_rcRegion.left + width, m_rcRegion.top + m_downOffest, m_fZPos); m_realRect = m_rcRegion + KRect(width, m_downOffest, width, m_downOffest); if(ratioSub == 0.0f) { m_collisionState = COLLISION_STATE::CS_MOVE_DOWN; m_collisionEffectStartTime = m_curTime; } } break; case COLLISION_STATE::CS_MOVE_DOWN: _CalDownOffset(csTimeDiff); m_pCaptionPhrase->SetPosition(m_rcRegion.left - m_downOffest, m_rcRegion.top + m_downOffest, m_fZPos); m_realRect = m_rcRegion + KRect(-m_downOffest, m_downOffest, -m_downOffest, m_downOffest); break; } } void KUIControlEffectText::AddDownOffset(int count) { using namespace CONTROL_EFFECT_TEXT; if(m_collisionState == COLLISION_STATE::CS_NONE) return; m_remainDownOffest += DOWN_OFFSET * count; } void KUIControlEffectText::OnCollision() { using namespace CONTROL_EFFECT_TEXT; assert(m_collisionState == COLLISION_STATE::CS_NONE); m_collisionState = COLLISION_STATE::CS_MOVE_RIGHT; } void KUIControlEffectText::OnPosChangeNofity(int XOffset, int YOffset) { // 외부에서 Sprite Primitive의 Position 조절을 막기 위해서 using namespace CONTROL_EFFECT_TEXT; if(m_state == STATE_MOVE) return; KUIControl::OnPosChangeNofity(XOffset, YOffset); } void KUIControlEffectText::OnAlphaChangeNotify(float fAlpha) { // 외부에서 Sprite Primitive의 Visibility 조절을 막기 위해서 KUIWnd::OnAlphaChangeNotify(fAlpha); float resVisiCap = m_fAlpha * m_curCaptionAlpha; float resVisiPrim = m_fAlpha * m_curPrimitiveAlpha; if(m_pCaptionPhrase) m_pCaptionPhrase->SetVisibility( resVisiCap); m_Back.SetVisibility( resVisiPrim); m_BackLine.SetVisibility( resVisiPrim); } namespace { K3DMatrix SCALE_MATRIX = K3DMatrix(K3DVector(0.7f,0.f,0.f), K3DVector(0.0f,0.7f,0.f), K3DVector(0.0f,0.f,1.f) ); } void KUIControlEffectText::SetEffectInfo(LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, bool scaleDown) { using namespace CONTROL_EFFECT_TEXT; m_scaleDown = scaleDown; int x = m_rcRegion.left; int y = m_rcRegion.top; // Sprite Image 추가 KResSprite* pBack = _getSpriteSet()->GetSpriteRes(TYPE_TO_BACK_NAME[type], 0); m_Back.SetRes(pBack); m_Back.SetPosition(x,y,m_fZPos); m_Back.SetRenderEnable(false); KResSprite* pLine = _getSpriteSet()->GetSpriteRes(TYPE_TO_LINE_NAME[type], 0); m_BackLine.SetRes(pLine); m_BackLine.SetPosition(x,y,m_fZPos); m_BackLine.SetRenderEnable(false); _registerSprite(&m_Back); _registerSprite(&m_BackLine); // caption 추가 std::string newCaption = TYPE_TO_COLOR[type]; newCaption += ""; newCaption += scaleDown ? "" : ""; newCaption += name; SetCaption(newCaption.c_str() ); m_curCaptionAlpha = 0.f; m_pCaptionPhrase->SetVisibility(m_curCaptionAlpha); float scale_down_factor = 1.f; // 70%만 표시 if( true == m_scaleDown) { m_Back.SetTransform(SCALE_MATRIX); m_BackLine.SetTransform(SCALE_MATRIX); scale_down_factor = 0.7f; } m_backWidth = pBack->GetSizeX() * scale_down_factor; // 넓이 보정 ( 충돌체크용) KTextPhrase::GetOneLineStringSize(newCaption.c_str(), &m_captionWidth); m_rcRegion.right = m_rcRegion.left + pBack->GetSizeX() * scale_down_factor; m_rcRegion.bottom= m_rcRegion.top + pBack->GetSizeY() * scale_down_factor; m_realRect = m_rcRegion; } void KUIControlEffectText::_ChangeCurAlpha(float fAlpha) { m_curCaptionAlpha = fAlpha; m_curPrimitiveAlpha = fAlpha; float resVisiCaption = m_curCaptionAlpha * m_fAlpha; float resVisiPrim = m_curPrimitiveAlpha * m_fAlpha; if(NULL != m_pCaptionPhrase) m_pCaptionPhrase->SetVisibility( resVisiCaption); m_Back.SetVisibility( resVisiPrim); m_BackLine.SetVisibility( resVisiPrim); } void KUIControlEffectText::_CalDownOffset(DWORD csTimeDiff) { using namespace CONTROL_EFFECT_TEXT; if(m_remainDownOffest > m_downOffest) { int downHeight = std::min(m_remainDownOffest,static_cast( csTimeDiff * DOWN_SPEED) ); m_downOffest = downHeight; } } ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// // KUIControlEffectTextGroup Implement ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// namespace CONTROL_EFFECT_TEXT_GROUP { KUIWnd* EffectTextGroupCreator() { return new KUIControlEffectTextGroup; } bool bRegister = KUIFactory::GetInstance()->RegisterCreator( EffectTextGroupCreator, "effect_text_group"); } void KUIControlEffectTextGroup::Process(DWORD time) { KUIControl::Process(time); // 예전엔 충돌 체크가 들어갔었는데, 현재는 안들어감. // 소스코드를 걍 지우고 싶지만, 혹시나 기획에서의 태클을 대비해서 우선은 남겨둠 // 충돌 체크가 돌아가기 위해서는 KUIControlEffectText에서 RealRect를 제대로 설정해 줘야 한다는것을 명심할 것! //// 충돌 체크 //int collisionCount = 0; //for(std::list::iterator it = m_listChild.begin(); it != m_listChild.end(); ++it) //{ // KUIControlEffectText* pText = static_cast(*it); // if(pText->GetCollisionState() != CONTROL_EFFECT_TEXT::CS_NONE) // continue; // for(std::list::iterator compIt = m_listChild.begin(); compIt != m_listChild.end(); ++compIt) // { // KUIControlEffectText* pComp = static_cast(*compIt); // // 아직 이동하는 녀석이면 즐 // if(pText == pComp || pComp->GetCollisionState() != CONTROL_EFFECT_TEXT::CS_NONE || pComp->GetState() == CONTROL_EFFECT_TEXT::STATE_MOVE) // continue; // KRect rect1 = pText->GetRealRect(); // KRect rect2 = pComp->GetRealRect(); // // 충돌 체크시 좀더 먼저 팅기게 할려고 // rect2.left -= 10; // // if(rect1.IsIntersect(rect2) ) // { // pComp->OnCollision(); // collisionCount++; // } // } //} //// 밀리는 만큼 밀어주자. //if(collisionCount > 0) //{ // for(std::list::iterator it = m_listChild.begin(); it != m_listChild.end(); ++it) // { // KUIControlEffectText* pText = static_cast(*it); // pText->AddDownOffset(collisionCount); // } //} #ifndef _KUI_INVALIDATION // 죽은놈 삭제 for(std::list::iterator it = m_listChild.begin(); it != m_listChild.end();) { KUIWnd* pWnd = *it; if(pWnd->IsDestroy() ) { delete pWnd; it = m_listChild.erase(it); } else { ++it; } } #endif } #ifdef _KUI_INVALIDATION KUIControl* KUIControlEffectTextGroup::AddEffectControl(KUIWnd* pParent, LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, bool scaleDown) { return CONTROL_EFFECT_TEXT::CreateEffectText(m_pManager, pParent, name, type, m_rcRegion.left-200, m_rcRegion.top, scaleDown); } #else void KUIControlEffectTextGroup::AddEffectControl(LPCSTR name, KUIControlEffectText::EFFECT_TYPE type, bool scaleDown) { CONTROL_EFFECT_TEXT::CreateEffectText(m_pManager, this, name, type, m_rcRegion.left-200, m_rcRegion.top, scaleDown); } #endif #endif