Collision detection system
This commit is contained in:
87
collision/types.go
Normal file
87
collision/types.go
Normal file
@@ -0,0 +1,87 @@
|
||||
package collision
|
||||
|
||||
type Point struct {
|
||||
X float64
|
||||
Y float64
|
||||
}
|
||||
|
||||
type Polygon struct {
|
||||
Points []Point
|
||||
}
|
||||
|
||||
type ObjectType int
|
||||
|
||||
const (
|
||||
Hero ObjectType = 1 << iota
|
||||
Zombie
|
||||
)
|
||||
|
||||
type Collidable interface {
|
||||
CollisionShape() Polygon
|
||||
HandleCollisionEvent(other Collidable)
|
||||
CollisionObjectType() ObjectType
|
||||
}
|
||||
|
||||
// Helper function to calculate the dot product of two points
|
||||
func dot(p1, p2 Point) float64 {
|
||||
return p1.X*p2.X + p1.Y*p2.Y
|
||||
}
|
||||
|
||||
// Helper function to get the normal of the edge between two points
|
||||
func edgeNormal(p1, p2 Point) Point {
|
||||
return Point{X: p2.Y - p1.Y, Y: p1.X - p2.X}
|
||||
}
|
||||
|
||||
// Project a polygon onto an axis and return the min and max projections
|
||||
func projectPolygon(axis Point, polygon Polygon) (float64, float64) {
|
||||
min := dot(axis, polygon.Points[0])
|
||||
max := min
|
||||
for _, p := range polygon.Points[1:] {
|
||||
projection := dot(axis, p)
|
||||
if projection < min {
|
||||
min = projection
|
||||
}
|
||||
if projection > max {
|
||||
max = projection
|
||||
}
|
||||
}
|
||||
return min, max
|
||||
}
|
||||
|
||||
// Check if two projections on an axis overlap
|
||||
func overlap(minA, maxA, minB, maxB float64) bool {
|
||||
if minA > maxB || minB > maxA {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// Overlaps checks if two polygons overlap using the Separating Axis Theorem
|
||||
func (p Polygon) Overlaps(p2 Polygon) bool {
|
||||
if len(p.Points) == 0 || len(p2.Points) == 0 {
|
||||
return false
|
||||
}
|
||||
for i := 0; i < len(p.Points); i++ {
|
||||
next := (i + 1) % len(p.Points)
|
||||
axis := edgeNormal(p.Points[i], p.Points[next])
|
||||
minA, maxA := projectPolygon(axis, p)
|
||||
minB, maxB := projectPolygon(axis, p2)
|
||||
|
||||
if !overlap(minA, maxA, minB, maxB) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
for i := 0; i < len(p2.Points); i++ {
|
||||
next := (i + 1) % len(p2.Points)
|
||||
axis := edgeNormal(p2.Points[i], p2.Points[next])
|
||||
minA, maxA := projectPolygon(axis, p)
|
||||
minB, maxB := projectPolygon(axis, p2)
|
||||
|
||||
if !overlap(minA, maxA, minB, maxB) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
Reference in New Issue
Block a user