feat: add configurable speed and expanded grid presets for snake
- Add per-game speed setting with presets (Slow/Normal/Fast/Insane) - Add speed selector UI in snake lobby - Expand grid presets with Tiny (15x15) and XL (50x30) - Auto-calculate cell size based on grid dimensions - Preserve speed setting in rematch games
This commit is contained in:
@@ -21,6 +21,8 @@ type LobbyProps struct {
|
||||
SnakeSoloClicks []h.H
|
||||
SnakeMultiClicks []h.H
|
||||
ActiveSnakeGames []*snake.SnakeGame
|
||||
SelectedSpeedIndex int
|
||||
SpeedSelectClicks []h.H
|
||||
}
|
||||
|
||||
func LobbyView(p LobbyProps) h.H {
|
||||
@@ -41,7 +43,7 @@ func LobbyView(p LobbyProps) h.H {
|
||||
|
||||
var tabContent h.H
|
||||
if p.ActiveTab == "snake" {
|
||||
tabContent = SnakeLobbyTab(p.SnakeNicknameBind, p.SnakeSoloClicks, p.SnakeMultiClicks, p.ActiveSnakeGames)
|
||||
tabContent = SnakeLobbyTab(p.SnakeNicknameBind, p.SnakeSoloClicks, p.SnakeMultiClicks, p.ActiveSnakeGames, p.SelectedSpeedIndex, p.SpeedSelectClicks)
|
||||
} else {
|
||||
tabContent = connect4LobbyContent(p)
|
||||
}
|
||||
|
||||
@@ -45,10 +45,7 @@ func SnakeBoard(sg *snake.SnakeGame) h.H {
|
||||
}
|
||||
|
||||
// Cell size scales with grid dimensions
|
||||
cellSize := 20
|
||||
if state.Width <= 20 {
|
||||
cellSize = 24
|
||||
}
|
||||
cellSize := cellSizeForGrid(state.Width, state.Height)
|
||||
|
||||
var rows []h.H
|
||||
for y := 0; y < state.Height; y++ {
|
||||
@@ -94,3 +91,22 @@ func SnakeBoard(sg *snake.SnakeGame) h.H {
|
||||
attrs = append(attrs, rows...)
|
||||
return h.Div(attrs...)
|
||||
}
|
||||
|
||||
func cellSizeForGrid(width, height int) int {
|
||||
maxDim := width
|
||||
if height > maxDim {
|
||||
maxDim = height
|
||||
}
|
||||
switch {
|
||||
case maxDim <= 15:
|
||||
return 28
|
||||
case maxDim <= 20:
|
||||
return 24
|
||||
case maxDim <= 30:
|
||||
return 20
|
||||
case maxDim <= 40:
|
||||
return 16
|
||||
default:
|
||||
return 14
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ import (
|
||||
"github.com/ryanhamamura/via/h"
|
||||
)
|
||||
|
||||
func SnakeLobbyTab(nicknameBind h.H, soloClicks, multiClicks []h.H, activeGames []*snake.SnakeGame) h.H {
|
||||
func SnakeLobbyTab(nicknameBind h.H, soloClicks, multiClicks []h.H, activeGames []*snake.SnakeGame, selectedSpeedIndex int, speedSelectClicks []h.H) h.H {
|
||||
// Solo play buttons
|
||||
var soloButtons []h.H
|
||||
for i, preset := range snake.GridPresets {
|
||||
@@ -56,6 +56,29 @@ func SnakeLobbyTab(nicknameBind h.H, soloClicks, multiClicks []h.H, activeGames
|
||||
),
|
||||
)
|
||||
|
||||
// Speed selector
|
||||
var speedButtons []h.H
|
||||
for i, preset := range snake.SpeedPresets {
|
||||
btnClass := "btn btn-sm"
|
||||
if i == selectedSpeedIndex {
|
||||
btnClass += " btn-active"
|
||||
}
|
||||
var click h.H
|
||||
if i < len(speedSelectClicks) {
|
||||
click = speedSelectClicks[i]
|
||||
}
|
||||
speedButtons = append(speedButtons, h.Button(
|
||||
h.Class(btnClass),
|
||||
h.Type("button"),
|
||||
h.Text(preset.Name),
|
||||
click,
|
||||
))
|
||||
}
|
||||
speedSelector := h.Div(h.Class("mb-4"),
|
||||
h.Label(h.Class("label"), h.Text("Speed")),
|
||||
h.Div(append([]h.H{h.Class("btn-group")}, speedButtons...)...),
|
||||
)
|
||||
|
||||
soloSection := h.Div(h.Class("mb-6"),
|
||||
h.H3(h.Class("text-lg font-bold mb-2"), h.Text("Play Solo")),
|
||||
h.Div(append([]h.H{h.Class("flex gap-2 justify-center")}, soloButtons...)...),
|
||||
@@ -93,6 +116,7 @@ func SnakeLobbyTab(nicknameBind h.H, soloClicks, multiClicks []h.H, activeGames
|
||||
|
||||
return h.Div(
|
||||
nicknameField,
|
||||
speedSelector,
|
||||
soloSection,
|
||||
multiSection,
|
||||
gameListEl,
|
||||
|
||||
Reference in New Issue
Block a user