2021-08-05 12:26:41 +10:00
|
|
|
package engine
|
|
|
|
|
2021-08-05 12:33:23 +10:00
|
|
|
import (
|
|
|
|
"image"
|
2021-08-23 10:09:49 +10:00
|
|
|
"io/fs"
|
2021-08-27 15:39:10 +10:00
|
|
|
"reflect"
|
2021-08-05 12:33:23 +10:00
|
|
|
|
2021-09-08 20:08:57 +10:00
|
|
|
"drjosh.dev/gurgle/geom"
|
2021-08-05 12:33:23 +10:00
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
|
|
|
)
|
|
|
|
|
2021-08-27 15:39:10 +10:00
|
|
|
// Reflection types used for queries... Is there a better way?
|
|
|
|
var (
|
|
|
|
// TypeOf(pointer to interface).Elem() is "idiomatic" -
|
|
|
|
// see https://pkg.go.dev/reflect#example-TypeOf
|
2021-09-10 17:18:20 +10:00
|
|
|
BoundingBoxerType = reflect.TypeOf((*BoundingBoxer)(nil)).Elem()
|
2021-09-21 12:50:57 +10:00
|
|
|
BoundingRecterType = reflect.TypeOf((*BoundingRecter)(nil)).Elem()
|
2021-09-10 17:18:20 +10:00
|
|
|
ColliderType = reflect.TypeOf((*Collider)(nil)).Elem()
|
|
|
|
DisablerType = reflect.TypeOf((*Disabler)(nil)).Elem()
|
2021-09-20 14:24:32 +10:00
|
|
|
DrawBoxerType = reflect.TypeOf((*DrawBoxer)(nil)).Elem()
|
2021-09-21 12:50:57 +10:00
|
|
|
DrawerType = reflect.TypeOf((*Drawer)(nil)).Elem()
|
|
|
|
DrawManagerType = reflect.TypeOf((*DrawManager)(nil)).Elem()
|
2021-09-20 14:24:32 +10:00
|
|
|
DrawOrdererType = reflect.TypeOf((*DrawOrderer)(nil)).Elem()
|
2021-09-10 17:18:20 +10:00
|
|
|
HiderType = reflect.TypeOf((*Hider)(nil)).Elem()
|
|
|
|
IdentifierType = reflect.TypeOf((*Identifier)(nil)).Elem()
|
|
|
|
LoaderType = reflect.TypeOf((*Loader)(nil)).Elem()
|
|
|
|
PrepperType = reflect.TypeOf((*Prepper)(nil)).Elem()
|
2021-09-21 14:42:18 +10:00
|
|
|
RegistrarType = reflect.TypeOf((*Registrar)(nil)).Elem()
|
2021-09-10 17:18:20 +10:00
|
|
|
SaverType = reflect.TypeOf((*Saver)(nil)).Elem()
|
2021-09-21 12:50:57 +10:00
|
|
|
ScannerType = reflect.TypeOf((*Scanner)(nil)).Elem()
|
2021-09-10 17:18:20 +10:00
|
|
|
TransformerType = reflect.TypeOf((*Transformer)(nil)).Elem()
|
|
|
|
UpdaterType = reflect.TypeOf((*Updater)(nil)).Elem()
|
2021-08-27 15:39:10 +10:00
|
|
|
|
|
|
|
// Behaviours lists all the behaviours that can be queried with Game.Query.
|
|
|
|
Behaviours = []reflect.Type{
|
2021-09-10 17:18:20 +10:00
|
|
|
BoundingBoxerType,
|
2021-09-21 12:51:26 +10:00
|
|
|
BoundingRecterType,
|
2021-08-27 15:39:10 +10:00
|
|
|
ColliderType,
|
|
|
|
DisablerType,
|
2021-09-20 14:24:32 +10:00
|
|
|
DrawBoxerType,
|
2021-09-21 12:51:26 +10:00
|
|
|
DrawerType,
|
|
|
|
DrawManagerType,
|
2021-09-20 14:24:32 +10:00
|
|
|
DrawOrdererType,
|
2021-08-27 15:39:10 +10:00
|
|
|
HiderType,
|
|
|
|
IdentifierType,
|
|
|
|
LoaderType,
|
|
|
|
PrepperType,
|
2021-09-21 14:42:18 +10:00
|
|
|
RegistrarType,
|
2021-08-27 15:39:10 +10:00
|
|
|
SaverType,
|
2021-09-21 12:51:26 +10:00
|
|
|
ScannerType,
|
2021-08-31 18:19:14 +10:00
|
|
|
TransformerType,
|
2021-08-27 15:39:10 +10:00
|
|
|
UpdaterType,
|
|
|
|
}
|
|
|
|
)
|
|
|
|
|
2021-09-10 17:18:20 +10:00
|
|
|
// BoundingBoxer components have a bounding box.
|
|
|
|
type BoundingBoxer interface {
|
|
|
|
BoundingBox() geom.Box
|
|
|
|
}
|
|
|
|
|
2021-09-21 13:04:29 +10:00
|
|
|
// BoundingRecter components have a bounding rectangle.
|
|
|
|
type BoundingRecter interface {
|
|
|
|
BoundingRect() image.Rectangle
|
|
|
|
}
|
|
|
|
|
2021-08-05 12:33:23 +10:00
|
|
|
// Collider components have tangible form.
|
|
|
|
type Collider interface {
|
2021-09-08 20:08:57 +10:00
|
|
|
CollidesWith(geom.Box) bool
|
2021-08-05 12:33:23 +10:00
|
|
|
}
|
2021-08-05 12:26:41 +10:00
|
|
|
|
2021-08-23 11:10:46 +10:00
|
|
|
// Disabler components can be disabled.
|
|
|
|
type Disabler interface {
|
2021-09-13 16:50:35 +10:00
|
|
|
Disabled() bool
|
2021-08-23 11:10:46 +10:00
|
|
|
Disable()
|
|
|
|
Enable()
|
|
|
|
}
|
|
|
|
|
2021-09-21 13:04:29 +10:00
|
|
|
// DrawBoxer components can both draw and have a bounding box (used for draw
|
|
|
|
// ordering).
|
|
|
|
type DrawBoxer interface {
|
|
|
|
BoundingBoxer
|
|
|
|
Drawer
|
2021-09-20 12:18:03 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
// Drawer components can draw themselves. Draw is called often. Draw is not
|
|
|
|
// requierd to call Draw on subcomponents, if they are known to the engine
|
|
|
|
// (as part of a DrawManager).
|
2021-08-05 12:26:41 +10:00
|
|
|
type Drawer interface {
|
2021-09-11 13:00:23 +10:00
|
|
|
Draw(*ebiten.Image, *ebiten.DrawImageOptions)
|
2021-09-17 14:56:00 +10:00
|
|
|
}
|
|
|
|
|
2021-09-21 13:04:29 +10:00
|
|
|
// DrawManager is a component responsible for calling Draw on all Drawer
|
|
|
|
// components beneath it, except those beneath another DrawManager (it might
|
|
|
|
// call Draw on the DrawManager, but that's it).
|
|
|
|
type DrawManager interface {
|
|
|
|
ManagesDrawingSubcomponents()
|
2021-09-20 12:18:03 +10:00
|
|
|
}
|
|
|
|
|
2021-09-17 14:56:00 +10:00
|
|
|
// DrawOrderer components have more specific ideas about draw ordering than
|
|
|
|
// merely "my Z is bigger than yours".
|
|
|
|
type DrawOrderer interface {
|
2021-09-11 13:00:23 +10:00
|
|
|
DrawAfter(Drawer) bool
|
|
|
|
DrawBefore(Drawer) bool
|
2021-08-18 14:25:51 +10:00
|
|
|
}
|
|
|
|
|
2021-08-23 10:34:56 +10:00
|
|
|
// Hider components can be hidden.
|
|
|
|
type Hider interface {
|
2021-09-13 16:50:35 +10:00
|
|
|
Hidden() bool
|
2021-08-23 10:34:56 +10:00
|
|
|
Hide()
|
|
|
|
Show()
|
|
|
|
}
|
|
|
|
|
2021-08-05 12:26:41 +10:00
|
|
|
// Identifier components have a sense of self. This makes it easier for
|
2021-09-16 10:34:54 +10:00
|
|
|
// components to find and interact with one another. Returning the empty string
|
|
|
|
// is treated as having no identifier.
|
2021-08-05 12:26:41 +10:00
|
|
|
type Identifier interface {
|
|
|
|
Ident() string
|
|
|
|
}
|
|
|
|
|
2021-08-20 15:01:31 +10:00
|
|
|
// Loader components get the chance to load themselves. This happens
|
|
|
|
// before preparation.
|
|
|
|
type Loader interface {
|
2021-08-23 10:09:49 +10:00
|
|
|
Load(fs.FS) error
|
2021-08-20 15:01:31 +10:00
|
|
|
}
|
|
|
|
|
2021-08-05 12:26:41 +10:00
|
|
|
// Prepper components can be prepared. It is called after the component
|
|
|
|
// database has been populated but before the game is run. The component can
|
|
|
|
// store the reference to game, if needed, and also query the component database.
|
|
|
|
type Prepper interface {
|
2021-08-27 14:52:24 +10:00
|
|
|
Prepare(game *Game) error
|
2021-08-05 12:26:41 +10:00
|
|
|
}
|
|
|
|
|
2021-09-21 14:42:18 +10:00
|
|
|
// Registrar components can register and unregister other components (usually
|
|
|
|
// into internal data structures). Registrars are expected to automatically
|
|
|
|
// register/unregister subcomponents of components (usually recursively).
|
|
|
|
type Registrar interface {
|
|
|
|
Register(component, parent interface{}) error
|
|
|
|
Unregister(component interface{})
|
|
|
|
}
|
|
|
|
|
2021-09-21 13:04:29 +10:00
|
|
|
// Saver components can be saved to disk.
|
|
|
|
type Saver interface {
|
|
|
|
Save() error
|
|
|
|
}
|
|
|
|
|
2021-08-05 12:26:41 +10:00
|
|
|
// Scanner components can be scanned. It is called when the game tree is walked
|
2021-09-22 15:48:02 +10:00
|
|
|
// (such as when the game component database is constructed) and various times
|
|
|
|
// afterward (such as during Update).
|
|
|
|
// Scan should visit each immediate subcomponent, aborting early if an error is
|
|
|
|
// returned from the visitor.
|
2021-08-05 12:26:41 +10:00
|
|
|
type Scanner interface {
|
2021-09-22 15:48:02 +10:00
|
|
|
Scan(visit func(interface{}) error) error
|
2021-08-05 12:26:41 +10:00
|
|
|
}
|
|
|
|
|
2021-09-07 14:00:50 +10:00
|
|
|
// Transformer components can provide draw options to apply to themselves and
|
|
|
|
// any child components. The opts passed to Draw of a component c will be the
|
|
|
|
// cumulative opts of all parents of c plus the value returned from c.Transform.
|
2021-08-31 18:19:14 +10:00
|
|
|
type Transformer interface {
|
2021-09-07 14:00:50 +10:00
|
|
|
Transform() ebiten.DrawImageOptions
|
2021-08-31 18:19:14 +10:00
|
|
|
}
|
|
|
|
|
2021-09-01 09:32:36 +10:00
|
|
|
// Updater components can update themselves. Update is called repeatedly. Each
|
|
|
|
// component must call Update on any internal components not known to the engine
|
|
|
|
// (i.e. not passed to Game.Register or returned from Scan).
|
2021-08-05 12:26:41 +10:00
|
|
|
type Updater interface {
|
|
|
|
Update() error
|
|
|
|
}
|