Add basic colour-determining functionality
This commit is contained in:
parent
45e5465a08
commit
266842afd4
|
|
@ -0,0 +1,79 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Seraphina
|
||||||
|
{
|
||||||
|
public static class ColorHelper
|
||||||
|
{
|
||||||
|
public static void ColorToHSV(Color color, out double hue, out double saturation, out double value)
|
||||||
|
{
|
||||||
|
int max = Math.Max(color.R, Math.Max(color.G, color.B));
|
||||||
|
int min = Math.Min(color.R, Math.Min(color.G, color.B));
|
||||||
|
|
||||||
|
hue = color.GetHue();
|
||||||
|
saturation = (max == 0) ? 0 : 1d - (1d * min / max);
|
||||||
|
value = max / 255d;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Color ColorFromHSV(double hue, double saturation = 1, double value = 1)
|
||||||
|
{
|
||||||
|
int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
|
||||||
|
double f = hue / 60 - Math.Floor(hue / 60);
|
||||||
|
|
||||||
|
value *= 255;
|
||||||
|
int v = Convert.ToInt32(value);
|
||||||
|
int p = Convert.ToInt32(value * (1 - saturation));
|
||||||
|
int q = Convert.ToInt32(value * (1 - f * saturation));
|
||||||
|
int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));
|
||||||
|
|
||||||
|
return hi switch
|
||||||
|
{
|
||||||
|
0 => Color.FromArgb(v, t, p),
|
||||||
|
1 => Color.FromArgb(q, v, p),
|
||||||
|
2 => Color.FromArgb(p, v, t),
|
||||||
|
3 => Color.FromArgb(p, q, v),
|
||||||
|
4 => Color.FromArgb(t, p, v),
|
||||||
|
_ => Color.FromArgb(v, p, q),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a colour from the provided HSL values.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hue">The hue, from 0 to 360.</param>
|
||||||
|
/// <param name="sat">The saturation, from 0 to 1.</param>
|
||||||
|
/// <param name="lightness">The lightness, from 0 to 1.</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static Color ColorFromHSL(double hue, double sat = 1, double lightness = 0.5)
|
||||||
|
{
|
||||||
|
if (sat == 0)
|
||||||
|
{
|
||||||
|
int L = (int)lightness;
|
||||||
|
return Color.FromArgb(255, L, L, L);
|
||||||
|
}
|
||||||
|
|
||||||
|
double min, max, h;
|
||||||
|
h = hue / 360d;
|
||||||
|
|
||||||
|
max = lightness < 0.5d ? lightness * (1 + sat) : (lightness + sat) - (lightness * sat);
|
||||||
|
min = (lightness * 2d) - max;
|
||||||
|
|
||||||
|
return Color.FromArgb(255, (int)(255 * RGBChannelFromHue(min, max, h + 1 / 3d)),
|
||||||
|
(int)(255 * RGBChannelFromHue(min, max, h)),
|
||||||
|
(int)(255 * RGBChannelFromHue(min, max, h - 1 / 3d)));
|
||||||
|
}
|
||||||
|
|
||||||
|
static double RGBChannelFromHue(double m1, double m2, double h)
|
||||||
|
{
|
||||||
|
h = (h + 1d) % 1d;
|
||||||
|
if (h < 0) h += 1;
|
||||||
|
if (h * 6 < 1) return m1 + (m2 - m1) * 6 * h;
|
||||||
|
else if (h * 2 < 1) return m2;
|
||||||
|
else if (h * 3 < 2) return m1 + (m2 - m1) * 6 * (2d / 3d - h);
|
||||||
|
else return m1;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
||||||
|
using Seraphina.Core;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Seraphina
|
||||||
|
{
|
||||||
|
public static class PlayerHealthColor
|
||||||
|
{
|
||||||
|
|
||||||
|
const int MinHp = 100;
|
||||||
|
const int MaxHp = 500;
|
||||||
|
const int HpDiff = MaxHp - MinHp;
|
||||||
|
|
||||||
|
const int MinHue = 100;
|
||||||
|
const int MaxHue = 300;
|
||||||
|
const int HueDiff = MaxHue - MinHue;
|
||||||
|
static readonly Color ZeroHp = Color.FromArgb(0, 255, 0, 0);
|
||||||
|
public static Color GetColor(HitPoint numerator, HitPoint denominator)
|
||||||
|
{
|
||||||
|
if (numerator <= 0) return ZeroHp; // Transparent red, for calculation consistency.
|
||||||
|
// XXX: Calculate the colour before rendering it transparent? Would it be a waste?
|
||||||
|
|
||||||
|
// Scale the HitPoint based on its percentage.
|
||||||
|
double pct = numerator.Value * 1.0 / denominator.Value;
|
||||||
|
if (denominator < MinHp)
|
||||||
|
{
|
||||||
|
return ColorHelper.ColorFromHSV(pct * 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Scale the maximum hue by dividing anything over 100 by 2.
|
||||||
|
// ie 100 => 100, 200 => 150, 300 => 200, 500 => 300
|
||||||
|
var maxHue = ((denominator.Value - MinHp) / 2) + MinHp;
|
||||||
|
|
||||||
|
// Cap at 300 hue if max HitPoint is over 500 for some reason.
|
||||||
|
maxHue = Math.Min(MaxHue, maxHue);
|
||||||
|
|
||||||
|
var color = ColorHelper.ColorFromHSV(maxHue * pct);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
using Seraphina.Core;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Drawing;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Seraphina
|
||||||
|
{
|
||||||
|
public static class PlayerManaColor
|
||||||
|
{
|
||||||
|
// NOTE to more future self: change these around to tweak mana colour.
|
||||||
|
const double minLightness = 0.2;
|
||||||
|
const double maxLightness = 0.8;
|
||||||
|
const double range = maxLightness - minLightness;
|
||||||
|
const int BlueHue = 210;
|
||||||
|
|
||||||
|
public static Color GetColor(ManaPoint current, ManaPoint max)
|
||||||
|
{
|
||||||
|
// NOTE to future self:
|
||||||
|
// Mana could use HSL scale with blue.
|
||||||
|
// The L value coudl follow this formula, assuming 100 max mana:
|
||||||
|
// (mana / 100 * 0.8) + 0.1
|
||||||
|
// Basically, get the mana percentage, multiply it by 80%,
|
||||||
|
// and add 0.1. This will Make the minimum lightness 0.1 and the max 0.9/
|
||||||
|
// This will leave some nice dark and light blues for the mana bar.
|
||||||
|
|
||||||
|
var pct = GetBrightnessValue(current, max);
|
||||||
|
|
||||||
|
return ColorHelper.ColorFromHSL(BlueHue, lightness: pct);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double GetBrightnessValue(ManaPoint num, ManaPoint denom)
|
||||||
|
{
|
||||||
|
var pct = num.Value * 1.0 / denom.Value;
|
||||||
|
pct *= range;
|
||||||
|
return pct + minLightness;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue