Skip to content

Instantly share code, notes, and snippets.

@joetifa2003
Created December 6, 2023 09:31
Show Gist options
  • Save joetifa2003/867bbf4aa2ec05027e12f5e388172626 to your computer and use it in GitHub Desktop.
Save joetifa2003/867bbf4aa2ec05027e12f5e388172626 to your computer and use it in GitHub Desktop.
Resolving player stucj problem
package collision
import (
rl "github.com/gen2brain/raylib-go/raylib"
)
type Line struct {
Start rl.Vector2
End rl.Vector2
}
func rectToLines(rect rl.Rectangle) [4]Line {
return [4]Line{
{Start: rl.Vector2{X: rect.X, Y: rect.Y + rect.Height}, End: rl.Vector2{X: rect.X, Y: rect.Y}}, // left
{Start: rl.Vector2{X: rect.X + rect.Width, Y: rect.Y}, End: rl.Vector2{X: rect.X + rect.Width, Y: rect.Y + rect.Height}}, // right
{Start: rl.Vector2{X: rect.X, Y: rect.Y}, End: rl.Vector2{X: rect.X + rect.Width, Y: rect.Y}}, // top
{Start: rl.Vector2{X: rect.X + rect.Width, Y: rect.Y + rect.Height}, End: rl.Vector2{X: rect.X, Y: rect.Y + rect.Height}}, // bottom
}
}
func MoveCollide(rect rl.Rectangle, newPos rl.Vector2, otherRect rl.Rectangle) rl.Rectangle {
if rect.X == newPos.X && rect.Y == newPos.Y {
return rect
}
otherRect.Width += rect.Width
otherRect.Height += rect.Height
otherRect.X -= rect.Width
otherRect.Y -= rect.Height
rectPos := rl.Vector2{rect.X, rect.Y}
movLine := Line{Start: rectPos, End: newPos}
resolvedPos := newPos
minIntersectionPoint := rl.Vector2{}
collidedFace := -1
collided := false
for i, line := range rectToLines(otherRect) {
intersection, intersects := lineIntersect(line, movLine)
if intersects {
if collided {
if rl.Vector2DistanceSqr(intersection, rectPos) < rl.Vector2DistanceSqr(minIntersectionPoint, rectPos) {
minIntersectionPoint = intersection
collidedFace = i
}
} else {
minIntersectionPoint = intersection
collidedFace = i
collided = true
}
}
}
if !collided {
rect.X = newPos.X
rect.Y = newPos.Y
return rect
}
switch collidedFace {
case 0: // left
if newPos.X >= minIntersectionPoint.X {
resolvedPos.X = minIntersectionPoint.X
}
case 1: // right
if newPos.X <= minIntersectionPoint.X {
resolvedPos.X = minIntersectionPoint.X
}
case 2: // top
if newPos.Y >= minIntersectionPoint.Y {
resolvedPos.Y = minIntersectionPoint.Y
}
case 3: // bottom
if newPos.Y <= minIntersectionPoint.Y {
resolvedPos.Y = minIntersectionPoint.Y
}
}
rect.X = resolvedPos.X
rect.Y = resolvedPos.Y
return rect
}
func lineIntersect(l1, l2 Line) (rl.Vector2, bool) {
det := (l1.End.X-l1.Start.X)*(l2.End.Y-l2.Start.Y) - (l1.End.Y-l1.Start.Y)*(l2.End.X-l2.Start.X)
if det == 0 {
return rl.Vector2{}, false
}
t := ((l2.Start.X-l1.Start.X)*(l2.End.Y-l2.Start.Y) - (l2.Start.Y-l1.Start.Y)*(l2.End.X-l2.Start.X)) / det
u := -((l1.Start.X-l1.End.X)*(l1.Start.Y-l2.Start.Y) - (l1.Start.Y-l1.End.Y)*(l1.Start.X-l2.Start.X)) / det
if t >= 0 && t <= 1 && u >= 0 && u <= 1 {
// Intersection point
intersectionX := l1.Start.X + t*(l1.End.X-l1.Start.X)
intersectionY := l1.Start.Y + t*(l1.End.Y-l1.Start.Y)
return rl.Vector2{intersectionX, intersectionY}, true
}
// Lines do not intersect within the given segments
return rl.Vector2{}, false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment