diff --git a/src/cmd/test/main.go b/src/cmd/test/main.go index 2ce5d05..a6cab2b 100644 --- a/src/cmd/test/main.go +++ b/src/cmd/test/main.go @@ -7,6 +7,7 @@ import ( "bytes" "log" "strings" + "fmt" ) type Player struct { @@ -17,26 +18,65 @@ type Player struct { type Debug struct{} +type Rect struct { + *gx.DrawableRectangle +} + +func NewRect() *Rect { + return &Rect{&gx.DrawableRectangle{ + Rectangle: gx.Rectangle{ + W: 200, + H: 400, + T: gx.T(), + }, + Color: gx.Color{ + gx.MaxColorV, + 0, + 0, + gx.MaxColorV, + }, + Visible: true, + /*Shader: gx.SolidWhiteColorShader, + Options: gx.ShaderOptions{ + Images: [4]*gx.Image{ + playerImg, + nil, + nil, + nil, + }, + },*/ + }} +} + +func (r *Rect) Update(e *gx.Engine) error { + return nil +} + var ( playerImg *gx.Image ) func NewPlayer() *Player { - return &Player{ + ret := &Player{ Sprite: &gx.Sprite{ T: gx.Transform { S: gx.Vector{5, 5}, RA: gx.Vector{320, 240}, }, - I: playerImg, Visible: true, + Shader: gx.SolidWhiteColorShader, }, MoveSpeed: 90., ScaleSpeed: .2, } + + ret.Images[0] = playerImg + + return ret } -func (p *Player) Start(e *gx.Engine) { +func (p *Player) Start(e *gx.Engine, v ...any) { + fmt.Println("starting") c := e.Camera() c.T.RA = gx.V(360, -240) } @@ -130,28 +170,6 @@ func main() { e.Add(0, NewPlayer()) e.Add(1, &Debug{}) - e.Add(-1, gx.DrawableRectangle{ - Rectangle: gx.Rectangle{ - W: 4, - H: 4, - T: gx.T(), - }, - Color: gx.Color{ - gx.MaxColorV, - 0, - 0, - gx.MaxColorV, - }, - Visible: true, - Shader: gx.SolidWhiteColorShader, - Options: gx.ShaderOptions{ - Images: [4]*gx.Image{ - playerImg, - nil, - nil, - nil, - }, - }, - }) + e.Add(-1, NewRect()) e.Run() } diff --git a/src/gx/main.go b/src/gx/main.go index a28c964..e0e9a77 100644 --- a/src/gx/main.go +++ b/src/gx/main.go @@ -20,8 +20,12 @@ type Layer int // Window configuration type. type WindowConfig struct { Title string - Width, Height int - FixedSize bool + + Width, + Height int + + FixedSize, + Fullscreen, VSync bool } @@ -29,7 +33,7 @@ type WindowConfig struct { type Engine struct { wcfg *WindowConfig layers *sparsex.Sparse[Layer, *poolx.Pool[Drawer]] - behavers *poolx.Pool[Behaver] + updaters *poolx.Pool[Updater] lastTime time.Time dt Float camera *Camera @@ -72,26 +76,36 @@ func New( S: Vector{1, 1}, }, }, - behavers: poolx.New[Behaver](), + updaters: poolx.New[Updater](), } } // Add new object considering what // interfaces it implements. func (e *Engine) Add(l Layer, b any) { - beh, ok := b.(Behaver) + starter, ok := b.(Starter) if ok { - e.addBehaver(beh) + starter.Start(e) + } + + updater, ok := b.(Updater) + if ok { + e.addUpdater(updater) } - drw, ok := b.(Drawer) + drawer, ok := b.(Drawer) if ok { - e.addDrawer(l, drw) + e.addDrawer(l, drawer) } } -// Del object from Engine. -func (e *Engine) Del(b any) { +// Delete object from Engine. +func (e *Engine) Del(b any, v ...any) { + deleter, ok := b.(Deleter) + if ok { + deleter.Delete(e, v...) + } + drawer, ok := b.(Drawer) if ok { for layer := range e.layers.Vals() { @@ -99,9 +113,9 @@ func (e *Engine) Del(b any) { } } - behaver, ok := b.(Behaver) + updater, ok := b.(Updater) if ok { - e.behavers.Del(behaver) + e.updaters.Del(updater) } } @@ -121,9 +135,8 @@ func (e *Engine) addDrawer(l Layer, d Drawer) { } -func (e *Engine) addBehaver(b Behaver) { - e.behavers.Append(b) - b.Start(e) +func (e *Engine) addUpdater(b Updater) { + e.updaters.Append(b) } func (e *engine) Update() error { @@ -134,7 +147,7 @@ func (e *engine) Update() error { AppendPressedKeys(e.keys[:0]) e.dt = time.Since(e.lastTime).Seconds() - for p := range eng.behavers.Range() { + for p := range eng.updaters.Range() { err = p.V.Update(eng) if err != nil { return err diff --git a/src/gx/object.go b/src/gx/object.go index 178d6a9..679c4db 100644 --- a/src/gx/object.go +++ b/src/gx/object.go @@ -4,8 +4,9 @@ package gx // will call the function OnStart // when first appear on scene BEFORE // the OnUpdate. +// The v value will be get from Add function. type Starter interface { - Start(*Engine) + Start(*Engine, ...any) } // Implementing the interface type @@ -15,9 +16,10 @@ type Updater interface { Update(*Engine) error } -// The general interface for -type Behaver interface { - Starter - Updater +// Implementing the interface type +// will call the function on deleting +// the object. +type Deleter interface { + Delete(*Engine, ...any) } diff --git a/src/gx/rect.go b/src/gx/rect.go index 9be511d..8ade214 100644 --- a/src/gx/rect.go +++ b/src/gx/rect.go @@ -22,14 +22,19 @@ type Rectangle struct { type DrawableRectangle struct { Rectangle - Shader *Shader // Solid color of the rectangle. // Will be ignored if the Shader // field is not nil. Color Color - Options ShaderOptions + // Shader to be applied + Shader *Shader + // Shader variables. + Uniforms map[string] any + // Shader images + Images [4]*Image + // Should be draw or not. Visible bool } @@ -56,26 +61,29 @@ func NewImage(w, h int) (*Image) { return ebiten.NewImage(w, h) } -func (r DrawableRectangle) IsVisible() bool { +func (r *DrawableRectangle) IsVisible() bool { return r.Visible } -func (r DrawableRectangle) Draw( +func (r *DrawableRectangle) Draw( e *Engine, i *Image, ) { t := r.T - t.S.X *= r.W - t.S.Y *= r.H - - rm := e.Camera().RealMatrix(e, true) - m := t.Matrix(e) - m.Concat(rm) // Draw solid color if no shader. if r.Shader == nil { img := NewImage(1, 1) img.Set(0, 0, r.Color) + + t.S.X *= r.W + t.S.Y *= r.H + + m := t.Matrix(e) + rm := e.Camera().RealMatrix(e, true) + + m.Concat(rm) + opts := &ebiten.DrawImageOptions{ GeoM: m, } @@ -83,20 +91,35 @@ func (r DrawableRectangle) Draw( return } + // Use the Color as base image if no is provided. - if r.Options.Images[0] == nil { - r.Options.Images[0] = NewImage(1, 1) - r.Options.Images[0].Set(0, 0, r.Color) + var did bool + if r.Images[0] == nil { + r.Images[0] = NewImage(1, 1) + r.Images[0].Set(0, 0, r.Color) + did = true } + w, h := r.Images[0].Size() + if !did { + t.S.X /= Float(w) + t.S.Y /= Float(h) + + t.S.X *= r.W + t.S.Y *= r.H + } + + + rm := e.Camera().RealMatrix(e, true) + m := t.Matrix(e) + m.Concat(rm) + // Drawing with shader. opts := &ebiten.DrawRectShaderOptions{ GeoM: m, - Images: r.Options.Images, - Uniforms: r.Options.Uniforms, + Images: r.Images, + Uniforms: r.Uniforms, } - - w, h := r.Options.Images[0].Size() i.DrawRectShader(w, h, r.Shader, opts) } diff --git a/src/gx/sprite.go b/src/gx/sprite.go index 699f240..f230be1 100644 --- a/src/gx/sprite.go +++ b/src/gx/sprite.go @@ -5,9 +5,10 @@ import ( ) type Sprite struct { - I *Image T Transform - S *Shader + Shader *Shader + Images [4]*Image + Uniforms map[string] any Floating, Visible bool } @@ -15,25 +16,37 @@ func (s *Sprite) Draw( e *Engine, i *Image, ) { - op := &ebiten.DrawImageOptions{ - + // Nothing to draw. + if s.Images[0] == nil { + return } + m := &Matrix{} m.Concat(s.T.Matrix(e)) - if e.camera != nil { - m.Concat(e.camera.RealMatrix( + if !s.Floating { + m.Concat(e.Camera().RealMatrix( e, true, )) } - op.GeoM = *m - /*if s.S != nil { - bufImg := ebiten.NewImageFromImage(s.I) - } */ + // Drawing without shader. + if s.Shader == nil { + opts := &ebiten.DrawImageOptions{} + opts.GeoM = *m + i.DrawImage(s.Images[0], opts) + return + } - i.DrawImage(s.I, op) + // Drawing with shader. + w, h := s.Images[0].Size() + opts := &ebiten.DrawRectShaderOptions{ + Images: s.Images, + Uniforms: s.Uniforms, + GeoM: *m, + } + i.DrawRectShader(w, h, s.Shader, opts) } func (s *Sprite) IsVisible() bool {