parallax and interfaces

This commit is contained in:
Josh Deprez 2021-08-18 16:34:51 +10:00
parent 3b452fc3d0
commit 88482c390d
14 changed files with 136 additions and 21 deletions

BIN
asset_src/purple-space.jpeg Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

BIN
assets/space.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 472 KiB

View file

@ -5,6 +5,9 @@ import (
"image" "image"
) )
// Ensure Actor satisfies interfaces.
var _ Prepper = &Actor{}
func init() { func init() {
gob.Register(Actor{}) gob.Register(Actor{})
} }

View file

@ -1,11 +1,25 @@
package engine package engine
import ( import (
"encoding/gob"
"image" "image"
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
// Ensure Camera satisfies interfaces.
var (
_ Identifier = &Camera{}
_ Drawer = &Camera{}
_ Prepper = &Camera{}
_ Scanner = &Camera{}
_ Updater = &Camera{}
)
func init() {
gob.Register(Camera{})
}
// Camera models a camera that is viewing a scene. // Camera models a camera that is viewing a scene.
// Changes to the configuration take effect immediately. // Changes to the configuration take effect immediately.
// Camera ignores Scene.Draw and calls Scene's children's Draw. // Camera ignores Scene.Draw and calls Scene's children's Draw.
@ -74,8 +88,8 @@ func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
for _, i := range c.Scene.Components { for _, i := range c.Scene.Components {
if d, ok := i.(Drawer); ok { if d, ok := i.(Drawer); ok {
cs := 1.0 cs := 1.0
if s, ok := i.(CoordScaler); ok { if s, ok := i.(ParallaxScaler); ok {
cs = s.CoordScale() cs = s.ParallaxFactor()
} }
var geom ebiten.GeoM var geom ebiten.GeoM
// 1. Move centre to the origin, subject to CoordScale // 1. Move centre to the origin, subject to CoordScale

View file

@ -13,6 +13,14 @@ import (
"github.com/hajimehoshi/ebiten/v2/ebitenutil" "github.com/hajimehoshi/ebiten/v2/ebitenutil"
) )
var (
_ Drawer = PerfDisplay{}
_ DrawOrderer = PerfDisplay{}
_ Prepper = &GobDumper{}
_ Updater = &GobDumper{}
)
func init() { func init() {
gob.Register(GobDumper{}) gob.Register(GobDumper{})
gob.Register(PerfDisplay{}) gob.Register(PerfDisplay{})

View file

@ -6,10 +6,13 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
// Ensure Fill satisfies Drawer.
var _ Drawer = &Fill{}
// Fill fills the screen with a colour. // Fill fills the screen with a colour.
type Fill struct { type Fill struct {
Color color.Color Color color.Color
DrawOrder ZOrder
Hidden bool Hidden bool
ID ID
} }

38
engine/image.go Normal file
View file

@ -0,0 +1,38 @@
package engine
import (
"encoding/gob"
"image"
"github.com/hajimehoshi/ebiten/v2"
)
// Ensure Image satisfies interfaces.
var (
_ Identifier = &Image{}
_ Drawer = &Image{}
_ DrawOrderer = &Image{}
_ ParallaxScaler = &Image{}
)
func init() {
gob.Register(Image{})
}
// Image draws an image at a position.
type Image struct {
ID
Parallax
ZOrder
Src ImageRef
Pos image.Point
}
// Draw draws the image.
func (i *Image) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
var geom ebiten.GeoM
geom.Translate(float64(i.Pos.X), float64(i.Pos.Y))
geom.Concat(opts.GeoM)
opts.GeoM = geom
screen.DrawImage(i.Src.Image(), &opts)
}

View file

@ -11,10 +11,10 @@ type Collider interface {
CollidesWith(image.Rectangle) bool CollidesWith(image.Rectangle) bool
} }
// CoordScaler components have a scaling factor. This is used for // ParallaxScaler components have a scaling factor. This is used for
// e.g. parallax layers in a scene, and can be thought of as 1/distance. // parallax layers in a scene, and can be thought of as 1/distance.
type CoordScaler interface { type ParallaxScaler interface {
CoordScale() float64 ParallaxFactor() float64
} }
// Drawer components can draw themselves. Draw is called often. // Drawer components can draw themselves. Draw is called often.

View file

@ -6,8 +6,14 @@ type ID string
// Ident returns id as a string. // Ident returns id as a string.
func (id ID) Ident() string { return string(id) } func (id ID) Ident() string { return string(id) }
// DrawOrder implements DrawOrderer directly (as a float64 value). // Parallax implements ParallaxScaler directly (as a float64 value).
type DrawOrder float64 type Parallax float64
// ParallaxFactor returns s as a float64.
func (s Parallax) ParallaxFactor() float64 { return float64(s) }
// ZOrder implements DrawOrderer directly (as a float64 value).
type ZOrder float64
// DrawOrder returns z as a float64. // DrawOrder returns z as a float64.
func (z DrawOrder) DrawOrder() float64 { return float64(z) } func (z ZOrder) DrawOrder() float64 { return float64(z) }

View file

@ -8,6 +8,16 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
// Ensure Scene satisfies interfaces.
var (
_ Identifier = &Scene{}
_ Drawer = &Scene{}
_ DrawOrderer = &Scene{}
_ Prepper = &Scene{}
_ Scanner = &Scene{}
_ Updater = &Scene{}
)
func init() { func init() {
gob.Register(Scene{}) gob.Register(Scene{})
} }
@ -16,7 +26,7 @@ func init() {
type Scene struct { type Scene struct {
Components []interface{} Components []interface{}
Disabled bool Disabled bool
DrawOrder ZOrder
Hidden bool Hidden bool
ID ID
} }

View file

@ -5,6 +5,8 @@ import (
"image" "image"
) )
var _ Collider = SolidRect{}
func init() { func init() {
gob.Register(SolidRect{}) gob.Register(SolidRect{})
} }

View file

@ -7,6 +7,15 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
// Ensure Sprite satisfies interfaces.
var (
_ Identifier = &Sprite{}
_ Drawer = &Sprite{}
_ DrawOrderer = &Sprite{}
_ Scanner = &Sprite{}
_ Updater = &Sprite{}
)
func init() { func init() {
gob.Register(Sprite{}) gob.Register(Sprite{})
} }
@ -14,7 +23,7 @@ func init() {
// Sprite combines an Actor with the ability to Draw from a single spritesheet. // Sprite combines an Actor with the ability to Draw from a single spritesheet.
type Sprite struct { type Sprite struct {
Actor Actor
DrawOrder ZOrder
FrameSize image.Point FrameSize image.Point
FrameOffset image.Point FrameOffset image.Point
Hidden bool Hidden bool

View file

@ -7,6 +7,15 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
// Ensure Tilemap satisfies interfaces.
var (
_ Identifier = &Tilemap{}
_ Collider = &Tilemap{}
_ Drawer = &Tilemap{}
_ DrawOrderer = &Tilemap{}
_ Updater = &Tilemap{}
)
func init() { func init() {
gob.Register(AnimatedTile{}) gob.Register(AnimatedTile{})
gob.Register(StaticTile(0)) gob.Register(StaticTile(0))
@ -16,7 +25,7 @@ func init() {
// Tilemap renders a grid of tiles. // Tilemap renders a grid of tiles.
type Tilemap struct { type Tilemap struct {
Disabled bool Disabled bool
DrawOrder ZOrder
Hidden bool Hidden bool
ID ID
Map map[image.Point]Tile Map map[image.Point]Tile
@ -114,6 +123,12 @@ type Tile interface {
TileIndex() int TileIndex() int
} }
// Ensure StaticTile and AnimatedTile satisfy Tile.
var (
_ Tile = StaticTile(0)
_ Tile = &AnimatedTile{}
)
// StaticTile returns a fixed tile index. // StaticTile returns a fixed tile index.
type StaticTile int type StaticTile int

23
main.go
View file

@ -51,15 +51,22 @@ func main() {
ID: "level_1", ID: "level_1",
Components: []interface{}{ Components: []interface{}{
&engine.Fill{ &engine.Fill{
Color: color.Gray{100}, Color: color.Gray{100},
DrawOrder: 0, ZOrder: 0,
},
&engine.Image{
ID: "bg_image",
Parallax: 0.5,
ZOrder: 1,
Pos: image.Pt(-160, -120),
Src: engine.ImageRef{Path: "assets/space.png"},
}, },
&engine.Tilemap{ &engine.Tilemap{
ID: "terrain", ID: "terrain",
DrawOrder: 1, ZOrder: 2,
Map: tiles, Map: tiles,
Src: engine.ImageRef{Path: "assets/boxes.png"}, Src: engine.ImageRef{Path: "assets/boxes.png"},
TileSize: 16, TileSize: 16,
}, },
&engine.SolidRect{ &engine.SolidRect{
ID: "ceiling", ID: "ceiling",
@ -82,7 +89,7 @@ func main() {
Pos: image.Pt(100, 100), Pos: image.Pt(100, 100),
Size: image.Pt(8, 16), Size: image.Pt(8, 16),
}, },
DrawOrder: 2, ZOrder: 3,
FrameOffset: image.Pt(-1, 0), FrameOffset: image.Pt(-1, 0),
FrameSize: image.Pt(10, 16), FrameSize: image.Pt(10, 16),
Src: engine.ImageRef{Path: "assets/aw.png"}, Src: engine.ImageRef{Path: "assets/aw.png"},