// Object represents an object that can be spread across one or more Cells in a Space. An Object is essentially an AABB (Axis-Aligned Bounding Box) Rectangle.
typeObjectstruct{
ShapeShape// A shape for more specific collision-checking.
Space*Space// Reference to the Space the Object exists within
X,Y,W,Hfloat64// Position and size of the Object in the Space
TouchingCells[]*Cell// An array of Cells the Object is touching
Datainterface{}// A pointer to a user-definable object
ignoreListmap[*Object]bool// Set of Objects to ignore when checking for collisions
tags[]string// A list of tags the Object has
}
// NewObject returns a new Object of the specified position and size.
// Update updates the object's association to the Cells in the Space. This should be called whenever an Object is moved.
// This is automatically called once when creating the Object, so you don't have to call it for static objects.
func(obj*Object)Update(){
ifobj.Space!=nil{
// Object.Space.Remove() sets the removed object's Space to nil, indicating it's been removed. Because we're updating
// the Object (which is essentially removing it from its previous Cells / position and re-adding it to the new Cells /
// position), we store the original Space to re-set it.
space:=obj.Space
obj.Space.Remove(obj)
obj.Space=space
cx,cy,ex,ey:=obj.BoundsToSpace(0,0)
fory:=cy;y<=ey;y++{
forx:=cx;x<=ex;x++{
c:=obj.Space.Cell(x,y)
ifc!=nil{
c.register(obj)
obj.TouchingCells=append(obj.TouchingCells,c)
}
}
}
}
ifobj.Shape!=nil{
obj.Shape.SetPosition(obj.X,obj.Y)
}
}
// AddTags adds tags to the Object.
func(obj*Object)AddTags(tags...string){
obj.tags=append(obj.tags,tags...)
}
// RemoveTags removes tags from the Object.
func(obj*Object)RemoveTags(tags...string){
for_,tag:=rangetags{
fori,t:=rangeobj.tags{
ift==tag{
obj.tags=append(obj.tags[:i],obj.tags[i+1:]...)
break
}
}
}
}
// HasTags indicates if an Object has any of the tags indicated.
func(obj*Object)HasTags(tags...string)bool{
for_,tag:=rangetags{
for_,t:=rangeobj.tags{
ift==tag{
returntrue
}
}
}
returnfalse
}
// Tags returns the tags an Object has.
func(obj*Object)Tags()[]string{
returnappend([]string{},obj.tags...)
}
// SetShape sets the Shape on the Object, in case you need to use precise per-Shape intersection detection. SetShape calls Object.Update() as well, so that it's able to
// update the Shape's position to match its Object as necessary. (If you don't use this, the Shape's position might not match the Object's, depending on if you set the Shape
// after you added the Object to a Space and if you don't call Object.Update() yourself afterwards.)
func(obj*Object)SetShape(shapeShape){
ifobj.Shape!=shape{
obj.Shape=shape
obj.Update()
}
}
// BoundsToSpace returns the Space coordinates of the shape (x, y, w, and h), given its world position and size, and a supposed movement of dx and dy.
// In my use case, order of objects within a collision instance is not needed, and this also favors both runtime performance & size reduction of `jsexport.js`.
// AddToIgnoreList adds the specified Object to the Object's internal collision ignoral list. Cells that contain the specified Object will not be counted when calling Check().
// RemoveFromIgnoreList removes the specified Object from the Object's internal collision ignoral list. Objects removed from this list will once again be counted for Check().