M12: ljud, inställningar och release v0.1.0
All checks were successful
release / build-release (push) Successful in 1m35s
All checks were successful
release / build-release (push) Successful in 1m35s
tools/gensound syntetiserar 21 ljud: fyra stationsmelodier i klockklang (en per station via melody-fältet eller banans id), ankomstjingel, ding-dong vid inrullning, dörrsignal vid avgång, spärrens pip och nekande, kiosk, toalett, lärt ord, bekräfta/varning, byte, personal, vinst, förlust, flygplan, sorl och menymusik. sfx.go spelar effekter utifrån vad som hänt i sim.Run sedan förra bildrutan. Ljudlagret har huvudvolym × effekter/musik och byter inte slinga i onödan. Inställningar (S på bankartan, sparas): volymer, språk sv/en som laddas om direkt, fönsterskala, fullskärm (F11 överallt) och tangentöversikt. Fönsterikon från genart. CHANGELOG.md. Tester för ljudfiler, melodival och inställningar. Docs, wiki och skärmdumpar uppdaterade. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
117
internal/game/scene_settings.go
Normal file
117
internal/game/scene_settings.go
Normal file
@@ -0,0 +1,117 @@
|
||||
package game
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
|
||||
"github.com/hajimehoshi/ebiten/v2"
|
||||
"github.com/hajimehoshi/ebiten/v2/vector"
|
||||
|
||||
"gitea.brasse-pc.eu/brasse/metro-puzzle-jp/internal/save"
|
||||
)
|
||||
|
||||
// SettingsScene är inställningarna: volymer, språk, fönsterskala och
|
||||
// fullskärm. Pilar väljer rad och ändrar, Enter växlar, Esc/S går tillbaka.
|
||||
// Allt sparas direkt.
|
||||
type SettingsScene struct {
|
||||
back Scene
|
||||
sel int
|
||||
}
|
||||
|
||||
const settingsRows = 6
|
||||
|
||||
// NewSettingsScene öppnar inställningarna.
|
||||
func NewSettingsScene(back Scene) *SettingsScene { return &SettingsScene{back: back} }
|
||||
|
||||
func (s *SettingsScene) Update(g *Game) error {
|
||||
if backJustPressed() || settingsJustPressed() {
|
||||
g.SetScene(s.back)
|
||||
return nil
|
||||
}
|
||||
s.sel = (s.sel + menuMove() + settingsRows) % settingsRows
|
||||
dx, _ := miniMoveXY()
|
||||
toggle := confirmJustPressed()
|
||||
if dx == 0 && !toggle {
|
||||
return nil
|
||||
}
|
||||
st := g.State.Settings
|
||||
step := func(v *int, lo, hi int) {
|
||||
*v = max(lo, min(hi, *v+dx))
|
||||
}
|
||||
switch s.sel {
|
||||
case 0:
|
||||
step(&st.Master, 0, 10)
|
||||
case 1:
|
||||
step(&st.Effects, 0, 10)
|
||||
case 2:
|
||||
step(&st.Music, 0, 10)
|
||||
case 3:
|
||||
if st.Lang == "sv" {
|
||||
st.Lang = "en"
|
||||
} else {
|
||||
st.Lang = "sv"
|
||||
}
|
||||
case 4:
|
||||
step(&st.Scale, 0, 6)
|
||||
case 5:
|
||||
st.Fullscreen = !st.Fullscreen
|
||||
}
|
||||
g.applySettings()
|
||||
g.Save()
|
||||
g.Audio.Play(SoundConfirm, 0.6)
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *SettingsScene) Draw(g *Game, screen *ebiten.Image) {
|
||||
a := g.Assets
|
||||
st := g.State.Settings
|
||||
screen.Fill(color.RGBA{24, 20, 37, 255})
|
||||
vector.DrawFilledRect(screen, 0, 0, ScreenW, 22, color.RGBA{38, 43, 68, 255}, false)
|
||||
a.DrawBig(screen, a.T("settings.title"), 8, 5, colText)
|
||||
scale := a.T("settings.scale_auto")
|
||||
if st.Scale > 0 {
|
||||
scale = fmt.Sprintf("%d× (%d×%d)", st.Scale, ScreenW*st.Scale, ScreenH*st.Scale)
|
||||
}
|
||||
fs := a.T("menu.off")
|
||||
if st.Fullscreen {
|
||||
fs = a.T("menu.on")
|
||||
}
|
||||
rows := [settingsRows][2]string{
|
||||
{a.T("settings.master"), ""},
|
||||
{a.T("settings.effects"), ""},
|
||||
{a.T("settings.music"), ""},
|
||||
{a.T("settings.lang"), a.T("lang." + st.Lang)},
|
||||
{a.T("settings.scale"), scale},
|
||||
{a.T("settings.fullscreen"), fs},
|
||||
}
|
||||
levels := [3]int{st.Master, st.Effects, st.Music}
|
||||
y := 30
|
||||
for i, r := range rows {
|
||||
col := colText
|
||||
if i == s.sel {
|
||||
vector.DrawFilledRect(screen, 6, float32(y-2), ScreenW-12, LineH+1, colBar, false)
|
||||
col = colKnown
|
||||
}
|
||||
a.Draw(screen, r[0], 10, y, col)
|
||||
if i < 3 { // volymstapel i tio segment
|
||||
for k := 0; k < 10; k++ {
|
||||
c := color.RGBA{70, 80, 110, 255}
|
||||
if k < levels[i] {
|
||||
c = color.RGBA{120, 200, 120, 255}
|
||||
}
|
||||
vector.DrawFilledRect(screen, float32(130+k*9), float32(y+2), 7, 7, c, false)
|
||||
}
|
||||
a.Draw(screen, fmt.Sprintf("%d", levels[i]), 224, y, col)
|
||||
} else {
|
||||
a.Draw(screen, r[1], 130, y, col)
|
||||
}
|
||||
y += LineH + 1
|
||||
}
|
||||
y += 4
|
||||
for _, l := range a.wrapLine(plainLine(a.T("settings.keys"), colDim), ScreenW-20) {
|
||||
a.drawLines(screen, []line{l}, 10, y)
|
||||
y += LineH
|
||||
}
|
||||
a.Draw(screen, a.T("settings.hint"), 8, ScreenH-12, colDim)
|
||||
_ = save.DefaultSettings // (inställningarnas standardvärden ligger i save)
|
||||
}
|
||||
Reference in New Issue
Block a user