package main import ( "math" rl "github.com/gen2brain/raylib-go/raylib" ) type movementPattern func(*enemy) *enemy type patternDuration struct { duration duration move movementPattern } type statePipeline []patternDuration func shootStill() movementPattern { return func(e *enemy) *enemy { if e.shoot != nil { e.shoot(e) } return e } } func (sp statePipeline) MovementPattern(g *game) movementPattern { state := -1 t := newTimer(0) return func(e *enemy) *enemy { if !t.isTimeout() { t.tick(g) } else if state < len(sp)-1 { state++ t = newTimer(sp[state].duration) } sp[state].move(e) return e } } func horizonalPattern(g *game) movementPattern { direction := 1 return func(e *enemy) *enemy { if e.shoot != nil { e.shoot(e) } delta := rl.Vector2{ X: 400, Y: 0, } if e.pos.X < e.hitBoxRadius || e.pos.X > float32(g.arenaWidth-int32(e.hitBoxRadius)) { direction = -direction } e.pos = rl.Vector2Add( e.pos, rl.Vector2Scale( rl.Vector2{X: float32(direction) * delta.X, Y: delta.Y}, rl.GetFrameTime()*g.gameSpeed, ), ) return e } } func descentMove(g *game, y0, y1 float32, d duration) movementPattern { t := newTimer(d) return func(e *enemy) *enemy { if e.shoot != nil { e.shoot(e) } if !t.isTimeout() { t.tick(g) } else { return e } e.pos.Y = lerp(y0, y1, easeInOutSine(t.unit())) return e } } func sineDescentMove(g *game, y0, y1 float32, d duration) movementPattern { t := newTimer(d) return func(e *enemy) *enemy { if e.shoot != nil { e.shoot(e) } if !t.isTimeout() { t.tick(g) } else { return e } e.pos.Y = lerp(y0, y1, easeInOutSine(t.unit())) e.pos.X += float32(math.Sin(rl.GetTime() * 5 * float64(g.gameSpeed))) return e } } func sineHorizonalPattern(g *game, offset float64) movementPattern { direction := 1 return func(e *enemy) *enemy { if e.shoot != nil { e.shoot(e) } sine := math.Sin(rl.GetTime()*5*float64(g.gameSpeed)+offset) * 150 delta := rl.Vector2{ X: 400, Y: float32(sine), } if e.pos.X < e.hitBoxRadius || e.pos.X > float32(g.arenaWidth-int32(e.hitBoxRadius)) { direction = -direction } e.pos = rl.Vector2Add( e.pos, rl.Vector2Scale( rl.Vector2{X: float32(direction) * delta.X, Y: delta.Y}, rl.GetFrameTime()*g.gameSpeed, ), ) return e } }