1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21: 22: 23: 24: 25: 26: 27: 28: 29: 30: 31: 32: 33: 34: 35: 36: 37: 38: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108:
| function RectRectIntersect(A, B: TRect; var C: TRect): boolean; begin result := (A.Left <= B.Right) AND (A.Right >= B.Left) AND (A.Top <= B.Bottom) AND (A.Bottom >= B.Top);
if result then with C do begin Left := max(min(A.Right, B.Left), min(A.Left, B.Right)); Right := min(max(A.Right, B.Left), max(A.Left, B.Right)); Top := max(min(A.Bottom, B.Top), min(A.Top, B.Bottom)); Bottom := min(max(A.Bottom, B.Top), max(A.Top, B.Bottom)); end; end;
function ResolveCollision(A, B: TRect; var mtd: integer): TCollisionType; var C: TRect; w, h: integer; function Stuck: TCollisionType; var Aw, Ah, Bw, Bh, Ax, Ay, Bx, By, Cx, Cy: integer; begin Aw := (A.Right - A.Left); Ah := (A.Bottom - A.Top); Ax := A.Left + Aw; Ay := A.Top + Ah; Bw := (B.Right - B.Left); Bh := (B.Bottom - B.Top); Bx := B.Left + Bw; By := B.Top + Bh; Cx := Ax - Bx; Cy := Ay - By; if abs(Cx) <= abs(Cy) then begin mtd := Aw div 2 + Bw div 2; if Cx > 0 then result := ctRight; if Cx < 0 then result := ctLeft; end else begin mtd := Ah div 2 + Bh div 2; if Cy > 0 then result := ctBottom; if Cy < 0 then result := ctTop; end; end; function Vertical: TCollisionType; forward; function Horizontal: TCollisionType; begin mtd := w; if (A.right >= B.left) and (A.Left <= B.Left) then begin result := ctLeft; exit; end; if (A.Left <= B.Right) and (A.Right >= B.Right) then begin result := ctRight; exit; end; if (A.left >= B.Left) and (A.Right <= B.Right) then if (A.Top >= B.Top) and (A.Bottom <= B.Bottom) then result := Stuck else result := Vertical; end; function Vertical: TCollisionType; begin mtd := h; if (A.Bottom >= B.Top) and (A.Top <= B.Top) then begin result := ctTop; exit; end; if (A.Top <= B.Bottom) and (A.Bottom >= B.Bottom) then begin result := ctRight; exit; end; if (A.Top >= B.Top) and (A.Bottom <= B.Bottom) then if (A.left >= B.Left) and (A.Right <= B.Right) then result := Stuck else result := Horizontal; end; begin result := ctNone; if RectRectIntersect(A, B, C) then begin w := C.right - C.Left; h := C.bottom - C.Top; if (w <= h) then result := Horizontal else result := Vertical; end; end; |