修复切换场景未移除问题
This commit is contained in:
@@ -168,6 +168,7 @@ class Polygon extends Shape {
|
||||
}
|
||||
|
||||
public recalculateBounds(collider: Collider) {
|
||||
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始
|
||||
this.center = collider.localOffset;
|
||||
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform){
|
||||
@@ -180,6 +181,8 @@ class Polygon extends Shape {
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
|
||||
hasUnitScale = false;
|
||||
|
||||
// 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置
|
||||
let scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale);
|
||||
this.center = scaledOffset;
|
||||
}
|
||||
@@ -188,6 +191,8 @@ class Polygon extends Shape {
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation);
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
|
||||
// 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动我们的偏移使角度为0
|
||||
// 我们还需要处理这里的比例所以我们先对偏移进行缩放以得到合适的长度。
|
||||
let offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg;
|
||||
let offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
|
||||
this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle);
|
||||
@@ -196,9 +201,11 @@ class Polygon extends Shape {
|
||||
tempMat = Matrix2D.createTranslation(this._polygonCenter.x, this._polygonCenter.y);
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
|
||||
// 最后变换原始点
|
||||
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
|
||||
this.isUnrotated = collider.entity.rotation == 0;
|
||||
|
||||
// 如果旋转的话,我们只需要重建边的法线
|
||||
if (collider._isRotationDirty)
|
||||
this._areEdgeNormalsDirty = true;
|
||||
}
|
||||
|
||||
@@ -15,13 +15,17 @@ class ShapeCollisions {
|
||||
let polygonOffset = Vector2.subtract(first.position, second.position);
|
||||
let axis: Vector2;
|
||||
|
||||
// 循环穿过两个多边形的所有边
|
||||
for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) {
|
||||
// 1. 找出当前多边形是否相交
|
||||
// 多边形的归一化轴垂直于缓存给我们的当前边
|
||||
if (edgeIndex < firstEdges.length) {
|
||||
axis = firstEdges[edgeIndex];
|
||||
} else {
|
||||
axis = secondEdges[edgeIndex - firstEdges.length];
|
||||
}
|
||||
|
||||
// 求多边形在当前轴上的投影
|
||||
let minA = 0;
|
||||
let minB = 0;
|
||||
let maxA = 0;
|
||||
@@ -34,17 +38,24 @@ class ShapeCollisions {
|
||||
minB = tb.min;
|
||||
maxB = tb.max;
|
||||
|
||||
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
||||
let relativeIntervalOffset = Vector2.dot(polygonOffset, axis);
|
||||
minA += relativeIntervalOffset;
|
||||
maxA += relativeIntervalOffset;
|
||||
|
||||
// 检查多边形投影是否正在相交
|
||||
intervalDist = this.intervalDistance(minA, maxA, minB, maxB);
|
||||
if (intervalDist > 0)
|
||||
isIntersecting = false;
|
||||
|
||||
// 对于多对多数据类型转换,添加一个Vector2?参数称为deltaMovement。为了提高速度,我们这里不使用它
|
||||
// TODO: 现在找出多边形是否会相交。只要检查速度就行了
|
||||
|
||||
// 如果多边形不相交,也不会相交,退出循环
|
||||
if (!isIntersecting)
|
||||
return null;
|
||||
|
||||
// 检查当前间隔距离是否为最小值。如果是,则存储间隔距离和当前距离。这将用于计算最小平移向量
|
||||
intervalDist = Math.abs(intervalDist);
|
||||
if (intervalDist < minIntervalDistance) {
|
||||
minIntervalDistance = intervalDist;
|
||||
@@ -55,8 +66,9 @@ class ShapeCollisions {
|
||||
}
|
||||
}
|
||||
|
||||
// 利用最小平移向量对多边形进行推入。
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis), new Vector2(minIntervalDistance));
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -263,10 +275,11 @@ class ShapeCollisions {
|
||||
|
||||
let minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(new Vector2(0, 0))){
|
||||
// 计算MTV。如果它是零,我们就可以称它为非碰撞
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
|
||||
if (result.minimumTranslationVector == Vector2.zero)
|
||||
return false;
|
||||
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
|
||||
return null;
|
||||
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
@@ -278,6 +291,8 @@ class ShapeCollisions {
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
@@ -122,8 +122,8 @@ class SpatialHash {
|
||||
return cell;
|
||||
}
|
||||
|
||||
private cellCoords(x: number, y: number): Point {
|
||||
return new Point(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
private cellCoords(x: number, y: number): Vector2 {
|
||||
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user