diff --git a/cmd/krampus19/context.go b/cmd/krampus19/context.go index 7315cdc..9179421 100644 --- a/cmd/krampus19/context.go +++ b/cmd/krampus19/context.go @@ -27,7 +27,7 @@ type Context struct { ResourcesFs afero.Fs Textures map[string]texture Sprites map[string]sprite - Levels map[string]levelPack + Levels *levelPacks Progress progress SpriteDrawer SpriteDrawer Settings settings diff --git a/cmd/krampus19/game.go b/cmd/krampus19/game.go index a7ba679..d8da729 100644 --- a/cmd/krampus19/game.go +++ b/cmd/krampus19/game.go @@ -103,7 +103,7 @@ func (g *game) loadTextures(pathToName map[string]string) error { } func (g *game) loadLevelPacks() error { - g.ctx.Levels = map[string]levelPack{} + g.ctx.Levels = newLevelPacks() var ids []string const root = "levels" @@ -152,7 +152,7 @@ func (g *game) loadLevelPack(id string) error { if err != nil { return err } - g.ctx.Levels[id] = pack + g.ctx.Levels.Add(id, pack) return nil } @@ -206,7 +206,7 @@ func (g *game) loadAssets() error { if err != nil { return err } - log.Printf("Loaded %d levels packs.\n", len(g.ctx.Levels)) + log.Printf("Loaded %d levels packs (%d levels).\n", g.ctx.Levels.Len(), g.ctx.Levels.LenLevels()) log.Println("Loading fonts...") err = g.loadFonts() diff --git a/cmd/krampus19/levelpack.go b/cmd/krampus19/levelpack.go index 2cb087b..7116a62 100644 --- a/cmd/krampus19/levelpack.go +++ b/cmd/krampus19/levelpack.go @@ -29,6 +29,8 @@ func (p levelPack) FindNext(level string) (string, bool) { return p.order[idx+1], true } +func (p levelPack) Len() int { return len(p.order) } + type parseLevelPackContext struct { name string levels []string diff --git a/cmd/krampus19/levelpacks.go b/cmd/krampus19/levelpacks.go new file mode 100644 index 0000000..e22b306 --- /dev/null +++ b/cmd/krampus19/levelpacks.go @@ -0,0 +1,36 @@ +package main + +type levelPacks struct { + packs map[string]levelPack + order []string +} + +func newLevelPacks() *levelPacks { + return &levelPacks{map[string]levelPack{}, nil} +} + +func (p *levelPacks) Add(id string, pack levelPack) { + p.order = append(p.order, id) + p.packs[id] = pack +} + +func (p *levelPacks) ByID(id string) levelPack { return p.packs[id] } + +func (p *levelPacks) FirstPackID() string { + if p.Len() == 0 { + return "" + } + return p.order[0] +} + +func (p *levelPacks) Len() int { return len(p.order) } + +func (p *levelPacks) LenLevels() int { + var cnt int + for _, pack := range p.packs { + cnt += pack.Len() + } + return cnt +} + +func (p *levelPacks) MustSelect() bool { return p.Len() != 1 } diff --git a/cmd/krampus19/levelpackselect.go b/cmd/krampus19/levelpackselect.go new file mode 100644 index 0000000..f6ce3d5 --- /dev/null +++ b/cmd/krampus19/levelpackselect.go @@ -0,0 +1,40 @@ +package main + +import ( + "opslag.de/schobers/allg5" + + "opslag.de/schobers/krampus19/alui" +) + +type levelPackSelect struct { + alui.Menu + + ctx *Context +} + +func (s *levelPackSelect) Enter(ctx *Context) error { + s.ctx = ctx + s.Init() + s.AddChild(newHeader("Select a level pack")) + for _, id := range s.ctx.Levels.order { + var copy = id + s.Add(s.ctx.Levels.ByID(id).name, func() { + s.ctx.Navigation.SelectLevel(copy) + }) + } + s.Add("Back to main menu", func() { s.ctx.Navigation.ShowMainMenu() }) + return nil +} + +func (s *levelPackSelect) Handle(e allg5.Event) { + switch e := e.(type) { + case *allg5.KeyDownEvent: + switch e.KeyCode { + case allg5.KeyEscape: + s.ctx.Navigation.ShowMainMenu() + } + } + s.Menu.Handle(e) +} + +func (s *levelPackSelect) Leave() {} diff --git a/cmd/krampus19/levelselect.go b/cmd/krampus19/levelselect.go index 23f26fc..b99ce73 100644 --- a/cmd/krampus19/levelselect.go +++ b/cmd/krampus19/levelselect.go @@ -19,7 +19,7 @@ type levelSelect struct { func (s *levelSelect) Enter(ctx *Context) error { s.ctx = ctx - s.pack = s.ctx.Levels[s.packID] + s.pack = s.ctx.Levels.ByID(s.packID) s.Init() name := func(i int, steps int) string { if steps == 0 { @@ -27,12 +27,20 @@ func (s *levelSelect) Enter(ctx *Context) error { } return fmt.Sprintf("Level %d (%d)", i, steps) } + if s.ctx.Levels.MustSelect() { + s.AddChild(newHeader(fmt.Sprintf("Select a '%s' level", s.pack.name))) + } else { + s.AddChild(newHeader("Select a level")) + } for i, id := range s.pack.order { levelID := id s.Add(name(i+1, s.ctx.Progress.Level(s.packID, levelID).Steps), func() { s.ctx.Navigation.PlayLevel(s.packID, levelID) }) } + if s.ctx.Levels.MustSelect() { + s.Add("Select level pack", func() { s.ctx.Navigation.SelectPack() }) + } s.Add("Back to main menu", func() { s.ctx.Navigation.ShowMainMenu() }) return nil } diff --git a/cmd/krampus19/mainmenu.go b/cmd/krampus19/mainmenu.go index bf5d3b5..885997a 100644 --- a/cmd/krampus19/mainmenu.go +++ b/cmd/krampus19/mainmenu.go @@ -11,11 +11,15 @@ type mainMenu struct { ctx *Context } +func newHeader(label string) alui.Control { + return alui.NewMargins(&alui.Label{ControlBase: alui.ControlBase{Font: "header"}, Text: label, TextAlign: allg5.AlignCenter}, 3*margin) +} + func (m *mainMenu) Enter(ctx *Context) error { m.ctx = ctx m.Init() - m.AddChild(alui.NewMargins(&alui.Label{ControlBase: alui.ControlBase{Font: "header"}, Text: "Sokodragon", TextAlign: allg5.AlignCenter}, 3*margin)) - m.Add("Play", func() { m.ctx.Navigation.SelectLevel("1") }) + m.AddChild(newHeader("Sokodragon")) + m.Add("Play", func() { m.ctx.Navigation.SelectPack() }) m.Add("Settings", func() { m.ctx.Navigation.ChangeSettings() }) m.Add("Quit", func() { m.ctx.Navigation.Quit() }) return nil diff --git a/cmd/krampus19/navigation.go b/cmd/krampus19/navigation.go index fc240f9..d8fba1b 100644 --- a/cmd/krampus19/navigation.go +++ b/cmd/krampus19/navigation.go @@ -28,6 +28,15 @@ func (n *navigation) SelectLevel(packID string) { n.switchTo(&levelSelect{packID: packID}) } +func (n *navigation) SelectPack() { + if n.game.ctx.Levels.MustSelect() { + n.switchTo(&levelPackSelect{}) + } else { + packID := n.game.ctx.Levels.FirstPackID() + n.SelectLevel(packID) + } +} + func (n *navigation) ShowMainMenu() { n.switchTo(&mainMenu{}) } diff --git a/cmd/krampus19/playlevel.go b/cmd/krampus19/playlevel.go index 7fa9c99..6609bea 100644 --- a/cmd/krampus19/playlevel.go +++ b/cmd/krampus19/playlevel.go @@ -82,6 +82,9 @@ func (l *playLevel) onComplete() { if ok { menu.Add("Continue with next", func() { l.ctx.Navigation.PlayLevel(l.packID, nextID) }) } + if l.ctx.Levels.MustSelect() { + menu.Add("Select level pack", func() { l.ctx.Navigation.SelectPack() }) + } menu.Add("Select level", func() { l.ctx.Navigation.SelectLevel(l.packID) }) menu.Add("Go to main menu", func() { l.ctx.Navigation.ShowMainMenu() }) diff --git a/cmd/krampus19/playlevelstate.go b/cmd/krampus19/playlevelstate.go index c47c61e..314b34a 100644 --- a/cmd/krampus19/playlevelstate.go +++ b/cmd/krampus19/playlevelstate.go @@ -61,7 +61,7 @@ func (s *playLevelState) IsNextToMagma(pos geom.Point) bool { func (s *playLevelState) Init(ctx *Context, pack, level string, onComplete func()) { s.ctx = ctx - s.pack = ctx.Levels[pack] + s.pack = ctx.Levels.ByID(pack) s.level = s.pack.levels[level] s.bricks = nil s.sunken = nil