diff options
| author | Florian Fischer <florian.fischer@muhq.space> | 2023-02-26 10:26:57 +0100 |
|---|---|---|
| committer | Florian Fischer <florian.fischer@muhq.space> | 2025-01-27 16:43:52 +0100 |
| commit | ea1df280fc4ced38ce35516c0f4e5c95e17ccc6d (patch) | |
| tree | b97908c0c03b5814602fcadf79fa56f08692f532 | |
| parent | fe0cfc82c6cf3d3576de94e0f8b294761067af81 (diff) | |
| download | muhqs-game-ea1df280fc4ced38ce35516c0f4e5c95e17ccc6d.tar.gz muhqs-game-ea1df280fc4ced38ce35516c0f4e5c95e17ccc6d.zip | |
ui: separate selection and options via their highlight color
| -rw-r--r-- | go/TODO | 1 | ||||
| -rw-r--r-- | go/client/game.go | 23 | ||||
| -rw-r--r-- | go/ui/cardGrid.go | 36 | ||||
| -rw-r--r-- | go/ui/colors.go | 3 | ||||
| -rw-r--r-- | go/ui/mapView.go | 70 |
5 files changed, 78 insertions, 55 deletions
@@ -1,5 +1,4 @@ * Fix data race between UI and game loop (possible big state lock) -* implement different highlighting used for selection and candidates * implement representation of next target and current seelction in prompt * implement equipment play equipped to next unit * implement equipment actions diff --git a/go/client/game.go b/go/client/game.go index 0e516815..787987d5 100644 --- a/go/client/game.go +++ b/go/client/game.go @@ -2,6 +2,7 @@ package main import ( "fmt" + "image/color" "log" "github.com/hajimehoshi/ebiten/v2" @@ -307,24 +308,24 @@ func (g *Game) removePrompt() { g.prompt = nil } -func (g *Game) addHighlight(obj interface{}) { +func (g *Game) addHighlight(obj interface{}, color color.Color) { switch obj := obj.(type) { case ui.HandCard: - g.handLayer.AddHighlightCard(obj.C) + g.handLayer.AddHighlightCard(obj.C, color) case *game.Card: - g.handLayer.AddHighlightCard(obj) + g.handLayer.AddHighlightCard(obj, color) case *game.Tile: - g.mapView.AddHighlightTile(obj) + g.mapView.AddHighlightTile(obj, color) case *game.Unit: - g.mapView.AddHighlightPermanent(obj) + g.mapView.AddHighlightPermanent(obj, color) default: log.Panicf("Unhandled highlight of type %T", obj) } } -func (g *Game) addHighlights(objs []interface{}) { +func (g *Game) addHighlights(objs []interface{}, color color.Color) { for _, obj := range objs { - g.addHighlight(obj) + g.addHighlight(obj, color) } } @@ -475,7 +476,7 @@ func (g *Game) handleSelection(obj interface{}, x, y int) { a := game.NewPlayAction(g.activePlayer, obj.C) if a.Targets().RequireSelection() { g.addPrompt(a, fmt.Sprintf("Select targets to play %v", obj.C.Name)) - g.handLayer.HighlightCard(obj.C) + g.handLayer.HighlightCard(obj.C, ui.HighlightSelectionColor) } else { g.declareAction(a) } @@ -493,7 +494,7 @@ func (g *Game) updateHighlight() { a := g.prompt.Action() if pa, ok := a.(*game.PlayAction); ok { - g.addHighlight(ui.HandCard{C: pa.Card}) + g.addHighlight(ui.HandCard{C: pa.Card}, ui.HighlightOptionColor) } targets := a.Targets() @@ -502,13 +503,13 @@ func (g *Game) updateHighlight() { } for _, t := range targets.Targets() { - g.addHighlights(t.Selection()) + g.addHighlights(t.Selection(), ui.HighlightSelectionColor) } target := targets.Cur() if target.AllowSelection() { options := target.Options() - g.addHighlights(options) + g.addHighlights(options, ui.HighlightOptionColor) } } diff --git a/go/ui/cardGrid.go b/go/ui/cardGrid.go index 1b86fe35..4cab2da7 100644 --- a/go/ui/cardGrid.go +++ b/go/ui/cardGrid.go @@ -1,14 +1,13 @@ package ui import ( + "image/color" "log" "math" "github.com/hajimehoshi/ebiten/v2" "muhq.space/muhqs-game/go/assets" "muhq.space/muhqs-game/go/game" - - "golang.org/x/exp/slices" ) type CardGrid struct { @@ -18,7 +17,7 @@ type CardGrid struct { scale float64 cardWidth, cardHeight float64 xOffset, yOffset int - highlights []*game.Card + highlights map[*game.Card]color.Color grid *ebiten.Image gridCards int } @@ -28,6 +27,7 @@ func NewCardGrid(x, y, width, height int, scale float64, cards game.PileOfCards) WidgetBase: NewWidgetBase(x, y, width, height), cards: cards, scale: scale, + highlights: make(map[*game.Card]color.Color), } w.renderImpl = func() *ebiten.Image { return w.render() } return w @@ -97,8 +97,8 @@ func (w *CardGrid) render() *ebiten.Image { op.GeoM.Scale(w.scale, w.scale) op.GeoM.Translate(xOffset, yOffset) - if slices.Contains(w.highlights, card) { - op.ColorM.Scale(1, 0, 0, 0.5) + if c, found := w.highlights[card]; found { + op.ColorM.ScaleWithColor(c) } w.grid.DrawImage(cardImg, op) @@ -151,23 +151,33 @@ func (w *CardGrid) FindObjectAt(_x, _y int) interface{} { return w.cards.Cards()[i] } -func (w *CardGrid) setHighlights(cards []*game.Card) { - w.highlights = cards - // Reset the grid card count to force grid to be redrawn containing the highlights +func (w *CardGrid) forceRedrawGrid() { + // Reset the grid card count to force grid to be redrawn containing highlight changes w.gridCards = 0 w.ForceRedraw() } -func (w *CardGrid) HighlightCard(card *game.Card) { - w.setHighlights([]*game.Card{card}) +func (w *CardGrid) setHighlights(cards []*game.Card, col color.Color) { + highlights := make(map[*game.Card]color.Color) + for _, c := range cards { + highlights[c] = col + } + + w.highlights = highlights + w.forceRedrawGrid() +} + +func (w *CardGrid) HighlightCard(card *game.Card, color color.Color) { + w.setHighlights([]*game.Card{card}, color) } -func (w *CardGrid) AddHighlightCard(card *game.Card) { - w.setHighlights(append(w.highlights, card)) +func (w *CardGrid) AddHighlightCard(card *game.Card, color color.Color) { + w.highlights[card] = color + w.forceRedrawGrid() } func (w *CardGrid) ClearHighlights() { - w.setHighlights([]*game.Card{}) + w.setHighlights([]*game.Card{}, nil) } func (w *CardGrid) Scroll(x, y int) { diff --git a/go/ui/colors.go b/go/ui/colors.go index d8422479..1f3fcb6c 100644 --- a/go/ui/colors.go +++ b/go/ui/colors.go @@ -7,4 +7,7 @@ import ( var ( Gray = color.RGBA{0x80, 0x80, 0x80, 0xff} ResourceBg = color.RGBA{230, 180, 128, 0xff} + + HighlightSelectionColor = color.RGBA{0xc7, 0x89, 0x33, 0xff} + HighlightOptionColor = color.RGBA{0xc7, 0x52, 0x33, 0xff} ) diff --git a/go/ui/mapView.go b/go/ui/mapView.go index 0553b348..721356ff 100644 --- a/go/ui/mapView.go +++ b/go/ui/mapView.go @@ -2,13 +2,12 @@ package ui import ( "fmt" + "image/color" "log" "math" "strings" "unicode" - "golang.org/x/exp/slices" - "github.com/hajimehoshi/ebiten/v2" "muhq.space/muhqs-game/go/assets" "muhq.space/muhqs-game/go/game" @@ -27,12 +26,16 @@ type MapView struct { gameState *game.State mapLayer *ebiten.Image permanentsLayer *ebiten.Image - tileHighlights []game.Position - permanentsHighlights []game.Permanent + tileHighlights map[game.Position]color.Color + permanentsHighlights map[game.Permanent]color.Color } func NewMapView(g *game.State) *MapView { - vw := &MapView{gameState: g} + vw := &MapView{ + gameState: g, + tileHighlights: make(map[game.Position]color.Color), + permanentsHighlights: make(map[game.Permanent]color.Color), + } vw.hoverPermInfo.init(vw) return vw } @@ -128,8 +131,8 @@ func (vw *MapView) drawMapLayer(screen *ebiten.Image) { op.GeoM.Translate(x_px, y_px) - if slices.Contains(vw.tileHighlights, pos) { - op.ColorM.Scale(1, 0, 0, 0.5) + if color, found := vw.tileHighlights[pos]; found { + op.ColorM.ScaleWithColor(color) } vw.mapLayer.DrawImage(tileImg, op) @@ -175,11 +178,8 @@ func (vw *MapView) drawPermanentsLayer(screen *ebiten.Image) { op.GeoM.Translate(float64(x_px), float64(y_px)) op.ColorM.ScaleWithColor(p.Controller().Color) - for _, h := range vw.permanentsHighlights { - if p == h { - op.ColorM.Scale(255, 0.5, 0.5, 1) - break - } + if color, found := vw.permanentsHighlights[p]; found { + op.ColorM.ScaleWithColor(color) } vw.permanentsLayer.DrawImage(permanentSymbol, op) @@ -244,50 +244,60 @@ func (vw *MapView) FindObjectAt(screenX, screenY int) interface{} { return nil } -func (vw *MapView) HighlightPositions(pos []game.Position) { - vw.tileHighlights = pos +func (vw *MapView) HighlightPositions(pos []game.Position, col color.Color) { + highlights := make(map[game.Position]color.Color) + for _, p := range pos { + highlights[p] = col + } + vw.tileHighlights = highlights vw.ForceRedraw() } -func (vw *MapView) AddHighlightPosition(pos game.Position) { - vw.HighlightPositions(append(vw.tileHighlights, pos)) +func (vw *MapView) AddHighlightPosition(pos game.Position, color color.Color) { + vw.tileHighlights[pos] = color + vw.ForceRedraw() } -func (vw *MapView) HighlightTiles(tiles []*game.Tile) { +func (vw *MapView) HighlightTiles(tiles []*game.Tile, color color.Color) { pos := make([]game.Position, 0, len(tiles)) for _, t := range tiles { pos = append(pos, t.Position) } - vw.HighlightPositions(pos) + vw.HighlightPositions(pos, color) } -func (vw *MapView) HighlightTile(t *game.Tile) { - vw.HighlightTiles([]*game.Tile{t}) +func (vw *MapView) HighlightTile(t *game.Tile, color color.Color) { + vw.HighlightTiles([]*game.Tile{t}, color) } -func (vw *MapView) AddHighlightTile(t *game.Tile) { - vw.AddHighlightPosition(t.Position) +func (vw *MapView) AddHighlightTile(t *game.Tile, color color.Color) { + vw.AddHighlightPosition(t.Position, color) } func (vw *MapView) ClearTileHighlights() { - vw.HighlightTiles([]*game.Tile{}) + vw.HighlightTiles([]*game.Tile{}, nil) } -func (vw *MapView) HighlightPermanents(permanents []game.Permanent) { - vw.permanentsHighlights = permanents +func (vw *MapView) HighlightPermanents(permanents []game.Permanent, col color.Color) { + highlights := make(map[game.Permanent]color.Color) + for _, p := range permanents { + highlights[p] = col + } + vw.permanentsHighlights = highlights vw.ForceRedraw() } -func (vw *MapView) AddHighlightPermanent(p game.Permanent) { - vw.HighlightPermanents(append(vw.permanentsHighlights, p)) +func (vw *MapView) AddHighlightPermanent(p game.Permanent, color color.Color) { + vw.ForceRedraw() + vw.permanentsHighlights[p] = color } -func (vw *MapView) HighlightPermanent(p game.Permanent) { - vw.HighlightPermanents([]game.Permanent{p}) +func (vw *MapView) HighlightPermanent(p game.Permanent, color color.Color) { + vw.HighlightPermanents([]game.Permanent{p}, color) } func (vw *MapView) ClearPermanentsHighlights() { - vw.HighlightPermanents([]game.Permanent{}) + vw.HighlightPermanents([]game.Permanent{}, nil) } func (mv *MapView) Contains(x, y int) bool { |
