2023-02-17 07:04:29 +03:00
|
|
|
package gx
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hajimehoshi/ebiten/v2"
|
2023-02-17 16:40:46 +03:00
|
|
|
"github.com/surdeus/godat/src/sparsex"
|
2023-02-17 23:51:40 +03:00
|
|
|
//"fmt"
|
|
|
|
"time"
|
2023-02-17 07:04:29 +03:00
|
|
|
)
|
|
|
|
|
2023-02-17 16:40:46 +03:00
|
|
|
// The type represents order of drawing.
|
|
|
|
type Layer int
|
|
|
|
|
2023-02-17 07:04:29 +03:00
|
|
|
type WindowConfig struct {
|
|
|
|
Title string
|
|
|
|
Width, Height int
|
2023-02-17 23:51:40 +03:00
|
|
|
FullScreen bool
|
2023-02-17 07:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
type Engine struct {
|
|
|
|
wcfg *WindowConfig
|
2023-02-17 23:51:40 +03:00
|
|
|
layers *sparsex.Sparse[Layer, *[]Drawer]
|
2023-02-17 16:40:46 +03:00
|
|
|
behavers []Behaver
|
2023-02-17 23:51:40 +03:00
|
|
|
lastTime time.Time
|
|
|
|
dt Float
|
2023-02-18 03:51:43 +03:00
|
|
|
camera *Camera
|
2023-02-17 07:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
type engine Engine
|
|
|
|
|
2023-02-18 03:51:43 +03:00
|
|
|
func (e *Engine) Camera() *Camera {
|
|
|
|
return e.camera
|
|
|
|
}
|
|
|
|
|
2023-02-17 07:04:29 +03:00
|
|
|
func New(
|
|
|
|
cfg *WindowConfig,
|
|
|
|
) *Engine {
|
|
|
|
return &Engine{
|
|
|
|
wcfg: cfg,
|
2023-02-17 16:40:46 +03:00
|
|
|
layers: sparsex.New[
|
|
|
|
Layer,
|
2023-02-17 23:51:40 +03:00
|
|
|
*[]Drawer,
|
2023-02-17 16:40:46 +03:00
|
|
|
](true),
|
2023-02-18 03:51:43 +03:00
|
|
|
camera: &Camera{
|
|
|
|
Object: &Object{
|
|
|
|
T: Transform{
|
|
|
|
S: Vector{0.1, 1},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
},
|
2023-02-17 16:40:46 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-17 23:51:40 +03:00
|
|
|
// Add new object considering what
|
|
|
|
// interfaces it implements.
|
|
|
|
func (e *Engine) Add(l Layer, b any) {
|
|
|
|
beh, ok := b.(Behaver)
|
|
|
|
if ok {
|
|
|
|
e.AddBehaver(beh)
|
|
|
|
}
|
|
|
|
|
|
|
|
drw, ok := b.(Drawer)
|
|
|
|
if ok {
|
|
|
|
e.AddDrawer(l, drw)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Engine) AddDrawer(l Layer, d Drawer) {
|
2023-02-17 16:40:46 +03:00
|
|
|
g, ok := e.layers.Get(l)
|
|
|
|
if !ok {
|
|
|
|
e.layers.Set(
|
|
|
|
l,
|
2023-02-17 23:51:40 +03:00
|
|
|
&[]Drawer{d},
|
2023-02-17 16:40:46 +03:00
|
|
|
)
|
|
|
|
} else {
|
2023-02-17 23:51:40 +03:00
|
|
|
set := append(*g, d)
|
2023-02-17 16:40:46 +03:00
|
|
|
*g = set
|
2023-02-17 07:04:29 +03:00
|
|
|
}
|
2023-02-17 16:40:46 +03:00
|
|
|
|
2023-02-17 23:51:40 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *Engine) AddBehaver(b Behaver) {
|
2023-02-17 16:40:46 +03:00
|
|
|
e.behavers = append(e.behavers, b)
|
2023-02-17 07:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *engine) Update() error {
|
2023-02-17 16:40:46 +03:00
|
|
|
eng := (*Engine)(e)
|
2023-02-17 23:51:40 +03:00
|
|
|
|
2023-02-18 02:03:28 +03:00
|
|
|
e.dt = time.Since(e.lastTime).Seconds()
|
2023-02-17 16:40:46 +03:00
|
|
|
for _, v := range eng.behavers {
|
|
|
|
v.Update(eng)
|
2023-02-17 23:51:40 +03:00
|
|
|
//fmt.Println(v)
|
2023-02-17 16:40:46 +03:00
|
|
|
}
|
2023-02-18 02:03:28 +03:00
|
|
|
e.lastTime = time.Now()
|
2023-02-17 16:40:46 +03:00
|
|
|
|
2023-02-17 07:04:29 +03:00
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2023-02-17 16:40:46 +03:00
|
|
|
|
2023-02-17 23:51:40 +03:00
|
|
|
func (e *engine) Draw(i *ebiten.Image) {
|
|
|
|
eng := (*Engine)(e)
|
|
|
|
for p := range e.layers.Vals() {
|
|
|
|
for _, d := range *p.V {
|
|
|
|
d.Draw(eng, i)
|
|
|
|
}
|
|
|
|
}
|
2023-02-17 07:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
func (e *engine) Layout(ow, oh int) (int, int) {
|
|
|
|
return e.wcfg.Width, e.wcfg.Height
|
|
|
|
}
|
|
|
|
|
2023-02-17 23:51:40 +03:00
|
|
|
// Return the delta time duration value.
|
|
|
|
func (e *Engine) DT() Float {
|
|
|
|
return e.dt
|
|
|
|
}
|
|
|
|
|
2023-02-17 07:04:29 +03:00
|
|
|
func (e *Engine) Run() error {
|
|
|
|
ebiten.SetWindowTitle(e.wcfg.Title)
|
|
|
|
ebiten.SetWindowSize(e.wcfg.Width, e.wcfg.Height)
|
|
|
|
|
2023-02-18 00:17:51 +03:00
|
|
|
e.lastTime = time.Now()
|
|
|
|
|
2023-02-17 07:04:29 +03:00
|
|
|
return ebiten.RunGame((*engine)(e))
|
|
|
|
}
|
|
|
|
|