diff --git a/TODO.md b/TODO.md index f876cf6..40c5c84 100644 --- a/TODO.md +++ b/TODO.md @@ -1,10 +1,12 @@ -- [ ] Increase difficulty. +- [X] Increase difficulty. - [ ] Add music & sounds. - [ ] Keep score/difficulty level (resume & restart). - [ ] Explain controls on info page. - [ ] Fix usage of go/embed (and remove rice again). -- [ ] Add monster animations (jumping on tile & towards new tile). +- [X] Add monster animations (~~jumping on tile &~~ towards new tile). - [ ] Scale icons (heart & star on right side) when playing. - [ ] Change layout when playing in portrait mode. - [X] Fix wobble animation. -- [ ] Add more unit tests? \ No newline at end of file +- [ ] Add more unit tests? +- [ ] Fix z-fighting of monsters. +- [ ] Add exploding animation of monsters. \ No newline at end of file diff --git a/cmd/tins2021/levelcontroller.go b/cmd/tins2021/levelcontroller.go index 0bd7e06..f152dbf 100644 --- a/cmd/tins2021/levelcontroller.go +++ b/cmd/tins2021/levelcontroller.go @@ -94,7 +94,7 @@ 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 < 15 { + if animation.Frame < 40 { // after 40 frames the player hit is checked continue } target := r.Level.MonsterTargets[pos] @@ -104,7 +104,7 @@ func (r *levelController) Handle(ctx ui.Context, e ui.Event) bool { r.Level.DecrementLive() continue } - if animation.Frame < 20 { + if animation.Frame < 50 { // after 50 frames the animation has finished continue } r.Level.MoveMonster(target, pos) @@ -149,8 +149,8 @@ func (r *levelController) Play(level *tins2021.Level) { "star": tins2021.NewAnimations(50*time.Millisecond, defaultAnimationFrames, true, true), "heart": tins2021.NewAnimations(80*time.Millisecond, defaultAnimationFrames, true, true), } - r.IdleMonsters = tins2021.NewAnimations(500*time.Millisecond, 100, false, false) - r.MovingMonsters = tins2021.NewAnimations(50*time.Millisecond, 20, false, false) + r.IdleMonsters = tins2021.NewAnimations(200*time.Millisecond, 100, false, false) + r.MovingMonsters = tins2021.NewAnimations(16*time.Millisecond, 50, false, false) for monster := range level.Monsters { r.IdleMonsters.Frame(monster) } @@ -206,9 +206,9 @@ func (r levelController) Render(ctx ui.Context) { distances := r.Level.Tiles.Distances(r.Level.Player) - positionOfTile := func(position geom.Point, tile *tins2021.Tile) (topLeft, centerOfPlatform geom.PointF32) { + positionOfTile := func(position geom.Point) (topLeft, centerOfPlatform geom.PointF32) { topLeft = toScreen(position) - if tile.Inversed { + if r.Level.Tiles[position].Inversed { return topLeft, topLeft.Add2D(.5*float32(cubeWidth), .6*float32(cubeHeight)) } return topLeft, topLeft.Add2D(.5*float32(cubeWidth), .2*float32(cubeHeight)) @@ -221,7 +221,7 @@ func (r levelController) Render(ctx ui.Context) { if tile == nil { continue } - screenPos, platformPos := positionOfTile(pos, tile) + screenPos, platformPos := positionOfTile(pos) tileTexture := cubes.Normal.Texture if tile.Inversed { tileTexture = cubes.Inversed.Texture @@ -253,9 +253,19 @@ func (r levelController) Render(ctx ui.Context) { if tile == nil { continue } - _, platformPos := positionOfTile(pos, tile) name := r.app.MonsterTextureNames[monsterType.Type()] - monsterTextures[monsterType.Type()].Draw(renderer, platformPos.Add(propOffset), r.Animations[name].Frame(pos)) + texture := monsterTextures[monsterType.Type()] + _, platformPos := positionOfTile(pos) + if target, ok := r.Level.MonsterTargets[pos]; ok { + _, targetPlatformPos := positionOfTile(target) + dt := float32(r.MovingMonsters.Frame(pos)) / 50. + delta := targetPlatformPos.Sub(platformPos) + curve := geom.PtF32(0, .6*geom.Sin32(dt*geom.Pi)*textureWidth) + interpolatedPos := platformPos.Add(delta.Mul(dt)).Sub(curve) + texture.Draw(renderer, interpolatedPos.Add(propOffset), r.Animations[name].Frame(pos)) + } else { + texture.Draw(renderer, platformPos.Add(propOffset), r.Animations[name].Frame(pos)) + } } textColor := ctx.Style().Palette.Text diff --git a/level.go b/level.go index 017a602..ab80919 100644 --- a/level.go +++ b/level.go @@ -170,7 +170,7 @@ func (l *Level) Randomize(difficulty int, stars int) { l.Tiles[pos].Star = true stars-- } - hearts := 1 + (100-difficulty)/50 // [3..1] (only difficulty has 3 hearts) + hearts := rand.Intn(2 + (100-difficulty)/50) // [3..1] (only difficulty 0 has 3 hearts) for hearts > 0 { pos := pick(difficulty) if l.Tiles[pos].Occupied() { @@ -179,9 +179,9 @@ func (l *Level) Randomize(difficulty int, stars int) { l.Tiles[pos].Heart = true hearts-- } - monsters := 2 + (8 * difficulty / 100) - minRandomMonster := (100-difficulty)*80/100 + 10 // [90..10] - minChaserMonster := (100-difficulty)*50/100 + 50 // [100..50] + monsters := 5 + (25 * difficulty / 100) + minRandomMonster := (100-difficulty)*60/100 + 10 // [70..10] + minChaserMonster := (100-difficulty)*70/100 + 25 // [95..25] for monsters > 0 { pos := pick(100 - difficulty) curr := l.Monsters[pos]