feat: too much to describe.
This commit is contained in:
parent
348c03cfc9
commit
067a127721
10 changed files with 179 additions and 54 deletions
|
@ -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)
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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,
|
||||||
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
122
engine.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
13
event.go
13
event.go
|
@ -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
10
keys.go
|
@ -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
|
|
||||||
}
|
|
||||||
|
|
22
mouse.go
22
mouse.go
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue