aboutsummaryrefslogtreecommitdiff
path: root/go/client/main.go
diff options
context:
space:
mode:
authorFlorian Fischer <florian.fischer@muhq.space>2023-01-24 00:27:50 +0100
committerFlorian Fischer <florian.fischer@muhq.space>2023-01-26 22:17:17 +0100
commit6ec593fb28a0ab789795f1718fba6705ea02ee49 (patch)
treef46010d2a6b69194100fa687e3b27656edb43178 /go/client/main.go
parent7df9fc5d603cc4d67e2a48424218e7a57bc7da18 (diff)
downloadmuhqs-game-6ec593fb28a0ab789795f1718fba6705ea02ee49.tar.gz
muhqs-game-6ec593fb28a0ab789795f1718fba6705ea02ee49.zip
intermediate commit
Diffstat (limited to 'go/client/main.go')
-rw-r--r--go/client/main.go185
1 files changed, 132 insertions, 53 deletions
diff --git a/go/client/main.go b/go/client/main.go
index c8f2e46d..f2b7e36f 100644
--- a/go/client/main.go
+++ b/go/client/main.go
@@ -9,7 +9,7 @@ import (
"github.com/hajimehoshi/ebiten/v2/ebitenutil"
"github.com/hajimehoshi/ebiten/v2/inpututil"
- "muhq.space/muhqs-game/go/assets"
+ "muhq.space/muhqs-game/go/font"
"muhq.space/muhqs-game/go/game"
"muhq.space/muhqs-game/go/ui"
)
@@ -24,23 +24,18 @@ const (
STACK_BUFFER_WIDTH = 300
HOVER_THRESHOLD = 60
-)
-
-type HandLayer struct{}
-func (l *HandLayer) Draw(screen *ebiten.Image) {
- cardImg := assets.GetCard("base/archer", "en")
- op := &ebiten.DrawImageOptions{}
- op.GeoM.Translate(0, float64(screenHeight))
- op.GeoM.Scale(0.5, 0.5)
- screen.DrawImage(cardImg, op)
-}
+ HAND_VIEW_HEIGHT = 500
+ HAND_VIEW_WIDTH = 700
-var (
- playerGreen = color.RGBA{1, 0xff, 1, 0xff}
- playerBlue = color.RGBA{1, 1, 0xff, 0xff}
+ STATE_BAR_WIDTH = 50
)
+var playerColors = []color.RGBA{
+ {1, 0xff, 1, 0xff},
+ {1, 1, 0xff, 0xff},
+}
+
type hoverDetector struct {
last_x, last_y int
ticks int
@@ -70,9 +65,14 @@ func (h *hoverDetector) startedHovering() bool {
type Game struct {
gameState *game.State
- handLayer *HandLayer
+ activePlayer *game.Player
+ playerCtrl *game.ChanPlayerControl
+ hasPriority bool
+ handLayer *ui.HandView
+ stateBar *ui.StateBar
mapView *ui.MapView
- resolveButton *ui.SimpleButton
+ actionChoice *ui.Choice
+ passButton *ui.SimpleButton
stackBuffer *ui.Buffer
widgets []ui.Widget
selectedObject interface{}
@@ -84,13 +84,14 @@ func NewGame() *Game {
g.widgets = []ui.Widget{}
g.gameState = game.NewState()
- g.resolveButton = ui.NewSimpleButton(screenWidth-125, screenHeight-DEFAULT_BUTTON_HEIGHT,
- 125, DEFAULT_BUTTON_HEIGHT, func(*ui.SimpleButton) {
- g.resolveAction()
- }, "Resolve")
- g.addWidget(g.resolveButton)
+ g.passButton = ui.NewSimpleButton(screenWidth-100, screenHeight-DEFAULT_BUTTON_HEIGHT,
+ 100, DEFAULT_BUTTON_HEIGHT, "Pass", func(*ui.SimpleButton) {
+ if g.hasPriority {
+ g.passPriority()
+ }
+ })
- g.stackBuffer = ui.NewBuffer(screenWidth-STACK_BUFFER_WIDTH, g.resolveButton.Y-400,
+ g.stackBuffer = ui.NewBuffer(screenWidth-STACK_BUFFER_WIDTH, g.passButton.Y-400,
STACK_BUFFER_WIDTH, 400)
return g
}
@@ -110,8 +111,21 @@ func (g *Game) loadMap(mapName string) {
g.mapView = ui.NewMapView(g.gameState)
}
-func (g *Game) addPlayer(name string, deck *game.Deck, color color.Color) {
- g.gameState.AddNewPlayer(name, deck, color)
+// func NewGameFromMapWithPlayers(mapName string, players []string, decks []*game.Deck) *Game {
+// g := NewGameFromMap(mapName)
+// activePlayer := g.addPlayer(players[0], decks[0], )
+// g.initPlayerUi(activePlayer)
+
+// for i, p := range players[1:] {
+// g.addPlayer(p, decks[i+1])
+// }
+// return g
+// }
+
+func (g *Game) addPlayer(name string, deck *game.Deck, store *game.Store) *game.Player {
+ color := playerColors[len(g.gameState.Players)]
+ g.gameState.AddNewPlayer(name, deck, game.NewStore(), color)
+ return g.getPlayer(name)
}
func (g *Game) getPlayer(name string) *game.Player {
@@ -123,6 +137,20 @@ func (g *Game) getPlayer(name string) *game.Player {
return nil
}
+func (g *Game) initPlayerUi(player *game.Player) {
+ g.activePlayer = player
+ g.playerCtrl = game.NewChanPlayerControl()
+ player.Ctrl = g.playerCtrl
+
+ g.handLayer = ui.NewHandView(STATE_BAR_WIDTH, g.mapView.GetHeight(),
+ HAND_VIEW_WIDTH, screenHeight-g.mapView.GetHeight(), player.Hand)
+ g.widgets = append(g.widgets, g.handLayer)
+
+ g.stateBar = ui.NewStateBar(0, screenHeight-HAND_VIEW_HEIGHT,
+ STATE_BAR_WIDTH, HAND_VIEW_HEIGHT, g.gameState, player)
+ g.widgets = append(g.widgets, g.stateBar)
+}
+
func (g *Game) addWidget(w ui.Widget) {
g.widgets = append(g.widgets, w)
}
@@ -140,6 +168,24 @@ func (g *Game) removeWidget(widget ui.Widget) {
}
}
+func (g *Game) addActionChoice(perm game.Permanent) {
+ actions := perm.GetAvailActionPrototypes()
+ if len(actions) > 0 {
+ g.selectedObject = perm
+ onClick := func(c *ui.Choice, x, y int) {
+ g.removeActionChoice()
+ g.selectedObject = actions[c.GetChoosen(x, y)]
+ }
+ g.actionChoice = ui.NewActionChoice(500, 200, actions, onClick)
+ g.addWidget(g.actionChoice)
+ }
+}
+
+func (g *Game) removeActionChoice() {
+ g.removeWidget(g.actionChoice)
+ g.actionChoice = nil
+}
+
func (g *Game) clearMapHighlights() {
g.mapView.ClearPermanentsHighlights()
g.mapView.ClearTileHighlights()
@@ -147,18 +193,34 @@ func (g *Game) clearMapHighlights() {
}
func (g *Game) declareAction(a game.Action) {
- a.Declare(g.gameState)
+ g.playerCtrl.SendAction(a)
g.clearMapHighlights()
- g.stackBuffer.AddLine(a.String())
+ g.hasPriority = false
+ g.removeWidget(g.passButton)
+ g.stateBar.ForceRedraw()
}
-func (g *Game) resolveAction() {
- if g.gameState.Stack.IsEmpty() {
- return
+func (g *Game) passPriority() {
+ g.declareAction(game.NewPassPriorityAction(g.activePlayer))
+}
+
+func (g *Game) handlePlayerNotifications() {
+ n := g.playerCtrl.RecvNotification()
+ for n != nil {
+ log.Printf("Recv player notification %v\n", n)
+ switch n.Notification {
+ case game.PriorityNotification:
+ g.addWidget(g.passButton)
+ g.hasPriority = true
+ case game.DeclaredActionNotification:
+ g.stackBuffer.AddLine(n.Action.String())
+ case game.ResolvedActionNotification:
+ g.clearMapHighlights()
+ g.stackBuffer.RemoveLast()
+ g.mapView.ForceRedraw()
+ }
+ n = g.playerCtrl.RecvNotification()
}
- g.gameState.Stack.Pop()
- g.clearMapHighlights()
- g.stackBuffer.RemoveLast()
}
func (g *Game) findObjectAt(x, y int) interface{} {
@@ -175,6 +237,8 @@ func (g *Game) findObjectAt(x, y int) interface{} {
}
func (g *Game) Update() error {
+ g.handlePlayerNotifications()
+
x, y := ebiten.CursorPosition()
g.hoverDetector.update(x, y)
@@ -195,11 +259,19 @@ func (g *Game) Update() error {
case *game.Tile:
tile := obj
if g.selectedObject != nil {
+ var action game.Action
switch obj := g.selectedObject.(type) {
case *game.MoveActionPrototype:
- action := obj.Specialize(tile)
- g.selectedObject = nil
+ action = obj.Specialize(tile)
+ case *game.Card:
+ if obj.IsPermanent() {
+ action = game.NewPlayAction(g.activePlayer, obj, tile.Position)
+ g.handLayer.ForceRedraw()
+ }
+ }
+ if action != nil {
g.declareAction(action)
+ g.selectedObject = nil
g.mapView.HighlightTile(tile)
}
} else {
@@ -209,15 +281,7 @@ func (g *Game) Update() error {
case game.Permanent:
perm := obj
if g.selectedObject == nil {
- actions := perm.GetAvailActionPrototypes()
- if len(actions) > 0 {
- g.selectedObject = perm
- onClick := func(c *ui.Choice, x, y int) {
- g.removeWidget(c)
- g.selectedObject = actions[c.GetChoosen(x, y)]
- }
- g.addWidget(ui.NewActionChoice(500, 200, actions, onClick))
- }
+ g.addActionChoice(perm)
} else {
switch obj := g.selectedObject.(type) {
case *game.AttackActionPrototype:
@@ -228,6 +292,9 @@ func (g *Game) Update() error {
}
}
+ case ui.HandCard:
+ g.selectedObject = obj.C
+
default:
log.Fatalf("Object of type %T not handled", obj)
}
@@ -238,6 +305,11 @@ func (g *Game) Update() error {
case *game.AttackActionPrototype:
perms := obj.Unit.AttackablePermanents(g.gameState.Map)
g.mapView.HighlightPermanents(perms)
+ case *game.Card:
+ if obj.IsPermanent() {
+ spawnTiles := g.gameState.SpawnTiles(g.activePlayer)
+ g.mapView.HighlightTiles(spawnTiles)
+ }
}
} else if g.hoverDetector.startedHovering() && g.selectedObject == nil && obj != nil {
var hoverHint *ui.TextBox
@@ -255,8 +327,9 @@ func (g *Game) Update() error {
}
}
} else if inpututil.IsKeyJustPressed(ebiten.KeySpace) {
- g.resolveAction()
+ g.passButton.Click(0, 0)
} else if inpututil.IsKeyJustPressed(ebiten.KeyEscape) {
+ g.removeActionChoice()
g.selectedObject = nil
g.hoverDetector.reset()
g.clearMapHighlights()
@@ -265,7 +338,6 @@ func (g *Game) Update() error {
}
func (g *Game) Draw(screen *ebiten.Image) {
- g.handLayer.Draw(screen)
g.mapView.Draw(screen)
for _, b := range g.widgets {
b.Draw(screen)
@@ -282,20 +354,27 @@ func (g *Game) Layout(outsideWidth, outsideHeight int) (int, int) {
}
func main() {
- ui.InitFont()
+ font.InitFont()
ebiten.SetWindowSize(screenWidth, screenHeight)
ebiten.SetWindowTitle("Muhq's Game")
- g := NewGameFromMap("2P-ring-street")
+ g := NewGameFromMap("the-kraken")
+
+ muhq := g.addPlayer("muhq",
+ game.NewDeckFromDeckList(g.gameState.Map.StartDeckList),
+ game.NewStore())
+ g.initPlayerUi(muhq)
- g.addPlayer("muhq", game.NewDeckFromDeckList(g.gameState.Map.StartDeckList), playerBlue)
- muhq := g.getPlayer("muhq")
- g.gameState.AddNewUnit("base/archer", game.Position{X: 0, Y: 0}, muhq)
+ enemy := g.addPlayer("enemy",
+ game.NewDeckFromDeckList(g.gameState.Map.StartDeckList),
+ game.NewStore())
+ enemy.Ctrl = &game.DummyPlayerControl{enemy}
- g.addPlayer("enemy", game.NewDeckFromDeckList(g.gameState.Map.StartDeckList), playerGreen)
- enemy := g.getPlayer("enemy")
- g.gameState.AddNewArtifact("base/palisade", game.Position{X: 1, Y: 1}, enemy)
+ go func() {
+ w := g.gameState.Loop()
+ log.Println("Winners are", w)
+ }()
if err := ebiten.RunGame(g); err != nil {
log.Fatal(err)