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
// it to the objects to get the real
// 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 {
/*if c.buf != nil {
// Bufferization
if c.buf != nil {
return *(c.buf)
}*/
}
g := &Matrix{}
g.Translate(-c.Position.X, -c.Position.Y)
g.Rotate(c.Rotation)

View file

@ -15,21 +15,38 @@ type Debug struct {
func (d *Debug) Draw(c *Context) {
e := c.Engine
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")
}
if rectMove.Vertices().Contained(rect).Len() > 0 ||
rect.Vertices().Contained(rectMove).Len() > 0 {
keyStrs = append(keyStrs, "rectangles intersect")
}
}*/
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.CursorPosition()))
keyStrs = append(keyStrs, fmt.Sprintf("%v", e.AbsCursorPosition()))
keyStrs = append(keyStrs, fmt.Sprintf(
"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()))
e.DebugPrint(c.Image,

View file

@ -82,9 +82,9 @@ func (p *Player) Update(c *Context) {
}
case gg.KeyF:
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 {
cam.Scale = cam.Scale.Add(gg.V1(-p.ScaleSpeed * dt))
cam.Scale = cam.Scale.Add(gg.V2(-p.ScaleSpeed * dt))
}
case gg.KeyG:
if c.IsPressed(gg.KeyShift) {
@ -124,6 +124,17 @@ func (p *Player) Event(c *gg.Context) {
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 {
ret := &Tri{}
ret.DrawablePolygon = &gg.DrawablePolygon{}
ret.Transform.Scale = gg.V(1, 1)
ret.Transform.Scale = gg.V2(1)
ret.Triangles = gg.Triangles{
gg.Triangle{

122
engine.go
View file

@ -6,6 +6,7 @@ import (
"github.com/di4f/gods/maps"
//"fmt"
"time"
"slices"
)
// The type represents order of drawing.
@ -53,8 +54,9 @@ type Engine struct {
// Temporary stuff
keys, prevKeys []Key
cursorPos, prevCursorPos Vector
mouseButtons, prevMouseButtons []MouseButton
buttons MouseButtonMap
wheel Vector
cursorPos Vector
outerEvents, handleEvents EventChan
}
@ -65,6 +67,18 @@ func (e *Engine) Keys() []Key {
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.
func NewEngine(
cfg *WindowConfig,
@ -79,6 +93,7 @@ func NewEngine(
ret.outerEvents = make(EventChan)
ret.handleEvents = make(EventChan)
ret.Objects = maps.NewOrdered[Object, struct{}]()
ret.buttons = MouseButtonMap{}
return ret
}
@ -141,18 +156,94 @@ func (e *Engine) Del(b any) error {
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 {
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.keys = inpututil.
AppendPressedKeys(e.keys[:0])
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)
for _, key := range diff {
x, y := ebiten.Wheel()
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
if eng.IsPressed(key) {
event = &KeyDown{
@ -166,7 +257,19 @@ func (e *engine) Update() error {
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() {
eventer, ok := object.(Eventer)
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
}

View file

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

10
keys.go
View file

@ -156,13 +156,3 @@ const (
KeyRightBracket Key = Key(ebiten.KeyBracketRight)
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"
)
type MouseButtonMap map[MouseButton] struct{}
type MouseButton = ebiten.MouseButton
const (
MouseButtonLeft MouseButton = ebiten.MouseButton0
MouseButtonMiddle MouseButton = ebiten.MouseButton1
MouseButtonRight MouseButton = ebiten.MouseButton2
func (e *Engine) CursorPosition() Vector {
x, y := ebiten.CursorPosition()
return V(Float(x), Float(y))
}
func (e *Engine) AbsCursorPosition() Vector {
m := &Matrix{}
m.Concat(e.Camera.AbsMatrix())
return e.CursorPosition().Apply(m)
}
MouseButton0 MouseButton = ebiten.MouseButton0
MouseButton1 MouseButton = ebiten.MouseButton1
MouseButton2 MouseButton = ebiten.MouseButton2
MouseButton3 MouseButton = ebiten.MouseButton3
MouseButton4 MouseButton = ebiten.MouseButton4
MouseButtonMax MouseButton = ebiten.MouseButton4
)

View file

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

View file

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