diff --git a/src/cmd/test/main.go b/src/cmd/test/main.go index 5f5db9d..f0171ff 100644 --- a/src/cmd/test/main.go +++ b/src/cmd/test/main.go @@ -2,18 +2,37 @@ package main import ( "github.com/surdeus/gox/src/gx" + "github.com/hajimehoshi/ebiten/v2/examples/resources/images" + "bytes" + "log" ) type Player struct { - *gx.Object + *gx.Sprite } +var ( + playerImg *gx.Image +) + func NewPlayer() *Player { return &Player{ - Object: &gx.Object{}, + Sprite: &gx.Sprite{ + Object: &gx.Object{ + T: gx.Transform { + P: gx.Vector{1, 1}, + S: gx.Vector{1, 1}, + }, + }, + Image: playerImg, + }, } } +func (p *Player) Update(e *gx.Engine) { + p.Sprite.Object.T.P.Y += 0.1 +} + func main() { e := gx.New(&gx.WindowConfig{ Title: "Test title", @@ -21,6 +40,13 @@ func main() { Height: 320, }) + var err error + playerImg, err = gx.LoadImage(bytes.NewReader(images.Runner_png)) + if err != nil { + log.Fatal(err) + } + + e.Add(0, NewPlayer()) e.Run() } diff --git a/src/gx/img.go b/src/gx/img.go new file mode 100644 index 0000000..5197278 --- /dev/null +++ b/src/gx/img.go @@ -0,0 +1,30 @@ +package gx + +import ( + "github.com/hajimehoshi/ebiten/v2" + "image" + _ "image/png" + "io" +) + +type Image = ebiten.Image +type Rectangle = image.Rectangle +type Point = image.Point + +// The interface describes anything that can be +// drawn. It will be drew corresponding to +// the layers order. +type Drawer interface { + Draw(*Engine, *Image) +} + +func LoadImage(input io.Reader) (*Image, error) { + img, _, err := image.Decode(input) + if err != nil { + return nil, err + } + + ret := ebiten.NewImageFromImage(img) + return ret, nil +} + diff --git a/src/gx/main.go b/src/gx/main.go index 836c7e0..adf9557 100644 --- a/src/gx/main.go +++ b/src/gx/main.go @@ -3,7 +3,8 @@ package gx import ( "github.com/hajimehoshi/ebiten/v2" "github.com/surdeus/godat/src/sparsex" - "fmt" + //"fmt" + "time" ) // The type represents order of drawing. @@ -12,12 +13,15 @@ type Layer int type WindowConfig struct { Title string Width, Height int + FullScreen bool } type Engine struct { wcfg *WindowConfig - layers *sparsex.Sparse[Layer, *[]Behaver] + layers *sparsex.Sparse[Layer, *[]Drawer] behavers []Behaver + lastTime time.Time + dt Float } type engine Engine @@ -29,44 +33,75 @@ func New( wcfg: cfg, layers: sparsex.New[ Layer, - *[]Behaver, + *[]Drawer, ](true), } } -func (e *Engine) Add(l Layer, b Behaver) { +// 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) { g, ok := e.layers.Get(l) if !ok { e.layers.Set( l, - &[]Behaver{b}, + &[]Drawer{d}, ) } else { - set := append(*g, b) + set := append(*g, d) *g = set } +} + +func (e *Engine) AddBehaver(b Behaver) { e.behavers = append(e.behavers, b) } func (e *engine) Update() error { eng := (*Engine)(e) + + e.dt = time.Since(e.lastTime).Seconds() for _, v := range eng.behavers { v.Update(eng) - fmt.Println(v) + //fmt.Println(v) } + e.lastTime = time.Now() return nil } -func (e *engine) Draw(s *ebiten.Image) { +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) + } + } } func (e *engine) Layout(ow, oh int) (int, int) { return e.wcfg.Width, e.wcfg.Height } +// Return the delta time duration value. +func (e *Engine) DT() Float { + return e.dt +} + func (e *Engine) Run() error { ebiten.SetWindowTitle(e.wcfg.Title) ebiten.SetWindowSize(e.wcfg.Width, e.wcfg.Height) diff --git a/src/gx/object.go b/src/gx/object.go index 31b4dff..1db9b37 100644 --- a/src/gx/object.go +++ b/src/gx/object.go @@ -3,7 +3,6 @@ package gx type Behaver interface { Start(*Engine) Update(*Engine) - GetObject() *Object } // The object type represents @@ -13,7 +12,6 @@ type Object struct { T Transform } -// The functions that func (o *Object) Start(e *Engine) {} func (o *Object) Update(e *Engine) {} func (o *Object) GetObject() *Object { diff --git a/src/gx/sprite.go b/src/gx/sprite.go index 435dd6d..12a6519 100644 --- a/src/gx/sprite.go +++ b/src/gx/sprite.go @@ -1,4 +1,21 @@ package gx +import ( + "github.com/hajimehoshi/ebiten/v2" +) + type Sprite struct { + *Object + *Image } + +func (s *Sprite) Draw( + e *Engine, + i *Image, +) { + op := &ebiten.DrawImageOptions{} + op.GeoM = s.Object.T.Matrix() + + i.DrawImage(s.Image, op) +} + diff --git a/src/gx/transform.go b/src/gx/transform.go index 6432c32..b006c78 100644 --- a/src/gx/transform.go +++ b/src/gx/transform.go @@ -1,6 +1,11 @@ package gx -type Float float64 +import ( + "github.com/hajimehoshi/ebiten/v2" +) + +type Matrix = ebiten.GeoM +type Float = float64 type Vector struct { X, Y Float @@ -18,3 +23,15 @@ func T() Transform { return ret } +// Returns the GeoM with corresponding +// to the transfrom transformation +func (t Transform)Matrix() Matrix { + g := &Matrix{} + + g.Scale(t.S.X, t.S.Y) + g.Rotate(t.R) + g.Translate(t.P.X, t.P.Y) + + return *g +} +