新增 circleCollider与 polygonCollider

This commit is contained in:
yhh
2020-07-09 15:11:30 +08:00
parent 6e3eb1189a
commit 817b703d4f
13 changed files with 253 additions and 18 deletions

View File

@@ -458,6 +458,14 @@ declare class BoxCollider extends Collider {
constructor();
setSize(width: number, height: number): this;
}
declare class CircleCollider extends Collider {
radius: number;
constructor(radius?: number);
setRadius(radius: number): CircleCollider;
}
declare class PolygonCollider extends Collider {
constructor(points: Vector2[]);
}
declare class EntitySystem {
private _scene;
private _entities;
@@ -873,6 +881,7 @@ declare class Polygon extends Shape {
recalculateCenterAndEdgeNormals(): void;
overlaps(other: Shape): any;
static findPolygonCenter(points: Vector2[]): Vector2;
static recenterPolygonVerts(points: Vector2[]): void;
static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): {
closestPoint: any;
distanceSquared: any;
@@ -895,7 +904,7 @@ declare class Box extends Polygon {
}
declare class Circle extends Shape {
radius: number;
private _originalRadius;
_originalRadius: number;
center: Vector2;
constructor(radius: number);
pointCollidesWithShape(point: Vector2): CollisionResult;

View File

@@ -2043,7 +2043,7 @@ var Collider = (function (_super) {
};
Collider.prototype.onAddedToEntity = function () {
if (this._colliderRequiresAutoSizing) {
if (!(this instanceof BoxCollider)) {
if (!(this instanceof BoxCollider || this instanceof CircleCollider)) {
console.error("Only box and circle colliders can be created automatically");
}
var renderable = this.entity.getComponent(RenderableComponent);
@@ -2051,7 +2051,12 @@ var Collider = (function (_super) {
var bounds = renderable.bounds;
var width = bounds.width / this.entity.scale.x;
var height = bounds.height / this.entity.scale.y;
if (this instanceof BoxCollider) {
if (this instanceof CircleCollider) {
var circleCollider = this;
circleCollider.radius = Math.max(width, height) * 0.5;
this.localOffset = bounds.location;
}
else {
var boxCollider = this;
boxCollider.width = width;
boxCollider.height = height;
@@ -2147,6 +2152,53 @@ var BoxCollider = (function (_super) {
};
return BoxCollider;
}(Collider));
var CircleCollider = (function (_super) {
__extends(CircleCollider, _super);
function CircleCollider(radius) {
var _this = _super.call(this) || this;
if (radius)
_this._colliderRequiresAutoSizing = true;
_this.shape = new Circle(radius ? radius : 1);
return _this;
}
Object.defineProperty(CircleCollider.prototype, "radius", {
get: function () {
return this.shape.radius;
},
set: function (value) {
this.setRadius(value);
},
enumerable: true,
configurable: true
});
CircleCollider.prototype.setRadius = function (radius) {
this._colliderRequiresAutoSizing = false;
var circle = this.shape;
if (radius != circle.radius) {
circle.radius = radius;
circle._originalRadius = radius;
if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this);
}
return this;
};
return CircleCollider;
}(Collider));
var PolygonCollider = (function (_super) {
__extends(PolygonCollider, _super);
function PolygonCollider(points) {
var _this = _super.call(this) || this;
var isPolygonClosed = points[0] == points[points.length - 1];
if (isPolygonClosed)
points.splice(points.length - 1, 1);
var center = Polygon.findPolygonCenter(points);
_this.setLocalOffset(center);
Polygon.recenterPolygonVerts(points);
_this.shape = new Polygon(points);
return _this;
}
return PolygonCollider;
}(Collider));
var EntitySystem = (function () {
function EntitySystem(matcher) {
this._entities = [];
@@ -3999,6 +4051,11 @@ var Polygon = (function (_super) {
}
return new Vector2(x / points.length, y / points.length);
};
Polygon.recenterPolygonVerts = function (points) {
var center = this.findPolygonCenter(points);
for (var i = 0; i < points.length; i++)
points[i] = Vector2.subtract(points[i], center);
};
Polygon.getClosestPointOnPolygonToPoint = function (points, point) {
var distanceSquared = Number.MAX_VALUE;
var edgeNormal = new Vector2(0, 0);
@@ -4439,6 +4496,12 @@ var SpatialHash = (function () {
results[resultCounter] = collider;
resultCounter++;
}
else if (collider instanceof CircleCollider) {
if (collider.shape.overlaps(this._overlapTestCircle)) {
results[resultCounter] = collider;
resultCounter++;
}
}
else {
throw new Error("overlapCircle against this collider type is not implemented!");
}

File diff suppressed because one or more lines are too long