Files
metro-puzzle-jp/internal/game/input.go
claude daa2089eda
All checks were successful
release / build-release (push) Successful in 1m49s
Inlärning (framsteg, stjärnor, ordlista) och M4: lämmeltåget
Inlärning enligt Björns regler:
- lang.Knowledge: framsteg per ord (3 läsningar = känt), språkpoäng,
  köp av valfria ord (kostnad = tier), Award per stjärna
- sim.Run: RunOptions med seed; stjärnor 1–3 mot par (parSec eller
  kortaste vägen × 0,5 s + 20 s); ≥2 stjärnor lär resmålets ord; att
  stanna på skylt/perrong ger seedad 35 % chans till framsteg per okänt ord
- game: ordlista (L) med kända ord, framsteg och kostnad; stjärnor, poäng
  och inlärt resmål på resultatskärmen; framstegsnotis; flaggor -points/-seed

M4 lämmeltåget:
- sim.Party: medlemmar med mat/dryck/toa-mätare, behov under tröskel,
  seedade händelser var 45 s / antal (toa, törst, hunger, distraktion),
  fartstraff, toalett (W, 3 s/person) och kiosk (K, 150 ¥/person),
  följare på ledarens spår
- level: rutor W och K, party och parSec i bandatan; banor med sällskap
  måste ha toalett och kiosk (testas); 001 har 2, 002 har 3 i sällskapet
- game: följare med färgton, behovsmarkering över huvudet, mätarpanel,
  facilitetsrutor med förlopp; genart ritar toalett och kiosk
- skriptläget: move stannar exakt på målrutan även när farten inte är
  bildruteexakt (sällskapets fartstraff), stall-skydd mot väggar
- docs/README/wiki/spelbeskrivning uppdaterade

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-23 21:29:09 +02:00

110 lines
3.7 KiB
Go

package game
import (
"github.com/hajimehoshi/ebiten/v2"
"github.com/hajimehoshi/ebiten/v2/inpututil"
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/sim"
)
const stickDeadzone = 0.5
// dirInput returnerar hållen riktning från tangentbord (pilar/WASD) eller
// gamepad (d-pad / vänster spak). None om inget hålls.
func dirInput() sim.Dir {
if virtual.held != sim.None {
return virtual.held
}
switch {
case ebiten.IsKeyPressed(ebiten.KeyArrowUp) || ebiten.IsKeyPressed(ebiten.KeyW):
return sim.Up
case ebiten.IsKeyPressed(ebiten.KeyArrowDown) || ebiten.IsKeyPressed(ebiten.KeyS):
return sim.Down
case ebiten.IsKeyPressed(ebiten.KeyArrowLeft) || ebiten.IsKeyPressed(ebiten.KeyA):
return sim.Left
case ebiten.IsKeyPressed(ebiten.KeyArrowRight) || ebiten.IsKeyPressed(ebiten.KeyD):
return sim.Right
}
for _, id := range ebiten.AppendGamepadIDs(nil) {
if !ebiten.IsStandardGamepadLayoutAvailable(id) {
continue
}
switch {
case ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftTop):
return sim.Up
case ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftBottom):
return sim.Down
case ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftLeft):
return sim.Left
case ebiten.IsStandardGamepadButtonPressed(id, ebiten.StandardGamepadButtonLeftRight):
return sim.Right
}
x := ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisLeftStickHorizontal)
y := ebiten.StandardGamepadAxisValue(id, ebiten.StandardGamepadAxisLeftStickVertical)
switch {
case y < -stickDeadzone:
return sim.Up
case y > stickDeadzone:
return sim.Down
case x < -stickDeadzone:
return sim.Left
case x > stickDeadzone:
return sim.Right
}
}
return sim.None
}
// confirmJustPressed: Enter/mellanslag eller gamepadens nedre knapp (A/kryss).
func confirmJustPressed() bool {
if virtual.pressed["enter"] {
return true
}
if inpututil.IsKeyJustPressed(ebiten.KeyEnter) || inpututil.IsKeyJustPressed(ebiten.KeySpace) {
return true
}
return gamepadJustPressed(ebiten.StandardGamepadButtonRightBottom)
}
// backJustPressed: Escape eller gamepadens högra knapp (B/cirkel).
func backJustPressed() bool {
return virtual.pressed["esc"] || inpututil.IsKeyJustPressed(ebiten.KeyEscape) || gamepadJustPressed(ebiten.StandardGamepadButtonRightRight)
}
// helpJustPressed: H eller gamepadens övre knapp (Y/triangel) = fråga om hjälp.
func helpJustPressed() bool {
return virtual.pressed["h"] || inpututil.IsKeyJustPressed(ebiten.KeyH) || gamepadJustPressed(ebiten.StandardGamepadButtonRightTop)
}
// wordsJustPressed: L = ordlistan/språkträdet.
func wordsJustPressed() bool {
return virtual.pressed["l"] || inpututil.IsKeyJustPressed(ebiten.KeyL) || gamepadJustPressed(ebiten.StandardGamepadButtonLeftRight)
}
// menuMove returnerar -1/+1 när användaren just tryckte upp/ner i en meny.
func menuMove() int {
switch {
case virtual.pressed["up"]:
return -1
case virtual.pressed["down"]:
return 1
case inpututil.IsKeyJustPressed(ebiten.KeyArrowUp) || inpututil.IsKeyJustPressed(ebiten.KeyW) || gamepadJustPressed(ebiten.StandardGamepadButtonLeftTop):
return -1
case inpututil.IsKeyJustPressed(ebiten.KeyArrowDown) || inpututil.IsKeyJustPressed(ebiten.KeyS) || gamepadJustPressed(ebiten.StandardGamepadButtonLeftBottom):
return 1
}
return 0
}
func gamepadJustPressed(b ebiten.StandardGamepadButton) bool {
for _, id := range ebiten.AppendGamepadIDs(nil) {
if ebiten.IsStandardGamepadLayoutAvailable(id) && inpututil.IsStandardGamepadButtonJustPressed(id, b) {
return true
}
}
return false
}
// inpututil_R: R = spela om banan.
func inpututil_R() bool { return virtual.pressed["r"] || inpututil.IsKeyJustPressed(ebiten.KeyR) }