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:
59
main.go
59
main.go
@@ -152,6 +152,19 @@ func main() {
|
||||
snakeNickname = c.Signal(username)
|
||||
}
|
||||
|
||||
// Speed selection signal (index into SpeedPresets, default to Normal which is index 1)
|
||||
selectedSpeedIndex := c.Signal(1)
|
||||
|
||||
// Speed selector actions
|
||||
var speedSelectClicks []h.H
|
||||
for i := range snake.SpeedPresets {
|
||||
idx := i
|
||||
speedSelectClicks = append(speedSelectClicks, c.Action(func() {
|
||||
selectedSpeedIndex.SetValue(idx)
|
||||
c.Sync()
|
||||
}).OnClick())
|
||||
}
|
||||
|
||||
// Snake create game actions — one per preset for solo and multiplayer
|
||||
var snakeSoloClicks []h.H
|
||||
var snakeMultiClicks []h.H
|
||||
@@ -163,7 +176,12 @@ func main() {
|
||||
return
|
||||
}
|
||||
c.Session().Set("nickname", name)
|
||||
si := snakeStore.Create(w, ht, snake.ModeSinglePlayer)
|
||||
speedIdx := selectedSpeedIndex.Int()
|
||||
speed := snake.DefaultSpeed
|
||||
if speedIdx >= 0 && speedIdx < len(snake.SpeedPresets) {
|
||||
speed = snake.SpeedPresets[speedIdx].Speed
|
||||
}
|
||||
si := snakeStore.Create(w, ht, snake.ModeSinglePlayer, speed)
|
||||
c.Redirectf("/snake/%s", si.ID())
|
||||
}).OnClick())
|
||||
snakeMultiClicks = append(snakeMultiClicks, c.Action(func() {
|
||||
@@ -172,28 +190,35 @@ func main() {
|
||||
return
|
||||
}
|
||||
c.Session().Set("nickname", name)
|
||||
si := snakeStore.Create(w, ht, snake.ModeMultiplayer)
|
||||
speedIdx := selectedSpeedIndex.Int()
|
||||
speed := snake.DefaultSpeed
|
||||
if speedIdx >= 0 && speedIdx < len(snake.SpeedPresets) {
|
||||
speed = snake.SpeedPresets[speedIdx].Speed
|
||||
}
|
||||
si := snakeStore.Create(w, ht, snake.ModeMultiplayer, speed)
|
||||
c.Redirectf("/snake/%s", si.ID())
|
||||
}).OnClick())
|
||||
}
|
||||
|
||||
c.View(func() h.H {
|
||||
return ui.LobbyView(ui.LobbyProps{
|
||||
NicknameBind: nickname.Bind(),
|
||||
CreateGameKeyDown: createGame.OnKeyDown("Enter"),
|
||||
CreateGameClick: createGame.OnClick(),
|
||||
IsLoggedIn: isLoggedIn,
|
||||
Username: username,
|
||||
LogoutClick: logout.OnClick(),
|
||||
UserGames: userGames,
|
||||
DeleteGameClick: deleteGame,
|
||||
ActiveTab: activeTab.String(),
|
||||
TabClickConnect4: tabClickConnect4.OnClick(),
|
||||
TabClickSnake: tabClickSnake.OnClick(),
|
||||
SnakeNicknameBind: snakeNickname.Bind(),
|
||||
SnakeSoloClicks: snakeSoloClicks,
|
||||
SnakeMultiClicks: snakeMultiClicks,
|
||||
ActiveSnakeGames: snakeStore.ActiveGames(),
|
||||
NicknameBind: nickname.Bind(),
|
||||
CreateGameKeyDown: createGame.OnKeyDown("Enter"),
|
||||
CreateGameClick: createGame.OnClick(),
|
||||
IsLoggedIn: isLoggedIn,
|
||||
Username: username,
|
||||
LogoutClick: logout.OnClick(),
|
||||
UserGames: userGames,
|
||||
DeleteGameClick: deleteGame,
|
||||
ActiveTab: activeTab.String(),
|
||||
TabClickConnect4: tabClickConnect4.OnClick(),
|
||||
TabClickSnake: tabClickSnake.OnClick(),
|
||||
SnakeNicknameBind: snakeNickname.Bind(),
|
||||
SnakeSoloClicks: snakeSoloClicks,
|
||||
SnakeMultiClicks: snakeMultiClicks,
|
||||
ActiveSnakeGames: snakeStore.ActiveGames(),
|
||||
SelectedSpeedIndex: selectedSpeedIndex.Int(),
|
||||
SpeedSelectClicks: speedSelectClicks,
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user