Update via to v0.4.0 and decouple tick rate from snake speed
Use via.OnKeyDownMap for snake keybindings, replacing the manual dataExpr/rawDataAttr workaround. Window-scoped key handling removes the need for tabindex/focus hacks, and WithPreventDefault on arrow keys prevents page scrolling during gameplay. Introduce a 60 FPS tick loop with a separate snake movement speed (7 cells/s) so direction input is polled every frame but game state only advances at the configured rate.
This commit is contained in:
@@ -5,7 +5,10 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
tickInterval = 500 * time.Millisecond
|
||||
targetFPS = 60
|
||||
tickInterval = time.Second / targetFPS
|
||||
snakeSpeed = 7 // cells per second
|
||||
moveInterval = time.Second / snakeSpeed
|
||||
countdownSeconds = 10
|
||||
inactivityLimit = 60 * time.Second
|
||||
)
|
||||
@@ -91,6 +94,7 @@ func (si *SnakeGameInstance) gamePhase() {
|
||||
defer ticker.Stop()
|
||||
|
||||
lastInput := time.Now()
|
||||
var moveAccum time.Duration
|
||||
|
||||
for {
|
||||
select {
|
||||
@@ -104,7 +108,7 @@ func (si *SnakeGameInstance) gamePhase() {
|
||||
return
|
||||
}
|
||||
|
||||
// Apply pending directions (iterate all 8 slots)
|
||||
// Apply pending directions every tick for responsive input
|
||||
inputReceived := false
|
||||
for i := 0; i < 8; i++ {
|
||||
if si.pendingDir[i] != nil && i < len(si.game.State.Snakes) && si.game.State.Snakes[i] != nil {
|
||||
@@ -128,6 +132,14 @@ func (si *SnakeGameInstance) gamePhase() {
|
||||
return
|
||||
}
|
||||
|
||||
// Only advance game state at snakeSpeed
|
||||
moveAccum += tickInterval
|
||||
if moveAccum < moveInterval {
|
||||
si.gameMu.Unlock()
|
||||
continue
|
||||
}
|
||||
moveAccum -= moveInterval
|
||||
|
||||
state := si.game.State
|
||||
|
||||
// Advance snakes
|
||||
|
||||
Reference in New Issue
Block a user