WIP: Add multiplayer Snake game
N-player (2-8) real-time Snake game alongside Connect 4. Lobby has tabs to switch between games. Players join via invite link with 10-second countdown. Game loop runs at tick-based intervals with NATS pub/sub for state sync. Keyboard input not yet working (Datastar keydown binding issue still under investigation).
This commit is contained in:
61
ui/lobby.go
61
ui/lobby.go
@@ -1,20 +1,63 @@
|
||||
package ui
|
||||
|
||||
import (
|
||||
"github.com/ryanhamamura/c4/snake"
|
||||
"github.com/ryanhamamura/via/h"
|
||||
)
|
||||
|
||||
func LobbyView(nicknameBind, createGameKeyDown, createGameClick h.H, isLoggedIn bool, username string, logoutClick h.H, userGames []GameListItem, deleteGameClick func(id string) h.H) h.H {
|
||||
type LobbyProps struct {
|
||||
NicknameBind h.H
|
||||
CreateGameKeyDown h.H
|
||||
CreateGameClick h.H
|
||||
IsLoggedIn bool
|
||||
Username string
|
||||
LogoutClick h.H
|
||||
UserGames []GameListItem
|
||||
DeleteGameClick func(id string) h.H
|
||||
ActiveTab string
|
||||
TabClickConnect4 h.H
|
||||
TabClickSnake h.H
|
||||
SnakeNicknameBind h.H
|
||||
SnakePresetClicks []h.H
|
||||
ActiveSnakeGames []*snake.SnakeGame
|
||||
}
|
||||
|
||||
func LobbyView(p LobbyProps) h.H {
|
||||
var authSection h.H
|
||||
if isLoggedIn {
|
||||
authSection = AuthHeader(username, logoutClick)
|
||||
if p.IsLoggedIn {
|
||||
authSection = AuthHeader(p.Username, p.LogoutClick)
|
||||
} else {
|
||||
authSection = GuestBanner()
|
||||
}
|
||||
|
||||
return h.Main(h.Class("max-w-sm mx-auto mt-8 text-center"),
|
||||
connect4Class := "tab"
|
||||
snakeClass := "tab"
|
||||
if p.ActiveTab == "snake" {
|
||||
snakeClass += " tab-active"
|
||||
} else {
|
||||
connect4Class += " tab-active"
|
||||
}
|
||||
|
||||
var tabContent h.H
|
||||
if p.ActiveTab == "snake" {
|
||||
tabContent = SnakeLobbyTab(p.SnakeNicknameBind, p.SnakePresetClicks, p.ActiveSnakeGames)
|
||||
} else {
|
||||
tabContent = connect4LobbyContent(p)
|
||||
}
|
||||
|
||||
return h.Main(h.Class("max-w-md mx-auto mt-8 text-center"),
|
||||
authSection,
|
||||
h.H1(h.Class("text-3xl font-bold"), h.Text("Connect 4")),
|
||||
h.H1(h.Class("text-3xl font-bold mb-4"), h.Text("Game Lobby")),
|
||||
h.Div(h.Class("tabs tabs-box mb-6 justify-center"),
|
||||
h.Button(h.Class(connect4Class), h.Type("button"), h.Text("Connect 4"), p.TabClickConnect4),
|
||||
h.Button(h.Class(snakeClass), h.Type("button"), h.Text("Snake"), p.TabClickSnake),
|
||||
),
|
||||
tabContent,
|
||||
)
|
||||
}
|
||||
|
||||
func connect4LobbyContent(p LobbyProps) h.H {
|
||||
return h.Div(
|
||||
h.P(h.Class("mb-4"), h.Text("Challenge a friend to a game of Connect 4!")),
|
||||
h.Form(
|
||||
h.FieldSet(h.Class("fieldset"),
|
||||
@@ -24,19 +67,19 @@ func LobbyView(nicknameBind, createGameKeyDown, createGameClick h.H, isLoggedIn
|
||||
h.ID("nickname"),
|
||||
h.Type("text"),
|
||||
h.Placeholder("Enter your nickname"),
|
||||
nicknameBind,
|
||||
p.NicknameBind,
|
||||
h.Attr("required"),
|
||||
createGameKeyDown,
|
||||
p.CreateGameKeyDown,
|
||||
),
|
||||
),
|
||||
h.Button(
|
||||
h.Class("btn btn-primary w-full"),
|
||||
h.Type("button"),
|
||||
h.Text("Create Game"),
|
||||
createGameClick,
|
||||
p.CreateGameClick,
|
||||
),
|
||||
),
|
||||
GameList(userGames, deleteGameClick),
|
||||
GameList(p.UserGames, p.DeleteGameClick),
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user