Skip to content

Instantly share code, notes, and snippets.

@Falconerd
Created March 16, 2026 05:50
Show Gist options
  • Select an option

  • Save Falconerd/60d1acfc96ac79f1281bb78b0b23f951 to your computer and use it in GitHub Desktop.

Select an option

Save Falconerd/60d1acfc96ac79f1281bb78b0b23f951 to your computer and use it in GitHub Desktop.
package main
import rl "vendor:raylib"
Vec2 :: rl.Vector2
Rect :: rl.Rectangle
Color :: rl.Color
BG :: Color{0, 0, 0x1C, 0xFF}
FG :: Color{0, 0xDF, 0, 0xFF}
FADED :: Color{0, 0xDF, 0, 0x44}
WINDOW_WIDTH :: 1920
WINDOW_HEIGHT :: 1080
MOVING_RECT_SIZE :: Vec2{90, 140}
SCREEN_CENTER :: Vec2{WINDOW_WIDTH / 2, WINDOW_HEIGHT / 2}
ITERATIONS :: 32
main :: proc() {
rl.InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "AABB Discrete")
static_rects: [dynamic]Rect
append(&static_rects, Rect{200, 200, 200, 300})
append(&static_rects, Rect{400, 200, 200, 300})
append(&static_rects, Rect{200, 500, 200, 300})
append(&static_rects, Rect{800, 500, 40, 300})
old_position: Vec2
for !rl.WindowShouldClose() {
rl.BeginDrawing()
rl.ClearBackground(BG)
mouse_position := rl.GetMousePosition()
if rl.IsMouseButtonPressed(.LEFT) {
old_position = mouse_position
}
old_rect := rect_from_pos_size(old_position - MOVING_RECT_SIZE / 2, MOVING_RECT_SIZE)
moving_rect := rect_from_pos_size(mouse_position - MOVING_RECT_SIZE / 2, MOVING_RECT_SIZE)
rl.DrawRectangleLinesEx(old_rect, 4, rl.GRAY)
rl.DrawRectangleLinesEx(moving_rect, 4, rl.WHITE)
rl.DrawLineEx(rect_center(moving_rect), rect_center(old_rect), 4, FADED)
for static_rect in static_rects {
rl.DrawRectangleLinesEx(static_rect, 4, rl.WHITE)
}
velocity := rect_center(moving_rect) - rect_center(old_rect)
next_position := compute_next_position(old_rect, static_rects[:], velocity)
rl.DrawRectangleV(next_position, MOVING_RECT_SIZE, rl.RED)
rl.EndDrawing()
}
}
compute_next_position :: proc(moving: Rect, statics: []Rect, v: Vec2) -> Vec2 {
next_rect := moving
// step := v / f32(ITERATIONS)
iterations := rl.Vector2Length(v)
step := v / iterations
for _ in 0 ..< i32(iterations) {
next_rect.x += step.x
next_rect.y += step.y
rl.DrawRectangleRec(next_rect, FADED)
for static_rect in statics {
if aabb_intersects_aabb(next_rect, static_rect) {
rl.DrawRectangleLinesEx(static_rect, 4, FG)
overlap := get_overlap(next_rect, static_rect)
if overlap.width < overlap.height {
// x axis
if next_rect.x < static_rect.x {
next_rect.x -= overlap.width
} else {
next_rect.x += overlap.width
}
step.x = 0
} else {
// y axis
if next_rect.y < static_rect.y {
next_rect.y -= overlap.height
} else {
next_rect.y += overlap.height
}
step.y = 0
}
}
}
}
return {next_rect.x, next_rect.y}
}
get_overlap :: proc(a, b: Rect) -> Rect {
x := max(a.x, b.x)
y := max(a.y, b.y)
z := min(a.x + a.width, b.x + b.width)
w := min(a.y + a.height, b.y + b.height)
return Rect{x, y, z - x, w - y}
}
aabb_intersects_aabb :: proc(a, b: Rect) -> bool {
if a.x >= b.x + b.width do return false // too far right
if a.y >= b.y + b.height do return false // too far down
if a.x + a.width <= b.x do return false // too far left
if a.y + a.height <= b.y do return false // too far up
return true
}
rect_from_pos_size :: proc(pos, size: Vec2) -> Rect {
return Rect{pos.x, pos.y, size.x, size.y}
}
rect_center :: proc(rect: Rect) -> Vec2 {
return {rect.x + rect.width / 2, rect.y + rect.height / 2}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment