feat: too much to describe.

This commit is contained in:
Andrey Parhomenko 2023-12-24 15:05:34 +03:00
parent 348c03cfc9
commit 067a127721
10 changed files with 179 additions and 54 deletions

View file

@ -22,12 +22,11 @@ func (e *Engine) NewCamera() *Camera {
// position, scale and rotation to apply // position, scale and rotation to apply
// it to the objects to get the real // it to the objects to get the real
// transform to display on the screen. // transform to display on the screen.
// (Should implement buffering it so we do not
// need to calculate it each time for each object. )
func (c *Camera)RealMatrix() Matrix { func (c *Camera)RealMatrix() Matrix {
/*if c.buf != nil { // Bufferization
if c.buf != nil {
return *(c.buf) return *(c.buf)
}*/ }
g := &Matrix{} g := &Matrix{}
g.Translate(-c.Position.X, -c.Position.Y) g.Translate(-c.Position.X, -c.Position.Y)
g.Rotate(c.Rotation) g.Rotate(c.Rotation)

View file

@ -15,21 +15,38 @@ type Debug struct {
func (d *Debug) Draw(c *Context) { func (d *Debug) Draw(c *Context) {
e := c.Engine e := c.Engine
keyStrs := []string{} keyStrs := []string{}
for _, k := range e.Keys() {
keyStrs = append(keyStrs, k.String())
}
if rectMove.ContainsPoint(e.AbsCursorPosition()) { keys := []string{}
for _, k := range e.Keys() {
keys = append(keys, k.String())
}
keyStrs = append(keyStrs, fmt.Sprintf(
"keys: %s", strings.Join(keys, ", "),
))
keyStrs = append(keyStrs, fmt.Sprintf(
"buttons: %v", c.MouseButtons(),
))
keyStrs = append(keyStrs, fmt.Sprintf(
"wheel: %v", c.Wheel(),
))
/*if rectMove.ContainsPoint(e.AbsCursorPosition()) {
keyStrs = append(keyStrs, "contains cursor") keyStrs = append(keyStrs, "contains cursor")
} }
if rectMove.Vertices().Contained(rect).Len() > 0 || if rectMove.Vertices().Contained(rect).Len() > 0 ||
rect.Vertices().Contained(rectMove).Len() > 0 { rect.Vertices().Contained(rectMove).Len() > 0 {
keyStrs = append(keyStrs, "rectangles intersect") keyStrs = append(keyStrs, "rectangles intersect")
} }*/
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.CursorPosition())) keyStrs = append(keyStrs, fmt.Sprintf(
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.AbsCursorPosition())) "camera position: %v %v",
c.Camera.Position.X,
c.Camera.Position.Y,
))
keyStrs = append(keyStrs, fmt.Sprintf("realCursorPos: %v", e.CursorPosition()))
keyStrs = append(keyStrs, fmt.Sprintf("absCursorPos: %v", e.AbsCursorPosition()))
keyStrs = append(keyStrs, fmt.Sprintf("absWinSize: %v", c.AbsWinSize())) keyStrs = append(keyStrs, fmt.Sprintf("absWinSize: %v", c.AbsWinSize()))
e.DebugPrint(c.Image, e.DebugPrint(c.Image,

View file

@ -82,9 +82,9 @@ func (p *Player) Update(c *Context) {
} }
case gg.KeyF: case gg.KeyF:
if c.IsPressed(gg.KeyShift) { if c.IsPressed(gg.KeyShift) {
cam.Scale = cam.Scale.Add(gg.V1(p.ScaleSpeed * dt)) cam.Scale = cam.Scale.Add(gg.V2(p.ScaleSpeed * dt))
} else { } else {
cam.Scale = cam.Scale.Add(gg.V1(-p.ScaleSpeed * dt)) cam.Scale = cam.Scale.Add(gg.V2(-p.ScaleSpeed * dt))
} }
case gg.KeyG: case gg.KeyG:
if c.IsPressed(gg.KeyShift) { if c.IsPressed(gg.KeyShift) {
@ -124,6 +124,17 @@ func (p *Player) Event(c *gg.Context) {
p.Layer = HighestL p.Layer = HighestL
} }
} }
case *gg.MouseMove :
if !c.IsButtoned(gg.MouseButtonRight) {
break
} }
pos := c.Camera.Position
c.Camera.Position = pos.Sub(ec.Abs)
case *gg.WheelChange :
c.Camera.Scale = c.Camera.Scale.Add(gg.V2(
ec.Offset.Y * c.DT() * p.ScaleSpeed,
))
}
} }

View file

