Skip to content

Commit

Permalink
Allow Sprite and Fonts to be tinted
Browse files Browse the repository at this point in the history
Long awaited feature!
  • Loading branch information
griffithsh committed Aug 10, 2024
1 parent 0717c01 commit cf0ae38
Show file tree
Hide file tree
Showing 6 changed files with 37 additions and 11 deletions.
1 change: 0 additions & 1 deletion game/embark/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,6 @@ func (em *Manager) addRoadwayEntity(key geom.Key, dir geom.DirectionType) {
X: sx, Y: sy,
W: 20, H: 12,
})

}

func (em *Manager) addFeatureEntity(feat Feature, m, n, layer int) {
Expand Down
14 changes: 9 additions & 5 deletions game/font.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@ type Font struct {
// Align string // Align should be (left|wrap|center|right)
// Width int // Width is relevant to wrap, center, and right Alignments

// N.B. Don't add Color here! A Color tint would need to be applied to a
// sprite anyway in order to tint the underlying Sprite-base Entities, so it
// should be it's one Component that could also be applied to Sprite directly.
// N.B. The color of text can be set with a Tint component. Don't be tempted
// to add coloring here.
}

// Type of this Component.
Expand Down Expand Up @@ -370,9 +369,9 @@ func switchRuneNormal(r rune) (w, h, x, y int) {
func (s *FontSystem) construct(parent ecs.Entity) {
font := s.mgr.Component(parent, "Font").(*Font)
position := s.mgr.Component(parent, "Position").(*Position)
scale, ok := s.mgr.Component(parent, "Scale").(*Scale)
tint, _ := s.mgr.Component(parent, "Tint").(*Tint)
offset, _ := s.mgr.Component(parent, "RenderOffset").(*RenderOffset)

scale, ok := s.mgr.Component(parent, "Scale").(*Scale)
if !ok {
scale = &Scale{
X: 1,
Expand Down Expand Up @@ -418,6 +417,11 @@ func (s *FontSystem) construct(parent ecs.Entity) {
Y: scale.Y,
})
}
if tint != nil {
s.mgr.AddComponent(e, &Tint{
R: tint.R, G: tint.G, B: tint.B,
})
}
s.mgr.AddComponent(e, &Position{
Center: Center{
X: position.Center.X + px + float64(w)/2,
Expand Down
6 changes: 1 addition & 5 deletions game/sprite.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,7 @@ type Sprite struct {
OffsetX int `json:"offsetX"`
OffsetY int `json:"offsetY"`

// This could include a color, but does not for now, as there are no uses for it.
// Color *color.RGBA
// NB It might make more sense to keep Color/Tint as a separate Component
// so that it can be applied to non-sprite renderable things, like solid-
// color or bordered shapes.
// FYI, you can alter a Sprite's color with the Tint component.
}

// Type of this Component.
Expand Down
14 changes: 14 additions & 0 deletions game/tint.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package game

// Tint sets the color of the entity when it is rendered.
type Tint struct {
R, G, B uint8
}

var TintPseudoBlack = Tint{R: 0x14, G: 0x1b, B: 0x27}
var TintPseudoWhite = Tint{R: 0xda, G: 0xe1, B: 0xe5}

// Type of this Component.
func (*Tint) Type() string {
return "Tint"
}
2 changes: 2 additions & 0 deletions output/uiVisualizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"
"image"

"github.com/griffithsh/squads/game"
"github.com/griffithsh/squads/ui"
"github.com/hajimehoshi/ebiten/v2"
)
Expand Down Expand Up @@ -229,6 +230,7 @@ func (uv *uiVisualizer) drawText(screen *ebiten.Image, value string, size ui.Tex
img := img.SubImage(image.Rect(char.X, char.Y, char.X+char.Width, char.Y+char.Height)).(*ebiten.Image)
op := ebiten.DrawImageOptions{}
op.GeoM.Translate(x, y)
op.ColorScale.Scale(float32(game.TintPseudoWhite.R)/255, float32(game.TintPseudoWhite.G)/255, float32(game.TintPseudoWhite.B)/255, 1)
screen.DrawImage(img, &op)
x += float64(char.Width)

Expand Down
11 changes: 11 additions & 0 deletions output/visualizer.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ type entity struct {
p *game.Position
offset *game.RenderOffset
scale *game.Scale
tint *game.Tint
repeat *game.SpriteRepeat
alpha *game.Alpha
}
Expand Down Expand Up @@ -151,6 +152,9 @@ func (r *Visualizer) getEntities(mgr *ecs.World) []entity {
if scale, ok := mgr.Component(e, "Scale").(*game.Scale); ok {
ent.scale = scale
}
if tint, ok := mgr.Component(e, "Tint").(*game.Tint); ok {
ent.tint = tint
}
if repeat, ok := mgr.Component(e, "SpriteRepeat").(*game.SpriteRepeat); ok {
ent.repeat = repeat
}
Expand Down Expand Up @@ -329,13 +333,20 @@ func (r *Visualizer) renderEntity(e entity, focusX, focusY, zoom, screenW, scree
offX, offY := float64(x), float64(y)

op := e.drawImageOptions(focusX, focusY, screenW/zoom, screenH/zoom, offX, offY)
if e.tint != nil {
op.ColorScale.Scale(float32(e.tint.R)/255, float32(e.tint.G)/255, float32(e.tint.B)/255, 1)
}
target.DrawImage(tile, op)

}
}
return nil
}

op := e.drawImageOptions(focusX, focusY, screenW/zoom, screenH/zoom, 0, 0)
if e.tint != nil {
op.ColorScale.Scale(float32(e.tint.R)/255, float32(e.tint.G)/255, float32(e.tint.B)/255, 1)
}
target.DrawImage(img, op)

return nil
Expand Down

0 comments on commit cf0ae38

Please sign in to comment.