box 重载 collidesWith
This commit is contained in:
@@ -7,6 +7,13 @@ class Rectangle {
|
||||
private _tempMat: Matrix2D;
|
||||
private _transformMat: Matrix2D;
|
||||
|
||||
/**
|
||||
* 获取矩形的最大点,即右下角
|
||||
*/
|
||||
public get max(){
|
||||
return new Vector2(this.right, this.bottom);
|
||||
}
|
||||
|
||||
public get left() {
|
||||
return this.x;
|
||||
}
|
||||
@@ -124,6 +131,32 @@ class Rectangle {
|
||||
return { res: res, edgeNormal: edgeNormal };
|
||||
}
|
||||
|
||||
public getClosestPointOnBoundsToOrigin(){
|
||||
let max = this.max;
|
||||
let minDist = Math.abs(this.location.x);
|
||||
let boundsPoint = new Vector2(this.location.x, 0);
|
||||
|
||||
if (Math.abs(max.x) < minDist){
|
||||
minDist = Math.abs(max.x);
|
||||
boundsPoint.x = max.x;
|
||||
boundsPoint.y = 0;
|
||||
}
|
||||
|
||||
if (Math.abs(max.y) < minDist){
|
||||
minDist = Math.abs(max.y);
|
||||
boundsPoint.x = 0;
|
||||
boundsPoint.y = max.y;
|
||||
}
|
||||
|
||||
if (Math.abs(this.location.y) < minDist){
|
||||
minDist = Math.abs(this.location.y);
|
||||
boundsPoint.x = 0;
|
||||
boundsPoint.y = this.location.y;
|
||||
}
|
||||
|
||||
return boundsPoint;
|
||||
}
|
||||
|
||||
public calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2,
|
||||
rotation: number, width: number, height: number) {
|
||||
if (rotation == 0) {
|
||||
|
||||
@@ -21,6 +21,20 @@ class Box extends Polygon {
|
||||
return verts;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public collidesWithShape(other: Shape){
|
||||
if (this.isUnrotated && other instanceof Box && other.isUnrotated){
|
||||
return ShapeCollisions.boxToBox(this, other);
|
||||
}
|
||||
|
||||
// TODO: 让 minkowski 运行于 cricleToBox
|
||||
|
||||
return super.collidesWithShape(other);
|
||||
}
|
||||
|
||||
public updateBox(width: number, height: number){
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
class CollisionResult {
|
||||
public collider: Collider;
|
||||
public minimumTranslationVector: Vector2;
|
||||
public normal: Vector2;
|
||||
public point: Vector2;
|
||||
public minimumTranslationVector: Vector2 = Vector2.zero;
|
||||
public normal: Vector2 = Vector2.zero;
|
||||
public point: Vector2 = Vector2.zero;
|
||||
|
||||
public invertResult(){
|
||||
this.minimumTranslationVector = Vector2.negate(this.minimumTranslationVector);
|
||||
|
||||
@@ -252,4 +252,34 @@ class ShapeCollisions {
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param first
|
||||
* @param second
|
||||
*/
|
||||
public static boxToBox(first: Box, second: Box){
|
||||
let result = new CollisionResult();
|
||||
|
||||
let minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(new Vector2(0, 0))){
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
|
||||
if (result.minimumTranslationVector == Vector2.zero)
|
||||
return false;
|
||||
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private static minkowskiDifference(first: Box, second: Box){
|
||||
let positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2))));
|
||||
let topLeft = Vector2.subtract(Vector2.add(first.bounds.location, positionOffset), second.bounds.max);
|
||||
let fullSize = Vector2.add(first.bounds.size, second.bounds.size);
|
||||
|
||||
return new Rectangle(topLeft.x, topLeft.y, fullSize.x, fullSize.y)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user