Added entityList.

Moved animations to separate code unit.
This commit is contained in:
Sander Schobers 2019-12-29 15:32:01 +01:00
parent 214d08f2b3
commit a4ab1a265e
4 changed files with 102 additions and 83 deletions

View File

@ -0,0 +1,52 @@
package main
import (
"time"
"opslag.de/schobers/geom"
)
type moveAnimation struct {
e *entity
from, to geom.Point
pos geom.PointF32
}
func newMoveAnimation(e *entity, to geom.Point) *moveAnimation {
ani := &moveAnimation{e: e, from: e.pos, to: to, pos: e.pos.ToF32()}
ani.e.pos = to
return ani
}
func (a *moveAnimation) Animate(start, now time.Duration) bool {
const duration = 210 * time.Millisecond
progress := float32((now-start)*1000/duration) * .001
from, to := a.from.ToF32(), a.to.ToF32()
if progress >= 1 {
a.e.scr.pos = to
return false
}
a.e.scr.pos = to.Sub(from).Mul(progress).Add(from)
return true
}
type sinkAnimation struct {
e *entity
}
func newSinkAnimation(e *entity) *sinkAnimation {
return &sinkAnimation{e: e}
}
func (a *sinkAnimation) Animate(start, now time.Duration) bool {
const duration = 70 * time.Millisecond
progress := float32((now-start)*1000/duration) * .001
if progress >= 1 {
a.e.scr.z = 80
return false
}
a.e.scr.z = progress * 80
return true
}

View File

@ -1,8 +1,6 @@
package main
import (
"time"
"opslag.de/schobers/geom"
)
@ -20,48 +18,3 @@ type entityLoc struct {
func newEntity(typ entityType, pos geom.Point) *entity {
return &entity{typ, pos, entityLoc{pos.ToF32(), 0}}
}
type moveAnimation struct {
e *entity
from, to geom.Point
pos geom.PointF32
}
func newMoveAnimation(e *entity, to geom.Point) *moveAnimation {
ani := &moveAnimation{e: e, from: e.pos, to: to, pos: e.pos.ToF32()}
ani.e.pos = to
return ani
}
func (a *moveAnimation) Animate(start, now time.Duration) bool {
const duration = 210 * time.Millisecond
progress := float32((now-start)*1000/duration) * .001
from, to := a.from.ToF32(), a.to.ToF32()
if progress >= 1 {
a.e.scr.pos = to
return false
}
a.e.scr.pos = to.Sub(from).Mul(progress).Add(from)
return true
}
type sinkAnimation struct {
e *entity
}
func newSinkAnimation(e *entity) *sinkAnimation {
return &sinkAnimation{e: e}
}
func (a *sinkAnimation) Animate(start, now time.Duration) bool {
const duration = 70 * time.Millisecond
progress := float32((now-start)*1000/duration) * .001
if progress >= 1 {
a.e.scr.z = 80
return false
}
a.e.scr.z = progress * 80
return true
}

View File

@ -0,0 +1,35 @@
package main
import "opslag.de/schobers/geom"
type entityList []*entity
func (l entityList) Add(e *entity) entityList {
return append(l, e)
}
func (l entityList) AddList(list entityList) entityList {
return append(l, list...)
}
func (l entityList) Find(pos geom.Point) int {
for i, e := range l {
if e.pos == pos {
return i
}
}
return -1
}
func (l entityList) FindEntity(pos geom.Point) *entity {
idx := l.Find(pos)
if idx == -1 {
return nil
}
return l[idx]
}
func (l entityList) Remove(pos geom.Point) entityList {
idx := l.Find(pos)
return append(l[:idx], l[idx+1:]...)
}

View File

@ -9,23 +9,6 @@ import (
"opslag.de/schobers/krampus19/gut"
)
func findEntityAt(entities []*entity, pos geom.Point) *entity {
idx := findEntityIdx(entities, pos)
if idx == -1 {
return nil
}
return entities[idx]
}
func findEntityIdx(entities []*entity, pos geom.Point) int {
for i, e := range entities {
if e.pos == pos {
return i
}
}
return -1
}
type playLevelState struct {
ctx *Context
@ -33,8 +16,8 @@ type playLevelState struct {
level level
player *entity
villain *entity
bricks []*entity
sunken []*entity
bricks entityList
sunken entityList
steps int
complete bool
@ -45,16 +28,13 @@ type playLevelState struct {
keysDown keyPressedState
}
func (s *playLevelState) Entities() []*entity {
var entities []*entity
entities = append(entities, s.player)
entities = append(entities, s.villain)
entities = append(entities, s.bricks...)
return entities
func (s *playLevelState) Entities() entityList {
var entities entityList
return entities.Add(s.player).Add(s.villain).AddList(s.bricks)
}
func (s *playLevelState) FindSunkenBrick(pos geom.Point) *entity {
return findEntityAt(s.sunken, pos)
return s.sunken.FindEntity(pos)
}
func (s *playLevelState) IsNextToMagma(pos geom.Point) bool {
@ -126,16 +106,15 @@ func (s *playLevelState) TryPlayerMove(dir geom.Point, key allg5.Key) {
}
})
if brick := findEntityAt(s.bricks, to); brick != nil {
if brick := s.bricks.FindEntity(to); brick != nil {
log.Printf("Pushing brick at %s", to)
brickTo := to.Add(dir)
s.ani.StartFn(s.ctx.Tick, newMoveAnimation(brick, brickTo), func() {
log.Printf("Brick movement finished")
if s.checkTile(brickTo, s.wouldBrickSink) {
log.Printf("Sinking brick at %s", brickTo)
idx := findEntityIdx(s.bricks, brickTo)
s.bricks = append(s.bricks[:idx], s.bricks[idx+1:]...)
s.sunken = append(s.sunken, brick)
s.bricks = s.bricks.Remove(brickTo)
s.sunken = s.sunken.Add(brick)
s.ani.Start(s.ctx.Tick, newSinkAnimation(brick))
}
})
@ -147,7 +126,7 @@ func (s *playLevelState) canMove(from, dir geom.Point) bool {
if !s.checkTile(to, s.isSolidTile) {
return false
}
brick := findEntityAt(s.bricks, to)
brick := s.bricks.FindEntity(to)
if brick != nil {
brickTo := to.Add(dir)
return !s.checkTileNotFound(brickTo, s.isObstructed, true)
@ -171,17 +150,17 @@ func (s *playLevelState) findEntityAt(pos geom.Point) *entity {
if s.player.pos == pos {
return s.player
}
brick := findEntityAt(s.bricks, pos)
brick := s.bricks.FindEntity(pos)
if brick != nil {
return brick
}
return findEntityAt(s.sunken, pos)
return s.sunken.FindEntity(pos)
}
func (s *playLevelState) isIdle() bool { return s.ani.Idle() }
func (s *playLevelState) isObstructed(pos geom.Point, idx int, t tile) bool {
if findEntityAt(s.bricks, pos) != nil {
if s.bricks.FindEntity(pos) != nil {
return true // brick
}
switch s.level.tiles[idx] {
@ -200,11 +179,11 @@ func (s *playLevelState) isSolidTile(pos geom.Point, idx int, t tile) bool {
case tileBasic:
return true
case tileMagma:
return findEntityAt(s.sunken, pos) != nil
return s.sunken.FindEntity(pos) != nil
}
return false
}
func (s *playLevelState) wouldBrickSink(pos geom.Point, idx int, t tile) bool {
return t == tileMagma && findEntityAt(s.sunken, pos) == nil
return t == tileMagma && s.sunken.FindEntity(pos) == nil
}