From 4c627f74b6f9d486fd8d368668f8618caca0e36d Mon Sep 17 00:00:00 2001 From: Tobias Loose Date: Mon, 9 Dec 2013 22:17:19 +0100 Subject: [PATCH] Add easing to GuiPhaseBar, simplify math a bit. --- projects/mtg/include/Easing.h | 2 +- projects/mtg/include/GameStateShop.h | 1 - projects/mtg/include/GuiPhaseBar.h | 16 ++++- projects/mtg/src/GameStateShop.cpp | 6 +- projects/mtg/src/GuiPhaseBar.cpp | 95 +++++++++++----------------- 5 files changed, 53 insertions(+), 67 deletions(-) diff --git a/projects/mtg/include/Easing.h b/projects/mtg/include/Easing.h index 1b5cf35a9..49d574026 100644 --- a/projects/mtg/include/Easing.h +++ b/projects/mtg/include/Easing.h @@ -95,7 +95,7 @@ public: */ void update(float dt) { - if(duration > 0) + if(time_acc < duration) { time_acc += dt; diff --git a/projects/mtg/include/GameStateShop.h b/projects/mtg/include/GameStateShop.h index 1de196b5f..f6765ab74 100644 --- a/projects/mtg/include/GameStateShop.h +++ b/projects/mtg/include/GameStateShop.h @@ -65,7 +65,6 @@ private: JQuadPtr pspIcons[8]; WSrcCards * srcCards; TaskList * taskList; - float mElapsed; WGuiMenu * shopMenu; WGuiFilters * filterMenu; //Filter menu slides in sideways from right, or up from bottom. WGuiCardImage * bigDisplay; diff --git a/projects/mtg/include/GuiPhaseBar.h b/projects/mtg/include/GuiPhaseBar.h index 49dafac6e..78cec2677 100644 --- a/projects/mtg/include/GuiPhaseBar.h +++ b/projects/mtg/include/GuiPhaseBar.h @@ -4,15 +4,25 @@ #include "GuiLayers.h" #include "PhaseRing.h" #include "WEvent.h" +#include "PlayGuiObject.h" + +#include "Easing.h" class GuiPhaseBar: public GuiLayer, public PlayGuiObject { -protected: - Phase* phase; +private: + static const float zoom_big; + static const float zoom_small; + static const float step; + + int displayedPhaseId; float angle; float zoomFactor; - DuelLayers* mpDuelLayers; + OutQuadEasing angleEasing; + InOutQuadEasing zoomFactorEasing; + DuelLayers* mpDuelLayers; + void DrawGlyph(JQuad *inQuad, int phaseId, float x, float y, float scale); public: GuiPhaseBar(DuelLayers* duelLayers); ~GuiPhaseBar(); diff --git a/projects/mtg/src/GameStateShop.cpp b/projects/mtg/src/GameStateShop.cpp index 7055ed9f5..84ca3f6e4 100644 --- a/projects/mtg/src/GameStateShop.cpp +++ b/projects/mtg/src/GameStateShop.cpp @@ -102,7 +102,6 @@ void GameStateShop::Start() bListCards = false; mTouched = false; mStage = STAGE_FADE_IN; - mElapsed = 0; needLoad = true; booster = NULL; srcCards = NEW WSrcUnlockedCards(0); @@ -427,7 +426,7 @@ void GameStateShop::End() { save(); JRenderer::GetInstance()->EnableVSync(false); - mElapsed = 0; + SAFE_DELETE(shopMenu); SAFE_DELETE(bigDisplay); SAFE_DELETE(srcCards); @@ -469,9 +468,6 @@ void GameStateShop::Update(float dt) if (lightAlpha > 50) lightAlpha = 50; - if (mStage != STAGE_FADE_IN) - mElapsed += dt; - JButton btn; switch (mStage) { diff --git a/projects/mtg/src/GuiPhaseBar.cpp b/projects/mtg/src/GuiPhaseBar.cpp index 0accc8a08..8d36cb0f9 100644 --- a/projects/mtg/src/GuiPhaseBar.cpp +++ b/projects/mtg/src/GuiPhaseBar.cpp @@ -24,26 +24,28 @@ }; */ +const float GuiPhaseBar::zoom_big = 1.5 * 1.4; +const float GuiPhaseBar::zoom_small = 1.5; +const float GuiPhaseBar::step = M_PI/6.0f; + namespace { + //width and height of the phase symbol textures const float kWidth = 28; const float kHeight = kWidth; - const unsigned kPhases = 12; + const unsigned kPhases = NB_MTG_PHASES - 2; //there are two phases we do not show +} - const float ICONSCALE = 1.5; - const float CENTER = SCREEN_HEIGHT_F / 2 + 10; - - void DrawGlyph(JQuad* inQuad, int inGlyph, float inY, float, unsigned int inP, float inScale) - { - float xPos = static_cast ((inP + inGlyph * (int) (kWidth + 1)) % (kPhases * (int) (kWidth + 1))); - inQuad->SetTextureRect(xPos, 0, kWidth, kHeight); - JRenderer::GetInstance()->RenderQuad(inQuad, 0, inY, 0.0, inScale, inScale); - } +void GuiPhaseBar::DrawGlyph(JQuad *inQuad, int phaseId, float x, float y, float scale) +{ + inQuad->SetTextureRect(phaseId * (kWidth + 1), 0, kWidth, kHeight); + JRenderer::GetInstance()->RenderQuad(inQuad, x, y - scale * kWidth/2, 0.0f, scale, scale); } GuiPhaseBar::GuiPhaseBar(DuelLayers* duelLayers) : - GuiLayer(duelLayers->getObserver()), PlayGuiObject(0, 0, 106, 0, false), - phase(NULL), angle(0.0f), zoomFactor(ICONSCALE), mpDuelLayers(duelLayers) + GuiLayer(duelLayers->getObserver()), PlayGuiObject(80, 0, 106, 0, false), + displayedPhaseId(0), angle(0.0f), zoomFactor(zoom_small), angleEasing(angle), + zoomFactorEasing(zoomFactor), mpDuelLayers(duelLayers) { if(duelLayers->getObserver()->getResourceManager()) { @@ -57,10 +59,7 @@ GuiPhaseBar::GuiPhaseBar(DuelLayers* duelLayers) : GameApp::systemError = "Error loading phasebar texture : " __FILE__; } - - zoom = ICONSCALE; mpDuelLayers->getCardSelector()->Add(this); - } GuiPhaseBar::~GuiPhaseBar() @@ -69,32 +68,27 @@ GuiPhaseBar::~GuiPhaseBar() void GuiPhaseBar::Update(float dt) { - if (angle > 3 * dt) - angle -= 3 * dt; - else - angle = 0; + angleEasing.update(dt); - if (dt > 0.05f) dt = 0.05f; - if(zoomFactor + 0.05f < zoom) + if(angle <= -step) { - zoomFactor += dt; - } - else if (zoomFactor - 0.05f > zoom) - { - zoomFactor -= dt; + displayedPhaseId = (displayedPhaseId + 1) % kPhases; + angleEasing.translate(step); } + + zoomFactorEasing.update(dt); } void GuiPhaseBar::Entering() { mHasFocus = true; - zoom = 1.4f*ICONSCALE; + zoomFactorEasing.start(zoom_big, 0.3f); } bool GuiPhaseBar::Leaving(JButton) { mHasFocus = false; - zoom = ICONSCALE; + zoomFactorEasing.start(zoom_small, 0.6f); return true; } @@ -102,41 +96,28 @@ void GuiPhaseBar::Render() { JQuadPtr quad = WResourceManager::Instance()->GetQuad("phasebar"); //uncomment to draw a hideous line across hires screens. - // JRenderer::GetInstance()->DrawLine(0, CENTER, SCREEN_WIDTH, CENTER, ARGB(255, 255, 255, 255)); + // JRenderer::GetInstance()->DrawLine(0, CENTER, SCREEN_WIDTH, CENTER, ARGB(255, 255, 255, 255)); - unsigned int p = (phase->id + kPhases - 4) * (int) (kWidth + 1); - float centerYPosition = CENTER + (kWidth / 2) * angle * zoomFactor / (M_PI / 6) - zoomFactor * kWidth / 4; - float yPos = centerYPosition; - float scale = 0; - for (int glyph = 3; glyph < 6; ++glyph) - { - scale = zoomFactor * sinf(angle + glyph * M_PI / 6) / 2; - DrawGlyph(quad.get(), glyph, yPos, angle, p, scale); - yPos += kWidth * scale; - } + const float radius = 25 * zoomFactor; - yPos = centerYPosition; - for (int glyph = 2; glyph > 0; --glyph) + for(int i = 0; i < 6; ++i) { - scale = zoomFactor * sinf(angle + glyph * M_PI / 6) / 2; - yPos -= kWidth * scale; - DrawGlyph(quad.get(), glyph, yPos, angle, p, scale); - } + //the position of the glyphe in the circle + const float circPos = (i - 2) * step + angle; + const float glyphY = this->y + this->mHeight / 2 + sin(circPos) * radius; - if (angle > 0) - { - scale = zoomFactor * sinf(angle) / 2; - yPos -= kWidth * scale; - float xPos = static_cast (p % (kPhases * (int) (kWidth + 1))); - quad->SetTextureRect(xPos, kHeight, kWidth, kHeight); - JRenderer::GetInstance()->RenderQuad(quad.get(), 0, yPos, 0.0, scale, scale); + //the scale is computed so that the glyphes touch each other + //hint: sin(circPos + PI/2) = cos(circPos) + const float glyphScale = zoomFactor * cosf(circPos) * 0.5; + + DrawGlyph(quad.get(), (displayedPhaseId - 3 + kPhases + i) % kPhases, 0, glyphY, glyphScale); } //print phase name WFont * font = WResourceManager::Instance()->GetWFont(Fonts::MAIN_FONT); string currentP = _("your turn"); string interrupt = ""; - if (observer->currentPlayer == mpDuelLayers->getRenderedPlayerOpponent()) + if (observer->currentPlayer == mpDuelLayers->getRenderedPlayerOpponent()) { currentP = _("opponent's turn"); } @@ -147,7 +128,7 @@ void GuiPhaseBar::Render() } if (observer->currentlyActing() != observer->currentPlayer) { - if (observer->currentPlayer == mpDuelLayers->getRenderedPlayer()) + if (observer->currentPlayer == mpDuelLayers->getRenderedPlayer()) { interrupt = _(" - ") + _("opponent plays"); } @@ -159,7 +140,7 @@ void GuiPhaseBar::Render() char buf[200]; //running this string through translate returns gibberish even though we defined the variables in the lang.txt - string phaseNameToTranslate = observer->phaseRing->phaseName(phase->id); + string phaseNameToTranslate = observer->phaseRing->phaseName(displayedPhaseId); phaseNameToTranslate = _(phaseNameToTranslate); sprintf(buf, _("(%s%s) %s").c_str(), currentP.c_str(), interrupt.c_str(),phaseNameToTranslate.c_str()); font->DrawString(buf, SCREEN_WIDTH - 5, 2, JGETEXT_RIGHT); @@ -170,8 +151,8 @@ int GuiPhaseBar::receiveEventMinus(WEvent *e) WEventPhaseChange *event = dynamic_cast (e); if (event) { - angle = M_PI / 6; - phase = event->to; + int phasesToAnimate = (event->to->id - displayedPhaseId + kPhases) % kPhases; + angleEasing.start(float(phasesToAnimate * (- step)), 0.3f * float(sqrt(phasesToAnimate))); } return 1; }