✨ Interactable object!
This commit is contained in:
parent
9025859fac
commit
5414fbfac8
@ -5,6 +5,8 @@ import "github.com/veandco/go-sdl2/sdl"
|
||||
type Object interface {
|
||||
Create()
|
||||
Update()
|
||||
AddChild(child Object)
|
||||
GetChildren() []Object
|
||||
}
|
||||
|
||||
type DrawableObject interface {
|
||||
@ -27,3 +29,7 @@ func (p *BaseObject) Update() {
|
||||
func (p *BaseObject) AddChild(child Object) {
|
||||
p.Children = append(p.Children, child)
|
||||
}
|
||||
|
||||
func (p *BaseObject) GetChildren() []Object {
|
||||
return p.Children
|
||||
}
|
||||
|
@ -1,5 +1,15 @@
|
||||
package land
|
||||
|
||||
type PositionedObject interface {
|
||||
GetPosition() Vector2D
|
||||
GetSize() Vector2D
|
||||
}
|
||||
|
||||
func IsOverlapWithPoint(obj PositionedObject, point Vector2D) bool {
|
||||
return point.X >= obj.GetPosition().X && point.X <= obj.GetPosition().X+obj.GetSize().X &&
|
||||
point.Y >= obj.GetPosition().Y && point.Y <= obj.GetPosition().Y+obj.GetSize().Y
|
||||
}
|
||||
|
||||
type CollidableObject interface {
|
||||
GetPosition() Vector2D
|
||||
GetSize() Vector2D
|
||||
|
7
pkg/internal/land/object_interactable.go
Normal file
7
pkg/internal/land/object_interactable.go
Normal file
@ -0,0 +1,7 @@
|
||||
package land
|
||||
|
||||
type InteractableObject interface {
|
||||
GetPosition() Vector2D
|
||||
GetSize() Vector2D
|
||||
OnClick(mousePos Vector2D)
|
||||
}
|
@ -35,26 +35,60 @@ func (p *RootObject) RunEventLoop(tickDuration time.Duration) {
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
if event.Type == sdl.MOUSEBUTTONDOWN {
|
||||
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)
|
||||
if isOverlap {
|
||||
interChild.OnClick(vec)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (p *RootObject) Update() {
|
||||
p.BaseObject.Update()
|
||||
|
||||
// Check collision
|
||||
for _, child := range p.Children {
|
||||
for _, other := range p.Children {
|
||||
p.ForEachChildren(func(child Object) {
|
||||
p.ForEachChildren(func(other Object) {
|
||||
if child == other {
|
||||
return
|
||||
}
|
||||
collidableChild, ok := child.(CollidableObject)
|
||||
if !ok {
|
||||
continue
|
||||
return
|
||||
}
|
||||
collidableOther, ok := other.(CollidableObject)
|
||||
if !ok {
|
||||
continue
|
||||
return
|
||||
}
|
||||
if child != other && checkCollisionBetweenObject(collidableChild, collidableOther) {
|
||||
if checkCollisionBetweenObject(collidableChild, collidableOther) {
|
||||
collidableChild.OnCollide(collidableOther)
|
||||
collidableOther.OnCollide(collidableChild)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
p.Analyzer.Tick()
|
||||
}
|
||||
@ -65,11 +99,15 @@ func (p *RootObject) Draw(pen *sdl.Renderer) {
|
||||
pen.Clear()
|
||||
|
||||
// Render each child
|
||||
for _, child := range p.Children {
|
||||
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()
|
||||
}
|
||||
|
@ -1,9 +1,15 @@
|
||||
package land
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Vector2D struct {
|
||||
X, Y float64
|
||||
}
|
||||
|
||||
func (p Vector2D) String() string {
|
||||
return fmt.Sprintf("(%.2f, %.2f)", p.X, p.Y)
|
||||
}
|
||||
|
||||
func (p Vector2D) IsZero() bool {
|
||||
return p.X == 0 && p.Y == 0
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package tiles
|
||||
import (
|
||||
"git.solsynth.dev/highland/codingland/pkg/internal/land"
|
||||
"github.com/veandco/go-sdl2/sdl"
|
||||
"log"
|
||||
)
|
||||
|
||||
type Tile struct {
|
||||
@ -38,3 +39,7 @@ func (p *Tile) GetSize() land.Vector2D {
|
||||
|
||||
func (p *Tile) OnCollide(other land.CollidableObject) {
|
||||
}
|
||||
|
||||
func (p *Tile) OnClick(mousePos land.Vector2D) {
|
||||
log.Printf("user clicked tile: %s", mousePos.String())
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ func main() {
|
||||
Size: land.Vector2D{X: 50, Y: 50},
|
||||
})
|
||||
root.AddChild(&tiles.Tile{
|
||||
Position: land.Vector2D{X: 25, Y: 25},
|
||||
Position: land.Vector2D{X: 50, Y: 50},
|
||||
Size: land.Vector2D{X: 50, Y: 50},
|
||||
})
|
||||
|
||||
@ -57,6 +57,8 @@ func main() {
|
||||
switch event.(type) {
|
||||
case *sdl.QuitEvent:
|
||||
running = false
|
||||
case *sdl.MouseButtonEvent:
|
||||
root.HandleUserEvent(event)
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user