diff --git a/cmd/tins2021/levelcontroller.go b/cmd/tins2021/levelcontroller.go index 48b746c..f0935b7 100644 --- a/cmd/tins2021/levelcontroller.go +++ b/cmd/tins2021/levelcontroller.go @@ -10,6 +10,7 @@ import ( "opslag.de/schobers/geom" "opslag.de/schobers/tins2021" + "opslag.de/schobers/zntg" "opslag.de/schobers/zntg/ui" ) @@ -89,6 +90,18 @@ func IsModifierPressed(modifiers ui.KeyModifier, pressed ui.KeyModifier) bool { } func (r levelController) Handle(ctx ui.Context, e ui.Event) bool { + switch e := e.(type) { + case *ui.KeyDownEvent: + switch e.Key { + case ui.KeyEscape: + r.app.ShowMainMenu(ctx) + } + } + + if r.Level.GameOver { + return false + } + switch e := e.(type) { case *ui.KeyDownEvent: switch e.Key { @@ -100,10 +113,9 @@ func (r levelController) Handle(ctx ui.Context, e ui.Event) bool { r.Level.MovePlayer(tins2021.DirectionDownRight) case ui.KeyA: r.Level.MovePlayer(tins2021.DirectionDownLeft) - case ui.KeyEscape: - r.app.ShowMainMenu(ctx) } } + for _, animations := range r.Animations { animations.Update() } @@ -111,14 +123,22 @@ func (r levelController) Handle(ctx ui.Context, e ui.Event) bool { r.MovingMonsters.Update() var jumped []geom.Point for pos, animation := range r.MovingMonsters.Values { - if animation.Frame < 20 { + if animation.Frame < 15 { continue } target := r.Level.MonsterTargets[pos] - r.Level.Monsters[target] = r.Level.Monsters[pos] - delete(r.Level.MonsterTargets, pos) - delete(r.Level.Monsters, pos) + if target == r.Level.Player { // player is hit + r.Level.DestroyMonster(pos) + jumped = append(jumped, pos) + r.Level.DecrementLive() + continue + } + if animation.Frame < 20 { + continue + } + r.Level.MoveMonster(target, pos) jumped = append(jumped, pos) + r.IdleMonsters.Frame(target) } for _, pos := range jumped { @@ -261,4 +281,12 @@ func (r levelController) Render(ctx ui.Context) { scoreTopLeft.Y += textureWidth heart.Draw(renderer, scoreTopLeft, 0) renderer.Text(scoreFont, scoreTopLeft.Add2D(textureWidth, fontOffsetY), textColor, fmt.Sprintf("x %d", r.Level.Lives)) + + if r.Level.GameOver { + bounds := r.Bounds() + titleFont := ctx.Fonts().Font("title") + renderer.FillRectangle(bounds, zntg.MustHexColor(`#0000007F`)) + offsetY := .5*bounds.Dy() - titleFont.Height() + renderer.TextAlign(titleFont, geom.PtF32(.5*bounds.Dx(), offsetY), textColor, "GAME OVER", ui.AlignCenter) + } } diff --git a/level.go b/level.go index ee46fd1..1a01545 100644 --- a/level.go +++ b/level.go @@ -14,6 +14,7 @@ type Level struct { Tiles Tiles Monsters Monsters MonsterTargets map[geom.Point]geom.Point + GameOver bool Bounds geom.Rectangle } @@ -71,6 +72,23 @@ func (l Level) CanMonsterMoveTo(p geom.Point) bool { return true } +func (l *Level) DecrementLive() { + l.Lives-- + if l.Lives == 0 { + l.GameOver = true + } +} + +func (l *Level) DestroyMonster(pos geom.Point) { + delete(l.MonsterTargets, pos) + delete(l.Monsters, pos) +} + +func (l *Level) MoveMonster(target, source geom.Point) { + l.Monsters[target] = l.Monsters[source] + l.DestroyMonster(source) +} + func (l *Level) MovePlayer(dir Direction) bool { towards, allowed := l.CanPlayerMove(dir) if !allowed { @@ -86,6 +104,10 @@ func (l *Level) MovePlayer(dir Direction) bool { l.StarsCollected++ tile.Star = false } + if l.Monsters[towards] != nil { + l.DecrementLive() + l.DestroyMonster(towards) + } return true }