✨ 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 {
|
type Object interface {
|
||||||
Create()
|
Create()
|
||||||
Update()
|
Update()
|
||||||
|
AddChild(child Object)
|
||||||
|
GetChildren() []Object
|
||||||
}
|
}
|
||||||
|
|
||||||
type DrawableObject interface {
|
type DrawableObject interface {
|
||||||
@ -27,3 +29,7 @@ func (p *BaseObject) Update() {
|
|||||||
func (p *BaseObject) AddChild(child Object) {
|
func (p *BaseObject) AddChild(child Object) {
|
||||||
p.Children = append(p.Children, child)
|
p.Children = append(p.Children, child)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *BaseObject) GetChildren() []Object {
|
||||||
|
return p.Children
|
||||||
|
}
|
||||||
|
@ -1,5 +1,15 @@
|
|||||||
package land
|
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 {
|
type CollidableObject interface {
|
||||||
GetPosition() Vector2D
|
GetPosition() Vector2D
|
||||||
GetSize() 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() {
|
func (p *RootObject) Update() {
|
||||||
p.BaseObject.Update()
|
p.BaseObject.Update()
|
||||||
|
|
||||||
// Check collision
|
// Check collision
|
||||||
for _, child := range p.Children {
|
p.ForEachChildren(func(child Object) {
|
||||||
for _, other := range p.Children {
|
p.ForEachChildren(func(other Object) {
|
||||||
|
if child == other {
|
||||||
|
return
|
||||||
|
}
|
||||||
collidableChild, ok := child.(CollidableObject)
|
collidableChild, ok := child.(CollidableObject)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
collidableOther, ok := other.(CollidableObject)
|
collidableOther, ok := other.(CollidableObject)
|
||||||
if !ok {
|
if !ok {
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
if child != other && checkCollisionBetweenObject(collidableChild, collidableOther) {
|
if checkCollisionBetweenObject(collidableChild, collidableOther) {
|
||||||
collidableChild.OnCollide(collidableOther)
|
collidableChild.OnCollide(collidableOther)
|
||||||
collidableOther.OnCollide(collidableChild)
|
collidableOther.OnCollide(collidableChild)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
})
|
||||||
|
|
||||||
p.Analyzer.Tick()
|
p.Analyzer.Tick()
|
||||||
}
|
}
|
||||||
@ -65,11 +99,15 @@ func (p *RootObject) Draw(pen *sdl.Renderer) {
|
|||||||
pen.Clear()
|
pen.Clear()
|
||||||
|
|
||||||
// Render each child
|
// 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 {
|
if drawableChild, ok := child.(DrawableObject); ok {
|
||||||
drawableChild.Draw(pen)
|
drawableChild.Draw(pen)
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
|
|
||||||
p.Analyzer.Draw()
|
p.Analyzer.Draw()
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,15 @@
|
|||||||
package land
|
package land
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
type Vector2D struct {
|
type Vector2D struct {
|
||||||
X, Y float64
|
X, Y float64
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p Vector2D) String() string {
|
||||||
|
return fmt.Sprintf("(%.2f, %.2f)", p.X, p.Y)
|
||||||
|
}
|
||||||
|
|
||||||
func (p Vector2D) IsZero() bool {
|
func (p Vector2D) IsZero() bool {
|
||||||
return p.X == 0 && p.Y == 0
|
return p.X == 0 && p.Y == 0
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package tiles
|
|||||||
import (
|
import (
|
||||||
"git.solsynth.dev/highland/codingland/pkg/internal/land"
|
"git.solsynth.dev/highland/codingland/pkg/internal/land"
|
||||||
"github.com/veandco/go-sdl2/sdl"
|
"github.com/veandco/go-sdl2/sdl"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Tile struct {
|
type Tile struct {
|
||||||
@ -38,3 +39,7 @@ func (p *Tile) GetSize() land.Vector2D {
|
|||||||
|
|
||||||
func (p *Tile) OnCollide(other land.CollidableObject) {
|
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},
|
Size: land.Vector2D{X: 50, Y: 50},
|
||||||
})
|
})
|
||||||
root.AddChild(&tiles.Tile{
|
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},
|
Size: land.Vector2D{X: 50, Y: 50},
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -57,6 +57,8 @@ func main() {
|
|||||||
switch event.(type) {
|
switch event.(type) {
|
||||||
case *sdl.QuitEvent:
|
case *sdl.QuitEvent:
|
||||||
running = false
|
running = false
|
||||||
|
case *sdl.MouseButtonEvent:
|
||||||
|
root.HandleUserEvent(event)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user