From: Daniel Karbach Date: Wed, 8 Aug 2012 09:38:10 +0000 (+0200) Subject: added gauges for health, mana, and ikari displays X-Git-Url: https://git.localhorst.tv/?a=commitdiff_plain;h=2e0bbc9fcc1cce3e1faeff85cc63de7f676e8077;p=l2e.git added gauges for health, mana, and ikari displays --- diff --git a/Debug/src/graphics/subdir.mk b/Debug/src/graphics/subdir.mk index b7c5c2d..df30151 100644 --- a/Debug/src/graphics/subdir.mk +++ b/Debug/src/graphics/subdir.mk @@ -5,14 +5,17 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ ../src/graphics/Frame.cpp \ +../src/graphics/Gauge.cpp \ ../src/graphics/Sprite.cpp OBJS += \ ./src/graphics/Frame.o \ +./src/graphics/Gauge.o \ ./src/graphics/Sprite.o CPP_DEPS += \ ./src/graphics/Frame.d \ +./src/graphics/Gauge.d \ ./src/graphics/Sprite.d diff --git a/Release/src/graphics/subdir.mk b/Release/src/graphics/subdir.mk index 1471b9c..44c1049 100644 --- a/Release/src/graphics/subdir.mk +++ b/Release/src/graphics/subdir.mk @@ -5,14 +5,17 @@ # Add inputs and outputs from these tool invocations to the build variables CPP_SRCS += \ ../src/graphics/Frame.cpp \ +../src/graphics/Gauge.cpp \ ../src/graphics/Sprite.cpp OBJS += \ ./src/graphics/Frame.o \ +./src/graphics/Gauge.o \ ./src/graphics/Sprite.o CPP_DEPS += \ ./src/graphics/Frame.d \ +./src/graphics/Gauge.d \ ./src/graphics/Sprite.d diff --git a/src/battle/BattleState.cpp b/src/battle/BattleState.cpp index 6cb3b32..b1eaa4d 100644 --- a/src/battle/BattleState.cpp +++ b/src/battle/BattleState.cpp @@ -50,7 +50,7 @@ void BattleState::EnterState(Application &ctrl, SDL_Surface *screen) { heroesLayout->CalculatePositions(background->w, background->h, heroesPositions); attackChoices.resize(heroes.size()); for (vector::size_type i(0), end(heroes.size()); i < end; ++i) { - heroTags.push_back(HeroTag(&heroes[i], &attackChoices[i], heroTagFrame, activeHeroTagFrame, HeroTag::Alignment((i + 1) % 2))); + heroTags.push_back(HeroTag(&heroes[i], &attackChoices[i], heroTagFrame, activeHeroTagFrame, healthGauge, manaGauge, ikariGauge, HeroTag::Alignment((i + 1) % 2))); } } @@ -112,16 +112,15 @@ void BattleState::RenderHeroes(SDL_Surface *screen, const Vector &offset) { } void BattleState::RenderHeroTags(SDL_Surface *screen, const Vector &offset) { - int margin(attackTypeMenu.Height() * 3 / 48); - int tagHeight(attackTypeMenu.Height() - 2 * margin); - int tagWidth(attackTypeMenu.Width() * 2 + attackTypeMenu.Width() / 2 - 2 * margin); - int xOffset((BackgroundWidth() - 2 * tagWidth - 2 * margin) / 2); + int tagHeight(attackTypeMenu.Height()); + int tagWidth(attackTypeMenu.Width() * 2 + attackTypeMenu.Width() / 2); + int xOffset((BackgroundWidth() - 2 * tagWidth) / 2); Point tagPosition[4]; - tagPosition[0] = Point(xOffset, BackgroundHeight() - 2 * tagHeight - 3 * margin); - tagPosition[1] = Point(xOffset + tagWidth + 2 * margin, BackgroundHeight() - 2 * tagHeight - 3 * margin); - tagPosition[2] = Point(xOffset, BackgroundHeight() - tagHeight - margin); - tagPosition[3] = Point(xOffset + tagWidth + 2 * margin, BackgroundHeight() - tagHeight - margin); + tagPosition[0] = Point(xOffset, BackgroundHeight() - 2 * tagHeight); + tagPosition[1] = Point(xOffset + tagWidth, BackgroundHeight() - 2 * tagHeight); + tagPosition[2] = Point(xOffset, BackgroundHeight() - tagHeight); + tagPosition[3] = Point(xOffset + tagWidth, BackgroundHeight() - tagHeight); for (vector::size_type i(0), end(heroTags.size()); i < end; ++i) { heroTags[i].Render(screen, tagWidth, tagHeight, tagPosition[i] + offset, (int)i == activeHero); diff --git a/src/battle/BattleState.h b/src/battle/BattleState.h index f4f8bc1..b56b9fe 100644 --- a/src/battle/BattleState.h +++ b/src/battle/BattleState.h @@ -24,6 +24,7 @@ namespace app { class Input; } namespace graphics { class Frame; + class Gauge; class Sprite; } @@ -35,12 +36,15 @@ class BattleState : public app::State { public: - BattleState(SDL_Surface *background, const PartyLayout &monstersLayout, const PartyLayout &heroesLayout, const graphics::Sprite *attackIcons, const graphics::Sprite *moveIcons, const graphics::Frame *heroTagFrame, const graphics::Frame *activeHeroTagFrame) + BattleState(SDL_Surface *background, const PartyLayout &monstersLayout, const PartyLayout &heroesLayout, const graphics::Sprite *attackIcons, const graphics::Sprite *moveIcons, const graphics::Frame *heroTagFrame, const graphics::Frame *activeHeroTagFrame, const graphics::Gauge *healthGauge, const graphics::Gauge *manaGauge, const graphics::Gauge *ikariGauge) : background(background) , monstersLayout(&monstersLayout) , heroesLayout(&heroesLayout) , heroTagFrame(heroTagFrame) , activeHeroTagFrame(activeHeroTagFrame) + , healthGauge(healthGauge) + , manaGauge(manaGauge) + , ikariGauge(ikariGauge) , attackTypeMenu(attackIcons) , moveMenu(moveIcons) , activeHero(-1) { } @@ -91,6 +95,9 @@ private: const PartyLayout *heroesLayout; const graphics::Frame *heroTagFrame; const graphics::Frame *activeHeroTagFrame; + const graphics::Gauge *healthGauge; + const graphics::Gauge *manaGauge; + const graphics::Gauge *ikariGauge; AttackTypeMenu attackTypeMenu; MoveMenu moveMenu; std::vector > monsterPositions; diff --git a/src/battle/HeroTag.cpp b/src/battle/HeroTag.cpp index 87f35dd..851e88e 100644 --- a/src/battle/HeroTag.cpp +++ b/src/battle/HeroTag.cpp @@ -11,6 +11,7 @@ #include "../geometry/operators.h" #include "../geometry/Vector.h" #include "../graphics/Frame.h" +#include "../graphics/Gauge.h" #include "../graphics/Sprite.h" using geometry::Point; @@ -19,17 +20,37 @@ using geometry::Vector; namespace battle { void HeroTag::Render(SDL_Surface *screen, int width, int height, Point position, bool active) const { + // frame + Vector frameOffset; if (active) { activeFrame->Draw(screen, position, width, height); + frameOffset = Vector(activeFrame->BorderWidth(), activeFrame->BorderHeight()); } else { frame->Draw(screen, position, width, height); + frameOffset = Vector(frame->BorderWidth(), frame->BorderHeight()); } - int verticalHeroOffset((height - hero->Sprite()->Height()) / 2); - + int yOffset((height - hero->Sprite()->Height()) / 2); + + // gauges + // NOTE: assuming frame border is unit size until charsets are impemented + int gaugeX((align == LEFT ? 10 : 6) * frameOffset.X()); + // 4 units reserved for hero, gaugeX already includes frame offset + int gaugeWidth(width - gaugeX - (align == LEFT ? 1 : 5) * frameOffset.X()); + // health gauge, second line + Vector healthGaugeOffset(gaugeX, 2 * frameOffset.Y()); + healthGauge->Draw(screen, position + healthGaugeOffset, gaugeWidth, hero->RelativeHealth(256)); + // mana gauge, third line + Vector manaGaugeOffset(gaugeX, 3 * frameOffset.Y()); + manaGauge->Draw(screen, position + manaGaugeOffset, gaugeWidth, hero->RelativeMana(256)); + // ikari gauge, fourth line + Vector ikariGaugeOffset(gaugeX, 4 * frameOffset.Y()); + ikariGauge->Draw(screen, position + ikariGaugeOffset, gaugeWidth, hero->RelativeIP(256)); + + // hero Vector heroOffset( - (align == LEFT) ? verticalHeroOffset : width - hero->Sprite()->Width() - verticalHeroOffset, - verticalHeroOffset); + (align == LEFT) ? yOffset : width - hero->Sprite()->Width() - yOffset, + yOffset); hero->Sprite()->Draw(screen, position + heroOffset, 0, hero->Health() > 0 ? 0 : 2); } diff --git a/src/battle/HeroTag.h b/src/battle/HeroTag.h index 6799e94..b5ab475 100644 --- a/src/battle/HeroTag.h +++ b/src/battle/HeroTag.h @@ -12,7 +12,10 @@ #include -namespace graphics { class Frame; } +namespace graphics { + class Frame; + class Gauge; +} namespace battle { @@ -28,8 +31,8 @@ public: }; public: - HeroTag(const Hero *hero, const AttackChoice *choice, const graphics::Frame *frame, const graphics::Frame *activeFrame, Alignment align) - : hero(hero), choice(choice), frame(frame), activeFrame(activeFrame), align(align) { } + HeroTag(const Hero *hero, const AttackChoice *choice, const graphics::Frame *frame, const graphics::Frame *activeFrame, const graphics::Gauge *healthGauge, const graphics::Gauge *manaGauge, const graphics::Gauge *ikariGauge, Alignment align) + : hero(hero), choice(choice), frame(frame), activeFrame(activeFrame), healthGauge(healthGauge), manaGauge(manaGauge), ikariGauge(ikariGauge), align(align) { } ~HeroTag() { } public: @@ -40,6 +43,9 @@ private: const AttackChoice *choice; const graphics::Frame *frame; const graphics::Frame *activeFrame; + const graphics::Gauge *healthGauge; + const graphics::Gauge *manaGauge; + const graphics::Gauge *ikariGauge; Alignment align; }; diff --git a/src/graphics/Frame.h b/src/graphics/Frame.h index 0f1287c..3743640 100644 --- a/src/graphics/Frame.h +++ b/src/graphics/Frame.h @@ -23,6 +23,8 @@ public: public: int MinWidth() const { return 2 * borderWidth; } int MinHeight() const { return 2 * borderHeight; } + int BorderWidth() const { return borderWidth; } + int BorderHeight() const { return borderHeight; } void Draw(SDL_Surface *dest, geometry::Point position, int width, int height) const; private: diff --git a/src/graphics/Gauge.cpp b/src/graphics/Gauge.cpp new file mode 100644 index 0000000..042dc27 --- /dev/null +++ b/src/graphics/Gauge.cpp @@ -0,0 +1,123 @@ +/* + * Gauge.cpp + * + * Created on: Aug 7, 2012 + * Author: holy + */ + +#include "Gauge.h" + +using geometry::Point; + +namespace graphics { + +// TODO: add start and end "ignore" offsets +void Gauge::Draw(SDL_Surface *dest, Point position, int width, Uint8 level) const { + int fullWidth(width * level / 255); + SDL_Rect srcRect, destRect; + + // start + srcRect.h = height; + destRect.x = position.X(); + destRect.y = position.Y(); + // full part + if (fullWidth >= startWidth) { // completely filled + srcRect.x = fullX; + srcRect.y = fullY; + srcRect.w = startWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } else if (fullWidth > 0) { // partially filled + srcRect.x = fullX; + srcRect.y = fullY; + srcRect.w = fullWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } + // empty part + if (fullWidth == 0) { // completely empty + srcRect.x = emptyX; + srcRect.y = emptyY; + srcRect.w = startWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } else if (fullWidth < startWidth) { // partially empty + srcRect.x = emptyX + fullWidth; + srcRect.y = emptyY; + srcRect.w = startWidth - fullWidth; + destRect.x = position.X() + fullWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } + + destRect.x = position.X() + startWidth; + + // fill + if (fullWidth >= width - endWidth) { // completely filled + srcRect.x = fullX + startWidth; + srcRect.y = fullY; + srcRect.w = repeatWidth; + int fillWidth(width - startWidth - endWidth); + int fillCursor(0); + while (fillCursor < fillWidth) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + fillCursor += repeatWidth; + } + } else if (fullWidth <= startWidth) { // completely empty + srcRect.x = emptyX + startWidth; + srcRect.y = emptyY; + srcRect.w = repeatWidth; + int fillWidth(width - startWidth - endWidth); + int fillCursor(0); + while (fillCursor < fillWidth) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + fillCursor += repeatWidth; + } + } else { // partially filled/empty + srcRect.x = fullX + startWidth; + srcRect.y = fullY; + srcRect.w = repeatWidth; + int fillCursor(0); + while (fillCursor < fullWidth) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + fillCursor += repeatWidth; + } + srcRect.x = emptyX + startWidth; + srcRect.y = emptyY; + int remaining(width - startWidth - endWidth); + while (fillCursor < remaining) { + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + destRect.x += repeatWidth; + fillCursor += repeatWidth; + } + } + + // end + // full part + if (fullWidth >= width) { // completely filled + srcRect.x = fullX + startWidth + repeatWidth; + srcRect.y = fullY; + srcRect.w = endWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } else if (fullWidth > (width - endWidth)) { // partially filled + srcRect.x = fullX + startWidth + repeatWidth; + srcRect.y = fullY; + srcRect.w = endWidth - width + fullWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } + // empty part + if (fullWidth <= width - endWidth) { // completely empty + srcRect.x = emptyX + startWidth + repeatWidth; + srcRect.y = emptyY; + srcRect.w = startWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } else if (fullWidth > (width - endWidth) && fullWidth < width) { // partially empty + srcRect.x = emptyX + startWidth + repeatWidth + fullWidth - width + endWidth; + srcRect.y = emptyY; + srcRect.w = width - fullWidth; + destRect.x = position.X() + fullWidth; + SDL_BlitSurface(surface, &srcRect, dest, &destRect); + } + +} + +} diff --git a/src/graphics/Gauge.h b/src/graphics/Gauge.h new file mode 100644 index 0000000..dde1db0 --- /dev/null +++ b/src/graphics/Gauge.h @@ -0,0 +1,43 @@ +/* + * Gauge.h + * + * Created on: Aug 7, 2012 + * Author: holy + */ + +#ifndef GRAPHICS_GAUGE_H_ +#define GRAPHICS_GAUGE_H_ + +#include "../geometry/Point.h" + +#include + +namespace graphics { + +class Gauge { + +public: + Gauge(SDL_Surface *s, int fullX, int fullY, int emptyX, int emptyY, int height, int startWidth, int repeatWidth, int endWidth) + : surface(s), fullX(fullX), fullY(fullY), emptyX(emptyX), emptyY(emptyY), height(height), startWidth(startWidth), repeatWidth(repeatWidth), endWidth(endWidth) { } + +public: + int MinWidth() const { return startWidth + endWidth; } + int Height() const { return height; } + void Draw(SDL_Surface *dest, geometry::Point position, int width, Uint8 level) const; + +private: + SDL_Surface *surface; + int fullX; + int fullY; + int emptyX; + int emptyY; + int height; + int startWidth; + int repeatWidth; + int endWidth; + +}; + +} + +#endif /* GRAPHICS_GAUGE_H_ */ diff --git a/src/main.cpp b/src/main.cpp index f12b275..e230433 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -13,6 +13,7 @@ #include "battle/PartyLayout.h" #include "geometry/Point.h" #include "graphics/Frame.h" +#include "graphics/Gauge.h" #include "graphics/Sprite.h" #include "sdl/InitImage.h" #include "sdl/InitScreen.h" @@ -31,6 +32,7 @@ using battle::Monster; using battle::PartyLayout; using geometry::Point; using graphics::Frame; +using graphics::Gauge; using graphics::Sprite; using sdl::InitImage; using sdl::InitScreen; @@ -77,18 +79,23 @@ int main(int argc, char **argv) { hero.SetMaxHealth(100); hero.SetHealth(50); hero.SetMaxMana(100); - hero.SetMana(66); - hero.SetIP(160); + hero.SetMana(0); + hero.SetIP(255); SDL_Surface *attackIcons(IMG_Load("test-data/attack-type-icons.png")); Sprite attackIconsSprite(attackIcons, 32, 32); SDL_Surface *moveIcons(IMG_Load("test-data/move-icons.png")); Sprite moveIconsSprite(moveIcons, 32, 32); SDL_Surface *tagFrames(IMG_Load("test-data/tag-frames.png")); - Frame heroTagFrame(tagFrames, 8, 8, 1, 1, 17); - Frame activeHeroTagFrame(tagFrames, 8, 8); + Frame heroTagFrame(tagFrames, 16, 16, 1, 1, 0, 33); + Frame activeHeroTagFrame(tagFrames, 16, 16); - BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &attackIconsSprite, &moveIconsSprite, &heroTagFrame, &activeHeroTagFrame)); + SDL_Surface *gauges(IMG_Load("test-data/gauges.png")); + Gauge healthGauge(gauges, 0, 16, 0, 0, 16, 6, 1, 6); + Gauge manaGauge(gauges, 0, 32, 0, 0, 16, 6, 1, 6); + Gauge ikariGauge(gauges, 0, 48, 0, 0, 16, 6, 1, 6); + + BattleState *battleState(new BattleState(bg, monstersLayout, heroesLayout, &attackIconsSprite, &moveIconsSprite, &heroTagFrame, &activeHeroTagFrame, &healthGauge, &manaGauge, &ikariGauge)); battleState->AddMonster(monster); battleState->AddMonster(monster); battleState->AddMonster(monster); diff --git a/test-data/battle-bg.png b/test-data/battle-bg.png index b62ab74..65fa408 100644 Binary files a/test-data/battle-bg.png and b/test-data/battle-bg.png differ diff --git a/test-data/gauges.png b/test-data/gauges.png new file mode 100644 index 0000000..381fd1b Binary files /dev/null and b/test-data/gauges.png differ diff --git a/test-data/tag-frames.png b/test-data/tag-frames.png index 6387c4d..b998d98 100644 Binary files a/test-data/tag-frames.png and b/test-data/tag-frames.png differ