2021-09-01 10:27:13 +10:00
|
|
|
package engine
|
|
|
|
|
|
|
|
import (
|
|
|
|
"encoding/gob"
|
|
|
|
"fmt"
|
|
|
|
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
|
|
)
|
|
|
|
|
|
|
|
var _ interface {
|
|
|
|
Prepper
|
|
|
|
Scanner
|
|
|
|
Transformer
|
|
|
|
} = &Parallax{}
|
|
|
|
|
|
|
|
func init() {
|
|
|
|
gob.Register(&Parallax{})
|
|
|
|
}
|
|
|
|
|
2021-09-01 12:12:25 +10:00
|
|
|
// Parallax is a container that translates based on the position of a
|
2021-09-01 10:27:13 +10:00
|
|
|
// camera, intended to produce a "parallax" like effect.
|
|
|
|
type Parallax struct {
|
|
|
|
CameraID string
|
2021-09-01 12:12:25 +10:00
|
|
|
Factor float64 // how much to translate in response to the camera
|
2021-09-01 10:27:13 +10:00
|
|
|
Child interface{}
|
|
|
|
|
|
|
|
camera *Camera
|
|
|
|
}
|
|
|
|
|
2021-09-01 12:12:25 +10:00
|
|
|
// Prepare obtains a reference to the camera.
|
2021-09-01 10:27:13 +10:00
|
|
|
func (p *Parallax) Prepare(game *Game) error {
|
|
|
|
c, ok := game.Component(p.CameraID).(*Camera)
|
|
|
|
if !ok {
|
|
|
|
return fmt.Errorf("component %q type != *Camera", p.CameraID)
|
|
|
|
}
|
|
|
|
p.camera = c
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2021-09-01 12:12:25 +10:00
|
|
|
// Scan returns the child component.
|
2021-09-01 10:27:13 +10:00
|
|
|
func (p *Parallax) Scan() []interface{} { return []interface{}{p.Child} }
|
|
|
|
|
2021-09-01 12:12:25 +10:00
|
|
|
// Transform returns a GeoM translation of Factor * camera.Centre.
|
2021-09-01 10:27:13 +10:00
|
|
|
func (p *Parallax) Transform() (opts ebiten.DrawImageOptions) {
|
2021-09-01 17:24:43 +10:00
|
|
|
x, y := pfloat(p.camera.Centre)
|
2021-09-01 10:27:13 +10:00
|
|
|
opts.GeoM.Translate(x*p.Factor, y*p.Factor)
|
|
|
|
return opts
|
|
|
|
}
|