aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Kagamino Lehoux <martin@lehoux.net>2025-07-25 12:20:07 +0200
committerMartin Kagamino Lehoux <martin@lehoux.net>2025-07-25 12:20:07 +0200
commit34455230043d42e4324fc27483688a856851d65d (patch)
tree967f1d30f471946ab2843e8023755becd7381075
parenta4db8814ccb2fc255bd909d8fa827ba23896322f (diff)
refactor: ECS bounds
-rw-r--r--entity.go11
-rw-r--r--main.go10
-rw-r--r--physics/geometry.go7
-rw-r--r--selection/selection.go12
4 files changed, 21 insertions, 19 deletions
diff --git a/entity.go b/entity.go
index 4657be7..35d2777 100644
--- a/entity.go
+++ b/entity.go
@@ -11,6 +11,7 @@ import (
type Entity struct {
Position ecs.Component[physics.Point]
+ RelBounds ecs.Component[physics.Rectangle]
Image ecs.Component[*ebiten.Image]
Selection ecs.Component[selection.Selection]
Move ecs.Component[physics.Move]
@@ -21,13 +22,6 @@ type Entity struct {
Spawn ecs.Component[Spawn]
}
-func (e Entity) Bounds() physics.Rectangle {
- return physics.Rectangle{
- Min: e.Position.Value,
- Max: e.Position.Value.Add(e.Image.Value.Bounds().Size()),
- }
-}
-
type EntityBuilder struct {
entity Entity
}
@@ -43,8 +37,9 @@ func (b EntityBuilder) WithPosition(position physics.Point) EntityBuilder {
return b
}
-func (b EntityBuilder) WithImage(image *ebiten.Image) EntityBuilder {
+func (b EntityBuilder) WithSolid(image *ebiten.Image) EntityBuilder {
b.entity.Image = ecs.C(image)
+ b.entity.RelBounds = ecs.C(image.Bounds())
return b
}
diff --git a/main.go b/main.go
index 86dc59b..e4c82f3 100644
--- a/main.go
+++ b/main.go
@@ -78,13 +78,13 @@ func (g *Game) updateSelecting(cursor physics.Point, moveMap physics.MoveMap) {
if g.Selection.IsActive && physics.Distance(g.Selection.Start, cursor) > 10 {
selector := selection.NewMultiple(g.Selection.Start, cursor)
for _, e := range g.Entities {
- selector.Preselect(e.Position, e.Bounds(), &e.Selection)
+ selector.Preselect(e.Position, e.RelBounds, &e.Selection)
}
selector.Select()
} else {
selector := selection.NewSingle(cursor)
for _, e := range g.Entities {
- selector.Select(e.Position, e.Bounds(), &e.Selection)
+ selector.Select(e.Position, e.RelBounds, &e.Selection)
}
}
g.Selection.IsActive = false
@@ -166,11 +166,11 @@ func main() {
s, err := text.NewGoTextFaceSource(bytes.NewReader(goregular.TTF))
kcore.Expect(err, "failed to create font source")
game.FaceSource = s
- ironMine := NewEntityBuilder().WithPosition(physics.Point{X: 1000, Y: 1000}).WithImage(NewFilledRectangleImage(physics.Point{X: 100, Y: 100}, color.RGBA{0x80, 0x80, 0x80, 0xff})).WithResourceSource(1000).WithSelection("square", selection.Building).Build()
+ ironMine := NewEntityBuilder().WithPosition(physics.Point{X: 1000, Y: 1000}).WithSolid(NewFilledRectangleImage(physics.Point{X: 100, Y: 100}, color.RGBA{0x80, 0x80, 0x80, 0xff})).WithResourceSource(1000).WithSelection("square", selection.Building).Build()
game.Entities = append(game.Entities, &ironMine)
- townCenter := NewEntityBuilder().WithPosition(physics.Point{X: 1000, Y: 2000}).WithImage(NewFilledRectangleImage(physics.Point{X: 100, Y: 100}, color.RGBA{0x0, 0x0, 0xff, 0xff})).WithResourceStorage().WithSelection("square", selection.Building).WithSpawn(NewSpawn(50, 1*time.Second)).Build()
+ townCenter := NewEntityBuilder().WithPosition(physics.Point{X: 1000, Y: 2000}).WithSolid(NewFilledRectangleImage(physics.Point{X: 100, Y: 100}, color.RGBA{0x0, 0x0, 0xff, 0xff})).WithResourceStorage().WithSelection("square", selection.Building).WithSpawn(NewSpawn(50, 1*time.Second)).Build()
game.Entities = append(game.Entities, &townCenter)
- game.UnitBuilder = NewEntityBuilder().WithImage(NewFilledCircleImage(100, color.White)).WithSelection("round", selection.Unit).WithMove().WithOrder().WithResourceGatherer(15)
+ game.UnitBuilder = NewEntityBuilder().WithSolid(NewFilledCircleImage(100, color.White)).WithSelection("round", selection.Unit).WithMove().WithOrder().WithResourceGatherer(15)
for i := 0; i < 0; i++ {
spawnPosition, _ := physics.Closest(townCenter.Position.Value, physics.AdjacentPoints(townCenter.Position.Value), game.getMoveMap())
person := game.UnitBuilder.Build()
diff --git a/physics/geometry.go b/physics/geometry.go
index 9949466..07a41e3 100644
--- a/physics/geometry.go
+++ b/physics/geometry.go
@@ -20,6 +20,13 @@ func Normalize(p Point) Point {
return p.Div(int(Length(p)))
}
+func Translate(r Rectangle, offset Point) Rectangle {
+ return Rectangle{
+ Min: r.Min.Add(offset),
+ Max: r.Max.Add(offset),
+ }
+}
+
func AdjacentPoints(from Point) []Point {
return []Point{
from.Add(Point{X: 0, Y: -100}),
diff --git a/selection/selection.go b/selection/selection.go
index d8fa6fe..eb12c91 100644
--- a/selection/selection.go
+++ b/selection/selection.go
@@ -40,12 +40,12 @@ func NewMultiple(start physics.Point, end physics.Point) Multiple {
}
}
-func (m *Multiple) Preselect(position ecs.Component[physics.Point], bounds physics.Rectangle, selection *ecs.Component[Selection]) {
- if !selection.IsEnabled {
+func (m *Multiple) Preselect(position ecs.Component[physics.Point], relBounds ecs.Component[physics.Rectangle], selection *ecs.Component[Selection]) {
+ if !selection.IsEnabled || !position.IsEnabled || !relBounds.IsEnabled {
return
}
selection.Value.IsSelected = false
- if m.Bounds.Overlaps(bounds) {
+ if m.Bounds.Overlaps(physics.Translate(relBounds.Value, position.Value)) {
m.Preselected = append(m.Preselected, selection)
}
}
@@ -79,12 +79,12 @@ func NewSingle(cursor physics.Point) Single {
}
}
-func (s *Single) Select(position ecs.Component[physics.Point], bounds physics.Rectangle, selection *ecs.Component[Selection]) {
- if !selection.IsEnabled {
+func (s *Single) Select(position ecs.Component[physics.Point], relBounds ecs.Component[physics.Rectangle], selection *ecs.Component[Selection]) {
+ if !selection.IsEnabled || !position.IsEnabled || !relBounds.IsEnabled {
return
}
selection.Value.IsSelected = false
- if s.HasSelected || !s.Cursor.In(bounds) {
+ if s.HasSelected || !s.Cursor.In(physics.Translate(relBounds.Value, position.Value)) {
return
}
selection.Value.IsSelected = true