feat: using the new Context model I perform everywhere.

This commit is contained in:
Andrey Parhomenko 2023-12-20 22:39:33 +03:00
parent 4fdb569bca
commit d4ac7909db
13 changed files with 114 additions and 102 deletions

View file

@ -4,6 +4,7 @@ package gg
// for the main window. // for the main window.
type Camera struct { type Camera struct {
Transform Transform
buf *Matrix
} }
// Returns the matrix satysfying camera // Returns the matrix satysfying camera
@ -12,22 +13,24 @@ type Camera struct {
// transform to display on the screen. // transform to display on the screen.
// (Should implement buffering it so we do not // (Should implement buffering it so we do not
// need to calculate it each time for each object. ) // need to calculate it each time for each object. )
func (c *Camera)RealMatrix( func (c *Camera)RealMatrix() Matrix {
e *Engine,
) Matrix {
g := &Matrix{} g := &Matrix{}
g.Translate(-c.P.X, -c.P.Y) g.Translate(-c.P.X, -c.P.Y)
g.Rotate(c.R) g.Rotate(c.R)
g.Scale(c.S.X, c.S.Y) g.Scale(c.S.X, c.S.Y)
g.Translate(c.RA.X, c.RA.Y) g.Translate(c.RA.X, c.RA.Y)
c.buf = g
return *g return *g
} }
func (c *Camera) AbsMatrix( // The matrix to convert things into the
e *Engine, // inside engine representation,
) Matrix { // get the position of cursor inside the world
m := c.RealMatrix(e) // basing on its window position.
func (c *Camera) AbsMatrix() Matrix {
m := c.RealMatrix()
m.Invert() m.Invert()
return m return m
} }

View file

@ -11,6 +11,8 @@ import (
"math/rand" "math/rand"
) )
type Context = gg.Context
const ( const (
HighestL gg.Layer = -iota HighestL gg.Layer = -iota
DebugL DebugL
@ -28,6 +30,7 @@ type Player struct {
} }
type Debug struct { type Debug struct {
gg.Visibility
gg.Layer gg.Layer
} }
@ -98,11 +101,15 @@ func NewRect() *Rect {
return ret return ret
} }
func (r *Rect) Update(e *gg.Engine) error { func (r *Rect) Update(c *Context) error {
//r.R += 0.3 * e.DT() //r.R += 0.3 * e.DT()
r.P = c.AbsCursorPosition()
return nil return nil
} }
func (r *Rect) Event(c *Context) {
}
var ( var (
playerImg *gg.Image playerImg *gg.Image
player *Player player *Player
@ -134,8 +141,8 @@ func NewPlayer() *Player {
return ret return ret
} }
func (p *Player) Draw(e *gg.Engine, i *gg.Image) { func (p *Player) Draw(c *Context) {
p.Sprite.Draw(e, i) p.Sprite.Draw(c)
t := p.Transform t := p.Transform
t.S.X *= 4. t.S.X *= 4.
t.S.Y *= 4. t.S.Y *= 4.
@ -146,31 +153,31 @@ func (p *Player) Draw(e *gg.Engine, i *gg.Image) {
Rectangle: rectMove, Rectangle: rectMove,
Color: gg.Color{0, 0, gg.MaxColorV, gg.MaxColorV}, Color: gg.Color{0, 0, gg.MaxColorV, gg.MaxColorV},
} }
r.Draw(e, i) r.Draw(c)
} }
func (p *Player) Start(e *gg.Engine, v ...any) { func (p *Player) Start(c *Context) {
fmt.Println("starting") fmt.Println("starting")
c := e.Camera() cam := c.Camera()
c.RA = gg.V(360, 240) cam.RA = gg.V(360, 240)
} }
func (p *Player) Update(e *gg.Engine) error { func (p *Player) Update(c *Context) error {
dt := e.DT() dt := c.DT()
c := e.Camera() cam := c.Camera()
keys := e.Keys() keys := c.Keys()
p.Uniforms["Random"] = any(rand.Float32()) p.Uniforms["Random"] = any(rand.Float32())
for _, v := range keys { for _, v := range keys {
switch v { switch v {
case ebiten.KeyArrowUp: case ebiten.KeyArrowUp:
c.P.Y += p.MoveSpeed * dt cam.P.Y += p.MoveSpeed * dt
case ebiten.KeyArrowLeft: case ebiten.KeyArrowLeft:
c.P.X -= p.MoveSpeed * dt cam.P.X -= p.MoveSpeed * dt
case ebiten.KeyArrowDown: case ebiten.KeyArrowDown:
c.P.Y -= p.MoveSpeed * dt cam.P.Y -= p.MoveSpeed * dt
case ebiten.KeyArrowRight: case ebiten.KeyArrowRight:
c.P.X += p.MoveSpeed * dt cam.P.X += p.MoveSpeed * dt
case ebiten.KeyW: case ebiten.KeyW:
p.P.Y += p.MoveSpeed * dt p.P.Y += p.MoveSpeed * dt
case ebiten.KeyA: case ebiten.KeyA:
@ -180,61 +187,61 @@ func (p *Player) Update(e *gg.Engine) error {
case ebiten.KeyD: case ebiten.KeyD:
p.P.X += p.MoveSpeed * dt p.P.X += p.MoveSpeed * dt
case ebiten.KeyR: case ebiten.KeyR:
c.R += gg.Pi * p.ScaleSpeed * dt cam.R += gg.Pi * p.ScaleSpeed * dt
case ebiten.KeyT: case ebiten.KeyT:
c.R -= gg.Pi * p.ScaleSpeed * dt cam.R -= gg.Pi * p.ScaleSpeed * dt
case ebiten.KeyRightBracket: case ebiten.KeyRightBracket:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(gg.KeyShift) {
p.R -= gg.Pi * 0.3 * dt p.R -= gg.Pi * 0.3 * dt
} else { } else {
p.R += gg.Pi * 0.3 * dt p.R += gg.Pi * 0.3 * dt
} }
case ebiten.KeyF: case gg.KeyF:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(ebiten.KeyShift) {
c.S.X -= gg.Pi * p.ScaleSpeed * dt cam.S.X -= gg.Pi * p.ScaleSpeed * dt
} else { } else {
c.S.X += gg.Pi * p.ScaleSpeed * dt cam.S.X += gg.Pi * p.ScaleSpeed * dt
} }
case ebiten.KeyG: case gg.KeyG:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(ebiten.KeyShift) {
c.S.Y -= gg.Pi * p.ScaleSpeed * dt cam.S.Y -= gg.Pi * p.ScaleSpeed * dt
} else { } else {
c.S.Y += gg.Pi * p.ScaleSpeed * dt cam.S.Y += gg.Pi * p.ScaleSpeed * dt
} }
case ebiten.KeyZ: case gg.KeyZ:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(ebiten.KeyShift) {
c.RA.X -= gg.Pi * p.MoveSpeed * dt cam.RA.X -= gg.Pi * p.MoveSpeed * dt
} else { } else {
c.RA.X += gg.Pi * p.MoveSpeed * dt cam.RA.X += gg.Pi * p.MoveSpeed * dt
} }
case ebiten.KeyX: case gg.KeyX:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(ebiten.KeyShift) {
c.RA.Y -= gg.Pi * p.MoveSpeed * dt cam.RA.Y -= gg.Pi * p.MoveSpeed * dt
} else { } else {
c.RA.Y += gg.Pi * p.MoveSpeed * dt cam.RA.Y += gg.Pi * p.MoveSpeed * dt
} }
case ebiten.KeyV: case gg.KeyV:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(ebiten.KeyShift) {
tri.R -= gg.Pi * 0.3 * dt tri.R -= gg.Pi * 0.3 * dt
} else { } else {
tri.R += gg.Pi * 0.3 * dt tri.R += gg.Pi * 0.3 * dt
} }
case ebiten.KeyLeftBracket: case gg.KeyLeftBracket:
if e.IsPressed(ebiten.KeyShift) { if c.IsPressed(ebiten.KeyShift) {
rect.R -= gg.Pi * 0.3 * dt rect.R -= gg.Pi * 0.3 * dt
} else { } else {
rect.R += gg.Pi * 0.3 * dt rect.R += gg.Pi * 0.3 * dt
} }
case ebiten.Key0: case gg.Key0:
e.Del(p) c.Del(p)
case ebiten.KeyB: case gg.KeyB:
} }
} }
return nil return nil
} }
func (p *Player) Event(e *gg.Engine, ev any) { func (p *Player) Signal(e *gg.Engine, ev any) {
fmt.Println("event:", ev) fmt.Println("event:", ev)
switch ec := ev.(type) { switch ec := ev.(type) {
case *gg.KeyDown: case *gg.KeyDown:
@ -249,10 +256,8 @@ func (p *Player) Event(e *gg.Engine, ev any) {
} }
} }
func (d *Debug) Draw( func (d *Debug) Draw(c *Context) {
e *gg.Engine, e := c.Engine
i *gg.Image,
) {
keyStrs := []string{} keyStrs := []string{}
for _, k := range e.Keys() { for _, k := range e.Keys() {
keyStrs = append(keyStrs, k.String()) keyStrs = append(keyStrs, k.String())
@ -270,7 +275,7 @@ func (d *Debug) Draw(
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.CursorPosition())) keyStrs = append(keyStrs, fmt.Sprintf("%v", e.CursorPosition()))
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.AbsCursorPosition())) keyStrs = append(keyStrs, fmt.Sprintf("%v", e.AbsCursorPosition()))
e.DebugPrint(i, e.DebugPrint(c.Image,
strings.Join(keyStrs, ", ")) strings.Join(keyStrs, ", "))
} }

