collider更改

This commit is contained in:
yhh
2020-07-20 16:38:49 +08:00
parent 2a38858838
commit 6b8569b0b5
13 changed files with 110 additions and 196 deletions

View File

@@ -894,6 +894,7 @@ declare class Rectangle extends egret.Rectangle {
edgeNormal: Vector2; edgeNormal: Vector2;
}; };
getClosestPointOnBoundsToOrigin(): Vector2; getClosestPointOnBoundsToOrigin(): Vector2;
setEgretRect(rect: egret.Rectangle): Rectangle;
static rectEncompassingPoints(points: Vector2[]): Rectangle; static rectEncompassingPoints(points: Vector2[]): Rectangle;
} }
declare class Vector3 { declare class Vector3 {
@@ -930,7 +931,7 @@ declare class Collisions {
static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean; static isCircleToCircle(circleCenter1: Vector2, circleRadius1: number, circleCenter2: Vector2, circleRadius2: number): boolean;
static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean; static isCircleToLine(circleCenter: Vector2, radius: number, lineFrom: Vector2, lineTo: Vector2): boolean;
static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean; static isCircleToPoint(circleCenter: Vector2, radius: number, point: Vector2): boolean;
static isRectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean; static isRectToCircle(rect: egret.Rectangle, cPosition: Vector2, cRadius: number): boolean;
static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2): boolean; static isRectToLine(rect: Rectangle, lineFrom: Vector2, lineTo: Vector2): boolean;
static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2): boolean; static isRectToPoint(rX: number, rY: number, rW: number, rH: number, point: Vector2): boolean;
static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors; static getSector(rX: number, rY: number, rW: number, rH: number, point: Vector2): PointSectors;
@@ -955,22 +956,21 @@ declare class Physics {
static updateCollider(collider: Collider): void; static updateCollider(collider: Collider): void;
static debugDraw(secondsToDisplay: any): void; static debugDraw(secondsToDisplay: any): void;
} }
declare abstract class Shape { declare abstract class Shape extends egret.DisplayObject {
bounds: Rectangle; abstract bounds: Rectangle;
position: Vector2; position: Vector2;
abstract center: Vector2; abstract center: Vector2;
abstract recalculateBounds(collider: Collider): any;
abstract pointCollidesWithShape(point: Vector2): CollisionResult; abstract pointCollidesWithShape(point: Vector2): CollisionResult;
abstract overlaps(other: Shape): any; abstract overlaps(other: Shape): any;
abstract collidesWithShape(other: Shape): CollisionResult; abstract collidesWithShape(other: Shape): CollisionResult;
} }
declare class Polygon extends Shape { declare class Polygon extends Shape {
points: Vector2[]; points: Vector2[];
isUnrotated: boolean;
private _polygonCenter; private _polygonCenter;
private _areEdgeNormalsDirty; private _areEdgeNormalsDirty;
protected _originalPoints: Vector2[]; protected _originalPoints: Vector2[];
center: Vector2; center: Vector2;
readonly bounds: Rectangle;
_edgeNormals: Vector2[]; _edgeNormals: Vector2[];
readonly edgeNormals: Vector2[]; readonly edgeNormals: Vector2[];
isBox: boolean; isBox: boolean;
@@ -990,11 +990,8 @@ declare class Polygon extends Shape {
pointCollidesWithShape(point: Vector2): CollisionResult; pointCollidesWithShape(point: Vector2): CollisionResult;
containsPoint(point: Vector2): boolean; containsPoint(point: Vector2): boolean;
static buildSymmertricalPolygon(vertCount: number, radius: number): any[]; static buildSymmertricalPolygon(vertCount: number, radius: number): any[];
recalculateBounds(collider: Collider): void;
} }
declare class Box extends Polygon { declare class Box extends Polygon {
width: number;
height: number;
constructor(width: number, height: number); constructor(width: number, height: number);
private static buildBox; private static buildBox;
overlaps(other: Shape): any; overlaps(other: Shape): any;
@@ -1006,10 +1003,10 @@ declare class Circle extends Shape {
radius: number; radius: number;
_originalRadius: number; _originalRadius: number;
center: Vector2; center: Vector2;
readonly bounds: Rectangle;
constructor(radius: number); constructor(radius: number);
pointCollidesWithShape(point: Vector2): CollisionResult; pointCollidesWithShape(point: Vector2): CollisionResult;
collidesWithShape(other: Shape): CollisionResult; collidesWithShape(other: Shape): CollisionResult;
recalculateBounds(collider: Collider): void;
overlaps(other: Shape): any; overlaps(other: Shape): any;
} }
declare class CollisionResult { declare class CollisionResult {
@@ -1062,7 +1059,6 @@ declare class RaycastResultParser {
declare class NumberDictionary { declare class NumberDictionary {
private _store; private _store;
private getKey; private getKey;
private intToUint;
add(x: number, y: number, list: Collider[]): void; add(x: number, y: number, list: Collider[]): void;
remove(obj: Collider): void; remove(obj: Collider): void;
tryGetValue(x: number, y: number): Collider[]; tryGetValue(x: number, y: number): Collider[];

View File

@@ -2197,8 +2197,9 @@ var Collider = (function (_super) {
} }
Object.defineProperty(Collider.prototype, "bounds", { Object.defineProperty(Collider.prototype, "bounds", {
get: function () { get: function () {
this.shape.recalculateBounds(this); var shapeBounds = this.shape.bounds;
return this.shape.bounds; var colliderBuonds = new Rectangle(this.x + this.localOffset.x, this.y + this.localOffset.y, shapeBounds.width, shapeBounds.height);
return colliderBuonds;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -2261,9 +2262,8 @@ var Collider = (function (_super) {
this.localOffset = bounds.location; this.localOffset = bounds.location;
} }
else { else {
var boxCollider = this; this.width = width;
boxCollider.width = width; this.height = height;
boxCollider.height = height;
this.localOffset = bounds.location; this.localOffset = bounds.location;
} }
} }
@@ -4402,6 +4402,13 @@ var Rectangle = (function (_super) {
} }
return boundsPoint; return boundsPoint;
}; };
Rectangle.prototype.setEgretRect = function (rect) {
this.x = rect.x;
this.y = rect.y;
this.width = rect.width;
this.height = rect.height;
return this;
};
Rectangle.rectEncompassingPoints = function (points) { Rectangle.rectEncompassingPoints = function (points) {
var minX = Number.POSITIVE_INFINITY; var minX = Number.POSITIVE_INFINITY;
var minY = Number.POSITIVE_INFINITY; var minY = Number.POSITIVE_INFINITY;
@@ -4687,24 +4694,32 @@ var Physics = (function () {
Physics.allLayers = -1; Physics.allLayers = -1;
return Physics; return Physics;
}()); }());
var Shape = (function () { var Shape = (function (_super) {
__extends(Shape, _super);
function Shape() { function Shape() {
this.bounds = new Rectangle(); var _this = _super !== null && _super.apply(this, arguments) || this;
this.position = Vector2.zero; _this.position = Vector2.zero;
return _this;
} }
return Shape; return Shape;
}()); }(egret.DisplayObject));
var Polygon = (function (_super) { var Polygon = (function (_super) {
__extends(Polygon, _super); __extends(Polygon, _super);
function Polygon(points, isBox) { function Polygon(points, isBox) {
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this.isUnrotated = true;
_this._areEdgeNormalsDirty = true; _this._areEdgeNormalsDirty = true;
_this.center = new Vector2(); _this.center = new Vector2();
_this.setPoints(points); _this.setPoints(points);
_this.isBox = isBox; _this.isBox = isBox;
return _this; return _this;
} }
Object.defineProperty(Polygon.prototype, "bounds", {
get: function () {
return new Rectangle(0, 0, this.width, this.height);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Polygon.prototype, "edgeNormals", { Object.defineProperty(Polygon.prototype, "edgeNormals", {
get: function () { get: function () {
if (this._areEdgeNormalsDirty) if (this._areEdgeNormalsDirty)
@@ -4829,36 +4844,6 @@ var Polygon = (function (_super) {
} }
return verts; return verts;
}; };
Polygon.prototype.recalculateBounds = function (collider) {
var localOffset = collider.localOffset;
if (collider.shouldColliderScaleAndRotateWithTransform) {
var hasUnitScale = true;
var tempMat = void 0;
var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
if (collider.entity.scale != Vector2.one) {
tempMat = Matrix2D.createScale(collider.entity.scale.x, collider.entity.scale.y);
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
hasUnitScale = false;
var scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale);
localOffset = scaledOffset;
}
if (collider.entity.rotation != 0) {
tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg;
var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
localOffset = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle);
}
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;
}
this.position = Vector2.add(collider.entity.position, localOffset);
this.bounds = Rectangle.rectEncompassingPoints(this.points);
this.bounds.location = Vector2.add(this.bounds.location, this.position);
this.center = localOffset;
};
return Polygon; return Polygon;
}(Shape)); }(Shape));
var Box = (function (_super) { var Box = (function (_super) {
@@ -4880,16 +4865,14 @@ var Box = (function (_super) {
return verts; return verts;
}; };
Box.prototype.overlaps = function (other) { Box.prototype.overlaps = function (other) {
if (this.isUnrotated) { if (other instanceof Box)
if (other instanceof Box && other.isUnrotated)
return this.bounds.intersects(other.bounds); return this.bounds.intersects(other.bounds);
if (other instanceof Circle) if (other instanceof Circle)
return Collisions.isRectToCircle(this.bounds, other.position, other.radius); return Collisions.isRectToCircle(this.bounds, other.position, other.radius);
}
return _super.prototype.overlaps.call(this, other); return _super.prototype.overlaps.call(this, other);
}; };
Box.prototype.collidesWithShape = function (other) { Box.prototype.collidesWithShape = function (other) {
if (this.isUnrotated && other instanceof Box && other.isUnrotated) { if (other instanceof Box) {
return ShapeCollisions.boxToBox(this, other); return ShapeCollisions.boxToBox(this, other);
} }
return _super.prototype.collidesWithShape.call(this, other); return _super.prototype.collidesWithShape.call(this, other);
@@ -4907,9 +4890,7 @@ var Box = (function (_super) {
this._originalPoints[i] = this.points[i]; this._originalPoints[i] = this.points[i];
}; };
Box.prototype.containsPoint = function (point) { Box.prototype.containsPoint = function (point) {
if (this.isUnrotated)
return this.bounds.contains(point.x, point.y); return this.bounds.contains(point.x, point.y);
return _super.prototype.containsPoint.call(this, point);
}; };
return Box; return Box;
}(Polygon)); }(Polygon));
@@ -4922,11 +4903,18 @@ var Circle = (function (_super) {
_this._originalRadius = radius; _this._originalRadius = radius;
return _this; return _this;
} }
Object.defineProperty(Circle.prototype, "bounds", {
get: function () {
return new Rectangle().setEgretRect(this.getBounds());
},
enumerable: true,
configurable: true
});
Circle.prototype.pointCollidesWithShape = function (point) { Circle.prototype.pointCollidesWithShape = function (point) {
return ShapeCollisions.pointToCircle(point, this); return ShapeCollisions.pointToCircle(point, this);
}; };
Circle.prototype.collidesWithShape = function (other) { Circle.prototype.collidesWithShape = function (other) {
if (other instanceof Box && other.isUnrotated) { if (other instanceof Box) {
return ShapeCollisions.circleToBox(this, other); return ShapeCollisions.circleToBox(this, other);
} }
if (other instanceof Circle) { if (other instanceof Circle) {
@@ -4937,24 +4925,8 @@ var Circle = (function (_super) {
} }
throw new Error("Collisions of Circle to " + other + " are not supported"); throw new Error("Collisions of Circle to " + other + " are not supported");
}; };
Circle.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotateWithTransform) {
var scale = collider.entity.scale;
var hasUnitScale = scale.x == 1 && scale.y == 1;
var maxScale = Math.max(scale.x, scale.y);
this.radius = this._originalRadius * maxScale;
if (collider.entity.rotation != 0) {
var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg;
var 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);
}
}
this.position = Vector2.add(collider.entity.position, this.center);
this.bounds = new Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2);
};
Circle.prototype.overlaps = function (other) { Circle.prototype.overlaps = function (other) {
if (other instanceof Box && other.isUnrotated) if (other instanceof Box)
return Collisions.isRectToCircle(other.bounds, this.position, this.radius); return Collisions.isRectToCircle(other.bounds, this.position, this.radius);
if (other instanceof Circle) if (other instanceof Circle)
return Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius); return Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius);
@@ -5306,13 +5278,7 @@ var NumberDictionary = (function () {
this._store = new Map(); this._store = new Map();
} }
NumberDictionary.prototype.getKey = function (x, y) { NumberDictionary.prototype.getKey = function (x, y) {
return Long.fromNumber(x).shiftLeft(32).or(this.intToUint(y)).toString(); return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, false)).toString();
};
NumberDictionary.prototype.intToUint = function (i) {
if (i >= 0)
return i;
else
return 4294967296 + i;
}; };
NumberDictionary.prototype.add = function (x, y, list) { NumberDictionary.prototype.add = function (x, y, list) {
this._store.set(this.getKey(x, y), list); this._store.set(this.getKey(x, y), list);
@@ -6296,8 +6262,12 @@ var RectangleExt = (function () {
} }
RectangleExt.union = function (first, point) { RectangleExt.union = function (first, point) {
var rect = new Rectangle(point.x, point.y, 0, 0); var rect = new Rectangle(point.x, point.y, 0, 0);
var rectResult = first.union(rect); var result = new Rectangle();
return new Rectangle(rectResult.x, rectResult.y, rectResult.width, rectResult.height); result.x = Math.min(first.x, rect.x);
result.y = Math.min(first.y, rect.y);
result.width = Math.max(first.right, rect.right) - result.x;
result.height = Math.max(first.bottom, result.bottom) - result.y;
return result;
}; };
return RectangleExt; return RectangleExt;
}()); }());

File diff suppressed because one or more lines are too long

View File

@@ -24,8 +24,9 @@ abstract class Collider extends Component {
protected _isColliderRegistered; protected _isColliderRegistered;
public get bounds(): Rectangle { public get bounds(): Rectangle {
this.shape.recalculateBounds(this); let shapeBounds = this.shape.bounds;
return this.shape.bounds; let colliderBuonds = new Rectangle(this.x + this.localOffset.x, this.y + this.localOffset.y, shapeBounds.width, shapeBounds.height);
return colliderBuonds;
} }
public get localOffset() { public get localOffset() {
@@ -118,9 +119,8 @@ abstract class Collider extends Component {
this.localOffset = bounds.location; this.localOffset = bounds.location;
} else { } else {
let boxCollider = this; this.width = width;
boxCollider.width = width; this.height = height;
boxCollider.height = height;
this.localOffset = bounds.location; this.localOffset = bounds.location;
} }

View File

@@ -138,6 +138,18 @@ class Rectangle extends egret.Rectangle {
return boundsPoint; return boundsPoint;
} }
/**
* 将egret矩形转化为Rectangle
* @param rect
*/
public setEgretRect(rect: egret.Rectangle): Rectangle{
this.x = rect.x;
this.y = rect.y;
this.width = rect.width;
this.height = rect.height;
return this;
}
/** /**
* 给定多边形的点,计算边界 * 给定多边形的点,计算边界
* @param points * @param points

View File

@@ -78,7 +78,7 @@ class Collisions {
return Vector2.distanceSquared(circleCenter, point) < radius * radius; return Vector2.distanceSquared(circleCenter, point) < radius * radius;
} }
public static isRectToCircle(rect: Rectangle, cPosition: Vector2, cRadius: number): boolean { public static isRectToCircle(rect: egret.Rectangle, cPosition: Vector2, cRadius: number): boolean {
let ew = rect.width * 0.5; let ew = rect.width * 0.5;
let eh = rect.height * 0.5; let eh = rect.height * 0.5;
let vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew); let vx = Math.max(0, Math.max(cPosition.x - rect.x) - ew);

View File

@@ -3,9 +3,6 @@
* 多边形的特殊情况。在进行SAT碰撞检查时我们只需要检查2个轴而不是8个轴 * 多边形的特殊情况。在进行SAT碰撞检查时我们只需要检查2个轴而不是8个轴
*/ */
class Box extends Polygon { class Box extends Polygon {
public width: number;
public height: number;
constructor(width: number, height: number){ constructor(width: number, height: number){
super(Box.buildBox(width, height), true); super(Box.buildBox(width, height), true);
this.width = width; this.width = width;
@@ -32,20 +29,18 @@ class Box extends Polygon {
public overlaps(other: Shape){ public overlaps(other: Shape){
// 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测 // 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测
if (this.isUnrotated){ if (other instanceof Box)
if (other instanceof Box && other.isUnrotated)
return this.bounds.intersects(other.bounds); return this.bounds.intersects(other.bounds);
if (other instanceof Circle) if (other instanceof Circle)
return Collisions.isRectToCircle(this.bounds, other.position, other.radius); return Collisions.isRectToCircle(this.bounds, other.position, other.radius);
}
return super.overlaps(other); return super.overlaps(other);
} }
public collidesWithShape(other: Shape){ public collidesWithShape(other: Shape){
// 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测 // 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测
if (this.isUnrotated && other instanceof Box && other.isUnrotated){ if (other instanceof Box){
return ShapeCollisions.boxToBox(this, other); return ShapeCollisions.boxToBox(this, other);
} }
@@ -76,10 +71,11 @@ class Box extends Polygon {
this._originalPoints[i] = this.points[i]; this._originalPoints[i] = this.points[i];
} }
/**
*
* @param point
*/
public containsPoint(point: Vector2){ public containsPoint(point: Vector2){
if (this.isUnrotated)
return this.bounds.contains(point.x, point.y); return this.bounds.contains(point.x, point.y);
return super.containsPoint(point);
} }
} }

View File

@@ -4,6 +4,10 @@ class Circle extends Shape {
public _originalRadius: number; public _originalRadius: number;
public center = new Vector2(); public center = new Vector2();
public get bounds(){
return new Rectangle().setEgretRect(this.getBounds());
}
constructor(radius: number) { constructor(radius: number) {
super(); super();
this.radius = radius; this.radius = radius;
@@ -15,7 +19,7 @@ class Circle extends Shape {
} }
public collidesWithShape(other: Shape): CollisionResult { public collidesWithShape(other: Shape): CollisionResult {
if (other instanceof Box && (other as Box).isUnrotated) { if (other instanceof Box) {
return ShapeCollisions.circleToBox(this, other); return ShapeCollisions.circleToBox(this, other);
} }
@@ -30,28 +34,8 @@ class Circle extends Shape {
throw new Error(`Collisions of Circle to ${other} are not supported`); throw new Error(`Collisions of Circle to ${other} are not supported`);
} }
public recalculateBounds(collider: Collider) {
this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotateWithTransform) {
let scale = collider.entity.scale;
let hasUnitScale = scale.x == 1 && scale.y == 1;
let maxScale = Math.max(scale.x, scale.y);
this.radius = this._originalRadius * maxScale;
if (collider.entity.rotation != 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);
}
}
this.position = Vector2.add(collider.entity.position, this.center);
this.bounds = new Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2);
}
public overlaps(other: Shape){ public overlaps(other: Shape){
if (other instanceof Box && (other as Box).isUnrotated) if (other instanceof Box)
return Collisions.isRectToCircle(other.bounds, this.position, this.radius); return Collisions.isRectToCircle(other.bounds, this.position, this.radius);
if (other instanceof Circle) if (other instanceof Circle)

View File

@@ -1,12 +1,15 @@
///<reference path="./Shape.ts" /> ///<reference path="./Shape.ts" />
class Polygon extends Shape { class Polygon extends Shape {
public points: Vector2[]; public points: Vector2[];
public isUnrotated: boolean = true;
private _polygonCenter: Vector2; private _polygonCenter: Vector2;
private _areEdgeNormalsDirty = true; private _areEdgeNormalsDirty = true;
protected _originalPoints: Vector2[]; protected _originalPoints: Vector2[];
public center = new Vector2(); public center = new Vector2();
public get bounds(){
return new Rectangle(0, 0, this.width, this.height);
}
public _edgeNormals: Vector2[]; public _edgeNormals: Vector2[];
public get edgeNormals(){ public get edgeNormals(){
if (this._areEdgeNormalsDirty) if (this._areEdgeNormalsDirty)
@@ -195,49 +198,4 @@ class Polygon extends Shape {
return verts; return verts;
} }
public recalculateBounds(collider: Collider) {
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心我们会从那开始
// this.center = collider.localOffset;
let localOffset = collider.localOffset;
if (collider.shouldColliderScaleAndRotateWithTransform){
let hasUnitScale = true;
let tempMat: Matrix2D;
let combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
if (collider.entity.scale != Vector2.one){
tempMat = Matrix2D.createScale(collider.entity.scale.x, collider.entity.scale.y);
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
hasUnitScale = false;
// 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置
let scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale);
localOffset = scaledOffset;
}
if (collider.entity.rotation != 0){
tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
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();
localOffset = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle);
}
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;
}
this.position = Vector2.add(collider.entity.position, localOffset);
this.bounds = Rectangle.rectEncompassingPoints(this.points);
this.bounds.location = Vector2.add(this.bounds.location, this.position);
this.center = localOffset;
}
} }

View File

@@ -1,9 +1,8 @@
abstract class Shape { abstract class Shape extends egret.DisplayObject {
public bounds: Rectangle = new Rectangle(); public abstract bounds: Rectangle;
public position: Vector2 = Vector2.zero; public position: Vector2 = Vector2.zero;
public abstract center: Vector2; public abstract center: Vector2;
public abstract recalculateBounds(collider: Collider);
public abstract pointCollidesWithShape(point: Vector2): CollisionResult; public abstract pointCollidesWithShape(point: Vector2): CollisionResult;
public abstract overlaps(other: Shape); public abstract overlaps(other: Shape);
public abstract collidesWithShape(other: Shape): CollisionResult; public abstract collidesWithShape(other: Shape): CollisionResult;

View File

@@ -209,26 +209,15 @@ class RaycastResultParser {
* 它的主要目的是将int、int x、y坐标散列到单个Uint32键中使用O(1)查找。 * 它的主要目的是将int、int x、y坐标散列到单个Uint32键中使用O(1)查找。
*/ */
class NumberDictionary { class NumberDictionary {
private _store: Map<number, Collider[]> = new Map<number, Collider[]>(); private _store: Map<string, Collider[]> = new Map<string, Collider[]>();
/** /**
* 根据x和y值计算并返回散列键 * 根据x和y值计算并返回散列键
* @param x * @param x
* @param y * @param y
*/ */
private getKey(x: number, y: number): number { private getKey(x: number, y: number): string {
return Long.fromNumber(x).shiftLeft(32).or(this.intToUint(y)).toString(); return Long.fromNumber(x).shiftLeft(32).or(Long.fromNumber(y, false)).toString();
}
/**
*
* @param i
*/
private intToUint(i) {
if (i >= 0)
return i;
else
return 4294967296 + i;
} }
public add(x: number, y: number, list: Collider[]) { public add(x: number, y: number, list: Collider[]) {

View File

@@ -1,7 +1,17 @@
class RectangleExt { class RectangleExt {
/**
* 计算两个矩形的并集。结果将是一个包含其他两个的矩形。
* @param first
* @param point
*/
public static union(first: Rectangle, point: Vector2){ public static union(first: Rectangle, point: Vector2){
let rect = new Rectangle(point.x, point.y, 0, 0); let rect = new Rectangle(point.x, point.y, 0, 0);
let rectResult = first.union(rect); // let rectResult = first.union(rect);
return new Rectangle(rectResult.x, rectResult.y, rectResult.width, rectResult.height); let result = new Rectangle();
result.x = Math.min(first.x, rect.x);
result.y = Math.min(first.y, rect.y);
result.width = Math.max(first.right, rect.right) - result.x;
result.height = Math.max(first.bottom, result.bottom) - result.y;
return result;
} }
} }

View File

@@ -11,7 +11,7 @@
"es5", "es5",
"dom", "dom",
"es2015.promise", "es2015.promise",
"es6" "es6",
] , ] ,
}, },
"include": [ "include": [