all in on interfaces
This commit is contained in:
parent
7e76032ee2
commit
0f5346bf0e
7 changed files with 71 additions and 29 deletions
|
@ -126,12 +126,12 @@ func (r *SceneRef) Load(assets fs.FS) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// Scene returns the loaded scene, or nil if not yet loaded.
|
||||
func (r SceneRef) Scene() *Scene { return r.scene }
|
||||
|
||||
// The rest of the methods forward to r.scene, as such they will
|
||||
// panic if the scene isn't loaded.
|
||||
|
||||
// BoundingRect returns the Bounds from the scene.
|
||||
func (r SceneRef) BoundingRect() image.Rectangle { return r.scene.BoundingRect() }
|
||||
|
||||
// Draw draws the scene.
|
||||
func (r SceneRef) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||
r.scene.Draw(screen, opts)
|
||||
|
@ -140,6 +140,15 @@ func (r SceneRef) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
|||
// DrawOrder returns the value of DrawOrder from the scene.
|
||||
func (r SceneRef) DrawOrder() float64 { return r.scene.DrawOrder() }
|
||||
|
||||
// IsHidden returns the value of IsHidden from the scene.
|
||||
func (r SceneRef) IsHidden() bool { return r.scene.IsHidden() }
|
||||
|
||||
// Hide calls Hide on the scene.
|
||||
func (r SceneRef) Hide() { r.scene.Hide() }
|
||||
|
||||
// Show calls Show on the scene.
|
||||
func (r SceneRef) Show() { r.scene.Show() }
|
||||
|
||||
// Ident returns the value of Ident from the scene.
|
||||
func (r SceneRef) Ident() string { return r.scene.Ident() }
|
||||
|
||||
|
|
|
@ -37,14 +37,16 @@ type Camera struct {
|
|||
|
||||
// Draw applies transformations to opts, then calls c.Scene.Draw with it.
|
||||
func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
||||
if c.Scene.Scene().Hidden {
|
||||
if c.Scene.IsHidden() {
|
||||
return
|
||||
}
|
||||
|
||||
br := c.Scene.BoundingRect()
|
||||
|
||||
// The lower bound on zoom is the larger of
|
||||
// { (ScreenWidth / BoundsWidth), (ScreenHeight / BoundsHeight) }
|
||||
zoom := c.Zoom
|
||||
sz := c.Scene.Scene().Bounds.Size()
|
||||
sz := br.Size()
|
||||
if z := float64(c.game.ScreenWidth) / float64(sz.X); zoom < z {
|
||||
zoom = z
|
||||
}
|
||||
|
@ -57,17 +59,17 @@ func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
|||
// Camera frame currently Rectangle{ centre ± (screen/(2*zoom)) }.
|
||||
sw2, sh2 := float64(c.game.ScreenWidth/2), float64(c.game.ScreenHeight/2)
|
||||
swz, shz := int(sw2/zoom), int(sh2/zoom)
|
||||
if centre.X-swz < c.Scene.Scene().Bounds.Min.X {
|
||||
centre.X = c.Scene.Scene().Bounds.Min.X + swz
|
||||
if centre.X-swz < br.Min.X {
|
||||
centre.X = br.Min.X + swz
|
||||
}
|
||||
if centre.Y-shz < c.Scene.Scene().Bounds.Min.Y {
|
||||
centre.Y = c.Scene.Scene().Bounds.Min.Y + shz
|
||||
if centre.Y-shz < br.Min.Y {
|
||||
centre.Y = br.Min.Y + shz
|
||||
}
|
||||
if centre.X+swz > c.Scene.Scene().Bounds.Max.X {
|
||||
centre.X = c.Scene.Scene().Bounds.Max.X - swz
|
||||
if centre.X+swz > br.Max.X {
|
||||
centre.X = br.Max.X - swz
|
||||
}
|
||||
if centre.Y+shz > c.Scene.Scene().Bounds.Max.Y {
|
||||
centre.Y = c.Scene.Scene().Bounds.Max.Y - shz
|
||||
if centre.Y+shz > br.Max.Y {
|
||||
centre.Y = br.Max.Y - shz
|
||||
}
|
||||
|
||||
// Apply other options
|
||||
|
@ -101,7 +103,7 @@ func (c *Camera) Draw(screen *ebiten.Image, opts ebiten.DrawImageOptions) {
|
|||
}
|
||||
|
||||
// Update passes the call to c.Scene.
|
||||
func (c *Camera) Update() error { return c.Scene.Scene().Update() }
|
||||
func (c *Camera) Update() error { return c.Scene.Update() }
|
||||
|
||||
// Scan returns the only child (c.Scene).
|
||||
func (c *Camera) Scan() []interface{} { return []interface{}{c.Scene} }
|
||||
|
|
|
@ -7,6 +7,11 @@ import (
|
|||
"github.com/hajimehoshi/ebiten/v2"
|
||||
)
|
||||
|
||||
// Bounder components have a bounding rectangle.
|
||||
type Bounder interface {
|
||||
BoundingRect() image.Rectangle
|
||||
}
|
||||
|
||||
// Collider components have tangible form.
|
||||
type Collider interface {
|
||||
CollidesWith(image.Rectangle) bool
|
||||
|
@ -31,6 +36,13 @@ type DrawUpdater interface {
|
|||
Updater
|
||||
}
|
||||
|
||||
// Hider components can be hidden.
|
||||
type Hider interface {
|
||||
IsHidden() bool
|
||||
Hide()
|
||||
Show()
|
||||
}
|
||||
|
||||
// Identifier components have a sense of self. This makes it easier for
|
||||
// components to find and interact with one another.
|
||||
type Identifier interface {
|
||||
|
@ -75,14 +87,14 @@ type Scener interface {
|
|||
// }
|
||||
// It seems cleaner to let the engine assert only for the interface it needs at that moment.
|
||||
|
||||
Bounder
|
||||
Drawer
|
||||
DrawOrderer
|
||||
Hider
|
||||
Identifier
|
||||
Prepper
|
||||
Scanner
|
||||
Updater
|
||||
|
||||
Scene() *Scene
|
||||
}
|
||||
|
||||
// Updater components can update themselves. Update is called repeatedly.
|
||||
|
|
|
@ -1,11 +1,31 @@
|
|||
package engine
|
||||
|
||||
import "image"
|
||||
|
||||
// ID implements Identifier directly (as a string value).
|
||||
type ID string
|
||||
|
||||
// Ident returns id as a string.
|
||||
func (id ID) Ident() string { return string(id) }
|
||||
|
||||
// Bounds implements Bounder directly (as an image.Rectangle value).
|
||||
type Bounds image.Rectangle
|
||||
|
||||
// BoundingRect returns b as an image.Rectangle.
|
||||
func (b Bounds) BoundingRect() image.Rectangle { return image.Rectangle(b) }
|
||||
|
||||
// Hidden implements Hider directly (as a bool).
|
||||
type Hidden bool
|
||||
|
||||
// IsHidden returns h as a bool.
|
||||
func (h Hidden) IsHidden() bool { return bool(h) }
|
||||
|
||||
// Hide sets h to true.
|
||||
func (h *Hidden) Hide() { *h = true }
|
||||
|
||||
// Show sets h to false.
|
||||
func (h *Hidden) Show() { *h = false }
|
||||
|
||||
// Parallax implements ParallaxScaler directly (as a float64 value).
|
||||
type Parallax float64
|
||||
|
||||
|
|
|
@ -2,7 +2,6 @@ package engine
|
|||
|
||||
import (
|
||||
"encoding/gob"
|
||||
"image"
|
||||
"math"
|
||||
"sort"
|
||||
|
||||
|
@ -18,11 +17,11 @@ func init() {
|
|||
|
||||
// Scene manages drawing and updating a bunch of components.
|
||||
type Scene struct {
|
||||
Bounds image.Rectangle // world coordinates
|
||||
ID
|
||||
Bounds // world coordinates
|
||||
Components []interface{}
|
||||
Disabled bool
|
||||
Hidden bool
|
||||
ID
|
||||
Hidden
|
||||
ZOrder
|
||||
}
|
||||
|
||||
|
|
|
@ -13,7 +13,7 @@ func init() {
|
|||
|
||||
type SolidRect struct {
|
||||
ID
|
||||
Rect image.Rectangle
|
||||
Bounds
|
||||
}
|
||||
|
||||
func (s SolidRect) CollidesWith(r image.Rectangle) bool { return s.Rect.Overlaps(r) }
|
||||
func (s SolidRect) CollidesWith(r image.Rectangle) bool { return s.BoundingRect().Overlaps(r) }
|
||||
|
|
14
main.go
14
main.go
|
@ -51,7 +51,7 @@ func main() {
|
|||
|
||||
level1 := &engine.Scene{
|
||||
ID: "level_1",
|
||||
Bounds: image.Rect(-32, -32, 320+32, 240+32),
|
||||
Bounds: engine.Bounds(image.Rect(-32, -32, 320+32, 240+32)),
|
||||
Components: []interface{}{
|
||||
&engine.Fill{
|
||||
Color: color.Gray{100},
|
||||
|
@ -72,16 +72,16 @@ func main() {
|
|||
TileSize: 16,
|
||||
},
|
||||
&engine.SolidRect{
|
||||
ID: "ceiling",
|
||||
Rect: image.Rect(0, -1, 320, 0),
|
||||
ID: "ceiling",
|
||||
Bounds: engine.Bounds(image.Rect(0, -1, 320, 0)),
|
||||
},
|
||||
&engine.SolidRect{
|
||||
ID: "left_wall",
|
||||
Rect: image.Rect(-1, 0, 0, 240),
|
||||
ID: "left_wall",
|
||||
Bounds: engine.Bounds(image.Rect(-1, 0, 0, 240)),
|
||||
},
|
||||
&engine.SolidRect{
|
||||
ID: "right_wall",
|
||||
Rect: image.Rect(320, 0, 321, 240),
|
||||
ID: "right_wall",
|
||||
Bounds: engine.Bounds(image.Rect(320, 0, 321, 240)),
|
||||
},
|
||||
&game.Awakeman{
|
||||
CameraID: "game_camera",
|
||||
|
|
Loading…
Reference in a new issue