overlap detection

master
Jordan Orelli 4 years ago
parent bfb399d89d
commit 87fa287fa3

@ -0,0 +1,43 @@
package sim
import (
"time"
"github.com/jordanorelli/blammo"
)
type door struct {
*blammo.Log
}
func (d *door) update(time.Duration) {}
func (d *door) onStartOverlap(e *entity) {
d.Info("start overlap: %v", e)
}
func (d *door) onOverlap(e *entity) {
d.Info("overlap: %v", e)
}
func (d *door) onStopOverlap(e *entity) {
d.Info("stop overlap: %v", e)
}
/*
··········
··········
··········
··········
··········
·····d····
··········
··········
··········
··········
*/

@ -7,13 +7,73 @@ import (
)
type entity struct {
ID int `json:"id"`
Position math.Vec `json:"pos"`
Glyph rune `json:"glyph"`
solid bool `json:"-"`
ID int `json:"id"`
Position math.Vec `json:"pos"`
Glyph rune `json:"glyph"`
solid bool `json:"-"`
overlapped map[int]*entity
behavior
}
func (e *entity) overlapping(others ...*entity) {
idx := make(map[int]*entity, len(others))
for i, _ := range others {
e2 := others[i]
if e2 == e {
continue
}
idx[e2.ID] = e2
}
for _, e2 := range e.overlapped {
if idx[e2.ID] == nil {
e.stopOverlap(e2)
}
}
for _, e2 := range idx {
e.overlap(e2)
}
e.overlapped = idx
}
func (e *entity) overlap(e2 *entity) {
if e.overlapped == nil {
e.overlapped = make(map[int]*entity, 4)
}
type overlapStarter interface {
onStartOverlap(*entity)
}
if e.behavior != nil && e.overlapped[e2.ID] == nil {
if b, ok := e.behavior.(overlapStarter); ok {
b.onStartOverlap(e2)
}
}
type overlapper interface {
onOverlap(*entity)
}
if e.behavior != nil {
if b, ok := e.behavior.(overlapper); ok {
b.onOverlap(e2)
}
}
}
func (e *entity) stopOverlap(e2 *entity) {
type overlapStopper interface {
onStopOverlap(*entity)
}
if e.behavior != nil {
if b, ok := e.behavior.(overlapStopper); ok {
b.onStopOverlap(e2)
}
}
}
type behavior interface {
// update is the standard tick function
update(time.Duration)

@ -1,5 +1,9 @@
package sim
import (
"time"
)
type tile struct {
floor floor
here []*entity
@ -26,3 +30,24 @@ func (t *tile) removeEntity(id int) {
}
t.here = here
}
func (t *tile) update(d time.Duration) {
for _, e := range t.here {
e.update(d)
}
}
func (t *tile) overlaps() {
switch len(t.here) {
case 0:
return
case 1:
t.here[0].overlapping()
return
default:
}
for _, e := range t.here {
e.overlapping(t.here...)
}
}

@ -61,6 +61,15 @@ func newWorld(log *blammo.Log) *world {
behavior: doNothing{},
})
foyer.addEntity(&entity{
ID: -4,
Position: math.Vec{9, 5},
Glyph: '◇',
behavior: &door{
Log: log.Child("door"),
},
})
hall := room{
Log: log.Child("hall"),
name: "hall",
@ -201,14 +210,22 @@ func (w *world) tick(d time.Duration) {
}
}
// run all object effects
// run all object updates
for _, r := range w.rooms {
for _, t := range r.tiles {
for _, e := range t.here {
e.update(d)
}
t.update(d)
}
}
// check all overlapping entities
for _, r := range w.rooms {
for _, t := range r.tiles {
t.overlaps()
}
}
// send frame data to all players
for _, r := range w.rooms {
frame := wire.Frame{
Entities: r.allEntities(),
Players: r.playerAvatars(),

Loading…
Cancel
Save