aboutsummaryrefslogtreecommitdiff
path: root/go/ui/hand.go
blob: f71572328aabed10c017fdb4686c18e15de16aaa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package ui

import (
	"log"

	"github.com/hajimehoshi/ebiten/v2"
	"muhq.space/muhqs-game/go/assets"
	"muhq.space/muhqs-game/go/game"

	"golang.org/x/exp/slices"
)

type HandCard struct {
	C *game.Card
}

type HandView struct {
	WidgetBase
	hand          *game.Hand
	cardWidth     float64
	cardHeight    float64
	scale         float64
	bottomAligned bool
	highlights    []*game.Card
}

func NewHandView(x, y, width, height int, h *game.Hand, bottomAligned bool) *HandView {
	hv := &HandView{
		WidgetBase:    NewWidgetBase(x, y, width, height),
		hand:          h,
		cardWidth:     0,
		cardHeight:    0,
		scale:         0,
		bottomAligned: bottomAligned,
		highlights:    []*game.Card{},
	}
	hv.renderImpl = func() *ebiten.Image { return hv.render() }
	return hv
}

func (hv *HandView) render() *ebiten.Image {
	img := ebiten.NewImage(hv.Width, hv.Height)
	handCards := hv.hand.Cards()
	nHandCards := len(handCards)
	for i, card := range handCards {
		cardImg := assets.GetCard(card.Path(), "en")
		if cardImg == nil {
			log.Fatalf("No image found for %s", card.Path())
		}

		if hv.scale == 0 {
			b := cardImg.Bounds()
			x_scale := (float64(hv.Width) / float64(nHandCards)) / float64(b.Dx())
			y_scale := float64(hv.Height) / float64(b.Dy())
			hv.scale = x_scale
			if y_scale < x_scale {
				hv.scale = y_scale
			}
			hv.cardWidth = float64(b.Dx()) * hv.scale
			hv.cardHeight = float64(b.Dy()) * hv.scale
		}

		yOffset := 0.0
		if hv.bottomAligned {
			yOffset = float64(hv.Height) - hv.cardHeight
		}

		op := &ebiten.DrawImageOptions{}
		op.GeoM.Scale(hv.scale, hv.scale)
		op.GeoM.Translate(float64(i)*hv.cardWidth, yOffset)

		if slices.Contains(hv.highlights, card) {
			op.ColorM.Scale(1, 0, 0, 0.5)
		}

		img.DrawImage(cardImg, op)
	}
	return img
}

func (hv *HandView) FindObjectAt(x, y int) interface{} {
	if !hv.Contains(x, y) {
		return nil
	}

	if hv.bottomAligned && float64(y-hv.Y) < float64(hv.Height)-hv.cardHeight {
		return nil
	}

	i := int(float64(x) / hv.cardWidth)
	if i >= hv.hand.Size() {
		return nil
	}

	return HandCard{hv.hand.Cards()[i]}
}

func (hv *HandView) setHighlights(cards []*game.Card) {
	hv.highlights = cards
	hv.ForceRedraw()
}

func (hv *HandView) HighlightCard(card *game.Card) {
	hv.setHighlights([]*game.Card{card})
}

func (hv *HandView) AddHighlightCard(card *game.Card) {
	hv.setHighlights(append(hv.highlights, card))
}

func (hv *HandView) ClearHighlights() {
	hv.setHighlights([]*game.Card{})
}