Added audio settings.
This commit is contained in:
parent
99e87cef6e
commit
65db973699
2
TODO.md
2
TODO.md
@ -10,7 +10,7 @@
|
|||||||
- [ ] Add more unit tests?
|
- [ ] Add more unit tests?
|
||||||
- [X] Fix z-fighting of monsters.
|
- [X] Fix z-fighting of monsters.
|
||||||
- [X] Add exploding animation of monsters.
|
- [X] Add exploding animation of monsters.
|
||||||
- [ ] Add audio settings (music & sound volume).
|
- [X] Add audio settings (music & sound volume).
|
||||||
- [X] Hearts must be saved as well for resume.
|
- [X] Hearts must be saved as well for resume.
|
||||||
- [ ] Add demo mode.
|
- [ ] Add demo mode.
|
||||||
- [ ] Add touch controls
|
- [ ] Add touch controls
|
||||||
|
@ -41,6 +41,9 @@ func newAppContext(ctx ui.Context, settings *tins2021.Settings, score *tins2021.
|
|||||||
DyingMonsterTextures: map[tins2021.MonsterType]tins2021.AnimatedTexture{},
|
DyingMonsterTextures: map[tins2021.MonsterType]tins2021.AnimatedTexture{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
app.Audio.SampleVolume = settings.Audio.SoundVolume
|
||||||
|
app.Audio.MusicVolume = settings.Audio.MusicVolume
|
||||||
|
|
||||||
monsterNames := map[tins2021.MonsterType]string{
|
monsterNames := map[tins2021.MonsterType]string{
|
||||||
tins2021.MonsterTypeStraight: "straight-walking",
|
tins2021.MonsterTypeStraight: "straight-walking",
|
||||||
tins2021.MonsterTypeRandom: "random-walking",
|
tins2021.MonsterTypeRandom: "random-walking",
|
||||||
@ -83,6 +86,33 @@ func (app *appContext) PlayNext(ctx ui.Context, controller *levelController) {
|
|||||||
controller.Play(level)
|
controller.Play(level)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (app *appContext) playNextGameMusic(ctx ui.Context) {
|
||||||
|
if app.GameMusic != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
const songs = 4
|
||||||
|
pick := func() int {
|
||||||
|
for {
|
||||||
|
s := rand.Intn(songs) + 1
|
||||||
|
if s == app.GameMusicSong {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
app.GameMusicSong = s
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
}
|
||||||
|
song := fmt.Sprintf("song_game_%d.mp3", pick())
|
||||||
|
app.GameMusic, _ = app.Audio.PlayMusic(song, func(m *Music) {
|
||||||
|
m.OnFinished = func() {
|
||||||
|
if app.GameMusic == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
app.GameMusic = nil
|
||||||
|
app.playNextGameMusic(ctx)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func (app *appContext) PlayResume(ctx ui.Context) {
|
func (app *appContext) PlayResume(ctx ui.Context) {
|
||||||
level := tins2021.NewLevel()
|
level := tins2021.NewLevel()
|
||||||
level.Score = app.Score.Current.Score
|
level.Score = app.Score.Current.Score
|
||||||
@ -131,31 +161,22 @@ func (app *appContext) ShowMainMenu(ctx ui.Context) {
|
|||||||
app.show(ctx, newMainMenu(app, ctx))
|
app.show(ctx, newMainMenu(app, ctx))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) playNextGameMusic(ctx ui.Context) {
|
func (app *appContext) setMusicVolume(volume float64) {
|
||||||
if app.GameMusic != nil {
|
app.Settings.Audio.MusicVolume = volume
|
||||||
return
|
app.Audio.MusicVolume = volume
|
||||||
|
menu := app.MenuMusic
|
||||||
|
if menu != nil {
|
||||||
|
menu.Volume.Volume = volume
|
||||||
}
|
}
|
||||||
const songs = 4
|
game := app.GameMusic
|
||||||
pick := func() int {
|
if game != nil {
|
||||||
for {
|
game.Volume.Volume = volume
|
||||||
s := rand.Intn(songs) + 1
|
|
||||||
if s == app.GameMusicSong {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
app.GameMusicSong = s
|
|
||||||
return s
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
song := fmt.Sprintf("song_game_%d.mp3", pick())
|
|
||||||
app.GameMusic, _ = app.Audio.PlayMusic(song, func(m *Music) {
|
func (app *appContext) setSoundVolume(volume float64) {
|
||||||
m.OnFinished = func() {
|
app.Settings.Audio.SoundVolume = volume
|
||||||
if app.GameMusic == nil {
|
app.Audio.SampleVolume = volume
|
||||||
return
|
|
||||||
}
|
|
||||||
app.GameMusic = nil
|
|
||||||
app.playNextGameMusic(ctx)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (app *appContext) switchToPlayMusic(ctx ui.Context) {
|
func (app *appContext) switchToPlayMusic(ctx ui.Context) {
|
||||||
|
@ -35,8 +35,8 @@ func NewAudioPlayer(resources ui.Resources, prefix string) *AudioPlayer {
|
|||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
SampleRate: rate,
|
SampleRate: rate,
|
||||||
Samples: map[string]Sample{},
|
Samples: map[string]Sample{},
|
||||||
SampleVolume: 1,
|
SampleVolume: 0,
|
||||||
MusicVolume: 1,
|
MusicVolume: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,8 +83,8 @@ func (p *AudioPlayer) PlaySample(name string) error {
|
|||||||
speaker.Play(&effects.Volume{
|
speaker.Play(&effects.Volume{
|
||||||
Streamer: p.resample(sample.Stream(), sample.SampleRate),
|
Streamer: p.resample(sample.Stream(), sample.SampleRate),
|
||||||
Base: 2,
|
Base: 2,
|
||||||
Volume: float64(sample.Volume),
|
Volume: p.SampleVolume - sample.Volume,
|
||||||
Silent: false,
|
Silent: p.SampleVolume == minVolume,
|
||||||
})
|
})
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -106,8 +106,8 @@ func (p *AudioPlayer) PlayMusic(name string, init func(*Music)) (*Music, error)
|
|||||||
Volume: &effects.Volume{
|
Volume: &effects.Volume{
|
||||||
Streamer: p.resample(closer, format.SampleRate),
|
Streamer: p.resample(closer, format.SampleRate),
|
||||||
Base: 2,
|
Base: 2,
|
||||||
Volume: 1,
|
Volume: p.MusicVolume,
|
||||||
Silent: false,
|
Silent: p.MusicVolume == minVolume,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if init != nil {
|
if init != nil {
|
||||||
|
@ -44,7 +44,7 @@ func newMainMenu(app *appContext, ctx ui.Context) ui.Control {
|
|||||||
menu.Add("Resume", func(ctx ui.Context) { app.PlayResume(ctx) })
|
menu.Add("Resume", func(ctx ui.Context) { app.PlayResume(ctx) })
|
||||||
}
|
}
|
||||||
menu.Add("Highscores", func(ctx ui.Context) { app.ShowHighscores(ctx) })
|
menu.Add("Highscores", func(ctx ui.Context) { app.ShowHighscores(ctx) })
|
||||||
menu.Add("Controls", func(ctx ui.Context) { app.ShowSettings(ctx) })
|
menu.Add("Settings", func(ctx ui.Context) { app.ShowSettings(ctx) })
|
||||||
menu.Add("Credits", func(ctx ui.Context) { app.ShowCredits(ctx) })
|
menu.Add("Credits", func(ctx ui.Context) { app.ShowCredits(ctx) })
|
||||||
menu.Add("Quit", func(ctx ui.Context) { ctx.Quit() })
|
menu.Add("Quit", func(ctx ui.Context) { ctx.Quit() })
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"image/color"
|
"image/color"
|
||||||
|
|
||||||
"github.com/golang/freetype/truetype"
|
"github.com/golang/freetype/truetype"
|
||||||
|
"github.com/llgcode/draw2d"
|
||||||
"github.com/llgcode/draw2d/draw2dimg"
|
"github.com/llgcode/draw2d/draw2dimg"
|
||||||
"opslag.de/schobers/geom"
|
"opslag.de/schobers/geom"
|
||||||
"opslag.de/schobers/tins2021"
|
"opslag.de/schobers/tins2021"
|
||||||
@ -13,6 +14,12 @@ import (
|
|||||||
"opslag.de/schobers/zntg/ui"
|
"opslag.de/schobers/zntg/ui"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
controlsTypeWASD = "wasd"
|
||||||
|
controlsTypeArrows = "arrows"
|
||||||
|
controlsTypeCustom = "custom"
|
||||||
|
)
|
||||||
|
|
||||||
const keyboardKeyCornerRadius = .1 * keyboardKeyWidth
|
const keyboardKeyCornerRadius = .1 * keyboardKeyWidth
|
||||||
const keyboardKeyHeight = .2 * keyboardLayoutTextureWidth
|
const keyboardKeyHeight = .2 * keyboardLayoutTextureWidth
|
||||||
const keyboardKeySkew = .15
|
const keyboardKeySkew = .15
|
||||||
@ -20,6 +27,14 @@ const keyboardKeyWidth = .25 * keyboardLayoutTextureWidth
|
|||||||
const keyboardLayoutTextureHeight = 256
|
const keyboardLayoutTextureHeight = 256
|
||||||
const keyboardLayoutTextureWidth = 2 * keyboardLayoutTextureHeight
|
const keyboardLayoutTextureWidth = 2 * keyboardLayoutTextureHeight
|
||||||
|
|
||||||
|
const maxVolume = 2
|
||||||
|
const minVolume = -8
|
||||||
|
|
||||||
|
const volumeControlBarWidth = 154
|
||||||
|
const volumeControlKnobWidth = 154
|
||||||
|
const volumeControlTextureHeight = 256
|
||||||
|
const volumeControlTextureWidth = 2*volumeControlKnobWidth + 2*volumeControlBarWidth
|
||||||
|
|
||||||
func drawKey(ctx *draw2dimg.GraphicContext, font *truetype.Font, center geom.PointF, key rune, color color.Color) {
|
func drawKey(ctx *draw2dimg.GraphicContext, font *truetype.Font, center geom.PointF, key rune, color color.Color) {
|
||||||
const cornerRadius = keyboardKeyCornerRadius
|
const cornerRadius = keyboardKeyCornerRadius
|
||||||
const keyHeight_5 = .5 * keyboardKeyHeight
|
const keyHeight_5 = .5 * keyboardKeyHeight
|
||||||
@ -115,6 +130,68 @@ func generateKeys(resources ui.Resources, keys ...keyboardLayoutKey) image.Image
|
|||||||
return im
|
return im
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func generateVolumeControlTexture() (image.Image, map[string]geom.RectangleF) {
|
||||||
|
im := image.NewRGBA(image.Rect(0, 0, volumeControlTextureWidth, volumeControlTextureHeight))
|
||||||
|
ctx := draw2dimg.NewGraphicContext(im)
|
||||||
|
|
||||||
|
const unitMultiplier = float64(volumeControlTextureHeight)
|
||||||
|
var left float64
|
||||||
|
coord := func(x, y float64) (float64, float64) {
|
||||||
|
return left + x*unitMultiplier, y * unitMultiplier
|
||||||
|
}
|
||||||
|
|
||||||
|
regions := map[string]geom.RectangleF{}
|
||||||
|
ctx.SetFillColor(color.White)
|
||||||
|
ctx.SetStrokeColor(color.White)
|
||||||
|
ctx.SetLineCap(draw2d.SquareCap)
|
||||||
|
|
||||||
|
ctx.SetLineWidth(16)
|
||||||
|
ctx.MoveTo(coord(.1, .5))
|
||||||
|
ctx.LineTo(coord(.4, .2))
|
||||||
|
ctx.LineTo(coord(.52, .32))
|
||||||
|
ctx.LineTo(coord(.52, .68))
|
||||||
|
ctx.LineTo(coord(.4, .8))
|
||||||
|
ctx.Close()
|
||||||
|
ctx.Stroke()
|
||||||
|
regions["leftKnob"] = geom.RectF(0, 0, volumeControlKnobWidth, volumeControlTextureHeight)
|
||||||
|
|
||||||
|
left += volumeControlKnobWidth
|
||||||
|
ctx.SetLineWidth(16)
|
||||||
|
ctx.MoveTo(coord(.1, .2))
|
||||||
|
ctx.LineTo(coord(.3, .0))
|
||||||
|
ctx.LineTo(coord(.5, .2))
|
||||||
|
ctx.LineTo(coord(.5, .8))
|
||||||
|
ctx.LineTo(coord(.3, 1))
|
||||||
|
ctx.LineTo(coord(.1, .8))
|
||||||
|
ctx.Close()
|
||||||
|
ctx.Stroke()
|
||||||
|
regions["bar"] = geom.RectF(left, 0, left+volumeControlBarWidth, volumeControlTextureHeight)
|
||||||
|
|
||||||
|
left += volumeControlBarWidth
|
||||||
|
ctx.MoveTo(coord(.1, .2))
|
||||||
|
ctx.LineTo(coord(.3, .0))
|
||||||
|
ctx.LineTo(coord(.5, .2))
|
||||||
|
ctx.LineTo(coord(.5, .8))
|
||||||
|
ctx.LineTo(coord(.3, 1))
|
||||||
|
ctx.LineTo(coord(.1, .8))
|
||||||
|
ctx.Close()
|
||||||
|
ctx.FillStroke()
|
||||||
|
regions["barFilled"] = geom.RectF(left, 0, left+volumeControlBarWidth, volumeControlTextureHeight)
|
||||||
|
|
||||||
|
left += volumeControlBarWidth
|
||||||
|
ctx.SetLineWidth(16)
|
||||||
|
ctx.MoveTo(coord(.5, .5))
|
||||||
|
ctx.LineTo(coord(.2, .2))
|
||||||
|
ctx.LineTo(coord(.08, .32))
|
||||||
|
ctx.LineTo(coord(.08, .68))
|
||||||
|
ctx.LineTo(coord(.2, .8))
|
||||||
|
ctx.Close()
|
||||||
|
ctx.Stroke()
|
||||||
|
regions["rightKnob"] = geom.RectF(left, 0, left+volumeControlKnobWidth, volumeControlTextureHeight)
|
||||||
|
|
||||||
|
return im, regions
|
||||||
|
}
|
||||||
|
|
||||||
func generateWASDKeys(resources ui.Resources) image.Image {
|
func generateWASDKeys(resources ui.Resources) image.Image {
|
||||||
return generateKeys(resources,
|
return generateKeys(resources,
|
||||||
keyboardLayoutKey{Position: geom.PtF(.45, .25), Key: 'W'},
|
keyboardLayoutKey{Position: geom.PtF(.45, .25), Key: 'W'},
|
||||||
@ -130,24 +207,19 @@ type keyboardLayoutKey struct {
|
|||||||
Highlight bool
|
Highlight bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type settings struct {
|
type keyboardLayoutSettings struct {
|
||||||
ui.StackPanel
|
ui.ControlBase
|
||||||
|
|
||||||
app *appContext
|
app *appContext
|
||||||
|
|
||||||
|
Active bool
|
||||||
ActiveLayout int
|
ActiveLayout int
|
||||||
SelectedLayout int
|
SelectedLayout int
|
||||||
|
|
||||||
SelectingCustom int
|
SelectingCustom int
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
func newKeyboardLayoutSettings(app *appContext, ctx ui.Context) *keyboardLayoutSettings {
|
||||||
controlsTypeWASD = "wasd"
|
|
||||||
controlsTypeArrows = "arrows"
|
|
||||||
controlsTypeCustom = "custom"
|
|
||||||
)
|
|
||||||
|
|
||||||
func newSettings(app *appContext, ctx ui.Context) *settings {
|
|
||||||
ctx.Textures().CreateTextureGo("layout-wasd", generateWASDKeys(ctx.Resources()), true)
|
ctx.Textures().CreateTextureGo("layout-wasd", generateWASDKeys(ctx.Resources()), true)
|
||||||
ctx.Textures().CreateTextureGo("layout-arrows", generateArrowKeys(ctx.Resources()), true)
|
ctx.Textures().CreateTextureGo("layout-arrows", generateArrowKeys(ctx.Resources()), true)
|
||||||
ctx.Textures().CreateTextureGo("layout-select-1", generateArrowKeysHighlight(ctx.Resources(), [4]bool{true, false, false, false}), true)
|
ctx.Textures().CreateTextureGo("layout-select-1", generateArrowKeysHighlight(ctx.Resources(), [4]bool{true, false, false, false}), true)
|
||||||
@ -163,42 +235,19 @@ func newSettings(app *appContext, ctx ui.Context) *settings {
|
|||||||
layout = 2
|
layout = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
settings := &settings{app: app, ActiveLayout: layout, SelectedLayout: layout}
|
settings := &keyboardLayoutSettings{app: app, ActiveLayout: layout, SelectedLayout: layout}
|
||||||
settings.renderCustomLayout(ctx)
|
settings.renderCustomLayout(ctx)
|
||||||
return settings
|
return settings
|
||||||
}
|
}
|
||||||
|
|
||||||
var supportedCustomKeys = map[ui.Key]string{
|
func (s *keyboardLayoutSettings) DesiredSize(ctx ui.Context, size geom.PointF32) geom.PointF32 {
|
||||||
ui.KeyA: "A",
|
scale := tins2021.FindScaleRound(keyboardLayoutTextureWidth, .28*size.X)
|
||||||
ui.KeyB: "B",
|
font := ctx.Fonts().Font("default")
|
||||||
ui.KeyC: "C",
|
return geom.PtF32(geom.NaN32(), 2*font.Height()+scale*keyboardLayoutTextureHeight)
|
||||||
ui.KeyD: "D",
|
|
||||||
ui.KeyE: "E",
|
|
||||||
ui.KeyF: "F",
|
|
||||||
ui.KeyG: "G",
|
|
||||||
ui.KeyH: "H",
|
|
||||||
ui.KeyI: "I",
|
|
||||||
ui.KeyJ: "J",
|
|
||||||
ui.KeyK: "K",
|
|
||||||
ui.KeyL: "L",
|
|
||||||
ui.KeyM: "M",
|
|
||||||
ui.KeyN: "N",
|
|
||||||
ui.KeyO: "O",
|
|
||||||
ui.KeyP: "P",
|
|
||||||
ui.KeyQ: "Q",
|
|
||||||
ui.KeyR: "R",
|
|
||||||
ui.KeyS: "S",
|
|
||||||
ui.KeyT: "T",
|
|
||||||
ui.KeyU: "U",
|
|
||||||
ui.KeyV: "V",
|
|
||||||
ui.KeyW: "W",
|
|
||||||
ui.KeyX: "X",
|
|
||||||
ui.KeyY: "Y",
|
|
||||||
ui.KeyZ: "Z",
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *settings) Handle(ctx ui.Context, e ui.Event) bool {
|
func (s *keyboardLayoutSettings) Handle(ctx ui.Context, e ui.Event) bool {
|
||||||
if s.StackPanel.Handle(ctx, e) {
|
if s.ControlBase.Handle(ctx, e) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
switch e := e.(type) {
|
switch e := e.(type) {
|
||||||
@ -241,12 +290,18 @@ func (s *settings) Handle(ctx ui.Context, e ui.Event) bool {
|
|||||||
s.app.MenuInteraction()
|
s.app.MenuInteraction()
|
||||||
return true
|
return true
|
||||||
case ui.KeyLeft:
|
case ui.KeyLeft:
|
||||||
|
if s.Active {
|
||||||
s.setActiveLayout(s.ActiveLayout - 1)
|
s.setActiveLayout(s.ActiveLayout - 1)
|
||||||
|
}
|
||||||
case ui.KeyRight:
|
case ui.KeyRight:
|
||||||
|
if s.Active {
|
||||||
s.setActiveLayout(s.ActiveLayout + 1)
|
s.setActiveLayout(s.ActiveLayout + 1)
|
||||||
|
}
|
||||||
case ui.KeyEnter:
|
case ui.KeyEnter:
|
||||||
|
if s.Active {
|
||||||
s.selectLayout()
|
s.selectLayout()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
case *ui.MouseMoveEvent:
|
case *ui.MouseMoveEvent:
|
||||||
if s.SelectingCustom == 0 {
|
if s.SelectingCustom == 0 {
|
||||||
layout := s.isOverLayout(ctx, e.Pos())
|
layout := s.isOverLayout(ctx, e.Pos())
|
||||||
@ -254,6 +309,7 @@ func (s *settings) Handle(ctx ui.Context, e ui.Event) bool {
|
|||||||
s.setActiveLayout(layout)
|
s.setActiveLayout(layout)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
s.Active = s.IsOver()
|
||||||
case *ui.MouseButtonDownEvent:
|
case *ui.MouseButtonDownEvent:
|
||||||
if s.SelectingCustom == 0 {
|
if s.SelectingCustom == 0 {
|
||||||
if e.Button == ui.MouseButtonLeft {
|
if e.Button == ui.MouseButtonLeft {
|
||||||
@ -268,34 +324,20 @@ func (s *settings) Handle(ctx ui.Context, e ui.Event) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *settings) selectLayout() {
|
func (s *keyboardLayoutSettings) isOverLayout(ctx ui.Context, mouse geom.PointF32) int {
|
||||||
s.app.MenuInteraction()
|
|
||||||
switch s.ActiveLayout {
|
|
||||||
case 0:
|
|
||||||
s.SelectedLayout = 0
|
|
||||||
s.app.Settings.Controls.Type = controlsTypeWASD
|
|
||||||
case 1:
|
|
||||||
s.SelectedLayout = 1
|
|
||||||
s.app.Settings.Controls.Type = controlsTypeArrows
|
|
||||||
case 2:
|
|
||||||
s.SelectingCustom = 1
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *settings) isOverLayout(ctx ui.Context, mouse geom.PointF32) int {
|
|
||||||
bounds := s.Bounds()
|
bounds := s.Bounds()
|
||||||
center := bounds.Center()
|
|
||||||
width := bounds.Dx()
|
width := bounds.Dx()
|
||||||
|
|
||||||
scale := tins2021.FindScaleRound(keyboardLayoutTextureWidth, .28*width)
|
scale := tins2021.FindScaleRound(keyboardLayoutTextureWidth, .28*width)
|
||||||
|
|
||||||
font := ctx.Fonts().Font("default")
|
font := ctx.Fonts().Font("default")
|
||||||
|
|
||||||
|
top := bounds.Min.Y
|
||||||
|
bottom := top + 2*font.Height() + scale*keyboardLayoutTextureHeight
|
||||||
|
|
||||||
for i := 0; i < 3; i++ {
|
for i := 0; i < 3; i++ {
|
||||||
left := (.04 + .32*float32(i)) * width
|
left := (.04 + .32*float32(i)) * width
|
||||||
right := left + .28*width
|
right := left + .28*width
|
||||||
top := center.Y - 2*font.Height()
|
|
||||||
bottom := center.Y + scale*keyboardLayoutTextureWidth
|
|
||||||
if mouse.In(geom.RectF32(left, top, right, bottom)) {
|
if mouse.In(geom.RectF32(left, top, right, bottom)) {
|
||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
@ -303,23 +345,37 @@ func (s *settings) isOverLayout(ctx ui.Context, mouse geom.PointF32) int {
|
|||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *settings) setActiveLayout(layout int) {
|
func (s *keyboardLayoutSettings) PostRender(ctx ui.Context) {
|
||||||
layout = (layout + 3) % 3
|
|
||||||
change := layout != s.ActiveLayout
|
|
||||||
s.ActiveLayout = (layout + 3) % 3
|
|
||||||
if change {
|
|
||||||
s.app.MenuInteraction()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *settings) Render(ctx ui.Context) {
|
|
||||||
bounds := s.Bounds()
|
bounds := s.Bounds()
|
||||||
center := bounds.Center()
|
|
||||||
width := bounds.Dx()
|
width := bounds.Dx()
|
||||||
renderer := ctx.Renderer()
|
renderer := ctx.Renderer()
|
||||||
|
|
||||||
scale := tins2021.FindScaleRound(keyboardLayoutTextureWidth, .28*width)
|
scale := tins2021.FindScaleRound(keyboardLayoutTextureWidth, .28*width)
|
||||||
|
font := ctx.Fonts().Font("default")
|
||||||
|
|
||||||
|
normalColor := ctx.Style().Palette.Text
|
||||||
|
|
||||||
|
top := bounds.Min.Y
|
||||||
|
layoutTop := top + 2*font.Height()
|
||||||
|
|
||||||
|
if s.SelectingCustom > 0 {
|
||||||
|
renderer.FillRectangle(geom.ZeroPtF32.RectRel(renderer.Size().ToF32()), zntg.MustHexColor(`#000000DF`))
|
||||||
|
|
||||||
|
selectTexture := fmt.Sprintf("layout-select-%d", s.SelectingCustom)
|
||||||
|
|
||||||
|
layoutLeft := .36 * width
|
||||||
|
layoutCenter := layoutLeft + .14*width
|
||||||
|
renderer.TextAlign(font, geom.PtF32(layoutCenter, top), normalColor, "PRESS KEY TO ASSIGN", ui.AlignCenter)
|
||||||
|
renderer.DrawTexturePoint(ctx.Textures().ScaledByName(selectTexture, scale), geom.PtF32(layoutLeft, layoutTop))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *keyboardLayoutSettings) Render(ctx ui.Context) {
|
||||||
|
bounds := s.Bounds()
|
||||||
|
width := bounds.Dx()
|
||||||
|
renderer := ctx.Renderer()
|
||||||
|
|
||||||
|
scale := tins2021.FindScaleRound(keyboardLayoutTextureWidth, .28*width)
|
||||||
font := ctx.Fonts().Font("default")
|
font := ctx.Fonts().Font("default")
|
||||||
|
|
||||||
layouts := []string{
|
layouts := []string{
|
||||||
@ -332,6 +388,8 @@ func (s *settings) Render(ctx ui.Context) {
|
|||||||
normalColor := ctx.Style().Palette.Text
|
normalColor := ctx.Style().Palette.Text
|
||||||
highlightColor := ctx.Style().Palette.Primary
|
highlightColor := ctx.Style().Palette.Primary
|
||||||
|
|
||||||
|
top := bounds.Min.Y
|
||||||
|
layoutTop := top + 2*font.Height()
|
||||||
for i, layout := range layouts {
|
for i, layout := range layouts {
|
||||||
layoutLeft := (.04 + .32*float32(i)) * width
|
layoutLeft := (.04 + .32*float32(i)) * width
|
||||||
layoutCenter := layoutLeft + .14*width
|
layoutCenter := layoutLeft + .14*width
|
||||||
@ -345,23 +403,12 @@ func (s *settings) Render(ctx ui.Context) {
|
|||||||
layoutColor = highlightColor
|
layoutColor = highlightColor
|
||||||
}
|
}
|
||||||
|
|
||||||
renderer.TextAlign(font, geom.PtF32(layoutCenter, center.Y-2*font.Height()), textColor, layout, ui.AlignCenter)
|
renderer.TextAlign(font, geom.PtF32(layoutCenter, top), textColor, layout, ui.AlignCenter)
|
||||||
renderer.DrawTexturePointOptions(ctx.Textures().ScaledByName(layoutTextures[i], scale), geom.PtF32(layoutLeft, center.Y), ui.DrawOptions{Tint: layoutColor})
|
renderer.DrawTexturePointOptions(ctx.Textures().ScaledByName(layoutTextures[i], scale), geom.PtF32(layoutLeft, layoutTop), ui.DrawOptions{Tint: layoutColor})
|
||||||
}
|
|
||||||
|
|
||||||
if s.SelectingCustom > 0 {
|
|
||||||
renderer.FillRectangle(bounds, zntg.MustHexColor(`#000000DF`))
|
|
||||||
|
|
||||||
selectTexture := fmt.Sprintf("layout-select-%d", s.SelectingCustom)
|
|
||||||
|
|
||||||
layoutLeft := .36 * width
|
|
||||||
layoutCenter := layoutLeft + .14*width
|
|
||||||
renderer.TextAlign(font, geom.PtF32(layoutCenter, center.Y-2*font.Height()), normalColor, "PRESS KEY TO ASSIGN", ui.AlignCenter)
|
|
||||||
renderer.DrawTexturePoint(ctx.Textures().ScaledByName(selectTexture, scale), geom.PtF32(layoutLeft, center.Y))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *settings) renderCustomLayout(ctx ui.Context) {
|
func (s *keyboardLayoutSettings) renderCustomLayout(ctx ui.Context) {
|
||||||
runeOrQuestionMark := func(s string) rune {
|
runeOrQuestionMark := func(s string) rune {
|
||||||
if len(s) == 0 {
|
if len(s) == 0 {
|
||||||
return '?'
|
return '?'
|
||||||
@ -377,6 +424,323 @@ func (s *settings) renderCustomLayout(ctx ui.Context) {
|
|||||||
ctx.Textures().CreateTextureGo("layout-custom", generateCustomKeys(ctx.Resources(), customKeys), true)
|
ctx.Textures().CreateTextureGo("layout-custom", generateCustomKeys(ctx.Resources(), customKeys), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *keyboardLayoutSettings) selectLayout() {
|
||||||
|
s.app.MenuInteraction()
|
||||||
|
switch s.ActiveLayout {
|
||||||
|
case 0:
|
||||||
|
s.SelectedLayout = 0
|
||||||
|
s.app.Settings.Controls.Type = controlsTypeWASD
|
||||||
|
case 1:
|
||||||
|
s.SelectedLayout = 1
|
||||||
|
s.app.Settings.Controls.Type = controlsTypeArrows
|
||||||
|
case 2:
|
||||||
|
s.SelectingCustom = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *keyboardLayoutSettings) setActiveLayout(layout int) {
|
||||||
|
layout = (layout + 3) % 3
|
||||||
|
change := layout != s.ActiveLayout
|
||||||
|
s.ActiveLayout = (layout + 3) % 3
|
||||||
|
if change {
|
||||||
|
s.app.MenuInteraction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type settings struct {
|
||||||
|
ui.Proxy
|
||||||
|
|
||||||
|
app *appContext
|
||||||
|
musicVolume *volumeControl
|
||||||
|
soundVolume *volumeControl
|
||||||
|
keyboard *keyboardLayoutSettings
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSettings(app *appContext, ctx ui.Context) *settings {
|
||||||
|
volumeControlTexture := generateTextureMapFromImage(ctx.Textures(), "volume-control", generateVolumeControlTexture)
|
||||||
|
|
||||||
|
settings := &settings{app: app,
|
||||||
|
musicVolume: newVolumeControl(app, volumeControlTexture, "Music", app.Settings.Audio.MusicVolume, func(volume float64) { app.setMusicVolume(volume) }),
|
||||||
|
soundVolume: newVolumeControl(app, volumeControlTexture, "Sounds", app.Settings.Audio.SoundVolume, func(volume float64) { app.setSoundVolume(volume) }),
|
||||||
|
keyboard: newKeyboardLayoutSettings(app, ctx),
|
||||||
|
}
|
||||||
|
|
||||||
|
settings.Content = ui.BuildStackPanel(ui.OrientationVertical, func(p *ui.StackPanel) {
|
||||||
|
p.AddChild(Center(label("SETTINGS", "title")))
|
||||||
|
p.AddChild(label("", "score"))
|
||||||
|
p.AddChild(Center(settings.musicVolume))
|
||||||
|
p.AddChild(label("", "score"))
|
||||||
|
p.AddChild(Center(settings.soundVolume))
|
||||||
|
p.AddChild(label("", "score"))
|
||||||
|
p.AddChild(settings.keyboard)
|
||||||
|
})
|
||||||
|
|
||||||
|
settings.musicVolume.Active = true
|
||||||
|
|
||||||
|
return settings
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *settings) currentActive() int {
|
||||||
|
switch {
|
||||||
|
case s.musicVolume.Active:
|
||||||
|
return 0
|
||||||
|
case s.soundVolume.Active:
|
||||||
|
return 1
|
||||||
|
case s.keyboard.Active:
|
||||||
|
return 2
|
||||||
|
default:
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *settings) Handle(ctx ui.Context, e ui.Event) bool {
|
||||||
|
if s.keyboard.Active && s.keyboard.SelectingCustom > 0 {
|
||||||
|
return s.Proxy.Handle(ctx, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch e := e.(type) {
|
||||||
|
case *ui.KeyDownEvent:
|
||||||
|
switch e.Key {
|
||||||
|
case ui.KeyUp:
|
||||||
|
s.setActive(s.currentActive() - 1)
|
||||||
|
case ui.KeyDown:
|
||||||
|
s.setActive(s.currentActive() + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.Proxy.Handle(ctx, e)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *settings) Render(ctx ui.Context) {
|
||||||
|
s.Proxy.Render(ctx)
|
||||||
|
s.keyboard.PostRender(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *settings) setActive(active int) {
|
||||||
|
controls := [3]*bool{
|
||||||
|
&s.musicVolume.Active,
|
||||||
|
&s.soundVolume.Active,
|
||||||
|
&s.keyboard.Active,
|
||||||
|
}
|
||||||
|
for active < 0 {
|
||||||
|
active += len(controls)
|
||||||
|
}
|
||||||
|
if active > 0 {
|
||||||
|
active = active % len(controls)
|
||||||
|
}
|
||||||
|
s.app.MenuInteraction()
|
||||||
|
|
||||||
|
for i := range controls {
|
||||||
|
*controls[i] = i == active
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func skewedKeyboardCoordinates(x, y float64) (float64, float64) {
|
func skewedKeyboardCoordinates(x, y float64) (float64, float64) {
|
||||||
return x - keyboardKeySkew*y, y
|
return x - keyboardKeySkew*y, y
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var supportedCustomKeys = map[ui.Key]string{
|
||||||
|
ui.KeyA: "A",
|
||||||
|
ui.KeyB: "B",
|
||||||
|
ui.KeyC: "C",
|
||||||
|
ui.KeyD: "D",
|
||||||
|
ui.KeyE: "E",
|
||||||
|
ui.KeyF: "F",
|
||||||
|
ui.KeyG: "G",
|
||||||
|
ui.KeyH: "H",
|
||||||
|
ui.KeyI: "I",
|
||||||
|
ui.KeyJ: "J",
|
||||||
|
ui.KeyK: "K",
|
||||||
|
ui.KeyL: "L",
|
||||||
|
ui.KeyM: "M",
|
||||||
|
ui.KeyN: "N",
|
||||||
|
ui.KeyO: "O",
|
||||||
|
ui.KeyP: "P",
|
||||||
|
ui.KeyQ: "Q",
|
||||||
|
ui.KeyR: "R",
|
||||||
|
ui.KeyS: "S",
|
||||||
|
ui.KeyT: "T",
|
||||||
|
ui.KeyU: "U",
|
||||||
|
ui.KeyV: "V",
|
||||||
|
ui.KeyW: "W",
|
||||||
|
ui.KeyX: "X",
|
||||||
|
ui.KeyY: "Y",
|
||||||
|
ui.KeyZ: "Z",
|
||||||
|
}
|
||||||
|
|
||||||
|
type volumeControl struct {
|
||||||
|
ui.ControlBase
|
||||||
|
|
||||||
|
app *appContext
|
||||||
|
texture *TextureMap
|
||||||
|
|
||||||
|
Active bool
|
||||||
|
overLeftKnob bool
|
||||||
|
overBar int
|
||||||
|
overRightKnob bool
|
||||||
|
|
||||||
|
Name string
|
||||||
|
Volume float64
|
||||||
|
VolumeChanged func(float64)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newVolumeControl(app *appContext, texture *TextureMap, name string, volume float64, changed func(float64)) *volumeControl {
|
||||||
|
control := &volumeControl{app: app, texture: texture, overBar: -1, Name: name, Volume: volume, VolumeChanged: changed}
|
||||||
|
return control
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *volumeControl) changeVolume(delta float64) {
|
||||||
|
c.setVolume(c.Volume + delta)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *volumeControl) setVolume(volume float64) {
|
||||||
|
volume = geom.Min(maxVolume, geom.Max(minVolume, volume))
|
||||||
|
if c.Volume == volume {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.Volume = volume
|
||||||
|
c.VolumeChanged(c.Volume)
|
||||||
|
c.app.MenuInteraction()
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *volumeControl) DesiredSize(ctx ui.Context, size geom.PointF32) geom.PointF32 {
|
||||||
|
font := ctx.Fonts().Font("default")
|
||||||
|
return geom.PtF32(geom.NaN32(), 2.5*font.Height())
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *volumeControl) Handle(ctx ui.Context, e ui.Event) bool {
|
||||||
|
if c.ControlBase.Handle(ctx, e) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
switch e := e.(type) {
|
||||||
|
case *ui.KeyDownEvent:
|
||||||
|
switch e.Key {
|
||||||
|
case ui.KeyLeft:
|
||||||
|
if c.Active {
|
||||||
|
c.changeVolume(-1)
|
||||||
|
}
|
||||||
|
case ui.KeyRight:
|
||||||
|
if c.Active {
|
||||||
|
c.changeVolume(1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case *ui.MouseMoveEvent:
|
||||||
|
over := c.isOver(ctx, e.Pos())
|
||||||
|
switch over {
|
||||||
|
case -1:
|
||||||
|
c.overLeftKnob = false
|
||||||
|
c.overBar = -1
|
||||||
|
c.overRightKnob = false
|
||||||
|
case 0:
|
||||||
|
if !c.overLeftKnob {
|
||||||
|
c.app.MenuInteraction()
|
||||||
|
}
|
||||||
|
c.overLeftKnob = true
|
||||||
|
c.overBar = -1
|
||||||
|
c.overRightKnob = false
|
||||||
|
case 11:
|
||||||
|
if !c.overRightKnob {
|
||||||
|
c.app.MenuInteraction()
|
||||||
|
}
|
||||||
|
c.overLeftKnob = false
|
||||||
|
c.overBar = -1
|
||||||
|
c.overRightKnob = true
|
||||||
|
default:
|
||||||
|
if over-1 != c.overBar {
|
||||||
|
c.app.MenuInteraction()
|
||||||
|
}
|
||||||
|
c.overLeftKnob = false
|
||||||
|
c.overBar = over - 1
|
||||||
|
c.overRightKnob = false
|
||||||
|
}
|
||||||
|
c.Active = c.IsOver()
|
||||||
|
case *ui.MouseButtonDownEvent:
|
||||||
|
if e.Button == ui.MouseButtonLeft {
|
||||||
|
over := c.isOver(ctx, e.Pos())
|
||||||
|
switch over {
|
||||||
|
case -1:
|
||||||
|
case 0:
|
||||||
|
c.changeVolume(-1)
|
||||||
|
case 11:
|
||||||
|
c.changeVolume(1)
|
||||||
|
default:
|
||||||
|
c.setVolume(float64(over + minVolume))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *volumeControl) isOver(ctx ui.Context, p geom.PointF32) int {
|
||||||
|
bounds := c.Bounds()
|
||||||
|
font := ctx.Fonts().Font("default")
|
||||||
|
|
||||||
|
top := bounds.Min.Y + 1.5*font.Height()
|
||||||
|
bottom := top + font.Height()
|
||||||
|
if p.Y < top || p.Y >= bottom {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
scale := tins2021.FindScaleRound(volumeControlTextureHeight, font.Height())
|
||||||
|
knobWidth := scale * volumeControlKnobWidth
|
||||||
|
barWidth := scale * volumeControlBarWidth
|
||||||
|
left := bounds.Center().X - 5*barWidth - knobWidth
|
||||||
|
if p.X < left {
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
widths := []float32{knobWidth, barWidth, barWidth, barWidth, barWidth, barWidth, barWidth, barWidth, barWidth, barWidth, barWidth, knobWidth}
|
||||||
|
for i, w := range widths {
|
||||||
|
right := left + w
|
||||||
|
if p.X < right {
|
||||||
|
return i
|
||||||
|
}
|
||||||
|
left = right
|
||||||
|
}
|
||||||
|
return -1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *volumeControl) Render(ctx ui.Context) {
|
||||||
|
font := ctx.Fonts().Font("default")
|
||||||
|
scale := tins2021.FindScaleRound(volumeControlTextureHeight, font.Height())
|
||||||
|
|
||||||
|
normalColor := ctx.Style().Palette.Text
|
||||||
|
activeColor := ctx.Style().Palette.Primary
|
||||||
|
|
||||||
|
bounds := c.Bounds()
|
||||||
|
center := bounds.Center()
|
||||||
|
renderer := ctx.Renderer()
|
||||||
|
top := bounds.Min.Y
|
||||||
|
fontColor := normalColor
|
||||||
|
if c.Active {
|
||||||
|
fontColor = activeColor
|
||||||
|
}
|
||||||
|
renderer.TextAlign(font, geom.PtF32(center.X, top), fontColor, c.Name, ui.AlignCenter)
|
||||||
|
tint := func(active bool) color.Color {
|
||||||
|
if active {
|
||||||
|
return activeColor
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
leftKnob, leftKnobRegion := c.texture.Scaled("leftKnob", scale)
|
||||||
|
leftKnobWidth := leftKnobRegion.Dx()
|
||||||
|
bar, barRegion := c.texture.Scaled("bar", scale)
|
||||||
|
barFilled, barFilledRegion := c.texture.Scaled("barFilled", scale)
|
||||||
|
barWidth := barRegion.Dx()
|
||||||
|
rightKnob, rightKnobRegion := c.texture.Scaled("rightKnob", scale)
|
||||||
|
left := center.X - 5*barWidth - leftKnobWidth
|
||||||
|
top += 1.5 * font.Height()
|
||||||
|
ctx.Renderer().DrawTexturePointOptions(leftKnob, geom.PtF32(left, top), ui.DrawOptions{Source: &leftKnobRegion, Tint: tint(c.overLeftKnob)})
|
||||||
|
left += leftKnobWidth
|
||||||
|
for i := 0; i < 10; i++ {
|
||||||
|
volume := float64(i + minVolume + 1)
|
||||||
|
if volume <= c.Volume {
|
||||||
|
ctx.Renderer().DrawTexturePointOptions(barFilled, geom.PtF32(left, top), ui.DrawOptions{Source: &barFilledRegion, Tint: tint(i == c.overBar)})
|
||||||
|
} else {
|
||||||
|
ctx.Renderer().DrawTexturePointOptions(bar, geom.PtF32(left, top), ui.DrawOptions{Source: &barRegion, Tint: tint(i == c.overBar)})
|
||||||
|
}
|
||||||
|
left += barWidth
|
||||||
|
}
|
||||||
|
ctx.Renderer().DrawTexturePointOptions(rightKnob, geom.PtF32(left, top), ui.DrawOptions{Source: &rightKnobRegion, Tint: tint(c.overRightKnob)})
|
||||||
|
}
|
||||||
|
42
cmd/tins2021/texturemap.go
Normal file
42
cmd/tins2021/texturemap.go
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"image"
|
||||||
|
|
||||||
|
"opslag.de/schobers/geom"
|
||||||
|
"opslag.de/schobers/tins2021"
|
||||||
|
"opslag.de/schobers/zntg/ui"
|
||||||
|
)
|
||||||
|
|
||||||
|
type TextureMap struct {
|
||||||
|
texture tins2021.NamedTexture
|
||||||
|
regions map[string]geom.RectangleF32
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTextureMapFromImage(textures *ui.Textures, name string, im image.Image, regions map[string]geom.RectangleF) *TextureMap {
|
||||||
|
texture, err := tins2021.CreateNamedTextureImage(textures, name, im)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
regionMap := map[string]geom.RectangleF32{}
|
||||||
|
for name, region := range regions {
|
||||||
|
regionMap[name] = region.ToF32()
|
||||||
|
}
|
||||||
|
return &TextureMap{
|
||||||
|
texture: texture,
|
||||||
|
regions: regionMap,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func generateTextureMapFromImage(textures *ui.Textures, name string, generate func() (image.Image, map[string]geom.RectangleF)) *TextureMap {
|
||||||
|
im, regions := generate()
|
||||||
|
return newTextureMapFromImage(textures, name, im, regions)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *TextureMap) Texture(name string) (ui.Texture, geom.RectangleF32) {
|
||||||
|
return m.texture.Texture(), m.regions[name]
|
||||||
|
}
|
||||||
|
|
||||||
|
func (m *TextureMap) Scaled(name string, scale float32) (ui.Texture, geom.RectangleF32) {
|
||||||
|
return m.texture.Scaled(scale), geom.RectangleF32{Min: m.regions[name].Min.Mul(scale), Max: m.regions[name].Max.Mul(scale)}
|
||||||
|
}
|
22
settings.go
22
settings.go
@ -8,7 +8,21 @@ import (
|
|||||||
|
|
||||||
const settingsFileName = "settings.json"
|
const settingsFileName = "settings.json"
|
||||||
|
|
||||||
|
type AudioSettings struct {
|
||||||
|
SoundVolume float64
|
||||||
|
MusicVolume float64
|
||||||
|
}
|
||||||
|
|
||||||
|
type ControlsSettings struct {
|
||||||
|
Type string
|
||||||
|
MoveDownRight string
|
||||||
|
MoveDownLeft string
|
||||||
|
MoveUpLeft string
|
||||||
|
MoveUpRight string
|
||||||
|
}
|
||||||
|
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
|
Audio AudioSettings
|
||||||
Controls ControlsSettings
|
Controls ControlsSettings
|
||||||
Window WindowSettings
|
Window WindowSettings
|
||||||
}
|
}
|
||||||
@ -25,14 +39,6 @@ func (s *Settings) Store() error {
|
|||||||
return SaveUserFileJSON(settingsFileName, s)
|
return SaveUserFileJSON(settingsFileName, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
type ControlsSettings struct {
|
|
||||||
Type string
|
|
||||||
MoveDownRight string
|
|
||||||
MoveDownLeft string
|
|
||||||
MoveUpLeft string
|
|
||||||
MoveUpRight string
|
|
||||||
}
|
|
||||||
|
|
||||||
type WindowSettings struct {
|
type WindowSettings struct {
|
||||||
Location *geom.Point
|
Location *geom.Point
|
||||||
Size *geom.Point
|
Size *geom.Point
|
||||||
|
Loading…
Reference in New Issue
Block a user