新增renderablecomponent显示
优化返回值
This commit is contained in:
81
source/bin/framework.d.ts
vendored
81
source/bin/framework.d.ts
vendored
@@ -133,6 +133,7 @@ declare module es {
|
||||
static transform(position: Vector2, matrix: Matrix2D): Vector2;
|
||||
static distance(value1: Vector2, value2: Vector2): number;
|
||||
static negate(value: Vector2): Vector2;
|
||||
equals(other: Vector2): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -387,13 +388,14 @@ declare module transform {
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
import HashObject = egret.HashObject;
|
||||
enum DirtyType {
|
||||
clean = 0,
|
||||
positionDirty = 1,
|
||||
scaleDirty = 2,
|
||||
rotationDirty = 3
|
||||
}
|
||||
class Transform {
|
||||
class Transform extends HashObject {
|
||||
readonly entity: Entity;
|
||||
parent: Transform;
|
||||
readonly childCount: number;
|
||||
@@ -448,6 +450,7 @@ declare module es {
|
||||
setDirty(dirtyFlagType: DirtyType): void;
|
||||
copyFrom(transform: Transform): void;
|
||||
toString(): string;
|
||||
equals(other: Transform): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -536,6 +539,7 @@ declare module es {
|
||||
}
|
||||
declare module es {
|
||||
abstract class RenderableComponent extends Component implements IRenderable {
|
||||
displayObject: egret.DisplayObject;
|
||||
readonly width: number;
|
||||
readonly height: number;
|
||||
readonly bounds: Rectangle;
|
||||
@@ -556,6 +560,7 @@ declare module es {
|
||||
setRenderLayer(renderLayer: number): RenderableComponent;
|
||||
setColor(color: number): RenderableComponent;
|
||||
setLocalOffset(offset: Vector2): RenderableComponent;
|
||||
sync(camera: Camera): void;
|
||||
toString(): string;
|
||||
}
|
||||
}
|
||||
@@ -667,12 +672,9 @@ declare module es {
|
||||
class Mover extends Component {
|
||||
private _triggerHelper;
|
||||
onAddedToEntity(): void;
|
||||
calculateMovement(motion: Vector2): {
|
||||
collisionResult: CollisionResult;
|
||||
motion: Vector2;
|
||||
};
|
||||
calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean;
|
||||
applyMovement(motion: Vector2): void;
|
||||
move(motion: Vector2): CollisionResult;
|
||||
move(motion: Vector2, collisionResult: CollisionResult): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -712,8 +714,8 @@ declare module es {
|
||||
onDisabled(): void;
|
||||
registerColliderWithPhysicsSystem(): void;
|
||||
unregisterColliderWithPhysicsSystem(): void;
|
||||
overlaps(other: Collider): any;
|
||||
collidesWith(collider: Collider, motion: Vector2): CollisionResult;
|
||||
overlaps(other: Collider): boolean;
|
||||
collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean;
|
||||
clone(): Component;
|
||||
}
|
||||
}
|
||||
@@ -1054,15 +1056,20 @@ declare module es {
|
||||
declare module es {
|
||||
abstract class Renderer {
|
||||
camera: Camera;
|
||||
readonly renderOrder: number;
|
||||
protected constructor(renderOrder: number, camera?: Camera);
|
||||
onAddedToScene(scene: Scene): void;
|
||||
unload(): void;
|
||||
protected beginRender(cam: Camera): void;
|
||||
abstract render(scene: Scene): any;
|
||||
unload(): void;
|
||||
protected renderAfterStateCheck(renderable: IRenderable, cam: Camera): void;
|
||||
onSceneBackBufferSizeChanged(newWidth: number, newHeight: number): void;
|
||||
compareTo(other: Renderer): number;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
class DefaultRenderer extends Renderer {
|
||||
constructor();
|
||||
render(scene: Scene): void;
|
||||
}
|
||||
}
|
||||
@@ -1197,10 +1204,7 @@ declare module es {
|
||||
containsRect(value: Rectangle): boolean;
|
||||
getHalfSize(): Vector2;
|
||||
static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle;
|
||||
getClosestPointOnRectangleBorderToPoint(point: Vector2): {
|
||||
res: Vector2;
|
||||
edgeNormal: Vector2;
|
||||
};
|
||||
getClosestPointOnRectangleBorderToPoint(point: Vector2, edgeNormal: Vector2): Vector2;
|
||||
getClosestPointOnBoundsToOrigin(): Vector2;
|
||||
calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void;
|
||||
setEgretRect(rect: egret.Rectangle): Rectangle;
|
||||
@@ -1260,14 +1264,8 @@ declare module es {
|
||||
static reset(): void;
|
||||
static clear(): void;
|
||||
static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number;
|
||||
static boxcastBroadphase(rect: Rectangle, layerMask?: number): {
|
||||
colliders: Collider[];
|
||||
rect: Rectangle;
|
||||
};
|
||||
static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask?: number): {
|
||||
tempHashSet: Collider[];
|
||||
bounds: Rectangle;
|
||||
};
|
||||
static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[];
|
||||
static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask?: number): Collider[];
|
||||
static addCollider(collider: Collider): void;
|
||||
static removeCollider(collider: Collider): void;
|
||||
static updateCollider(collider: Collider): void;
|
||||
@@ -1280,9 +1278,9 @@ declare module es {
|
||||
center: Vector2;
|
||||
bounds: Rectangle;
|
||||
abstract recalculateBounds(collider: Collider): any;
|
||||
abstract pointCollidesWithShape(point: Vector2): CollisionResult;
|
||||
abstract overlaps(other: Shape): any;
|
||||
abstract collidesWithShape(other: Shape): CollisionResult;
|
||||
abstract overlaps(other: Shape): boolean;
|
||||
abstract collidesWithShape(other: Shape, collisionResult: CollisionResult): boolean;
|
||||
abstract pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean;
|
||||
clone(): Shape;
|
||||
}
|
||||
}
|
||||
@@ -1303,16 +1301,12 @@ declare module es {
|
||||
static buildSymmetricalPolygon(vertCount: number, radius: number): any[];
|
||||
static recenterPolygonVerts(points: Vector2[]): void;
|
||||
static findPolygonCenter(points: Vector2[]): Vector2;
|
||||
static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): {
|
||||
closestPoint: any;
|
||||
distanceSquared: any;
|
||||
edgeNormal: any;
|
||||
};
|
||||
static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: number, edgeNormal: Vector2): Vector2;
|
||||
recalculateBounds(collider: Collider): void;
|
||||
overlaps(other: Shape): any;
|
||||
collidesWithShape(other: Shape): any;
|
||||
collidesWithShape(other: Shape, result: CollisionResult): boolean;
|
||||
containsPoint(point: Vector2): boolean;
|
||||
pointCollidesWithShape(point: Vector2): CollisionResult;
|
||||
pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -1323,7 +1317,7 @@ declare module es {
|
||||
private static buildBox;
|
||||
updateBox(width: number, height: number): void;
|
||||
overlaps(other: Shape): any;
|
||||
collidesWithShape(other: Shape): any;
|
||||
collidesWithShape(other: Shape, result: CollisionResult): boolean;
|
||||
containsPoint(point: Vector2): boolean;
|
||||
}
|
||||
}
|
||||
@@ -1334,8 +1328,8 @@ declare module es {
|
||||
constructor(radius: number);
|
||||
recalculateBounds(collider: es.Collider): void;
|
||||
overlaps(other: Shape): any;
|
||||
collidesWithShape(other: Shape): CollisionResult;
|
||||
pointCollidesWithShape(point: Vector2): CollisionResult;
|
||||
collidesWithShape(other: Shape, result: CollisionResult): boolean;
|
||||
pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean;
|
||||
}
|
||||
}
|
||||
declare module es {
|
||||
@@ -1349,19 +1343,19 @@ declare module es {
|
||||
}
|
||||
declare module es {
|
||||
class ShapeCollisions {
|
||||
static polygonToPolygon(first: Polygon, second: Polygon): CollisionResult;
|
||||
static polygonToPolygon(first: Polygon, second: Polygon, result: CollisionResult): boolean;
|
||||
static intervalDistance(minA: number, maxA: number, minB: number, maxB: any): number;
|
||||
static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): {
|
||||
min: number;
|
||||
max: number;
|
||||
};
|
||||
static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult;
|
||||
static circleToBox(circle: Circle, box: Box): CollisionResult;
|
||||
static pointToCircle(point: Vector2, circle: Circle): CollisionResult;
|
||||
static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean;
|
||||
static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean;
|
||||
static pointToCircle(point: Vector2, circle: Circle, result: CollisionResult): boolean;
|
||||
static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2;
|
||||
static pointToPoly(point: Vector2, poly: Polygon): CollisionResult;
|
||||
static circleToCircle(first: Circle, second: Circle): CollisionResult;
|
||||
static boxToBox(first: Box, second: Box): CollisionResult;
|
||||
static pointToPoly(point: Vector2, poly: Polygon, result: CollisionResult): boolean;
|
||||
static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean;
|
||||
static boxToBox(first: Box, second: Box, result: CollisionResult): boolean;
|
||||
private static minkowskiDifference;
|
||||
}
|
||||
}
|
||||
@@ -1383,10 +1377,7 @@ declare module es {
|
||||
clear(): void;
|
||||
debugDraw(secondsToDisplay: number, textScale?: number): void;
|
||||
private debugDrawCellDetails;
|
||||
aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): {
|
||||
tempHashSet: Collider[];
|
||||
bounds: Rectangle;
|
||||
};
|
||||
aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number): Collider[];
|
||||
overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask: any): number;
|
||||
}
|
||||
class NumberDictionary {
|
||||
|
||||
@@ -735,7 +735,7 @@ var es;
|
||||
return new Vector2(es.MathHelper.lerp(value1.x, value2.x, amount), es.MathHelper.lerp(value1.y, value2.y, amount));
|
||||
};
|
||||
Vector2.transform = function (position, matrix) {
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31, (position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32);
|
||||
};
|
||||
Vector2.distance = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
@@ -747,6 +747,9 @@ var es;
|
||||
result.y = -value.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.prototype.equals = function (other) {
|
||||
return other.x == this.x && other.y == this.y;
|
||||
};
|
||||
Vector2.unitYVector = new Vector2(0, 1);
|
||||
Vector2.unitXVector = new Vector2(1, 0);
|
||||
Vector2.unitVector2 = new Vector2(1, 1);
|
||||
@@ -1145,7 +1148,7 @@ var es;
|
||||
this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this);
|
||||
this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this);
|
||||
this.addEventListener(egret.Event.ENTER_FRAME, this.update, this);
|
||||
this.addEventListener(egret.Event.RENDER, this.draw, this);
|
||||
es.Input.initialize();
|
||||
this.initialize();
|
||||
};
|
||||
Core.prototype.onOrientationChanged = function () {
|
||||
@@ -1183,7 +1186,10 @@ var es;
|
||||
case 1:
|
||||
_a.sent();
|
||||
_a.label = 2;
|
||||
case 2: return [2];
|
||||
case 2: return [4, this.draw()];
|
||||
case 3:
|
||||
_a.sent();
|
||||
return [2];
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1778,6 +1784,7 @@ var transform;
|
||||
})(transform || (transform = {}));
|
||||
var es;
|
||||
(function (es) {
|
||||
var HashObject = egret.HashObject;
|
||||
var DirtyType;
|
||||
(function (DirtyType) {
|
||||
DirtyType[DirtyType["clean"] = 0] = "clean";
|
||||
@@ -1785,24 +1792,27 @@ var es;
|
||||
DirtyType[DirtyType["scaleDirty"] = 2] = "scaleDirty";
|
||||
DirtyType[DirtyType["rotationDirty"] = 3] = "rotationDirty";
|
||||
})(DirtyType = es.DirtyType || (es.DirtyType = {}));
|
||||
var Transform = (function () {
|
||||
var Transform = (function (_super) {
|
||||
__extends(Transform, _super);
|
||||
function Transform(entity) {
|
||||
this._localTransform = es.Matrix2D.create();
|
||||
this._worldTransform = es.Matrix2D.create().identity();
|
||||
this._worldToLocalTransform = es.Matrix2D.create().identity();
|
||||
this._worldInverseTransform = es.Matrix2D.create().identity();
|
||||
this._rotationMatrix = es.Matrix2D.create();
|
||||
this._translationMatrix = es.Matrix2D.create();
|
||||
this._scaleMatrix = es.Matrix2D.create();
|
||||
this._position = es.Vector2.zero;
|
||||
this._scale = es.Vector2.one;
|
||||
this._rotation = 0;
|
||||
this._localPosition = es.Vector2.zero;
|
||||
this._localScale = es.Vector2.one;
|
||||
this._localRotation = 0;
|
||||
this.entity = entity;
|
||||
this.scale = es.Vector2.one;
|
||||
this._children = [];
|
||||
var _this = _super.call(this) || this;
|
||||
_this._localTransform = es.Matrix2D.create();
|
||||
_this._worldTransform = es.Matrix2D.create().identity();
|
||||
_this._worldToLocalTransform = es.Matrix2D.create().identity();
|
||||
_this._worldInverseTransform = es.Matrix2D.create().identity();
|
||||
_this._rotationMatrix = es.Matrix2D.create();
|
||||
_this._translationMatrix = es.Matrix2D.create();
|
||||
_this._scaleMatrix = es.Matrix2D.create();
|
||||
_this._position = es.Vector2.zero;
|
||||
_this._scale = es.Vector2.one;
|
||||
_this._rotation = 0;
|
||||
_this._localPosition = es.Vector2.zero;
|
||||
_this._localScale = es.Vector2.one;
|
||||
_this._localRotation = 0;
|
||||
_this.entity = entity;
|
||||
_this.scale = es.Vector2.one;
|
||||
_this._children = [];
|
||||
return _this;
|
||||
}
|
||||
Object.defineProperty(Transform.prototype, "parent", {
|
||||
get: function () {
|
||||
@@ -1958,7 +1968,7 @@ var es;
|
||||
return this._children[index];
|
||||
};
|
||||
Transform.prototype.setParent = function (parent) {
|
||||
if (this._parent == parent)
|
||||
if (this._parent.equals(parent))
|
||||
return this;
|
||||
if (!this._parent) {
|
||||
this._parent._children.remove(this);
|
||||
@@ -1970,7 +1980,7 @@ var es;
|
||||
};
|
||||
Transform.prototype.setPosition = function (x, y) {
|
||||
var position = new es.Vector2(x, y);
|
||||
if (position == this._position)
|
||||
if (position.equals(this._position))
|
||||
return this;
|
||||
this._position = position;
|
||||
if (this.parent) {
|
||||
@@ -1983,7 +1993,7 @@ var es;
|
||||
return this;
|
||||
};
|
||||
Transform.prototype.setLocalPosition = function (localPosition) {
|
||||
if (localPosition == this._localPosition)
|
||||
if (localPosition.equals(this._localPosition))
|
||||
return this;
|
||||
this._localPosition = localPosition;
|
||||
this._localDirty = this._positionDirty = this._localPositionDirty = this._localRotationDirty = this._localScaleDirty = true;
|
||||
@@ -2108,8 +2118,11 @@ var es;
|
||||
Transform.prototype.toString = function () {
|
||||
return "[Transform: parent: " + this.parent + ", position: " + this.position + ", rotation: " + this.rotation + ",\n scale: " + this.scale + ", localPosition: " + this._localPosition + ", localRotation: " + this._localRotation + ",\n localScale: " + this._localScale + "]";
|
||||
};
|
||||
Transform.prototype.equals = function (other) {
|
||||
return other.hashCode == this.hashCode;
|
||||
};
|
||||
return Transform;
|
||||
}());
|
||||
}(HashObject));
|
||||
es.Transform = Transform;
|
||||
})(es || (es = {}));
|
||||
var es;
|
||||
@@ -2227,7 +2240,7 @@ var es;
|
||||
var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
|
||||
this._bounds.location = new es.Vector2(minX, minY);
|
||||
this._bounds.width = maxX - minX;
|
||||
this._bounds.height = maxX - minY;
|
||||
this._bounds.height = maxY - minY;
|
||||
}
|
||||
else {
|
||||
this._bounds.location = topLeft;
|
||||
@@ -2499,6 +2512,7 @@ var es;
|
||||
__extends(RenderableComponent, _super);
|
||||
function RenderableComponent() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.displayObject = new egret.DisplayObject();
|
||||
_this.color = 0x000000;
|
||||
_this._localOffset = es.Vector2.zero;
|
||||
_this._renderLayer = 0;
|
||||
@@ -2570,8 +2584,10 @@ var es;
|
||||
this._areBoundsDirty = true;
|
||||
};
|
||||
RenderableComponent.prototype.onBecameVisible = function () {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
};
|
||||
RenderableComponent.prototype.onBecameInvisible = function () {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
};
|
||||
RenderableComponent.prototype.isVisibleFromCamera = function (camera) {
|
||||
this.isVisible = camera.bounds.intersects(this.bounds);
|
||||
@@ -2596,6 +2612,13 @@ var es;
|
||||
}
|
||||
return this;
|
||||
};
|
||||
RenderableComponent.prototype.sync = function (camera) {
|
||||
this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x;
|
||||
this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y;
|
||||
this.displayObject.scaleX = this.entity.scale.x;
|
||||
this.displayObject.scaleY = this.entity.scale.y;
|
||||
this.displayObject.rotation = this.entity.rotation;
|
||||
};
|
||||
RenderableComponent.prototype.toString = function () {
|
||||
return "[RenderableComponent] renderLayer: " + this.renderLayer;
|
||||
};
|
||||
@@ -2626,6 +2649,7 @@ var es;
|
||||
})(es || (es = {}));
|
||||
var es;
|
||||
(function (es) {
|
||||
var Bitmap = egret.Bitmap;
|
||||
var SpriteRenderer = (function (_super) {
|
||||
__extends(SpriteRenderer, _super);
|
||||
function SpriteRenderer(sprite) {
|
||||
@@ -2644,8 +2668,8 @@ var es;
|
||||
this._bounds.calculateBounds(this.entity.transform.position, this._localOffset, this._origin, this.entity.transform.scale, this.entity.transform.rotation, this._sprite.sourceRect.width, this._sprite.sourceRect.height);
|
||||
this._areBoundsDirty = false;
|
||||
}
|
||||
return this._bounds;
|
||||
}
|
||||
return this._bounds;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
@@ -2684,12 +2708,17 @@ var es;
|
||||
this._sprite = sprite;
|
||||
if (this._sprite) {
|
||||
this._origin = this._sprite.origin;
|
||||
this.displayObject.anchorOffsetX = this._origin.x;
|
||||
this.displayObject.anchorOffsetY = this._origin.y;
|
||||
}
|
||||
this.displayObject = new Bitmap(sprite.texture2D);
|
||||
return this;
|
||||
};
|
||||
SpriteRenderer.prototype.setOrigin = function (origin) {
|
||||
if (this._origin != origin) {
|
||||
this._origin = origin;
|
||||
this.displayObject.anchorOffsetX = this._origin.x;
|
||||
this.displayObject.anchorOffsetY = this._origin.y;
|
||||
this._areBoundsDirty = true;
|
||||
}
|
||||
return this;
|
||||
@@ -2699,6 +2728,7 @@ var es;
|
||||
return this;
|
||||
};
|
||||
SpriteRenderer.prototype.render = function (camera) {
|
||||
this.sync(camera);
|
||||
};
|
||||
return SpriteRenderer;
|
||||
}(es.RenderableComponent));
|
||||
@@ -2942,10 +2972,9 @@ var es;
|
||||
Mover.prototype.onAddedToEntity = function () {
|
||||
this._triggerHelper = new es.ColliderTriggerHelper(this.entity);
|
||||
};
|
||||
Mover.prototype.calculateMovement = function (motion) {
|
||||
var collisionResult = new es.CollisionResult();
|
||||
Mover.prototype.calculateMovement = function (motion, collisionResult) {
|
||||
if (!this.entity.getComponent(es.Collider) || !this._triggerHelper) {
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
var colliders = this.entity.getComponents(es.Collider);
|
||||
for (var i = 0; i < colliders.length; i++) {
|
||||
@@ -2955,36 +2984,32 @@ var es;
|
||||
var bounds = collider.bounds;
|
||||
bounds.x += motion.x;
|
||||
bounds.y += motion.y;
|
||||
var boxcastResult = es.Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers);
|
||||
bounds = boxcastResult.bounds;
|
||||
var neighbors = boxcastResult.tempHashSet;
|
||||
var neighbors = es.Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers);
|
||||
for (var j = 0; j < neighbors.length; j++) {
|
||||
var neighbor = neighbors[j];
|
||||
if (neighbor.isTrigger)
|
||||
continue;
|
||||
var _internalcollisionResult = collider.collidesWith(neighbor, motion);
|
||||
if (_internalcollisionResult) {
|
||||
motion = es.Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector);
|
||||
if (_internalcollisionResult.collider) {
|
||||
var _internalcollisionResult = new es.CollisionResult();
|
||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
||||
motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
||||
if (_internalcollisionResult.collider != null) {
|
||||
collisionResult = _internalcollisionResult;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
es.ListPool.free(colliders);
|
||||
return { collisionResult: collisionResult, motion: motion };
|
||||
return collisionResult.collider != null;
|
||||
};
|
||||
Mover.prototype.applyMovement = function (motion) {
|
||||
this.entity.position = es.Vector2.add(this.entity.position, motion);
|
||||
if (this._triggerHelper)
|
||||
this._triggerHelper.update();
|
||||
};
|
||||
Mover.prototype.move = function (motion) {
|
||||
var movementResult = this.calculateMovement(motion);
|
||||
var collisionResult = movementResult.collisionResult;
|
||||
motion = movementResult.motion;
|
||||
Mover.prototype.move = function (motion, collisionResult) {
|
||||
this.calculateMovement(motion, collisionResult);
|
||||
this.applyMovement(motion);
|
||||
return collisionResult;
|
||||
return collisionResult.collider != null;
|
||||
};
|
||||
return Mover;
|
||||
}(es.Component));
|
||||
@@ -3010,8 +3035,8 @@ var es;
|
||||
var didCollide = false;
|
||||
this.entity.position = es.Vector2.add(this.entity.position, motion);
|
||||
var neighbors = es.Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
|
||||
for (var i = 0; i < neighbors.colliders.length; i++) {
|
||||
var neighbor = neighbors.colliders[i];
|
||||
for (var i = 0; i < neighbors.length; i++) {
|
||||
var neighbor = neighbors[i];
|
||||
if (this._collider.overlaps(neighbor) && neighbor.enabled) {
|
||||
didCollide = true;
|
||||
this.notifyTriggerListeners(this._collider, neighbor);
|
||||
@@ -3171,14 +3196,14 @@ var es;
|
||||
Collider.prototype.overlaps = function (other) {
|
||||
return this.shape.overlaps(other.shape);
|
||||
};
|
||||
Collider.prototype.collidesWith = function (collider, motion) {
|
||||
Collider.prototype.collidesWith = function (collider, motion, result) {
|
||||
var oldPosition = this.entity.position;
|
||||
this.entity.position = es.Vector2.add(this.entity.position, motion);
|
||||
var result = this.shape.collidesWithShape(collider.shape);
|
||||
if (result)
|
||||
this.entity.position.add(motion);
|
||||
var didCollide = this.shape.collidesWithShape(collider.shape, result);
|
||||
if (didCollide)
|
||||
result.collider = collider;
|
||||
this.entity.position = oldPosition;
|
||||
return result;
|
||||
return didCollide;
|
||||
};
|
||||
Collider.prototype.clone = function () {
|
||||
var collider = ObjectUtils.clone(this);
|
||||
@@ -3601,8 +3626,10 @@ var es;
|
||||
ComponentList.prototype.deregisterAllComponents = function () {
|
||||
for (var i = 0; i < this._components.length; i++) {
|
||||
var component = this._components[i];
|
||||
if (component instanceof es.RenderableComponent)
|
||||
if (component instanceof es.RenderableComponent) {
|
||||
this._entity.scene.removeChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
}
|
||||
this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
}
|
||||
@@ -3610,8 +3637,10 @@ var es;
|
||||
ComponentList.prototype.registerAllComponents = function () {
|
||||
for (var i = 0; i < this._components.length; i++) {
|
||||
var component = this._components[i];
|
||||
if (component instanceof es.RenderableComponent)
|
||||
if (component instanceof es.RenderableComponent) {
|
||||
this._entity.scene.addChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
}
|
||||
this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
}
|
||||
@@ -3627,8 +3656,10 @@ var es;
|
||||
if (this._componentsToAdd.length > 0) {
|
||||
for (var i = 0, count = this._componentsToAdd.length; i < count; i++) {
|
||||
var component = this._componentsToAdd[i];
|
||||
if (component instanceof es.RenderableComponent)
|
||||
if (component instanceof es.RenderableComponent) {
|
||||
this._entity.scene.addChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
}
|
||||
this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
this._components.push(component);
|
||||
@@ -3651,8 +3682,10 @@ var es;
|
||||
}
|
||||
};
|
||||
ComponentList.prototype.handleRemove = function (component) {
|
||||
if (component instanceof es.RenderableComponent)
|
||||
if (component instanceof es.RenderableComponent) {
|
||||
this._entity.scene.removeChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
}
|
||||
this._entity.componentBits.set(es.ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
component.onRemovedFromEntity();
|
||||
@@ -4909,15 +4942,23 @@ var es;
|
||||
var es;
|
||||
(function (es) {
|
||||
var Renderer = (function () {
|
||||
function Renderer() {
|
||||
function Renderer(renderOrder, camera) {
|
||||
if (camera === void 0) { camera = null; }
|
||||
this.renderOrder = 0;
|
||||
this.camera = camera;
|
||||
this.renderOrder = renderOrder;
|
||||
}
|
||||
Renderer.prototype.onAddedToScene = function (scene) { };
|
||||
Renderer.prototype.beginRender = function (cam) {
|
||||
};
|
||||
Renderer.prototype.unload = function () { };
|
||||
Renderer.prototype.beginRender = function (cam) { };
|
||||
Renderer.prototype.renderAfterStateCheck = function (renderable, cam) {
|
||||
renderable.render(cam);
|
||||
};
|
||||
Renderer.prototype.onSceneBackBufferSizeChanged = function (newWidth, newHeight) {
|
||||
};
|
||||
Renderer.prototype.compareTo = function (other) {
|
||||
return this.renderOrder - other.renderOrder;
|
||||
};
|
||||
return Renderer;
|
||||
}());
|
||||
es.Renderer = Renderer;
|
||||
@@ -4927,7 +4968,7 @@ var es;
|
||||
var DefaultRenderer = (function (_super) {
|
||||
__extends(DefaultRenderer, _super);
|
||||
function DefaultRenderer() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
return _super.call(this, 0, null) || this;
|
||||
}
|
||||
DefaultRenderer.prototype.render = function (scene) {
|
||||
var cam = this.camera ? this.camera : scene.camera;
|
||||
@@ -5567,8 +5608,8 @@ var es;
|
||||
Rectangle.fromMinMax = function (minX, minY, maxX, maxY) {
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
};
|
||||
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) {
|
||||
var edgeNormal = es.Vector2.zero;
|
||||
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point, edgeNormal) {
|
||||
edgeNormal = es.Vector2.zero;
|
||||
var res = new es.Vector2();
|
||||
res.x = es.MathHelper.clamp(point.x, this.left, this.right);
|
||||
res.y = es.MathHelper.clamp(point.y, this.top, this.bottom);
|
||||
@@ -5605,7 +5646,7 @@ var es;
|
||||
if (res.y == this.bottom)
|
||||
edgeNormal.y = 1;
|
||||
}
|
||||
return { res: res, edgeNormal: edgeNormal };
|
||||
return res;
|
||||
};
|
||||
Rectangle.prototype.getClosestPointOnBoundsToOrigin = function () {
|
||||
var max = this.max;
|
||||
@@ -5688,9 +5729,7 @@ var es;
|
||||
var colliders = this._entity.getComponents(es.Collider);
|
||||
for (var i = 0; i < colliders.length; i++) {
|
||||
var collider = colliders[i];
|
||||
var boxcastResult = es.Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
|
||||
collider.bounds = boxcastResult.rect;
|
||||
var neighbors = boxcastResult.colliders;
|
||||
var neighbors = es.Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
|
||||
var _loop_5 = function (j) {
|
||||
var neighbor = neighbors[j];
|
||||
if (!collider.isTrigger && !neighbor.isTrigger)
|
||||
@@ -5914,12 +5953,15 @@ var es;
|
||||
};
|
||||
Physics.overlapCircleAll = function (center, randius, results, layerMask) {
|
||||
if (layerMask === void 0) { layerMask = -1; }
|
||||
if (results.length == 0) {
|
||||
console.error("An empty results array was passed in. No results will ever be returned.");
|
||||
return;
|
||||
}
|
||||
return this._spatialHash.overlapCircle(center, randius, results, layerMask);
|
||||
};
|
||||
Physics.boxcastBroadphase = function (rect, layerMask) {
|
||||
if (layerMask === void 0) { layerMask = this.allLayers; }
|
||||
var boxcastResult = this._spatialHash.aabbBroadphase(rect, null, layerMask);
|
||||
return { colliders: boxcastResult.tempHashSet, rect: boxcastResult.bounds };
|
||||
return this._spatialHash.aabbBroadphase(rect, null, layerMask);
|
||||
};
|
||||
Physics.boxcastBroadphaseExcludingSelf = function (collider, rect, layerMask) {
|
||||
if (layerMask === void 0) { layerMask = this.allLayers; }
|
||||
@@ -6026,9 +6068,9 @@ var es;
|
||||
}
|
||||
return new es.Vector2(x / points.length, y / points.length);
|
||||
};
|
||||
Polygon.getClosestPointOnPolygonToPoint = function (points, point) {
|
||||
var distanceSquared = Number.MAX_VALUE;
|
||||
var edgeNormal = new es.Vector2(0, 0);
|
||||
Polygon.getClosestPointOnPolygonToPoint = function (points, point, distanceSquared, edgeNormal) {
|
||||
distanceSquared = Number.MAX_VALUE;
|
||||
edgeNormal = new es.Vector2(0, 0);
|
||||
var closestPoint = new es.Vector2(0, 0);
|
||||
var tempDistanceSquared;
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
@@ -6044,8 +6086,8 @@ var es;
|
||||
edgeNormal = new es.Vector2(-line.y, line.x);
|
||||
}
|
||||
}
|
||||
edgeNormal = es.Vector2.normalize(edgeNormal);
|
||||
return { closestPoint: closestPoint, distanceSquared: distanceSquared, edgeNormal: edgeNormal };
|
||||
es.Vector2Ext.normalize(edgeNormal);
|
||||
return closestPoint;
|
||||
};
|
||||
Polygon.prototype.recalculateBounds = function (collider) {
|
||||
this.center = collider.localOffset;
|
||||
@@ -6079,12 +6121,11 @@ var es;
|
||||
this.bounds.location = es.Vector2.add(this.bounds.location, this.position);
|
||||
};
|
||||
Polygon.prototype.overlaps = function (other) {
|
||||
var result;
|
||||
var result = new es.CollisionResult();
|
||||
if (other instanceof Polygon)
|
||||
return es.ShapeCollisions.polygonToPolygon(this, other);
|
||||
return es.ShapeCollisions.polygonToPolygon(this, other, result);
|
||||
if (other instanceof es.Circle) {
|
||||
result = es.ShapeCollisions.circleToPolygon(other, this);
|
||||
if (result) {
|
||||
if (es.ShapeCollisions.circleToPolygon(other, this, result)) {
|
||||
result.invertResult();
|
||||
return true;
|
||||
}
|
||||
@@ -6092,18 +6133,16 @@ var es;
|
||||
}
|
||||
throw new Error("overlaps of Pologon to " + other + " are not supported");
|
||||
};
|
||||
Polygon.prototype.collidesWithShape = function (other) {
|
||||
var result = new es.CollisionResult();
|
||||
Polygon.prototype.collidesWithShape = function (other, result) {
|
||||
if (other instanceof Polygon) {
|
||||
return es.ShapeCollisions.polygonToPolygon(this, other);
|
||||
return es.ShapeCollisions.polygonToPolygon(this, other, result);
|
||||
}
|
||||
if (other instanceof es.Circle) {
|
||||
result = es.ShapeCollisions.circleToPolygon(other, this);
|
||||
if (result) {
|
||||
if (es.ShapeCollisions.circleToPolygon(other, this, result)) {
|
||||
result.invertResult();
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
throw new Error("overlaps of Polygon to " + other + " are not supported");
|
||||
};
|
||||
@@ -6119,8 +6158,8 @@ var es;
|
||||
}
|
||||
return isInside;
|
||||
};
|
||||
Polygon.prototype.pointCollidesWithShape = function (point) {
|
||||
return es.ShapeCollisions.pointToPoly(point, this);
|
||||
Polygon.prototype.pointCollidesWithShape = function (point, result) {
|
||||
return es.ShapeCollisions.pointToPoly(point, this, result);
|
||||
};
|
||||
return Polygon;
|
||||
}(es.Shape));
|
||||
@@ -6167,11 +6206,11 @@ var es;
|
||||
}
|
||||
return _super.prototype.overlaps.call(this, other);
|
||||
};
|
||||
Box.prototype.collidesWithShape = function (other) {
|
||||
Box.prototype.collidesWithShape = function (other, result) {
|
||||
if (other instanceof Box && other.isUnrotated) {
|
||||
return es.ShapeCollisions.boxToBox(this, other);
|
||||
return es.ShapeCollisions.boxToBox(this, other, result);
|
||||
}
|
||||
return _super.prototype.collidesWithShape.call(this, other);
|
||||
return _super.prototype.collidesWithShape.call(this, other, result);
|
||||
};
|
||||
Box.prototype.containsPoint = function (point) {
|
||||
if (this.isUnrotated)
|
||||
@@ -6209,28 +6248,29 @@ var es;
|
||||
this.bounds = new es.Rectangle(this.position.x - this.radius, this.position.y - this.radius, this.radius * 2, this.radius * 2);
|
||||
};
|
||||
Circle.prototype.overlaps = function (other) {
|
||||
var result = new es.CollisionResult();
|
||||
if (other instanceof es.Box && other.isUnrotated)
|
||||
return es.Collisions.isRectToCircle(other.bounds, this.position, this.radius);
|
||||
if (other instanceof Circle)
|
||||
return es.Collisions.isCircleToCircle(this.position, this.radius, other.position, other.radius);
|
||||
if (other instanceof es.Polygon)
|
||||
return es.ShapeCollisions.circleToPolygon(this, other);
|
||||
return es.ShapeCollisions.circleToPolygon(this, other, result);
|
||||
throw new Error("overlaps of circle to " + other + " are not supported");
|
||||
};
|
||||
Circle.prototype.collidesWithShape = function (other) {
|
||||
Circle.prototype.collidesWithShape = function (other, result) {
|
||||
if (other instanceof es.Box && other.isUnrotated) {
|
||||
return es.ShapeCollisions.circleToBox(this, other);
|
||||
return es.ShapeCollisions.circleToBox(this, other, result);
|
||||
}
|
||||
if (other instanceof Circle) {
|
||||
return es.ShapeCollisions.circleToCircle(this, other);
|
||||
return es.ShapeCollisions.circleToCircle(this, other, result);
|
||||
}
|
||||
if (other instanceof es.Polygon) {
|
||||
return es.ShapeCollisions.circleToPolygon(this, other);
|
||||
return es.ShapeCollisions.circleToPolygon(this, other, result);
|
||||
}
|
||||
throw new Error("Collisions of Circle to " + other + " are not supported");
|
||||
};
|
||||
Circle.prototype.pointCollidesWithShape = function (point) {
|
||||
return es.ShapeCollisions.pointToCircle(point, this);
|
||||
Circle.prototype.pointCollidesWithShape = function (point, result) {
|
||||
return es.ShapeCollisions.pointToCircle(point, this, result);
|
||||
};
|
||||
return Circle;
|
||||
}(es.Shape));
|
||||
@@ -6257,8 +6297,7 @@ var es;
|
||||
var ShapeCollisions = (function () {
|
||||
function ShapeCollisions() {
|
||||
}
|
||||
ShapeCollisions.polygonToPolygon = function (first, second) {
|
||||
var result = new es.CollisionResult();
|
||||
ShapeCollisions.polygonToPolygon = function (first, second, result) {
|
||||
var isIntersecting = true;
|
||||
var firstEdges = first.edgeNormals;
|
||||
var secondEdges = second.edgeNormals;
|
||||
@@ -6291,7 +6330,7 @@ var es;
|
||||
if (intervalDist > 0)
|
||||
isIntersecting = false;
|
||||
if (!isIntersecting)
|
||||
return null;
|
||||
return false;
|
||||
intervalDist = Math.abs(intervalDist);
|
||||
if (intervalDist < minIntervalDistance) {
|
||||
minIntervalDistance = intervalDist;
|
||||
@@ -6302,7 +6341,7 @@ var es;
|
||||
}
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-translationAxis.x, -translationAxis.y), new es.Vector2(minIntervalDistance));
|
||||
return result;
|
||||
return true;
|
||||
};
|
||||
ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) {
|
||||
if (minA < minB)
|
||||
@@ -6323,16 +6362,13 @@ var es;
|
||||
}
|
||||
return { min: min, max: max };
|
||||
};
|
||||
ShapeCollisions.circleToPolygon = function (circle, polygon) {
|
||||
var result = new es.CollisionResult();
|
||||
ShapeCollisions.circleToPolygon = function (circle, polygon, result) {
|
||||
var poly2Circle = es.Vector2.subtract(circle.position, polygon.position);
|
||||
var gpp = es.Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle);
|
||||
var closestPoint = gpp.closestPoint;
|
||||
var distanceSquared = gpp.distanceSquared;
|
||||
result.normal = gpp.edgeNormal;
|
||||
var distanceSquared = 0;
|
||||
var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
||||
var circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
||||
if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly)
|
||||
return null;
|
||||
return false;
|
||||
var mtv;
|
||||
if (circleCenterInsidePoly) {
|
||||
mtv = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared) - circle.radius));
|
||||
@@ -6348,16 +6384,15 @@ var es;
|
||||
}
|
||||
result.minimumTranslationVector = mtv;
|
||||
result.point = es.Vector2.add(closestPoint, polygon.position);
|
||||
return result;
|
||||
return true;
|
||||
};
|
||||
ShapeCollisions.circleToBox = function (circle, box) {
|
||||
var result = new es.CollisionResult();
|
||||
var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position).res;
|
||||
ShapeCollisions.circleToBox = function (circle, box, result) {
|
||||
var closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
||||
if (box.containsPoint(circle.position)) {
|
||||
result.point = closestPointOnBounds;
|
||||
var safePlace = es.Vector2.add(closestPointOnBounds, es.Vector2.subtract(result.normal, new es.Vector2(circle.radius)));
|
||||
result.minimumTranslationVector = es.Vector2.subtract(circle.position, safePlace);
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
var sqrDistance = es.Vector2.distanceSquared(closestPointOnBounds, circle.position);
|
||||
if (sqrDistance == 0) {
|
||||
@@ -6366,14 +6401,14 @@ var es;
|
||||
else if (sqrDistance <= circle.radius * circle.radius) {
|
||||
result.normal = es.Vector2.subtract(circle.position, closestPointOnBounds);
|
||||
var depth = result.normal.length() - circle.radius;
|
||||
result.normal = es.Vector2Ext.normalize(result.normal);
|
||||
result.point = closestPointOnBounds;
|
||||
es.Vector2Ext.normalize(result.normal);
|
||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(depth), result.normal);
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
};
|
||||
ShapeCollisions.pointToCircle = function (point, circle) {
|
||||
var result = new es.CollisionResult();
|
||||
ShapeCollisions.pointToCircle = function (point, circle, result) {
|
||||
var distanceSquared = es.Vector2.distanceSquared(point, circle.position);
|
||||
var sumOfRadii = 1 + circle.radius;
|
||||
var collided = distanceSquared < sumOfRadii * sumOfRadii;
|
||||
@@ -6382,9 +6417,9 @@ var es;
|
||||
var depth = sumOfRadii - Math.sqrt(distanceSquared);
|
||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth, -depth), result.normal);
|
||||
result.point = es.Vector2.add(circle.position, es.Vector2.multiply(result.normal, new es.Vector2(circle.radius, circle.radius)));
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
};
|
||||
ShapeCollisions.closestPointOnLine = function (lineA, lineB, closestTo) {
|
||||
var v = es.Vector2.subtract(lineB, lineA);
|
||||
@@ -6393,22 +6428,17 @@ var es;
|
||||
t = es.MathHelper.clamp(t, 0, 1);
|
||||
return es.Vector2.add(lineA, es.Vector2.multiply(v, new es.Vector2(t, t)));
|
||||
};
|
||||
ShapeCollisions.pointToPoly = function (point, poly) {
|
||||
var result = new es.CollisionResult();
|
||||
ShapeCollisions.pointToPoly = function (point, poly, result) {
|
||||
if (poly.containsPoint(point)) {
|
||||
var distanceSquared = void 0;
|
||||
var gpp = es.Polygon.getClosestPointOnPolygonToPoint(poly.points, es.Vector2.subtract(point, poly.position));
|
||||
var closestPoint = gpp.closestPoint;
|
||||
distanceSquared = gpp.distanceSquared;
|
||||
result.normal = gpp.edgeNormal;
|
||||
var distanceSquared = 0;
|
||||
var closestPoint = es.Polygon.getClosestPointOnPolygonToPoint(poly.points, es.Vector2.subtract(point, poly.position), distanceSquared, result.normal);
|
||||
result.minimumTranslationVector = es.Vector2.multiply(result.normal, new es.Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared)));
|
||||
result.point = es.Vector2.add(closestPoint, poly.position);
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
};
|
||||
ShapeCollisions.circleToCircle = function (first, second) {
|
||||
var result = new es.CollisionResult();
|
||||
ShapeCollisions.circleToCircle = function (first, second, result) {
|
||||
var distanceSquared = es.Vector2.distanceSquared(first.position, second.position);
|
||||
var sumOfRadii = first.radius + second.radius;
|
||||
var collided = distanceSquared < sumOfRadii * sumOfRadii;
|
||||
@@ -6417,22 +6447,21 @@ var es;
|
||||
var depth = sumOfRadii - Math.sqrt(distanceSquared);
|
||||
result.minimumTranslationVector = es.Vector2.multiply(new es.Vector2(-depth), result.normal);
|
||||
result.point = es.Vector2.add(second.position, es.Vector2.multiply(result.normal, new es.Vector2(second.radius)));
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
};
|
||||
ShapeCollisions.boxToBox = function (first, second) {
|
||||
var result = new es.CollisionResult();
|
||||
ShapeCollisions.boxToBox = function (first, second, result) {
|
||||
var minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(0, 0)) {
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
|
||||
return null;
|
||||
if (result.minimumTranslationVector.equals(es.Vector2.zero))
|
||||
return false;
|
||||
result.normal = new es.Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
return null;
|
||||
return false;
|
||||
};
|
||||
ShapeCollisions.minkowskiDifference = function (first, second) {
|
||||
var positionOffset = es.Vector2.subtract(first.position, es.Vector2.add(first.bounds.location, es.Vector2.divide(first.bounds.size, new es.Vector2(2))));
|
||||
@@ -6544,16 +6573,14 @@ var es;
|
||||
}
|
||||
}
|
||||
}
|
||||
return { tempHashSet: this._tempHashSet, bounds: bounds };
|
||||
return this._tempHashSet;
|
||||
};
|
||||
SpatialHash.prototype.overlapCircle = function (circleCenter, radius, results, layerMask) {
|
||||
var bounds = new es.Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
|
||||
this._overlapTestCircle.radius = radius;
|
||||
this._overlapTestCircle.position = circleCenter;
|
||||
var resultCounter = 0;
|
||||
var aabbBroadphaseResult = this.aabbBroadphase(bounds, null, layerMask);
|
||||
bounds = aabbBroadphaseResult.bounds;
|
||||
var potentials = aabbBroadphaseResult.tempHashSet;
|
||||
var potentials = this.aabbBroadphase(bounds, null, layerMask);
|
||||
for (var i = 0; i < potentials.length; i++) {
|
||||
var collider = potentials[i];
|
||||
if (collider instanceof es.BoxCollider) {
|
||||
|
||||
2
source/bin/framework.min.js
vendored
2
source/bin/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -122,7 +122,7 @@ module es {
|
||||
|
||||
this._bounds.location = new Vector2(minX, minY);
|
||||
this._bounds.width = maxX - minX;
|
||||
this._bounds.height = maxX - minY;
|
||||
this._bounds.height = maxY - minY;
|
||||
} else {
|
||||
this._bounds.location = topLeft;
|
||||
this._bounds.width = bottomRight.x - topLeft.x;
|
||||
|
||||
@@ -205,7 +205,7 @@ module es {
|
||||
* 检查这个形状是否与物理系统中的其他对撞机重叠
|
||||
* @param other
|
||||
*/
|
||||
public overlaps(other: Collider) {
|
||||
public overlaps(other: Collider): boolean {
|
||||
return this.shape.overlaps(other.shape);
|
||||
}
|
||||
|
||||
@@ -213,20 +213,21 @@ module es {
|
||||
* 检查这个与运动应用的碰撞器(移动向量)是否与碰撞器碰撞。如果是这样,将返回true,并且结果将填充碰撞数据。
|
||||
* @param collider
|
||||
* @param motion
|
||||
* @param result
|
||||
*/
|
||||
public collidesWith(collider: Collider, motion: Vector2) {
|
||||
public collidesWith(collider: Collider, motion: Vector2, result: CollisionResult): boolean {
|
||||
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
|
||||
let oldPosition = this.entity.position;
|
||||
this.entity.position = Vector2.add(this.entity.position, motion);
|
||||
this.entity.position.add(motion);
|
||||
|
||||
let result = this.shape.collidesWithShape(collider.shape);
|
||||
if (result)
|
||||
let didCollide = this.shape.collidesWithShape(collider.shape, result);
|
||||
if (didCollide)
|
||||
result.collider = collider;
|
||||
|
||||
// 将图形位置返回到检查前的位置
|
||||
this.entity.position = oldPosition;
|
||||
|
||||
return result;
|
||||
return didCollide;
|
||||
}
|
||||
|
||||
public clone(): Component{
|
||||
|
||||
@@ -16,12 +16,11 @@ module es {
|
||||
/**
|
||||
* 计算修改运动矢量的运动,以考虑移动时可能发生的碰撞
|
||||
* @param motion
|
||||
* @param collisionResult
|
||||
*/
|
||||
public calculateMovement(motion: Vector2){
|
||||
let collisionResult = new CollisionResult();
|
||||
|
||||
public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean{
|
||||
if (!this.entity.getComponent(Collider) || !this._triggerHelper){
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
// 移动所有的非触发碰撞器并获得最近的碰撞
|
||||
@@ -37,9 +36,7 @@ module es {
|
||||
let bounds = collider.bounds;
|
||||
bounds.x += motion.x;
|
||||
bounds.y += motion.y;
|
||||
let boxcastResult = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers);
|
||||
bounds = boxcastResult.bounds;
|
||||
let neighbors = boxcastResult.tempHashSet;
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers);
|
||||
|
||||
for (let j = 0; j < neighbors.length; j ++){
|
||||
let neighbor = neighbors[j];
|
||||
@@ -47,13 +44,13 @@ module es {
|
||||
if (neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
let _internalcollisionResult = collider.collidesWith(neighbor, motion);
|
||||
if (_internalcollisionResult){
|
||||
let _internalcollisionResult: CollisionResult = new CollisionResult();
|
||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)){
|
||||
// 如果碰撞 则退回之前的移动量
|
||||
motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector);
|
||||
motion.subtract(_internalcollisionResult.minimumTranslationVector);
|
||||
|
||||
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
||||
if (_internalcollisionResult.collider){
|
||||
if (_internalcollisionResult.collider != null){
|
||||
collisionResult = _internalcollisionResult;
|
||||
}
|
||||
}
|
||||
@@ -62,7 +59,7 @@ module es {
|
||||
|
||||
ListPool.free(colliders);
|
||||
|
||||
return {collisionResult: collisionResult, motion: motion};
|
||||
return collisionResult.collider != null;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,15 +78,12 @@ module es {
|
||||
/**
|
||||
* 通过调用calculateMovement和applyMovement来移动考虑碰撞的实体;
|
||||
* @param motion
|
||||
* @param collisionResult
|
||||
*/
|
||||
public move(motion: Vector2){
|
||||
let movementResult = this.calculateMovement(motion);
|
||||
let collisionResult = movementResult.collisionResult;
|
||||
motion = movementResult.motion;
|
||||
|
||||
public move(motion: Vector2, collisionResult: CollisionResult){
|
||||
this.calculateMovement(motion, collisionResult);
|
||||
this.applyMovement(motion);
|
||||
|
||||
return collisionResult;
|
||||
return collisionResult.collider != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ module es {
|
||||
|
||||
// 获取任何可能在新位置发生碰撞的东西
|
||||
let neighbors = Physics.boxcastBroadphase(this._collider.bounds, this._collider.collidesWithLayers);
|
||||
for (let i = 0; i < neighbors.colliders.length; i ++){
|
||||
let neighbor = neighbors.colliders[i];
|
||||
for (let i = 0; i < neighbors.length; i ++){
|
||||
let neighbor = neighbors[i];
|
||||
if (this._collider.overlaps(neighbor) && neighbor.enabled){
|
||||
didCollide = true;
|
||||
this.notifyTriggerListeners(this._collider, neighbor);
|
||||
|
||||
@@ -4,6 +4,10 @@ module es {
|
||||
* 所有可渲染组件的基类
|
||||
*/
|
||||
export abstract class RenderableComponent extends Component implements IRenderable {
|
||||
/**
|
||||
* 用于装载egret显示对象
|
||||
*/
|
||||
public displayObject: egret.DisplayObject = new egret.DisplayObject();
|
||||
/**
|
||||
* renderableComponent的宽度
|
||||
* 如果你不重写bounds属性则需要实现这个
|
||||
@@ -107,6 +111,7 @@ module es {
|
||||
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
|
||||
*/
|
||||
protected onBecameVisible() {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -114,6 +119,7 @@ module es {
|
||||
* 如果渲染器不适用isVisibleFromCamera进行剔除检查 这些方法不会被调用
|
||||
*/
|
||||
protected onBecameInvisible() {
|
||||
this.displayObject.visible = this.isVisible;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -165,6 +171,17 @@ module es {
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 进行状态同步
|
||||
*/
|
||||
public sync(camera: Camera){
|
||||
this.displayObject.x = this.entity.position.x + this.localOffset.x - camera.position.x + camera.origin.x;
|
||||
this.displayObject.y = this.entity.position.y + this.localOffset.y - camera.position.y + camera.origin.y;
|
||||
this.displayObject.scaleX = this.entity.scale.x;
|
||||
this.displayObject.scaleY = this.entity.scale.y;
|
||||
this.displayObject.rotation = this.entity.rotation;
|
||||
}
|
||||
|
||||
public toString(){
|
||||
return `[RenderableComponent] renderLayer: ${this.renderLayer}`;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
module es {
|
||||
import Bitmap = egret.Bitmap;
|
||||
|
||||
export class SpriteRenderer extends RenderableComponent {
|
||||
public get bounds() {
|
||||
if (this._areBoundsDirty) {
|
||||
@@ -8,9 +10,9 @@ module es {
|
||||
this._sprite.sourceRect.height);
|
||||
this._areBoundsDirty = false;
|
||||
}
|
||||
|
||||
return this._bounds;
|
||||
}
|
||||
|
||||
return this._bounds;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -83,7 +85,10 @@ module es {
|
||||
this._sprite = sprite;
|
||||
if (this._sprite) {
|
||||
this._origin = this._sprite.origin;
|
||||
this.displayObject.anchorOffsetX = this._origin.x;
|
||||
this.displayObject.anchorOffsetY = this._origin.y;
|
||||
}
|
||||
this.displayObject = new Bitmap(sprite.texture2D);
|
||||
|
||||
return this;
|
||||
}
|
||||
@@ -95,6 +100,8 @@ module es {
|
||||
public setOrigin(origin: Vector2): SpriteRenderer {
|
||||
if (this._origin != origin) {
|
||||
this._origin = origin;
|
||||
this.displayObject.anchorOffsetX = this._origin.x;
|
||||
this.displayObject.anchorOffsetY = this._origin.y;
|
||||
this._areBoundsDirty = true;
|
||||
}
|
||||
|
||||
@@ -113,7 +120,7 @@ module es {
|
||||
}
|
||||
|
||||
public render(camera: Camera) {
|
||||
// TODO: render
|
||||
this.sync(camera);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,8 +81,8 @@ module es {
|
||||
this.addEventListener(egret.Event.RESIZE, this.onGraphicsDeviceReset, this);
|
||||
this.addEventListener(egret.StageOrientationEvent.ORIENTATION_CHANGE, this.onOrientationChanged, this);
|
||||
this.addEventListener(egret.Event.ENTER_FRAME, this.update, this);
|
||||
this.addEventListener(egret.Event.RENDER, this.draw, this);
|
||||
|
||||
Input.initialize();
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
@@ -135,6 +135,8 @@ module es {
|
||||
}
|
||||
|
||||
// this.endDebugUpdate();
|
||||
|
||||
await this.draw();
|
||||
}
|
||||
|
||||
public async draw() {
|
||||
|
||||
@@ -7,6 +7,8 @@ module transform {
|
||||
}
|
||||
|
||||
module es {
|
||||
import HashObject = egret.HashObject;
|
||||
|
||||
export enum DirtyType {
|
||||
clean,
|
||||
positionDirty,
|
||||
@@ -14,7 +16,7 @@ module es {
|
||||
rotationDirty,
|
||||
}
|
||||
|
||||
export class Transform {
|
||||
export class Transform extends HashObject {
|
||||
/** 与此转换关联的实体 */
|
||||
public readonly entity: Entity;
|
||||
/**
|
||||
@@ -243,6 +245,7 @@ module es {
|
||||
public _children: Transform[];
|
||||
|
||||
constructor(entity: Entity) {
|
||||
super();
|
||||
this.entity = entity;
|
||||
this.scale = Vector2.one;
|
||||
this._children = [];
|
||||
@@ -261,7 +264,7 @@ module es {
|
||||
* @param parent
|
||||
*/
|
||||
public setParent(parent: Transform): Transform {
|
||||
if (this._parent == parent)
|
||||
if (this._parent.equals(parent))
|
||||
return this;
|
||||
|
||||
if (!this._parent) {
|
||||
@@ -282,7 +285,7 @@ module es {
|
||||
*/
|
||||
public setPosition(x: number, y: number): Transform {
|
||||
let position = new Vector2(x, y);
|
||||
if (position == this._position)
|
||||
if (position.equals(this._position))
|
||||
return this;
|
||||
|
||||
this._position = position;
|
||||
@@ -301,7 +304,7 @@ module es {
|
||||
* @param localPosition
|
||||
*/
|
||||
public setLocalPosition(localPosition: Vector2): Transform {
|
||||
if (localPosition == this._localPosition)
|
||||
if (localPosition.equals(this._localPosition))
|
||||
return this;
|
||||
|
||||
this._localPosition = localPosition;
|
||||
@@ -493,5 +496,9 @@ module es {
|
||||
scale: ${this.scale}, localPosition: ${this._localPosition}, localRotation: ${this._localRotation},
|
||||
localScale: ${this._localScale}]`;
|
||||
}
|
||||
|
||||
public equals(other: Transform){
|
||||
return other.hashCode == this.hashCode;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -76,8 +76,11 @@ module es {
|
||||
let component = this._components[i];
|
||||
|
||||
// 处理渲染层列表
|
||||
if (component instanceof RenderableComponent)
|
||||
if (component instanceof RenderableComponent){
|
||||
this._entity.scene.removeChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
}
|
||||
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
@@ -88,8 +91,10 @@ module es {
|
||||
for (let i = 0; i < this._components.length; i++) {
|
||||
let component = this._components[i];
|
||||
|
||||
if (component instanceof RenderableComponent)
|
||||
if (component instanceof RenderableComponent){
|
||||
this._entity.scene.addChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
}
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
@@ -112,8 +117,11 @@ module es {
|
||||
if (this._componentsToAdd.length > 0) {
|
||||
for (let i = 0, count = this._componentsToAdd.length; i < count; i++) {
|
||||
let component = this._componentsToAdd[i];
|
||||
if (component instanceof RenderableComponent)
|
||||
if (component instanceof RenderableComponent){
|
||||
this._entity.scene.addChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.add(component);
|
||||
}
|
||||
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component));
|
||||
this._entity.scene.entityProcessors.onComponentAdded(this._entity);
|
||||
@@ -148,8 +156,11 @@ module es {
|
||||
|
||||
public handleRemove(component: Component) {
|
||||
// 处理渲染层列表
|
||||
if (component instanceof RenderableComponent)
|
||||
if (component instanceof RenderableComponent){
|
||||
this._entity.scene.removeChild(component.displayObject);
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
}
|
||||
|
||||
|
||||
this._entity.componentBits.set(ComponentTypeManager.getIndexFor(component), false);
|
||||
this._entity.scene.entityProcessors.onComponentRemoved(this._entity);
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
///<reference path="./Renderer.ts" />
|
||||
module es {
|
||||
export class DefaultRenderer extends Renderer {
|
||||
constructor(){
|
||||
super(0, null);
|
||||
}
|
||||
|
||||
public render(scene: Scene) {
|
||||
let cam = this.camera ? this.camera : scene.camera;
|
||||
this.beginRender(cam);
|
||||
|
||||
@@ -9,6 +9,15 @@ module es {
|
||||
* Renderer子类可以选择调用beginRender时使用的摄像头
|
||||
*/
|
||||
public camera: Camera;
|
||||
/**
|
||||
* 指定场景调用渲染器的顺序
|
||||
*/
|
||||
public readonly renderOrder: number = 0;
|
||||
|
||||
protected constructor(renderOrder: number, camera: Camera = null){
|
||||
this.camera = camera;
|
||||
this.renderOrder = renderOrder;
|
||||
}
|
||||
|
||||
/**
|
||||
* 当渲染器被添加到场景时调用
|
||||
@@ -16,17 +25,18 @@ module es {
|
||||
*/
|
||||
public onAddedToScene(scene: Scene){}
|
||||
|
||||
protected beginRender(cam: Camera){
|
||||
|
||||
}
|
||||
/**
|
||||
* 当场景结束或渲染器从场景中移除时调用。使用这个进行清理。
|
||||
*/
|
||||
public unload(){ }
|
||||
|
||||
/**
|
||||
*
|
||||
* @param scene
|
||||
* @param cam
|
||||
*/
|
||||
public abstract render(scene: Scene);
|
||||
protected beginRender(cam: Camera){ }
|
||||
|
||||
public unload(){ }
|
||||
public abstract render(scene: Scene);
|
||||
|
||||
/**
|
||||
*
|
||||
@@ -36,5 +46,18 @@ module es {
|
||||
protected renderAfterStateCheck(renderable: IRenderable, cam: Camera){
|
||||
renderable.render(cam);
|
||||
}
|
||||
|
||||
/**
|
||||
* 当默认场景渲染目标被调整大小和当场景已经开始添加渲染器时调用
|
||||
* @param newWidth
|
||||
* @param newHeight
|
||||
*/
|
||||
public onSceneBackBufferSizeChanged(newWidth: number, newHeight: number){
|
||||
|
||||
}
|
||||
|
||||
public compareTo(other: Renderer): number{
|
||||
return this.renderOrder - other.renderOrder;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -70,9 +70,10 @@ module es {
|
||||
/**
|
||||
* 获取矩形边界上与给定点最近的点
|
||||
* @param point
|
||||
* @param edgeNormal
|
||||
*/
|
||||
public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } {
|
||||
let edgeNormal = Vector2.zero;
|
||||
public getClosestPointOnRectangleBorderToPoint(point: Vector2, edgeNormal: Vector2): Vector2 {
|
||||
edgeNormal = Vector2.zero;
|
||||
|
||||
// 对于每个轴,如果点在盒子外面
|
||||
let res = new Vector2();
|
||||
@@ -107,7 +108,7 @@ module es {
|
||||
if (res.y == this.bottom) edgeNormal.y = 1;
|
||||
}
|
||||
|
||||
return { res: res, edgeNormal: edgeNormal };
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -197,7 +197,8 @@ module es {
|
||||
* @param matrix
|
||||
*/
|
||||
public static transform(position: Vector2, matrix: Matrix2D){
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21) + matrix.m31,
|
||||
(position.x * matrix.m12) + (position.y * matrix.m22) + matrix.m32);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -221,5 +222,9 @@ module es {
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public equals(other: Vector2){
|
||||
return other.x == this.x && other.y == this.y;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,9 +22,7 @@ module es {
|
||||
for (let i = 0; i < colliders.length; i++) {
|
||||
let collider = colliders[i];
|
||||
|
||||
let boxcastResult = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
|
||||
collider.bounds = boxcastResult.rect;
|
||||
let neighbors = boxcastResult.colliders;
|
||||
let neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
|
||||
for (let j = 0; j < neighbors.length; j++) {
|
||||
let neighbor = neighbors[j];
|
||||
if (!collider.isTrigger && !neighbor.isTrigger)
|
||||
|
||||
@@ -17,15 +17,37 @@ module es {
|
||||
this._spatialHash.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取位于指定圆内的所有碰撞器
|
||||
* @param center
|
||||
* @param randius
|
||||
* @param results
|
||||
* @param layerMask
|
||||
*/
|
||||
public static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask = -1){
|
||||
if (results.length == 0){
|
||||
console.error("An empty results array was passed in. No results will ever be returned.");
|
||||
return;
|
||||
}
|
||||
|
||||
return this._spatialHash.overlapCircle(center, randius, results, layerMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回所有碰撞器与边界相交的碰撞器。bounds。请注意,这是一个broadphase检查,所以它只检查边界,不做单个碰撞到碰撞器的检查!
|
||||
* @param rect
|
||||
* @param layerMask
|
||||
*/
|
||||
public static boxcastBroadphase(rect: Rectangle, layerMask: number = this.allLayers){
|
||||
let boxcastResult = this._spatialHash.aabbBroadphase(rect, null, layerMask);
|
||||
return {colliders: boxcastResult.tempHashSet, rect: boxcastResult.bounds};
|
||||
return this._spatialHash.aabbBroadphase(rect, null, layerMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回所有与边界相交的碰撞器,不包括传入的碰撞器(self)。如果您希望为其他查询自行创建扫过的边界,则此方法非常有用
|
||||
* @param collider
|
||||
* @param rect
|
||||
* @param layerMask
|
||||
*/
|
||||
public static boxcastBroadphaseExcludingSelf(collider: Collider, rect: Rectangle, layerMask = this.allLayers){
|
||||
return this._spatialHash.aabbBroadphase(rect, collider, layerMask);
|
||||
}
|
||||
|
||||
@@ -66,15 +66,15 @@ module es {
|
||||
return super.overlaps(other);
|
||||
}
|
||||
|
||||
public collidesWithShape(other: Shape){
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean{
|
||||
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
||||
if (other instanceof Box && (other as Box).isUnrotated){
|
||||
return ShapeCollisions.boxToBox(this, other);
|
||||
return ShapeCollisions.boxToBox(this, other, result);
|
||||
}
|
||||
|
||||
// TODO: 让 minkowski 运行于 cricleToBox
|
||||
|
||||
return super.collidesWithShape(other);
|
||||
return super.collidesWithShape(other, result);
|
||||
}
|
||||
|
||||
public containsPoint(point: Vector2){
|
||||
|
||||
@@ -34,6 +34,7 @@ module es {
|
||||
}
|
||||
|
||||
public overlaps(other: Shape) {
|
||||
let result: CollisionResult = new CollisionResult();
|
||||
if (other instanceof Box && (other as Box).isUnrotated)
|
||||
return Collisions.isRectToCircle(other.bounds, this.position, this.radius);
|
||||
|
||||
@@ -41,29 +42,29 @@ module es {
|
||||
return Collisions.isCircleToCircle(this.position, this.radius, other.position, (other as Circle).radius);
|
||||
|
||||
if (other instanceof Polygon)
|
||||
return ShapeCollisions.circleToPolygon(this, other);
|
||||
return ShapeCollisions.circleToPolygon(this, other, result);
|
||||
|
||||
throw new Error(`overlaps of circle to ${other} are not supported`);
|
||||
}
|
||||
|
||||
public collidesWithShape(other: Shape): CollisionResult {
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean {
|
||||
if (other instanceof Box && (other as Box).isUnrotated) {
|
||||
return ShapeCollisions.circleToBox(this, other);
|
||||
return ShapeCollisions.circleToBox(this, other, result);
|
||||
}
|
||||
|
||||
if (other instanceof Circle) {
|
||||
return ShapeCollisions.circleToCircle(this, other);
|
||||
return ShapeCollisions.circleToCircle(this, other, result);
|
||||
}
|
||||
|
||||
if (other instanceof Polygon) {
|
||||
return ShapeCollisions.circleToPolygon(this, other);
|
||||
return ShapeCollisions.circleToPolygon(this, other, result);
|
||||
}
|
||||
|
||||
throw new Error(`Collisions of Circle to ${other} are not supported`);
|
||||
}
|
||||
|
||||
public pointCollidesWithShape(point: Vector2): CollisionResult {
|
||||
return ShapeCollisions.pointToCircle(point, this);
|
||||
public pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean {
|
||||
return ShapeCollisions.pointToCircle(point, this, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,10 +141,12 @@ module es {
|
||||
* 点应该在多边形的空间中(点-多边形.位置)
|
||||
* @param points
|
||||
* @param point
|
||||
* @param distanceSquared
|
||||
* @param edgeNormal
|
||||
*/
|
||||
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint, distanceSquared, edgeNormal } {
|
||||
let distanceSquared = Number.MAX_VALUE;
|
||||
let edgeNormal = new Vector2(0, 0);
|
||||
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2, distanceSquared: number, edgeNormal: Vector2): Vector2 {
|
||||
distanceSquared = Number.MAX_VALUE;
|
||||
edgeNormal = new Vector2(0, 0);
|
||||
let closestPoint = new Vector2(0, 0);
|
||||
|
||||
let tempDistanceSquared;
|
||||
@@ -166,9 +168,9 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
edgeNormal = Vector2.normalize(edgeNormal);
|
||||
Vector2Ext.normalize(edgeNormal);
|
||||
|
||||
return { closestPoint: closestPoint, distanceSquared: distanceSquared, edgeNormal: edgeNormal };
|
||||
return closestPoint;
|
||||
}
|
||||
|
||||
public recalculateBounds(collider: Collider){
|
||||
@@ -221,13 +223,12 @@ module es {
|
||||
}
|
||||
|
||||
public overlaps(other: Shape){
|
||||
let result: CollisionResult;
|
||||
let result: CollisionResult = new CollisionResult();
|
||||
if (other instanceof Polygon)
|
||||
return ShapeCollisions.polygonToPolygon(this, other);
|
||||
return ShapeCollisions.polygonToPolygon(this, other, result);
|
||||
|
||||
if (other instanceof Circle){
|
||||
result = ShapeCollisions.circleToPolygon(other, this);
|
||||
if (result){
|
||||
if (ShapeCollisions.circleToPolygon(other, this, result)){
|
||||
result.invertResult();
|
||||
return true;
|
||||
}
|
||||
@@ -238,20 +239,18 @@ module es {
|
||||
throw new Error(`overlaps of Pologon to ${other} are not supported`);
|
||||
}
|
||||
|
||||
public collidesWithShape(other: Shape){
|
||||
let result = new CollisionResult();
|
||||
public collidesWithShape(other: Shape, result: CollisionResult): boolean{
|
||||
if (other instanceof Polygon){
|
||||
return ShapeCollisions.polygonToPolygon(this, other);
|
||||
return ShapeCollisions.polygonToPolygon(this, other, result);
|
||||
}
|
||||
|
||||
if (other instanceof Circle){
|
||||
result = ShapeCollisions.circleToPolygon(other, this);
|
||||
if (result){
|
||||
if (ShapeCollisions.circleToPolygon(other, this, result)){
|
||||
result.invertResult();
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
throw new Error(`overlaps of Polygon to ${other} are not supported`);
|
||||
@@ -278,8 +277,8 @@ module es {
|
||||
return isInside;
|
||||
}
|
||||
|
||||
public pointCollidesWithShape(point: Vector2): CollisionResult {
|
||||
return ShapeCollisions.pointToPoly(point, this);
|
||||
public pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean {
|
||||
return ShapeCollisions.pointToPoly(point, this, result);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -16,9 +16,9 @@ module es {
|
||||
public bounds: Rectangle;
|
||||
|
||||
public abstract recalculateBounds(collider: Collider);
|
||||
public abstract pointCollidesWithShape(point: Vector2): CollisionResult;
|
||||
public abstract overlaps(other: Shape);
|
||||
public abstract collidesWithShape(other: Shape): CollisionResult;
|
||||
public abstract overlaps(other: Shape): boolean;
|
||||
public abstract collidesWithShape(other: Shape, collisionResult: CollisionResult): boolean;
|
||||
public abstract pointCollidesWithShape(point: Vector2, result: CollisionResult): boolean;
|
||||
|
||||
public clone(): Shape{
|
||||
return ObjectUtils.clone<Shape>(this);
|
||||
|
||||
@@ -4,9 +4,9 @@ module es {
|
||||
* 检查两个多边形之间的碰撞
|
||||
* @param first
|
||||
* @param second
|
||||
* @param result
|
||||
*/
|
||||
public static polygonToPolygon(first: Polygon, second: Polygon) {
|
||||
let result = new CollisionResult();
|
||||
public static polygonToPolygon(first: Polygon, second: Polygon, result: CollisionResult): boolean {
|
||||
let isIntersecting = true;
|
||||
|
||||
let firstEdges = first.edgeNormals;
|
||||
@@ -54,7 +54,7 @@ module es {
|
||||
|
||||
// 如果多边形不相交,也不会相交,退出循环
|
||||
if (!isIntersecting)
|
||||
return null;
|
||||
return false;
|
||||
|
||||
// 检查当前间隔距离是否为最小值。如果是,则存储间隔距离和当前距离。这将用于计算最小平移向量
|
||||
intervalDist = Math.abs(intervalDist);
|
||||
@@ -71,7 +71,7 @@ module es {
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance));
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -115,20 +115,17 @@ module es {
|
||||
*
|
||||
* @param circle
|
||||
* @param polygon
|
||||
* @param result
|
||||
*/
|
||||
public static circleToPolygon(circle: Circle, polygon: Polygon) {
|
||||
let result = new CollisionResult();
|
||||
|
||||
public static circleToPolygon(circle: Circle, polygon: Polygon, result: CollisionResult): boolean {
|
||||
let poly2Circle = Vector2.subtract(circle.position, polygon.position);
|
||||
|
||||
let gpp = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle);
|
||||
let closestPoint: Vector2 = gpp.closestPoint;
|
||||
let distanceSquared: number = gpp.distanceSquared;
|
||||
result.normal = gpp.edgeNormal;
|
||||
let distanceSquared = 0;
|
||||
let closestPoint = Polygon.getClosestPointOnPolygonToPoint(polygon.points, poly2Circle, distanceSquared, result.normal);
|
||||
|
||||
let circleCenterInsidePoly = polygon.containsPoint(circle.position);
|
||||
if (distanceSquared > circle.radius * circle.radius && !circleCenterInsidePoly)
|
||||
return null;
|
||||
return false;
|
||||
|
||||
let mtv: Vector2;
|
||||
if (circleCenterInsidePoly) {
|
||||
@@ -145,17 +142,17 @@ module es {
|
||||
result.minimumTranslationVector = mtv;
|
||||
result.point = Vector2.add(closestPoint, polygon.position);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* 适用于圆心在方框内以及只与方框外圆心重叠的圆。
|
||||
* @param circle
|
||||
* @param box
|
||||
* @param result
|
||||
*/
|
||||
public static circleToBox(circle: Circle, box: Box): CollisionResult {
|
||||
let result = new CollisionResult();
|
||||
let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position).res;
|
||||
public static circleToBox(circle: Circle, box: Box, result: CollisionResult): boolean {
|
||||
let closestPointOnBounds = box.bounds.getClosestPointOnRectangleBorderToPoint(circle.position, result.normal);
|
||||
|
||||
if (box.containsPoint(circle.position)) {
|
||||
result.point = closestPointOnBounds;
|
||||
@@ -163,7 +160,7 @@ module es {
|
||||
let safePlace = Vector2.add(closestPointOnBounds, Vector2.subtract(result.normal, new Vector2(circle.radius)));
|
||||
result.minimumTranslationVector = Vector2.subtract(circle.position, safePlace);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
let sqrDistance = Vector2.distanceSquared(closestPointOnBounds, circle.position);
|
||||
@@ -172,23 +169,24 @@ module es {
|
||||
} else if (sqrDistance <= circle.radius * circle.radius) {
|
||||
result.normal = Vector2.subtract(circle.position, closestPointOnBounds);
|
||||
let depth = result.normal.length() - circle.radius;
|
||||
result.normal = Vector2Ext.normalize(result.normal);
|
||||
|
||||
result.point = closestPointOnBounds;
|
||||
Vector2Ext.normalize(result.normal);
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(depth), result.normal);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param point
|
||||
* @param circle
|
||||
* @param result
|
||||
*/
|
||||
public static pointToCircle(point: Vector2, circle: Circle) {
|
||||
let result = new CollisionResult();
|
||||
|
||||
public static pointToCircle(point: Vector2, circle: Circle, result: CollisionResult): boolean {
|
||||
let distanceSquared = Vector2.distanceSquared(point, circle.position);
|
||||
let sumOfRadii = 1 + circle.radius;
|
||||
let collided = distanceSquared < sumOfRadii * sumOfRadii;
|
||||
@@ -198,10 +196,10 @@ module es {
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth, -depth), result.normal);
|
||||
result.point = Vector2.add(circle.position, Vector2.multiply(result.normal, new Vector2(circle.radius, circle.radius)));
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -210,7 +208,7 @@ module es {
|
||||
* @param lineB
|
||||
* @param closestTo
|
||||
*/
|
||||
public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2) {
|
||||
public static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2 {
|
||||
let v = Vector2.subtract(lineB, lineA);
|
||||
let w = Vector2.subtract(closestTo, lineA);
|
||||
let t = Vector2.dot(w, v) / Vector2.dot(v, v);
|
||||
@@ -223,24 +221,20 @@ module es {
|
||||
*
|
||||
* @param point
|
||||
* @param poly
|
||||
* @param result
|
||||
*/
|
||||
public static pointToPoly(point: Vector2, poly: Polygon) {
|
||||
let result = new CollisionResult();
|
||||
|
||||
public static pointToPoly(point: Vector2, poly: Polygon, result: CollisionResult): boolean {
|
||||
if (poly.containsPoint(point)) {
|
||||
let distanceSquared: number;
|
||||
let gpp = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position));
|
||||
let closestPoint = gpp.closestPoint;
|
||||
distanceSquared = gpp.distanceSquared;
|
||||
result.normal = gpp.edgeNormal;
|
||||
let distanceSquared: number = 0;
|
||||
let closestPoint = Polygon.getClosestPointOnPolygonToPoint(poly.points, Vector2.subtract(point, poly.position), distanceSquared, result.normal);
|
||||
|
||||
result.minimumTranslationVector = Vector2.multiply(result.normal, new Vector2(Math.sqrt(distanceSquared), Math.sqrt(distanceSquared)));
|
||||
result.point = Vector2.add(closestPoint, poly.position);
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -248,9 +242,7 @@ module es {
|
||||
* @param first
|
||||
* @param second
|
||||
*/
|
||||
public static circleToCircle(first: Circle, second: Circle){
|
||||
let result = new CollisionResult();
|
||||
|
||||
public static circleToCircle(first: Circle, second: Circle, result: CollisionResult): boolean{
|
||||
let distanceSquared = Vector2.distanceSquared(first.position, second.position);
|
||||
let sumOfRadii = first.radius + second.radius;
|
||||
let collided = distanceSquared < sumOfRadii * sumOfRadii;
|
||||
@@ -260,35 +252,34 @@ module es {
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-depth), result.normal);
|
||||
result.point = Vector2.add(second.position, Vector2.multiply(result.normal, new Vector2(second.radius)));
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param first
|
||||
* @param second
|
||||
* @param result
|
||||
*/
|
||||
public static boxToBox(first: Box, second: Box){
|
||||
let result = new CollisionResult();
|
||||
|
||||
public static boxToBox(first: Box, second: Box, result: CollisionResult): boolean{
|
||||
let minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(0, 0)){
|
||||
// 计算MTV。如果它是零,我们就可以称它为非碰撞
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
|
||||
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
|
||||
return null;
|
||||
if (result.minimumTranslationVector.equals(Vector2.zero))
|
||||
return false;
|
||||
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
|
||||
return result;
|
||||
return true;
|
||||
}
|
||||
|
||||
return null;
|
||||
return false;
|
||||
}
|
||||
|
||||
private static minkowskiDifference(first: Box, second: Box){
|
||||
|
||||
@@ -144,7 +144,7 @@ module es {
|
||||
* @param excludeCollider
|
||||
* @param layerMask
|
||||
*/
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) {
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) : Collider[]{
|
||||
this._tempHashSet.length = 0;
|
||||
|
||||
let p1 = this.cellCoords(bounds.x, bounds.y);
|
||||
@@ -172,7 +172,7 @@ module es {
|
||||
}
|
||||
}
|
||||
|
||||
return {tempHashSet: this._tempHashSet, bounds: bounds};
|
||||
return this._tempHashSet;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -182,16 +182,14 @@ module es {
|
||||
* @param results
|
||||
* @param layerMask
|
||||
*/
|
||||
public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask) {
|
||||
public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask): number {
|
||||
let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
|
||||
|
||||
this._overlapTestCircle.radius = radius;
|
||||
this._overlapTestCircle.position = circleCenter;
|
||||
|
||||
let resultCounter = 0;
|
||||
let aabbBroadphaseResult = this.aabbBroadphase(bounds, null, layerMask);
|
||||
bounds = aabbBroadphaseResult.bounds;
|
||||
let potentials = aabbBroadphaseResult.tempHashSet;
|
||||
let potentials = this.aabbBroadphase(bounds, null, layerMask);
|
||||
for (let i = 0; i < potentials.length; i++) {
|
||||
let collider = potentials[i];
|
||||
if (collider instanceof BoxCollider) {
|
||||
|
||||
Reference in New Issue
Block a user