124 lines
2.6 KiB
Go
124 lines
2.6 KiB
Go
package land
|
|
|
|
import (
|
|
"github.com/veandco/go-sdl2/sdl"
|
|
"time"
|
|
)
|
|
|
|
type RootObject struct {
|
|
BaseObject
|
|
|
|
Analyzer *PerformanceAnalyzer
|
|
}
|
|
|
|
func NewRootObject() *RootObject {
|
|
in := &RootObject{
|
|
Analyzer: &PerformanceAnalyzer{},
|
|
}
|
|
|
|
go in.Analyzer.RunResetter(1 * time.Second)
|
|
|
|
return in
|
|
}
|
|
|
|
func (p *RootObject) RunEventLoop(tickDuration time.Duration) {
|
|
for {
|
|
startTime := time.Now()
|
|
|
|
p.Update()
|
|
|
|
elapsed := time.Since(startTime)
|
|
hangDuration := tickDuration - elapsed
|
|
if hangDuration > 0 {
|
|
time.Sleep(hangDuration)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (p *RootObject) ForEachChildren(cb func(child Object)) {
|
|
var caller func(current Object)
|
|
|
|
caller = func(current Object) {
|
|
cb(current)
|
|
for _, child := range current.GetChildren() {
|
|
caller(child)
|
|
}
|
|
}
|
|
|
|
caller(p)
|
|
}
|
|
|
|
func (p *RootObject) HandleUserEvent(event sdl.Event) {
|
|
switch event := event.(type) {
|
|
case *sdl.MouseButtonEvent:
|
|
x, y := float64(event.X), float64(event.Y)
|
|
vec := Vector2D{x, y}
|
|
p.ForEachChildren(func(child Object) {
|
|
if interChild, ok := child.(InteractableObject); ok {
|
|
if IsOverlapWithPoint(child.(PositionedObject), vec) {
|
|
if event.Type == sdl.MOUSEBUTTONDOWN {
|
|
interChild.OnEvent(UserEventMouseDown, vec)
|
|
} else if event.Type == sdl.MOUSEBUTTONUP {
|
|
interChild.OnEvent(UserEventMouseUp, vec)
|
|
}
|
|
}
|
|
}
|
|
})
|
|
case *sdl.MouseMotionEvent:
|
|
x, y := float64(event.X), float64(event.Y)
|
|
vec := Vector2D{x, y}
|
|
p.ForEachChildren(func(child Object) {
|
|
if interChild, ok := child.(InteractableObject); ok {
|
|
isOverlap := IsOverlapWithPoint(child.(PositionedObject), vec)
|
|
interChild.OnEvent(UserEventMouseMove, vec, isOverlap)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func (p *RootObject) Update() {
|
|
p.BaseObject.Update()
|
|
|
|
// Check collision
|
|
p.ForEachChildren(func(child Object) {
|
|
p.ForEachChildren(func(other Object) {
|
|
if child == other {
|
|
return
|
|
}
|
|
collidableChild, ok := child.(CollidableObject)
|
|
if !ok {
|
|
return
|
|
}
|
|
collidableOther, ok := other.(CollidableObject)
|
|
if !ok {
|
|
return
|
|
}
|
|
if checkCollisionBetweenObject(collidableChild, collidableOther) {
|
|
collidableChild.OnCollide(collidableOther)
|
|
collidableOther.OnCollide(collidableChild)
|
|
}
|
|
})
|
|
})
|
|
|
|
p.Analyzer.Tick()
|
|
}
|
|
|
|
func (p *RootObject) Draw(pen *sdl.Renderer) {
|
|
// Render background and clear previous state
|
|
pen.SetDrawColor(77, 77, 77, 255)
|
|
pen.Clear()
|
|
|
|
// Render each child
|
|
p.ForEachChildren(func(child Object) {
|
|
if child == p {
|
|
// Skip the current to prevent infinite drawing
|
|
return
|
|
}
|
|
if drawableChild, ok := child.(DrawableObject); ok {
|
|
drawableChild.Draw(pen)
|
|
}
|
|
})
|
|
|
|
p.Analyzer.Draw()
|
|
}
|