# 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
# 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
heroesLayout->CalculatePositions(background->w, background->h, heroesPositions);
attackChoices.resize(heroes.size());
for (vector<Hero>::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)));
}
}
}
void BattleState::RenderHeroTags(SDL_Surface *screen, const Vector<int> &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<int> tagPosition[4];
- tagPosition[0] = Point<int>(xOffset, BackgroundHeight() - 2 * tagHeight - 3 * margin);
- tagPosition[1] = Point<int>(xOffset + tagWidth + 2 * margin, BackgroundHeight() - 2 * tagHeight - 3 * margin);
- tagPosition[2] = Point<int>(xOffset, BackgroundHeight() - tagHeight - margin);
- tagPosition[3] = Point<int>(xOffset + tagWidth + 2 * margin, BackgroundHeight() - tagHeight - margin);
+ tagPosition[0] = Point<int>(xOffset, BackgroundHeight() - 2 * tagHeight);
+ tagPosition[1] = Point<int>(xOffset + tagWidth, BackgroundHeight() - 2 * tagHeight);
+ tagPosition[2] = Point<int>(xOffset, BackgroundHeight() - tagHeight);
+ tagPosition[3] = Point<int>(xOffset + tagWidth, BackgroundHeight() - tagHeight);
for (vector<HeroTag>::size_type i(0), end(heroTags.size()); i < end; ++i) {
heroTags[i].Render(screen, tagWidth, tagHeight, tagPosition[i] + offset, (int)i == activeHero);
namespace app { class Input; }
namespace graphics {
class Frame;
+ class Gauge;
class Sprite;
}
: 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) { }
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<geometry::Point<int> > monsterPositions;
#include "../geometry/operators.h"
#include "../geometry/Vector.h"
#include "../graphics/Frame.h"
+#include "../graphics/Gauge.h"
#include "../graphics/Sprite.h"
using geometry::Point;
namespace battle {
void HeroTag::Render(SDL_Surface *screen, int width, int height, Point<int> position, bool active) const {
+ // frame
+ Vector<int> frameOffset;
if (active) {
activeFrame->Draw(screen, position, width, height);
+ frameOffset = Vector<int>(activeFrame->BorderWidth(), activeFrame->BorderHeight());
} else {
frame->Draw(screen, position, width, height);
+ frameOffset = Vector<int>(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<int> healthGaugeOffset(gaugeX, 2 * frameOffset.Y());
+ healthGauge->Draw(screen, position + healthGaugeOffset, gaugeWidth, hero->RelativeHealth(256));
+ // mana gauge, third line
+ Vector<int> manaGaugeOffset(gaugeX, 3 * frameOffset.Y());
+ manaGauge->Draw(screen, position + manaGaugeOffset, gaugeWidth, hero->RelativeMana(256));
+ // ikari gauge, fourth line
+ Vector<int> ikariGaugeOffset(gaugeX, 4 * frameOffset.Y());
+ ikariGauge->Draw(screen, position + ikariGaugeOffset, gaugeWidth, hero->RelativeIP(256));
+
+ // hero
Vector<int> 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);
}
#include <SDL.h>
-namespace graphics { class Frame; }
+namespace graphics {
+ class Frame;
+ class Gauge;
+}
namespace battle {
};
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:
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;
};
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<int> position, int width, int height) const;
private:
--- /dev/null
+/*
+ * 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<int> 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);
+ }
+
+}
+
+}
--- /dev/null
+/*
+ * Gauge.h
+ *
+ * Created on: Aug 7, 2012
+ * Author: holy
+ */
+
+#ifndef GRAPHICS_GAUGE_H_
+#define GRAPHICS_GAUGE_H_
+
+#include "../geometry/Point.h"
+
+#include <SDL.h>
+
+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<int> 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_ */
#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"
using battle::PartyLayout;
using geometry::Point;
using graphics::Frame;
+using graphics::Gauge;
using graphics::Sprite;
using sdl::InitImage;
using sdl::InitScreen;
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);