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:
@@ -5,13 +5,11 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
targetFPS = 60
|
||||
tickInterval = time.Second / targetFPS
|
||||
snakeSpeed = 7 // cells per second
|
||||
moveInterval = time.Second / snakeSpeed
|
||||
countdownSecondsMultiplayer = 10
|
||||
countdownSecondsSinglePlayer = 3
|
||||
inactivityLimit = 60 * time.Second
|
||||
targetFPS = 60
|
||||
tickInterval = time.Second / targetFPS
|
||||
countdownSecondsMultiplayer = 10
|
||||
countdownSecondsSinglePlayer = 3
|
||||
inactivityLimit = 60 * time.Second
|
||||
)
|
||||
|
||||
func (si *SnakeGameInstance) startOrResetCountdownLocked() {
|
||||
@@ -114,18 +112,13 @@ func (si *SnakeGameInstance) gamePhase() {
|
||||
return
|
||||
}
|
||||
|
||||
// Apply pending directions every tick for responsive input
|
||||
inputReceived := false
|
||||
// Track input activity for inactivity timeout
|
||||
for i := 0; i < 8; i++ {
|
||||
if si.pendingDir[i] != nil && i < len(si.game.State.Snakes) && si.game.State.Snakes[i] != nil {
|
||||
si.game.State.Snakes[i].Dir = *si.pendingDir[i]
|
||||
si.pendingDir[i] = nil
|
||||
inputReceived = true
|
||||
if len(si.pendingDirQueue[i]) > 0 {
|
||||
lastInput = time.Now()
|
||||
break
|
||||
}
|
||||
}
|
||||
if inputReceived {
|
||||
lastInput = time.Now()
|
||||
}
|
||||
|
||||
// Inactivity timeout
|
||||
if time.Since(lastInput) > inactivityLimit {
|
||||
@@ -138,7 +131,14 @@ func (si *SnakeGameInstance) gamePhase() {
|
||||
return
|
||||
}
|
||||
|
||||
// Only advance game state at snakeSpeed
|
||||
// Compute move interval from per-game speed
|
||||
speed := si.game.Speed
|
||||
if speed <= 0 {
|
||||
speed = DefaultSpeed
|
||||
}
|
||||
moveInterval := time.Second / time.Duration(speed)
|
||||
|
||||
// Only advance game state at game speed
|
||||
moveAccum += tickInterval
|
||||
if moveAccum < moveInterval {
|
||||
si.gameMu.Unlock()
|
||||
@@ -146,6 +146,14 @@ func (si *SnakeGameInstance) gamePhase() {
|
||||
}
|
||||
moveAccum -= moveInterval
|
||||
|
||||
// Pop one direction from queue per movement frame
|
||||
for i := 0; i < 8; i++ {
|
||||
if len(si.pendingDirQueue[i]) > 0 && i < len(si.game.State.Snakes) && si.game.State.Snakes[i] != nil {
|
||||
si.game.State.Snakes[i].Dir = si.pendingDirQueue[i][0]
|
||||
si.pendingDirQueue[i] = si.pendingDirQueue[i][1:]
|
||||
}
|
||||
}
|
||||
|
||||
state := si.game.State
|
||||
|
||||
// Advance snakes
|
||||
|
||||
Reference in New Issue
Block a user