Files
pobounty/asb.go
2023-09-17 13:34:03 -04:00

201 lines
4.7 KiB
Go

package main
import (
"bytes"
_ "embed"
"fmt"
"image"
"image/color"
"log"
"math"
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/text"
)
const (
ASB_HEIGHT = 50
ASB_BUFFER = 10
ASB_WIDTH = 1400
ASB_COLOR = 0x5d2f6a
ASB_MARGIN = 10
ASB_GRAD_TOP = 0x9933cc
ASB_GRAD_BOTTOM = 0x5d2f6a
ASB_FLAME_SCALE = 1.56
ASB_FLAME_OFFSET = 15
ASB_MASK_WIDTH = 10
ASB_MASK_HEIGHT = ASB_HEIGHT
ASB_STRFADE_XOFFSET = 80
ASB_STRFADE_YOFFSET = 50
ASB_STRFADE_VALUE = 0x50
)
var (
//go:embed resources/images/barmask.png
barmaskAsset_png []byte
assetsBarmask *ebiten.Image
)
type AnimatedScoreBar struct {
ScoreImage *ebiten.Image
name string
target float64
value float64
gradient *image.RGBA
character *Character
flames *Flame
barbuffer *ebiten.Image
order int //ranking
sf float64 //scaling factor
}
func NewAnimatedScoreBar(t CharacterType, s string) *AnimatedScoreBar {
a := &AnimatedScoreBar{
name: s,
target: 0,
value: 0,
sf: 1,
ScoreImage: ebiten.NewImage(ASB_WIDTH, ASB_HEIGHT),
barbuffer: ebiten.NewImage(ASB_WIDTH, ASB_HEIGHT),
character: NewCharacter(t),
flames: NewFlame(),
order: 0,
}
a.character.RandomizeCycleStart()
//fill bar gradient
a.gradient = image.NewRGBA(image.Rect(0, 0, ASB_WIDTH, ASB_HEIGHT))
FillGradient(a.gradient, a.barbuffer.Bounds().Dx(), a.barbuffer.Bounds().Dy(), HexToRGBA(ASB_GRAD_TOP), HexToRGBA(ASB_GRAD_BOTTOM))
a.barbuffer.WritePixels(a.gradient.Pix)
//mask start of the bar for smooth edges
op := &ebiten.DrawImageOptions{}
op.Blend = ebiten.BlendDestinationOut
a.barbuffer.DrawImage(assetsBarmask.SubImage(image.Rect(0, 0, ASB_MASK_WIDTH, ASB_MASK_HEIGHT)).(*ebiten.Image), op)
//add name to the fill bar, which will gradually display as the value increases
text.Draw(a.barbuffer, a.name, DashFont.TeamBarName, ASB_MARGIN, ASB_HEIGHT-ASB_MARGIN, color.White)
return a
}
func (a *AnimatedScoreBar) GetCharacterType() CharacterType {
return a.character.GetType()
}
func (a *AnimatedScoreBar) Name() string {
return a.name
}
func (a *AnimatedScoreBar) SetTarget(t float64) {
a.target = t
}
func (a *AnimatedScoreBar) GetTarget() float64 {
return a.target
}
func (a *AnimatedScoreBar) GetValue() float64 {
return a.value
}
func (a *AnimatedScoreBar) Animate() {
a.ScoreImage.Clear()
a.AddFadedTeamName()
a.AddScoreBar()
a.AddCharacter()
a.AddTextScore()
a.AdjustValue()
}
func (a *AnimatedScoreBar) AddFadedTeamName() {
//alpha blended black for the team name
c := HexToRGBA(0x000000)
c.A = ASB_STRFADE_VALUE
text.Draw(a.ScoreImage, a.name, DashFont.TeamBackgroundName, ASB_STRFADE_XOFFSET, ASB_STRFADE_YOFFSET, c)
}
func (a *AnimatedScoreBar) SetOrder(order int) {
a.order = order
}
func (a *AnimatedScoreBar) GetOrder() int {
return a.order
}
// draw our score bar by using subset of full bar
func (a *AnimatedScoreBar) AddScoreBar() {
//ss = subset start, se = subset end
ssx := 0
ssy := 0
sex := int(a.value * a.sf)
sey := ASB_HEIGHT
barSubImage := a.barbuffer.SubImage(image.Rect(ssx, ssy, sex, sey)).(*ebiten.Image)
a.ScoreImage.DrawImage(barSubImage, nil)
//add trailing image mask to round out the edges
op := &ebiten.DrawImageOptions{}
op.Blend = ebiten.BlendDestinationOut
op.GeoM.Translate(float64(sex)-ASB_MASK_WIDTH, float64(sey)-ASB_MASK_HEIGHT)
msx := ASB_MASK_WIDTH
msy := 0
mex := ASB_MASK_WIDTH + ASB_MASK_WIDTH
mey := ASB_MASK_HEIGHT
a.ScoreImage.DrawImage(assetsBarmask.SubImage(image.Rect(msx, msy, mex, mey)).(*ebiten.Image), op)
}
func (a *AnimatedScoreBar) AddCharacter() {
op := &ebiten.DrawImageOptions{}
//if we're on the move, let's add some flair to the character
if a.target != a.value {
op.GeoM.Scale(ASB_FLAME_SCALE, ASB_FLAME_SCALE)
op.GeoM.Rotate(-math.Pi / 4)
op.GeoM.Translate(a.value*a.sf+ASB_BUFFER-ASB_FLAME_OFFSET*5/2, ASB_FLAME_OFFSET*3/2)
a.ScoreImage.DrawImage(a.flames.Sprite, op)
a.flames.Animate()
}
op = &ebiten.DrawImageOptions{}
op.GeoM.Translate(a.value*a.sf+ASB_BUFFER, 0)
a.ScoreImage.DrawImage(a.character.Sprite, op)
a.character.Animate()
}
func (a *AnimatedScoreBar) AddTextScore() {
tx := int(a.value*a.sf) + ASB_BUFFER + a.character.GetWidth()
ty := ASB_HEIGHT
text.Draw(a.ScoreImage, fmt.Sprintf("%0.f", a.value), DashFont.Title, tx, ty, color.White)
text.Draw(a.ScoreImage, "POINTS", DashFont.Title, tx+ASB_BUFFER*7, ty, color.White)
}
func (a *AnimatedScoreBar) AdjustValue() {
if a.value < a.target {
a.value++
}
}
func (a *AnimatedScoreBar) SetScaleFactor(sf float64) {
a.sf = sf
}
func (a *AnimatedScoreBar) Reset() {
a.value = 0
}
func init() {
img, _, err := image.Decode(bytes.NewReader(barmaskAsset_png))
if err != nil {
log.Fatal(err)
}
assetsBarmask = ebiten.NewImageFromImage(img)
}