@ -11,7 +11,7 @@ type Tri struct {
func NewTri() *Tri { func NewTri() *Tri {
ret := &Tri{} ret := &Tri{}
ret.DrawablePolygon = &gg.DrawablePolygon{} ret.DrawablePolygon = &gg.DrawablePolygon{}
ret.Transform.Scale = gg.V(1, 1) ret.Transform.Scale = gg.V2(1)
ret.Triangles = gg.Triangles{ ret.Triangles = gg.Triangles{
gg.Triangle{ gg.Triangle{

122
engine.go
View file

@ -6,6 +6,7 @@ import (
"github.com/di4f/gods/maps" "github.com/di4f/gods/maps"
//"fmt" //"fmt"
"time" "time"
"slices"
) )
// The type represents order of drawing. // The type represents order of drawing.
@ -53,8 +54,9 @@ type Engine struct {
// Temporary stuff // Temporary stuff
keys, prevKeys []Key keys, prevKeys []Key
cursorPos, prevCursorPos Vector buttons MouseButtonMap
mouseButtons, prevMouseButtons []MouseButton wheel Vector
cursorPos Vector
outerEvents, handleEvents EventChan outerEvents, handleEvents EventChan
} }
@ -65,6 +67,18 @@ func (e *Engine) Keys() []Key {
return e.keys return e.keys
} }
// Returns currently pressed buttons.
func (e *Engine) MouseButtons() []MouseButton {
ret := make([]MouseButton, len(e.buttons))
i := 0
for v := range e.buttons {
ret[i] = v
i++
}
slices.Sort(ret)
return ret
}
// Returns new empty Engine. // Returns new empty Engine.
func NewEngine( func NewEngine(
cfg *WindowConfig, cfg *WindowConfig,
@ -79,6 +93,7 @@ func NewEngine(
ret.outerEvents = make(EventChan) ret.outerEvents = make(EventChan)
ret.handleEvents = make(EventChan) ret.handleEvents = make(EventChan)
ret.Objects = maps.NewOrdered[Object, struct{}]() ret.Objects = maps.NewOrdered[Object, struct{}]()
ret.buttons = MouseButtonMap{}
return ret return ret
} }
@ -141,18 +156,94 @@ func (e *Engine) Del(b any) error {
return nil return nil
} }
var (
allButtons = []MouseButton{
MouseButton0,
MouseButton1,
MouseButton2,
MouseButton3,
MouseButton4,
}
)
func (e *Engine) IsPressed(k Key) bool {
keys := e.Keys()
for _, v := range keys {
if v == k {
return true
}
}
return false
}
func (e *Engine) IsButtoned(b MouseButton) bool {
_, ok := e.buttons[b]
return ok
}
func (e *Engine) Wheel() Vector {
return e.wheel
}
func (e *Engine) cursorPosition() Vector {
x, y := ebiten.CursorPosition()
return V(Float(x), Float(y))
}
func (e *Engine) CursorPosition() Vector {
return e.cursorPos
}
func (e *Engine) AbsCursorPosition() Vector {
m := &Matrix{}
m.Concat(e.Camera.AbsMatrix())
return e.CursorPosition().Apply(m)
}
func (e *engine) Update() error { func (e *engine) Update() error {
eng := (*Engine)(e) eng := (*Engine)(e)
e.dt = time.Since(e.lastTime).Seconds()
for object := range e.Objects.KeyChan() {
updater, ok := object.(Updater)
if !ok {
continue
}
updater.Update(&Context{
Engine: eng,
})
}
e.prevKeys = e.keys e.prevKeys = e.keys
e.keys = inpututil. e.keys = inpututil.
AppendPressedKeys(e.keys[:0]) AppendPressedKeys(e.keys[:0])
events := []any{} events := []any{}
btns := e.buttons
for _, btn := range allButtons {
if inpututil.IsMouseButtonJustPressed(btn) {
btns[btn] = struct{}{}
events = append(events, &MouseButtonDown{
MouseButton: btn,
})
} else if inpututil.IsMouseButtonJustReleased(btn) {
delete(btns, btn)
events = append(events, &MouseButtonUp{
MouseButton: btn,
})
}
}
diff := keyDiff(e.prevKeys, e.keys) x, y := ebiten.Wheel()
for _, key := range diff { eng.wheel = V(x, y)
if !(eng.wheel.Eq(ZV)) {
events = append(events, &WheelChange{
Offset: eng.wheel,
})
}
keyDiff := diffEm(e.prevKeys, e.keys)
for _, key := range keyDiff {
var event any var event any
if eng.IsPressed(key) { if eng.IsPressed(key) {
event = &KeyDown{ event = &KeyDown{
@ -166,7 +257,19 @@ func (e *engine) Update() error {
events = append(events, event) events = append(events, event)
} }
e.dt = time.Since(e.lastTime).Seconds() realPos := eng.cursorPosition()
if !realPos.Eq(eng.cursorPos) {
absM := eng.Camera.AbsMatrix()
absPrevPos :=eng.cursorPos.Apply(&absM)
absPos := realPos.Apply(&absM)
events = append(events, &MouseMove{
Real: realPos.Sub(eng.cursorPos),
Abs: absPos.Sub(absPrevPos),
})
eng.cursorPos = realPos
}
for object := range e.Objects.KeyChan() { for object := range e.Objects.KeyChan() {
eventer, ok := object.(Eventer) eventer, ok := object.(Eventer)
if ok { if ok {
@ -177,16 +280,9 @@ func (e *engine) Update() error {
}) })
} }
} }
updater, ok := object.(Updater)
if !ok {
continue
} }
updater.Update(&Context{
Engine: eng,
})
}
e.lastTime = time.Now()
e.lastTime = time.Now()
return nil return nil
} }

View file

@ -4,9 +4,9 @@ import (
//"github.com/hajimehoshi/ebiten/v2" //"github.com/hajimehoshi/ebiten/v2"
) )
func keyDiff(s1, s2 []Key) []Key { func diffEm[V comparable](s1, s2 []V) []V {
combinedSlice := append(s1, s2...) combinedSlice := append(s1, s2...)
dm := make(map[Key]int) dm := make(map[V]int)
for _, v := range combinedSlice { for _, v := range combinedSlice {
if _, ok := dm[v]; ok { if _, ok := dm[v]; ok {
// remove element later as it exist in both slice. // remove element later as it exist in both slice.
@ -16,7 +16,7 @@ func keyDiff(s1, s2 []Key) []Key {
// new entry, add in map! // new entry, add in map!
dm[v] = 1 dm[v] = 1
} }
var retSlice []Key var retSlice []V
for k, v := range dm { for k, v := range dm {
if v == 1 { if v == 1 {
retSlice = append(retSlice, k) retSlice = append(retSlice, k)
@ -44,7 +44,12 @@ type MouseButtonUp struct {
} }
type MouseMove struct { type MouseMove struct {
Delta Vector // Real and absolute deltas.
Real, Abs Vector
}
type WheelChange struct {
Offset Vector
} }
type EventChan chan any type EventChan chan any

10
keys.go
View file

@ -156,13 +156,3 @@ const (
KeyRightBracket Key = Key(ebiten.KeyBracketRight) KeyRightBracket Key = Key(ebiten.KeyBracketRight)
KeyArrowUp Key = Key(ebiten.KeyArrowUp) KeyArrowUp Key = Key(ebiten.KeyArrowUp)
) )
func (e *Engine) IsPressed(k Key) bool {
keys := e.Keys()
for _, v := range keys {
if v == k {
return true
}
}
return false
}

View file

@ -4,16 +4,18 @@ import (
"github.com/hajimehoshi/ebiten/v2" "github.com/hajimehoshi/ebiten/v2"
) )
type MouseButtonMap map[MouseButton] struct{}
type MouseButton = ebiten.MouseButton type MouseButton = ebiten.MouseButton
const (
MouseButtonLeft MouseButton = ebiten.MouseButton0
MouseButtonMiddle MouseButton = ebiten.MouseButton1
MouseButtonRight MouseButton = ebiten.MouseButton2
func (e *Engine) CursorPosition() Vector { MouseButton0 MouseButton = ebiten.MouseButton0
x, y := ebiten.CursorPosition() MouseButton1 MouseButton = ebiten.MouseButton1
return V(Float(x), Float(y)) MouseButton2 MouseButton = ebiten.MouseButton2
} MouseButton3 MouseButton = ebiten.MouseButton3
MouseButton4 MouseButton = ebiten.MouseButton4
func (e *Engine) AbsCursorPosition() Vector { MouseButtonMax MouseButton = ebiten.MouseButton4
m := &Matrix{} )
m.Concat(e.Camera.AbsMatrix())
return e.CursorPosition().Apply(m)
}

View file

@ -22,11 +22,12 @@ type Transform struct {
Parent *Transform Parent *Transform
} }
// Returns empty Transform // Returns the default Transform structure.
// with standard scaling. (1/1)
func T() Transform { func T() Transform {
ret := Transform{ ret := Transform{
// Rotate around
Scale: Vector{1, 1}, Scale: Vector{1, 1},
// Rotate around the center.
Around: V(.5, .5), Around: V(.5, .5),
} }
return ret return ret

View file

@ -5,6 +5,10 @@ import (
"math" "math"
) )
var (
ZV = V2(0)
)
type Vector struct { type Vector struct {
X, Y Float X, Y Float
} }
@ -18,7 +22,7 @@ func V(x, y Float) Vector {
return Vector{x, y} return Vector{x, y}
} }
func V1(v Float) Vector { func V2(v Float) Vector {
return V(v, v) return V(v, v)
} }