From 34455230043d42e4324fc27483688a856851d65d Mon Sep 17 00:00:00 2001 From: Martin Kagamino Lehoux Date: Fri, 25 Jul 2025 12:20:07 +0200 Subject: refactor: ECS bounds --- entity.go | 11 +++-------- main.go | 10 +++++----- physics/geometry.go | 7 +++++++ selection/selection.go | 12 ++++++------ 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 -- cgit v1.3