7
context.go Normal file
View file

@ -0,0 +1,7 @@
package gg
type Context struct {
*Engine
*Image
Event any
}

View file

@ -96,7 +96,9 @@ func (e *Engine) Add(b any) error {
starter, ok := b.(Starter) starter, ok := b.(Starter)
if ok { if ok {
starter.Start(e) starter.Start(&Context{
Engine: e,
})
} }
e.objects.Set(object, struct{}{}) e.objects.Set(object, struct{}{})
@ -113,7 +115,9 @@ func (e *Engine) Del(b any) error {
deleter, ok := b.(Deleter) deleter, ok := b.(Deleter)
if ok { if ok {
deleter.Delete(e) deleter.Delete(&Context{
Engine: e,
})
} }
e.objects.Del(b) e.objects.Del(b)
@ -152,14 +156,19 @@ func (e *engine) Update() error {
eventer, ok := object.(Eventer) eventer, ok := object.(Eventer)
if ok { if ok {
for _, event := range events { for _, event := range events {
eventer.Event(eng, event) eventer.Event(&Context{
Engine: eng,
Event: event,
})
} }
} }
updater, ok := object.(Updater) updater, ok := object.(Updater)
if !ok { if !ok {
continue continue
} }
err = updater.Update(eng) err = updater.Update(&Context{
Engine: eng,
})
if err != nil { if err != nil {
return err return err
} }
@ -193,7 +202,10 @@ func (e *engine) Draw(i *ebiten.Image) {
layers := maps.NewSparse[Layer, []Drawer](nil, m) layers := maps.NewSparse[Layer, []Drawer](nil, m)
for layer := range layers.Chan() { for layer := range layers.Chan() {
for _, drawer := range layer { for _, drawer := range layer {
drawer.Draw(eng, i) drawer.Draw(&Context{
Engine: eng,
Image: i,
})
} }
} }
} }

View file

@ -4,10 +4,6 @@ import (
//"github.com/hajimehoshi/ebiten/v2" //"github.com/hajimehoshi/ebiten/v2"
) )
type Eventer interface {
Event(e *Engine, ev any)
}
func keyDiff(s1, s2 []Key) []Key { func keyDiff(s1, s2 []Key) []Key {
combinedSlice := append(s1, s2...) combinedSlice := append(s1, s2...)
dm := make(map[Key]int) dm := make(map[Key]int)
@ -37,7 +33,6 @@ type KeyUp struct {
Key Key
} }
type MouseButtonDown struct { type MouseButtonDown struct {
MouseButton MouseButton
P Vector P Vector

View file

@ -2,7 +2,7 @@ package gg
import ( import (
"math" "math"
"fmt" //"fmt"
) )
// The type represents mathematical equation of line and line itself. // The type represents mathematical equation of line and line itself.

View file

@ -13,7 +13,7 @@ func (e *Engine) CursorPosition() Vector {
func (e *Engine) AbsCursorPosition() Vector { func (e *Engine) AbsCursorPosition() Vector {
m := &Matrix{} m := &Matrix{}
m.Concat(e.Camera().AbsMatrix(e)) m.Concat(e.Camera().AbsMatrix())
return e.CursorPosition().Apply(m) return e.CursorPosition().Apply(m)
} }

View file

@ -1,28 +1,35 @@
package gg package gg
// Implementing the interface lets the object
// to handle emited events.
type Eventer interface {
Event(*Context)
}
// Implementing the interface type // Implementing the interface type
// will call the function OnStart // will call the function OnStart
// when first appear on scene BEFORE // when first appear on scene BEFORE
// the OnUpdate. // the OnUpdate.
// The v value will be get from Add function. // The v value will be get from Add function.
type Starter interface { type Starter interface {
Start(*Engine) Start(*Context)
} }
// Implementing the interface type // Implementing the interface type
// will call the function on each // will call the function on each
// engine iteration. // engine iteration.
type Updater interface { type Updater interface {
Update(*Engine) error Update(*Context) error
} }
// Implementing the interface type // Implementing the interface type
// will call the function on deleting // will call the function on deleting
// the object. // the object.
type Deleter interface { type Deleter interface {
Delete(*Engine, ...any) Delete(*Context)
} }
// Feat to embed for turning visibility on and off.
type Visibility struct { type Visibility struct {
Visible bool Visible bool
} }
@ -30,15 +37,16 @@ func (v Visibility) IsVisible() bool {
return v.Visible return v.Visible
} }
// Feat to embed to make colorful objects.
type Colority struct { type Colority struct {
Color Color Color Color
} }
// The interface describes anything that can be // The interface describes anything that can be
// drawn. It will be drew corresponding to // drawn. It will be drew corresponding to
// the layers order. // the layers order so the layer must be returned.
type Drawer interface { type Drawer interface {
Draw(*Engine, *Image) Draw(*Context)
GetLayer() Layer GetLayer() Layer
IsVisible() bool IsVisible() bool
} }

View file

@ -38,15 +38,12 @@ func (p *Polygon) MakeTriangles() Triangles {
return ret return ret
} }
func (p *DrawablePolygon) Draw( func (p *DrawablePolygon) Draw(c *Context) {
e *Engine,
i *Image,
) {
(&DrawableTriangles{ (&DrawableTriangles{
Visibility: p.Visibility, Visibility: p.Visibility,
Colority: p.Colority, Colority: p.Colority,
ShaderOptions: p.ShaderOptions, ShaderOptions: p.ShaderOptions,
Triangles: p.MakeTriangles(), Triangles: p.MakeTriangles(),
}).Draw(e, i) }).Draw(c)
} }

11
rect.go
View file

@ -73,12 +73,9 @@ func (r *DrawableRectangle) IsVisible() bool {
return r.Visible return r.Visible
} }
func (r *DrawableRectangle) Draw( func (r *DrawableRectangle) Draw(c *Context) {
e *Engine,
i *Image,
) {
m := r.Matrix() m := r.Matrix()
rm := e.Camera().RealMatrix(e) rm := c.Camera().RealMatrix()
m.Concat(rm) m.Concat(rm)
// Draw solid color if no shader. // Draw solid color if no shader.
if r.Shader == nil { if r.Shader == nil {
@ -89,7 +86,7 @@ func (r *DrawableRectangle) Draw(
opts := &ebiten.DrawImageOptions{ opts := &ebiten.DrawImageOptions{
GeoM: m, GeoM: m,
} }
i.DrawImage(img, opts) c.DrawImage(img, opts)
return return
} }
@ -117,6 +114,6 @@ func (r *DrawableRectangle) Draw(
Images: r.Images, Images: r.Images,
Uniforms: r.Uniforms, Uniforms: r.Uniforms,
} }
i.DrawRectShader(w, h, r.Shader, opts) c.DrawRectShader(w, h, r.Shader, opts)
} }

View file

@ -10,10 +10,7 @@ type Sprite struct {
Floating, Visible bool Floating, Visible bool
} }
func (s *Sprite) Draw( func (s *Sprite) Draw(c *Context) {
e *Engine,
i *Image,
) {
// Nothing to draw. // Nothing to draw.
if s.Images[0] == nil { if s.Images[0] == nil {
return return
@ -23,16 +20,14 @@ func (s *Sprite) Draw(
m := &Matrix{} m := &Matrix{}
m.Concat(t.Matrix()) m.Concat(t.Matrix())
if !s.Floating { if !s.Floating {
m.Concat(e.Camera().RealMatrix( m.Concat(c.Camera().RealMatrix())
e,
))
} }
// Drawing without shader. // Drawing without shader.
if s.Shader == nil { if s.Shader == nil {
opts := &ebiten.DrawImageOptions{} opts := &ebiten.DrawImageOptions{}
opts.GeoM = *m opts.GeoM = *m
i.DrawImage(s.Images[0], opts) c.DrawImage(s.Images[0], opts)
return return
} }
@ -43,7 +38,7 @@ func (s *Sprite) Draw(
Uniforms: s.Uniforms, Uniforms: s.Uniforms,
GeoM: *m, GeoM: *m,
} }
i.DrawRectShader(w, h, s.Shader, opts) c.DrawRectShader(w, h, s.Shader, opts)
} }
// Check is sprite is visible. // Check is sprite is visible.

View file

@ -88,11 +88,8 @@ func (ts Triangles) ContainsPoint(p Point) bool {
return false return false
} }
func (r *DrawableTriangles) Draw( func (r *DrawableTriangles) Draw(c *Context) {
e *Engine, m := c.Camera().RealMatrix()
i *Image,
) {
m := e.Camera().RealMatrix(e)
cm := &m cm := &m
// Draw solid color if no shader. // Draw solid color if no shader.
@ -115,7 +112,7 @@ func (r *DrawableTriangles) Draw(
img := NewImage(1, 1) img := NewImage(1, 1)
img.Set(0, 0, r.Color) img.Set(0, 0, r.Color)
i.DrawTriangles(vs, is, img, &r.DrawTrianglesOptions) c.DrawTriangles(vs, is, img, &r.DrawTrianglesOptions)
return return
} }

View file

@ -14,10 +14,6 @@ type Point = Vector
type Vectors []Vector type Vectors []Vector
type Points []Point type Points []Point
type PointContainer interface {
ContainsPoint(Point) bool
}
func V(x, y Float) Vector { func V(x, y Float) Vector {
return Vector{x, y} return Vector{x, y}
} }