readme
This commit is contained in:
+152
@@ -0,0 +1,152 @@
|
||||
#include "StatBar.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
#include "Gui.h"
|
||||
|
||||
static constexpr float BAR_BORDER = 3.0f;
|
||||
static constexpr float LABEL_HEIGHT = 26.0f;
|
||||
static constexpr float LABEL_GAP = 2.0f;
|
||||
static constexpr float TRAIL_DELAY = 0.45f; // seconds the lost amount lingers before draining
|
||||
static constexpr float TRAIL_DRAIN_SPEED = 0.6f; // of the whole bar a second
|
||||
static constexpr float FLASH_TIME = 0.35f;
|
||||
|
||||
static const glm::vec3 BACKGROUND_COLOR(0.03f, 0.04f, 0.06f);
|
||||
static const glm::vec3 HURT_BACKGROUND_COLOR(0.45f, 0.06f, 0.05f);
|
||||
static const glm::vec3 TRAIL_COLOR(0.98f, 0.92f, 0.80f);
|
||||
static const glm::vec3 DIMMED_COLOR(0.38f, 0.40f, 0.44f);
|
||||
static const glm::vec3 TEXT_COLOR(0.95f, 0.97f, 1.0f);
|
||||
|
||||
// Drawn from images: the empty part is the fill image darkened, the lost part the fill image brightened
|
||||
static const glm::vec3 IMAGE_EMPTY_TINT(0.16f, 0.13f, 0.13f);
|
||||
static const glm::vec3 IMAGE_HURT_TINT(0.55f, 0.18f, 0.16f);
|
||||
static const glm::vec3 IMAGE_TRAIL_TINT(2.2f, 1.9f, 1.7f);
|
||||
|
||||
static ImageBox* MakeImage(Texture* texture) {
|
||||
ImageBox* image = new ImageBox();
|
||||
image->surface = SurfaceTexture::Stretched(texture);
|
||||
image->Opacity = 0.0f;
|
||||
image->BindToRenderSystem();
|
||||
return image;
|
||||
}
|
||||
|
||||
static Box* MakeBox(const glm::vec3& color) {
|
||||
Box* box = new Box();
|
||||
box->Color = color;
|
||||
box->Opacity = 0.0f;
|
||||
box->BindToRenderSystem();
|
||||
return box;
|
||||
}
|
||||
|
||||
StatBar::StatBar(Font* font, const Style& newStyle) : style(newStyle) {
|
||||
if (Images()) {
|
||||
background = MakeImage(style.fillImage);
|
||||
trail = MakeImage(style.fillImage);
|
||||
fill = MakeImage(style.fillImage);
|
||||
if (style.frameImage)
|
||||
frame = MakeImage(style.frameImage);
|
||||
}
|
||||
else {
|
||||
background = MakeBox(BACKGROUND_COLOR);
|
||||
background->rounding = 0.5f;
|
||||
trail = MakeBox(TRAIL_COLOR);
|
||||
fill = MakeBox(style.fillColor);
|
||||
}
|
||||
|
||||
label = new TextBox();
|
||||
label->font = font;
|
||||
label->fontsize = style.labelSize;
|
||||
label->Color = TEXT_COLOR;
|
||||
label->Opacity = 0.0f;
|
||||
label->textCenter = { 0.0f, 1.0f };
|
||||
label->BindToRenderSystem();
|
||||
}
|
||||
|
||||
float StatBar::GetHeight() const {
|
||||
return LABEL_HEIGHT + LABEL_GAP + style.height;
|
||||
}
|
||||
|
||||
void StatBar::Update(float dt, float opacity, float target, const std::string& text, const glm::vec2& position,
|
||||
bool reset, bool dimmed) {
|
||||
target = glm::clamp(target, 0.0f, 1.0f);
|
||||
if (reset) {
|
||||
fraction = trailFraction = target;
|
||||
flash = 0.0f;
|
||||
trailWait = 0.0f;
|
||||
}
|
||||
|
||||
if (style.showLoss && target < fraction - 0.0001f) {
|
||||
flash = 1.0f;
|
||||
trailWait = TRAIL_DELAY;
|
||||
}
|
||||
fraction = target;
|
||||
|
||||
if (style.showLoss) {
|
||||
trailWait -= dt;
|
||||
if (trailWait <= 0.0f)
|
||||
trailFraction = std::max(trailFraction - TRAIL_DRAIN_SPEED * dt, fraction);
|
||||
trailFraction = std::max(trailFraction, fraction); // filling back up doesn't leave a trail
|
||||
}
|
||||
else {
|
||||
trailFraction = fraction;
|
||||
}
|
||||
flash = std::max(flash - dt / FLASH_TIME, 0.0f);
|
||||
dim += ((dimmed ? 1.0f : 0.0f) - dim) * (1.0f - std::exp(-10.0f * dt));
|
||||
|
||||
const glm::vec2 barTopLeft = glm::round(position + glm::vec2(0.0f, LABEL_HEIGHT + LABEL_GAP));
|
||||
|
||||
label->text = text;
|
||||
label->t2d.position = { 0.0f, 0.0f, std::round(position.x + 2.0f), std::round(position.y) };
|
||||
label->t2d.size = { 0.0f, 0.0f, style.width, LABEL_HEIGHT };
|
||||
label->Opacity = text.empty() ? 0.0f : opacity;
|
||||
|
||||
// The fill color all the way down to lowFraction, then turning to lowColor
|
||||
const float low = 1.0f - glm::clamp(fraction / std::max(style.lowFraction, 0.0001f), 0.0f, 1.0f);
|
||||
glm::vec3 color = glm::mix(style.fillColor, style.lowColor, low);
|
||||
color = glm::mix(color, DIMMED_COLOR, dim);
|
||||
color = glm::mix(color, glm::vec3(1.0f), flash * 0.5f);
|
||||
|
||||
if (Images()) {
|
||||
// Every layer covers the whole bar, the trail and fill cropped from the left to how much they show
|
||||
auto Place = [&](Box* box, float shown) {
|
||||
box->t2d.position = { 0.0f, 0.0f, barTopLeft.x, barTopLeft.y };
|
||||
box->t2d.size = { 0.0f, 0.0f, std::round(style.width * shown), style.height };
|
||||
static_cast<ImageBox*>(box)->crop = glm::vec2(shown, 1.0f);
|
||||
};
|
||||
Place(background, 1.0f);
|
||||
background->Color = glm::mix(IMAGE_EMPTY_TINT, IMAGE_HURT_TINT, flash);
|
||||
background->Opacity = opacity * 0.9f;
|
||||
|
||||
Place(trail, trailFraction);
|
||||
trail->Color = IMAGE_TRAIL_TINT;
|
||||
trail->Opacity = trailFraction > fraction ? opacity : 0.0f;
|
||||
|
||||
Place(fill, fraction);
|
||||
fill->Color = color;
|
||||
fill->Opacity = fraction > 0.0f ? opacity : 0.0f;
|
||||
|
||||
if (frame) {
|
||||
Place(frame, 1.0f);
|
||||
frame->Opacity = opacity;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const float inner = style.width - BAR_BORDER * 2.0f;
|
||||
const float innerHeight = style.height - BAR_BORDER * 2.0f;
|
||||
|
||||
background->t2d.position = { 0.0f, 0.0f, barTopLeft.x, barTopLeft.y };
|
||||
background->t2d.size = { 0.0f, 0.0f, style.width, style.height };
|
||||
background->Color = glm::mix(BACKGROUND_COLOR, HURT_BACKGROUND_COLOR, flash);
|
||||
background->Opacity = opacity * 0.8f;
|
||||
|
||||
trail->t2d.position = { 0.0f, 0.0f, barTopLeft.x + BAR_BORDER, barTopLeft.y + BAR_BORDER };
|
||||
trail->t2d.size = { 0.0f, 0.0f, std::round(inner * trailFraction), innerHeight };
|
||||
trail->Opacity = opacity * 0.85f;
|
||||
|
||||
fill->t2d.position = { 0.0f, 0.0f, barTopLeft.x + BAR_BORDER, barTopLeft.y + BAR_BORDER };
|
||||
fill->t2d.size = { 0.0f, 0.0f, std::round(inner * fraction), innerHeight };
|
||||
fill->Color = color;
|
||||
fill->Opacity = opacity;
|
||||
}
|
||||
Reference in New Issue
Block a user