Implemented better rotating around system.

This commit is contained in:
Andrey Parhomenko 2023-06-03 10:39:15 +03:00
parent ccefc2669b
commit 3807fc4bc2
5 changed files with 71 additions and 15 deletions

View file

@ -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,

View file

@ -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)

View file

@ -20,6 +20,9 @@ type Color struct {
// the layers order.
type Drawer interface {
Draw(*Engine, *Image)
}
type Visibler interface {
IsVisible() bool
}

View file

@ -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()
}

View file

@ -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)