diff --git a/src/cmd/test/main.go b/src/cmd/test/main.go index fd7647f..cf1a426 100644 --- a/src/cmd/test/main.go +++ b/src/cmd/test/main.go @@ -68,7 +68,7 @@ func NewPlayer() *Player { Sprite: &gx.Sprite{ Transform: gx.Transform { S: gx.Vector{5, 5}, - RA: gx.Vector{320, 240}, + RA: gx.Vector{.5, .5}, }, Visible: true, ShaderOptions: gx.ShaderOptions { @@ -87,12 +87,12 @@ func NewPlayer() *Player { func (p *Player) Draw(e *gx.Engine, i *gx.Image) { p.Sprite.Draw(e, i) + t := p.Transform + t.S.X *= 4. + t.S.Y *= 4. r := &gx.DrawableRectangle{ Rectangle: gx.Rectangle{ - Transform: gx.Transform{ - P: player.P, - S: gx.Vector{100, 100}, - }, + Transform: t, }, Color: gx.Color{0, 0, gx.MaxColorV, gx.MaxColorV}, } @@ -132,6 +132,12 @@ func (p *Player) Update(e *gx.Engine) error { c.R += gx.Pi * p.ScaleSpeed * dt case ebiten.KeyT : c.R -= gx.Pi * p.ScaleSpeed * dt + case ebiten.KeyRightBracket : + if e.KeyIsPressed(ebiten.KeyShift) { + p.R -= gx.Pi * 0.3 * dt + } else { + p.R += gx.Pi * 0.3 * dt + } case ebiten.KeyF : if e.KeyIsPressed(ebiten.KeyShift) { c.S.X -= gx.Pi * p.ScaleSpeed * dt @@ -150,14 +156,18 @@ func (p *Player) Update(e *gx.Engine) error { } else { c.RA.X += gx.Pi * p.MoveSpeed * dt } - log.Println(c.RA.X) case ebiten.KeyX : if e.KeyIsPressed(ebiten.KeyShift) { c.RA.Y -= gx.Pi * p.MoveSpeed * dt } else { c.RA.Y += gx.Pi * p.MoveSpeed * dt } - log.Println(c.RA.Y) + case ebiten.KeyLeftBracket : + if e.KeyIsPressed(ebiten.KeyShift) { + rect.R -= gx.Pi * 0.3 * dt + } else { + rect.R += gx.Pi * 0.3 * dt + } case ebiten.Key0 : e.Del(p) }} @@ -186,7 +196,7 @@ func (d *Debug) Draw( func (d *Debug) IsVisible() bool {return true} func main() { - e := gx.New(&gx.WindowConfig{ + e := gx.NewEngine(&gx.WindowConfig{ Title: "Test title", Width: 720, Height: 480, diff --git a/src/gx/engine.go b/src/gx/engine.go index f85892e..9e8fa89 100644 --- a/src/gx/engine.go +++ b/src/gx/engine.go @@ -53,7 +53,7 @@ func (e *Engine) Keys() []Key { } // Returns new empty Engine. -func New( +func NewEngine( cfg *WindowConfig, ) *Engine { w := Float(cfg.Width) @@ -157,7 +157,8 @@ func (e *engine) Draw(i *ebiten.Image) { eng := (*Engine)(e) for p := range e.layers.Vals() { for pj := range p.V.Range() { - if !pj.V.IsVisible() { + visibler, ok := pj.V.(Visibler) + if ok && !visibler.IsVisible() { continue } pj.V.Draw(eng, i) diff --git a/src/gx/img.go b/src/gx/img.go index 5b3fcc5..dea07a2 100644 --- a/src/gx/img.go +++ b/src/gx/img.go @@ -20,6 +20,9 @@ type Color struct { // the layers order. type Drawer interface { Draw(*Engine, *Image) +} + +type Visibler interface { IsVisible() bool } diff --git a/src/gx/sprite.go b/src/gx/sprite.go index 0ac95c1..5546f66 100644 --- a/src/gx/sprite.go +++ b/src/gx/sprite.go @@ -19,9 +19,9 @@ func (s *Sprite) Draw( return } + t := s.Rectangle().Transform m := &Matrix{} - - m.Concat(s.Matrix()) + m.Concat(t.Matrix()) if !s.Floating { m.Concat(e.Camera().RealMatrix( e, @@ -36,8 +36,8 @@ func (s *Sprite) Draw( return } - // Drawing with shader. w, h := s.Images[0].Size() + // Drawing with shader. opts := &ebiten.DrawRectShaderOptions{ Images: s.Images, Uniforms: s.Uniforms, @@ -46,7 +46,26 @@ func (s *Sprite) Draw( i.DrawRectShader(w, h, s.Shader, opts) } +// Check is sprite is visible. func (s *Sprite) IsVisible() bool { return s.Visible } +// Return the rectangle that contains the sprite. +func (s *Sprite) Rectangle() Rectangle { + if s.Images[0] == nil { + panic("trying to get rectangle for nil image pointer") + } + + w, h := s.Images[0].Size() + t := s.Transform + t.RA.X *= Float(w) + t.RA.Y *= Float(h) + + return Rectangle{t} +} + +func (s *Sprite) Triangles() Triangles { + return s.Rectangle().Triangles() +} + diff --git a/src/gx/transform.go b/src/gx/transform.go index 4d212f0..0c9be30 100644 --- a/src/gx/transform.go +++ b/src/gx/transform.go @@ -5,8 +5,17 @@ import ( //"math" ) +// The structure represents basic transformation +// features: positioning, rotating and scaling. type Transform struct { - // Position, scale, rotate around(relatively of position, not absolute). + // P - absolute phisycal position in engine itself. + // + // S - scale width and height (X and Y). + // + // RA - rotate around(relatively of position, not absolute). + // + // For example RA=Vector{0, 0} will rotate around right up corner + // and RA=Vector{.5, .5} will rotate around center. P, S, RA Vector // Rotation angle in radians. R Float @@ -20,13 +29,27 @@ func T() Transform { return ret } +func (t Transform) ScaledToXY(x, y Float) Transform { + return t.ScaledToX(x).ScaledToY(y) +} + +func (t Transform) ScaledToX(x Float) Transform { + t.S.X = x + return t +} + +func (t Transform) ScaledToY(y Float) Transform { + t.S.Y = y + return t +} + // 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.Translate(-t.RA.X, -t.RA.Y) + g.Translate(-t.RA.X * t.S.X, -t.RA.Y * t.S.Y) g.Rotate(t.R) g.Translate(t.P.X, t.P.Y)