优化spriteRenderer渲染方法

This commit is contained in:
yhh
2020-07-08 18:12:17 +08:00
parent 299c1b8e7d
commit aea50926a9
25 changed files with 607 additions and 567 deletions

View File

@@ -27,7 +27,7 @@
data-entry-class="Main" data-entry-class="Main"
data-orientation="auto" data-orientation="auto"
data-scale-mode="fixedWidth" data-scale-mode="fixedWidth"
data-frame-rate="30" data-frame-rate="60"
data-content-width="640" data-content-width="640"
data-content-height="1136" data-content-height="1136"
data-multi-fingered="2" data-multi-fingered="2"

View File

@@ -176,12 +176,12 @@ declare abstract class Component extends egret.DisplayObjectContainer {
onDisabled(): void; onDisabled(): void;
update(): void; update(): void;
debugRender(): void; debugRender(): void;
onEntityTransformChanged(comp: TransformComponent): void;
registerComponent(): void; registerComponent(): void;
deregisterComponent(): void; deregisterComponent(): void;
} }
declare class Entity extends egret.DisplayObjectContainer { declare class Entity extends egret.DisplayObjectContainer {
private static _idGenerator; private static _idGenerator;
private _position;
name: string; name: string;
readonly id: number; readonly id: number;
scene: Scene; scene: Scene;
@@ -194,6 +194,7 @@ declare class Entity extends egret.DisplayObjectContainer {
readonly isDestoryed: boolean; readonly isDestoryed: boolean;
position: Vector2; position: Vector2;
scale: Vector2; scale: Vector2;
rotation: number;
enabled: boolean; enabled: boolean;
setEnabled(isEnabled: boolean): this; setEnabled(isEnabled: boolean): this;
tag: number; tag: number;
@@ -210,6 +211,7 @@ declare class Entity extends egret.DisplayObjectContainer {
getOrCreateComponent<T extends Component>(type: T): T; getOrCreateComponent<T extends Component>(type: T): T;
getComponent<T extends Component>(type: any): T; getComponent<T extends Component>(type: any): T;
getComponents(typeName: string | any, componentList?: any): any; getComponents(typeName: string | any, componentList?: any): any;
private onEntityTransformChanged;
removeComponentForType<T extends Component>(type: any): boolean; removeComponentForType<T extends Component>(type: any): boolean;
removeComponent(component: Component): void; removeComponent(component: Component): void;
removeAllComponents(): void; removeAllComponents(): void;
@@ -218,6 +220,11 @@ declare class Entity extends egret.DisplayObjectContainer {
onRemovedFromScene(): void; onRemovedFromScene(): void;
destroy(): void; destroy(): void;
} }
declare enum TransformComponent {
rotation = 0,
scale = 1,
position = 2
}
declare class Scene extends egret.DisplayObjectContainer { declare class Scene extends egret.DisplayObjectContainer {
camera: Camera; camera: Camera;
readonly entities: EntityList; readonly entities: EntityList;
@@ -267,6 +274,7 @@ declare class Camera extends Component {
private _origin; private _origin;
private _minimumZoom; private _minimumZoom;
private _maximumZoom; private _maximumZoom;
private _position;
followLerp: number; followLerp: number;
deadzone: Rectangle; deadzone: Rectangle;
focusOffset: Vector2; focusOffset: Vector2;
@@ -282,6 +290,8 @@ declare class Camera extends Component {
maximumZoom: number; maximumZoom: number;
origin: Vector2; origin: Vector2;
position: Vector2; position: Vector2;
x: number;
y: number;
constructor(); constructor();
onSceneSizeChanged(newWidth: number, newHeight: number): void; onSceneSizeChanged(newWidth: number, newHeight: number): void;
setMinimumZoom(minZoom: number): Camera; setMinimumZoom(minZoom: number): Camera;
@@ -348,11 +358,8 @@ declare class SpriteAnimation {
constructor(sprites: Sprite[], frameRate: number); constructor(sprites: Sprite[], frameRate: number);
} }
declare class SpriteRenderer extends RenderableComponent { declare class SpriteRenderer extends RenderableComponent {
private _origin;
private _sprite; private _sprite;
protected bitmap: egret.Bitmap; protected bitmap: egret.Bitmap;
origin: Vector2;
setOrigin(origin: Vector2): this;
sprite: Sprite; sprite: Sprite;
setSprite(sprite: Sprite): SpriteRenderer; setSprite(sprite: Sprite): SpriteRenderer;
setColor(color: number): SpriteRenderer; setColor(color: number): SpriteRenderer;
@@ -420,11 +427,9 @@ declare abstract class Collider extends Component {
physicsLayer: number; physicsLayer: number;
isTrigger: boolean; isTrigger: boolean;
registeredPhysicsBounds: Rectangle; registeredPhysicsBounds: Rectangle;
shouldColliderScaleAndRotationWithTransform: boolean; shouldColliderScaleAndRotateWithTransform: boolean;
collidesWithLayers: number; collidesWithLayers: number;
_localOffsetLength: number; _localOffsetLength: number;
_isPositionDirty: boolean;
_isRotationDirty: boolean;
protected _isParentEntityAddedToScene: any; protected _isParentEntityAddedToScene: any;
protected _colliderRequiresAutoSizing: any; protected _colliderRequiresAutoSizing: any;
protected _localOffset: Vector2; protected _localOffset: Vector2;
@@ -440,7 +445,7 @@ declare abstract class Collider extends Component {
onRemovedFromEntity(): void; onRemovedFromEntity(): void;
onEnabled(): void; onEnabled(): void;
onDisabled(): void; onDisabled(): void;
update(): void; onEntityTransformChanged(comp: TransformComponent): void;
} }
declare class BoxCollider extends Collider { declare class BoxCollider extends Collider {
width: number; width: number;
@@ -516,6 +521,7 @@ declare class ComponentList {
deregisterAllComponents(): void; deregisterAllComponents(): void;
registerAllComponents(): void; registerAllComponents(): void;
updateLists(): void; updateLists(): void;
onEntityTransformChanged(comp: TransformComponent): void;
private handleRemove; private handleRemove;
getComponent<T extends Component>(type: any, onlyReturnInitializedComponents: boolean): T; getComponent<T extends Component>(type: any, onlyReturnInitializedComponents: boolean): T;
getComponents(typeName: string | any, components?: any): any; getComponents(typeName: string | any, components?: any): any;
@@ -758,29 +764,19 @@ declare class Matrix2D {
static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D; static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D;
determinant(): number; determinant(): number;
static invert(matrix: Matrix2D, result?: Matrix2D): Matrix2D; static invert(matrix: Matrix2D, result?: Matrix2D): Matrix2D;
static createTranslation(xPosition: number, yPosition: number, result?: Matrix2D): Matrix2D; static createTranslation(xPosition: number, yPosition: number): Matrix2D;
static createTranslationVector(position: Vector2): Matrix2D;
static createRotation(radians: number, result?: Matrix2D): Matrix2D; static createRotation(radians: number, result?: Matrix2D): Matrix2D;
static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D; static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D;
toEgretMatrix(): egret.Matrix; toEgretMatrix(): egret.Matrix;
} }
declare class Rectangle { declare class Rectangle extends egret.Rectangle {
x: number;
y: number;
width: number;
height: number;
private _tempMat;
private _transformMat;
readonly max: Vector2; readonly max: Vector2;
readonly left: number;
readonly right: number;
readonly top: number;
readonly bottom: number;
readonly center: Vector2; readonly center: Vector2;
location: Vector2; location: Vector2;
size: Vector2; size: Vector2;
constructor(x?: number, y?: number, width?: number, height?: number); intersects(value: egret.Rectangle): boolean;
intersects(value: Rectangle): boolean; containsInVec(value: Vector2): boolean;
contains(value: Vector2): boolean;
containsRect(value: Rectangle): boolean; containsRect(value: Rectangle): boolean;
getHalfSize(): Vector2; getHalfSize(): Vector2;
static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle; static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle;
@@ -789,7 +785,6 @@ declare class Rectangle {
edgeNormal: Vector2; edgeNormal: Vector2;
}; };
getClosestPointOnBoundsToOrigin(): Vector2; getClosestPointOnBoundsToOrigin(): Vector2;
calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void;
static rectEncompassingPoints(points: Vector2[]): Rectangle; static rectEncompassingPoints(points: Vector2[]): Rectangle;
} }
declare class Vector3 { declare class Vector3 {

View File

@@ -917,6 +917,8 @@ var Component = (function (_super) {
}; };
Component.prototype.debugRender = function () { Component.prototype.debugRender = function () {
}; };
Component.prototype.onEntityTransformChanged = function (comp) {
};
Component.prototype.registerComponent = function () { Component.prototype.registerComponent = function () {
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false); this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
this.entity.scene.entityProcessors.onComponentAdded(this.entity); this.entity.scene.entityProcessors.onComponentAdded(this.entity);
@@ -931,7 +933,6 @@ var Entity = (function (_super) {
__extends(Entity, _super); __extends(Entity, _super);
function Entity(name) { function Entity(name) {
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this._position = Vector2.zero;
_this._updateOrder = 0; _this._updateOrder = 0;
_this._enabled = true; _this._enabled = true;
_this._tag = 0; _this._tag = 0;
@@ -950,10 +951,12 @@ var Entity = (function (_super) {
}); });
Object.defineProperty(Entity.prototype, "position", { Object.defineProperty(Entity.prototype, "position", {
get: function () { get: function () {
return this._position; return new Vector2(this.x, this.y);
}, },
set: function (value) { set: function (value) {
this._position = value; this.$setX(value.x);
this.$setY(value.y);
this.onEntityTransformChanged(TransformComponent.position);
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -963,8 +966,17 @@ var Entity = (function (_super) {
return new Vector2(this.scaleX, this.scaleY); return new Vector2(this.scaleX, this.scaleY);
}, },
set: function (value) { set: function (value) {
this.scaleX = value.x; this.$setScaleX(value.x);
this.scaleY = value.y; this.$setScaleY(value.y);
this.onEntityTransformChanged(TransformComponent.scale);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "rotation", {
set: function (value) {
this.$setRotation(value);
this.onEntityTransformChanged(TransformComponent.rotation);
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -1074,6 +1086,9 @@ var Entity = (function (_super) {
Entity.prototype.getComponents = function (typeName, componentList) { Entity.prototype.getComponents = function (typeName, componentList) {
return this.components.getComponents(typeName, componentList); return this.components.getComponents(typeName, componentList);
}; };
Entity.prototype.onEntityTransformChanged = function (comp) {
this.components.onEntityTransformChanged(comp);
};
Entity.prototype.removeComponentForType = function (type) { Entity.prototype.removeComponentForType = function (type) {
var comp = this.getComponent(type); var comp = this.getComponent(type);
if (comp) { if (comp) {
@@ -1110,6 +1125,12 @@ var Entity = (function (_super) {
}; };
return Entity; return Entity;
}(egret.DisplayObjectContainer)); }(egret.DisplayObjectContainer));
var TransformComponent;
(function (TransformComponent) {
TransformComponent[TransformComponent["rotation"] = 0] = "rotation";
TransformComponent[TransformComponent["scale"] = 1] = "scale";
TransformComponent[TransformComponent["position"] = 2] = "position";
})(TransformComponent || (TransformComponent = {}));
var Scene = (function (_super) { var Scene = (function (_super) {
__extends(Scene, _super); __extends(Scene, _super);
function Scene() { function Scene() {
@@ -1354,6 +1375,7 @@ var Camera = (function (_super) {
_this._origin = Vector2.zero; _this._origin = Vector2.zero;
_this._minimumZoom = 0.3; _this._minimumZoom = 0.3;
_this._maximumZoom = 3; _this._maximumZoom = 3;
_this._position = Vector2.zero;
_this.followLerp = 0.1; _this.followLerp = 0.1;
_this.deadzone = new Rectangle(); _this.deadzone = new Rectangle();
_this.focusOffset = new Vector2(); _this.focusOffset = new Vector2();
@@ -1415,10 +1437,30 @@ var Camera = (function (_super) {
}); });
Object.defineProperty(Camera.prototype, "position", { Object.defineProperty(Camera.prototype, "position", {
get: function () { get: function () {
return this.entity.position; return this._position;
}, },
set: function (value) { set: function (value) {
this.entity.position = value; this._position = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Camera.prototype, "x", {
get: function () {
return this._position.x;
},
set: function (value) {
this._position.x = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Camera.prototype, "y", {
get: function () {
return this._position.y;
},
set: function (value) {
this._position.y = value;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -1681,22 +1723,6 @@ var SpriteRenderer = (function (_super) {
function SpriteRenderer() { function SpriteRenderer() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
} }
Object.defineProperty(SpriteRenderer.prototype, "origin", {
get: function () {
return this._origin;
},
set: function (value) {
this.setOrigin(value);
},
enumerable: true,
configurable: true
});
SpriteRenderer.prototype.setOrigin = function (origin) {
if (this._origin != origin) {
this._origin = origin;
}
return this;
};
Object.defineProperty(SpriteRenderer.prototype, "sprite", { Object.defineProperty(SpriteRenderer.prototype, "sprite", {
get: function () { get: function () {
return this._sprite; return this._sprite;
@@ -1710,8 +1736,10 @@ var SpriteRenderer = (function (_super) {
SpriteRenderer.prototype.setSprite = function (sprite) { SpriteRenderer.prototype.setSprite = function (sprite) {
this.removeChildren(); this.removeChildren();
this._sprite = sprite; this._sprite = sprite;
if (this._sprite) if (this._sprite) {
this._origin = this._sprite.origin; this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width;
this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height;
}
this.bitmap = new egret.Bitmap(sprite.texture2D); this.bitmap = new egret.Bitmap(sprite.texture2D);
this.addChild(this.bitmap); this.addChild(this.bitmap);
return this; return this;
@@ -1736,8 +1764,8 @@ var SpriteRenderer = (function (_super) {
return this.isVisible; return this.isVisible;
}; };
SpriteRenderer.prototype.render = function (camera) { SpriteRenderer.prototype.render = function (camera) {
this.x = this.entity.position.x - this.origin.x - camera.position.x + camera.origin.x; this.x = -camera.position.x + camera.origin.x;
this.y = this.entity.position.y - this.origin.y - camera.position.y + camera.origin.y; this.y = -camera.position.y + camera.origin.y;
}; };
SpriteRenderer.prototype.onRemovedFromEntity = function () { SpriteRenderer.prototype.onRemovedFromEntity = function () {
if (this.parent) if (this.parent)
@@ -1940,27 +1968,23 @@ var Collider = (function (_super) {
function Collider() { function Collider() {
var _this = _super !== null && _super.apply(this, arguments) || this; var _this = _super !== null && _super.apply(this, arguments) || this;
_this.physicsLayer = 1 << 0; _this.physicsLayer = 1 << 0;
_this.shouldColliderScaleAndRotationWithTransform = true; _this.registeredPhysicsBounds = new Rectangle();
_this.shouldColliderScaleAndRotateWithTransform = true;
_this.collidesWithLayers = Physics.allLayers; _this.collidesWithLayers = Physics.allLayers;
_this._isPositionDirty = true;
_this._isRotationDirty = true;
_this._localOffset = new Vector2(0, 0); _this._localOffset = new Vector2(0, 0);
return _this; return _this;
} }
Object.defineProperty(Collider.prototype, "bounds", { Object.defineProperty(Collider.prototype, "bounds", {
get: function () { get: function () {
if (this._isPositionDirty || this._isRotationDirty) { var bds = this.entity.getBounds();
this.shape.recalculateBounds(this); return new Rectangle(bds.x, bds.y, bds.width, bds.height);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(Collider.prototype, "localOffset", { Object.defineProperty(Collider.prototype, "localOffset", {
get: function () { get: function () {
return this._localOffset; return new Vector2(this.x, this.y);
}, },
set: function (value) { set: function (value) {
this.setLocalOffset(value); this.setLocalOffset(value);
@@ -1971,9 +1995,9 @@ var Collider = (function (_super) {
Collider.prototype.setLocalOffset = function (offset) { Collider.prototype.setLocalOffset = function (offset) {
if (this._localOffset != offset) { if (this._localOffset != offset) {
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset; this.$setX(offset.x);
this.$setY(offset.y);
this._localOffsetLength = this._localOffset.length(); this._localOffsetLength = this._localOffset.length();
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
} }
}; };
@@ -2006,17 +2030,15 @@ var Collider = (function (_super) {
if (!(this instanceof BoxCollider)) { if (!(this instanceof BoxCollider)) {
console.error("Only box and circle colliders can be created automatically"); console.error("Only box and circle colliders can be created automatically");
} }
var renderable = this.entity.getComponent(RenderableComponent); var bounds = this.entity.getBounds();
if (renderable) { var renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
var renderbaleBounds = renderable.bounds; var width = renderbaleBounds.width / this.entity.scale.x;
var width = renderbaleBounds.width / this.entity.scale.x; var height = renderbaleBounds.height / this.entity.scale.y;
var height = renderbaleBounds.height / this.entity.scale.y; if (this instanceof BoxCollider) {
if (this instanceof BoxCollider) { var boxCollider = this;
var boxCollider = this; boxCollider.width = width;
boxCollider.width = width; boxCollider.height = height;
boxCollider.height = height; this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
}
} }
} }
this._isParentEntityAddedToScene = true; this._isParentEntityAddedToScene = true;
@@ -2028,17 +2050,13 @@ var Collider = (function (_super) {
}; };
Collider.prototype.onEnabled = function () { Collider.prototype.onEnabled = function () {
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
this._isPositionDirty = this._isRotationDirty = true;
}; };
Collider.prototype.onDisabled = function () { Collider.prototype.onDisabled = function () {
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
}; };
Collider.prototype.update = function () { Collider.prototype.onEntityTransformChanged = function (comp) {
var spriteRenderer = this.entity.getComponent(SpriteRenderer); if (this._isColliderRegistered)
if (spriteRenderer) { Physics.updateCollider(this);
this.bounds.x = spriteRenderer.x;
this.bounds.y = spriteRenderer.y;
}
}; };
return Collider; return Collider;
}(Component)); }(Component));
@@ -2065,7 +2083,6 @@ var BoxCollider = (function (_super) {
var box = this.shape; var box = this.shape;
if (width != box.width) { if (width != box.width) {
box.updateBox(width, box.height); box.updateBox(width, box.height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -2086,7 +2103,6 @@ var BoxCollider = (function (_super) {
var box = this.shape; var box = this.shape;
if (height != box.height) { if (height != box.height) {
box.updateBox(box.width, height); box.updateBox(box.width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -2096,7 +2112,6 @@ var BoxCollider = (function (_super) {
var box = this.shape; var box = this.shape;
if (width != box.width || height != box.height) { if (width != box.width || height != box.height) {
box.updateBox(width, height); box.updateBox(width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -2407,6 +2422,16 @@ var ComponentList = (function () {
this._tempBufferList.length = 0; this._tempBufferList.length = 0;
} }
}; };
ComponentList.prototype.onEntityTransformChanged = function (comp) {
for (var i = 0; i < this._components.length; i++) {
if (this._components[i].enabled)
this._components[i].onEntityTransformChanged(comp);
}
for (var i = 0; i < this._componentsToAdd.length; i++) {
if (this._componentsToAdd[i].enabled)
this._componentsToAdd[i].onEntityTransformChanged(comp);
}
};
ComponentList.prototype.handleRemove = function (component) { ComponentList.prototype.handleRemove = function (component) {
if (component instanceof RenderableComponent) if (component instanceof RenderableComponent)
this._entity.scene.renderableComponents.remove(component); this._entity.scene.renderableComponents.remove(component);
@@ -3413,8 +3438,8 @@ var Matrix2D = (function () {
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det; result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
return result; return result;
}; };
Matrix2D.createTranslation = function (xPosition, yPosition, result) { Matrix2D.createTranslation = function (xPosition, yPosition) {
result = result ? result : new Matrix2D(); var result = new Matrix2D();
result.m11 = 1; result.m11 = 1;
result.m12 = 0; result.m12 = 0;
result.m21 = 0; result.m21 = 0;
@@ -3423,6 +3448,9 @@ var Matrix2D = (function () {
result.m32 = yPosition; result.m32 = yPosition;
return result; return result;
}; };
Matrix2D.createTranslationVector = function (position) {
return this.createTranslation(position.x, position.y);
};
Matrix2D.createRotation = function (radians, result) { Matrix2D.createRotation = function (radians, result) {
result = new Matrix2D(); result = new Matrix2D();
var val1 = Math.cos(radians); var val1 = Math.cos(radians);
@@ -3450,12 +3478,10 @@ var Matrix2D = (function () {
Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0); Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0);
return Matrix2D; return Matrix2D;
}()); }());
var Rectangle = (function () { var Rectangle = (function (_super) {
function Rectangle(x, y, width, height) { __extends(Rectangle, _super);
this.x = x ? x : 0; function Rectangle() {
this.y = y ? y : 0; return _super !== null && _super.apply(this, arguments) || this;
this.width = width ? width : 0;
this.height = height ? height : 0;
} }
Object.defineProperty(Rectangle.prototype, "max", { Object.defineProperty(Rectangle.prototype, "max", {
get: function () { get: function () {
@@ -3464,34 +3490,6 @@ var Rectangle = (function () {
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(Rectangle.prototype, "left", {
get: function () {
return this.x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "right", {
get: function () {
return this.x + this.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "top", {
get: function () {
return this.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "bottom", {
get: function () {
return this.y + this.height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "center", { Object.defineProperty(Rectangle.prototype, "center", {
get: function () { get: function () {
return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
@@ -3527,7 +3525,7 @@ var Rectangle = (function () {
value.top < this.bottom && value.top < this.bottom &&
this.top < value.bottom; this.top < value.bottom;
}; };
Rectangle.prototype.contains = function (value) { Rectangle.prototype.containsInVec = function (value) {
return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && return ((((this.x <= value.x) && (value.x < (this.x + this.width))) &&
(this.y <= value.y)) && (this.y <= value.y)) &&
(value.y < (this.y + this.height))); (value.y < (this.y + this.height)));
@@ -3544,11 +3542,11 @@ var Rectangle = (function () {
return new Rectangle(minX, minY, maxX - minX, maxY - minY); return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}; };
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) { Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) {
var edgeNormal = new Vector2(0, 0); var edgeNormal = Vector2.zero;
var res = new Vector2(0, 0); var res = new Vector2();
res.x = MathHelper.clamp(point.x, this.left, this.right); res.x = MathHelper.clamp(point.x, this.left, this.right);
res.y = MathHelper.clamp(point.y, this.top, this.bottom); res.y = MathHelper.clamp(point.y, this.top, this.bottom);
if (this.contains(res)) { if (this.containsInVec(res)) {
var dl = res.x - this.left; var dl = res.x - this.left;
var dr = this.right - res.x; var dr = this.right - res.x;
var dt = res.y - this.top; var dt = res.y - this.top;
@@ -3572,18 +3570,14 @@ var Rectangle = (function () {
} }
} }
else { else {
if (res.x == this.left) { if (res.x == this.left)
edgeNormal.x = -1; edgeNormal.x = -1;
} if (res.x == this.right)
if (res.x == this.right) {
edgeNormal.x = 1; edgeNormal.x = 1;
} if (res.y == this.top)
if (res.y == this.top) {
edgeNormal.y = -1; edgeNormal.y = -1;
} if (res.y == this.bottom)
if (res.y == this.bottom) {
edgeNormal.y = 1; edgeNormal.y = 1;
}
} }
return { res: res, edgeNormal: edgeNormal }; return { res: res, edgeNormal: edgeNormal };
}; };
@@ -3608,40 +3602,6 @@ var Rectangle = (function () {
} }
return boundsPoint; return boundsPoint;
}; };
Rectangle.prototype.calculateBounds = function (parentPosition, position, origin, scale, rotation, width, height) {
if (rotation == 0) {
this.x = parentPosition.x + position.x - origin.x * scale.x;
this.y = parentPosition.y + position.y - origin.y * scale.y;
this.width = width * scale.x;
this.height = height * scale.y;
}
else {
var worldPosX = parentPosition.x + position.x;
var worldPosY = parentPosition.y + position.y;
this._transformMat = Matrix2D.createTranslation(-worldPosX - origin.x, -worldPosY - origin.y);
this._tempMat = Matrix2D.createScale(scale.x, scale.y);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
this._tempMat = Matrix2D.createRotation(rotation);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
this._tempMat = Matrix2D.createTranslation(worldPosX, worldPosY);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
var topLeft = new Vector2(worldPosX, worldPosY);
var topRight = new Vector2(worldPosX + width, worldPosY);
var bottomLeft = new Vector2(worldPosX, worldPosY + height);
var bottomRight = new Vector2(worldPosX + width, worldPosY + height);
topLeft = Vector2Ext.transformR(topLeft, this._transformMat);
topRight = Vector2Ext.transformR(topRight, this._transformMat);
bottomLeft = Vector2Ext.transformR(bottomLeft, this._transformMat);
bottomRight = Vector2Ext.transformR(bottomRight, this._transformMat);
var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
this.location = new Vector2(minX, minY);
this.width = maxX - minX;
this.height = maxY - minY;
}
};
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;
@@ -3649,23 +3609,19 @@ var Rectangle = (function () {
var maxY = Number.NEGATIVE_INFINITY; var maxY = Number.NEGATIVE_INFINITY;
for (var i = 0; i < points.length; i++) { for (var i = 0; i < points.length; i++) {
var pt = points[i]; var pt = points[i];
if (pt.x < minX) { if (pt.x < minX)
minX = pt.x; minX = pt.x;
} if (pt.x > maxX)
if (pt.x > maxX) {
maxX = pt.x; maxX = pt.x;
} if (pt.y < minY)
if (pt.y < minY) {
minY = pt.y; minY = pt.y;
} if (pt.y > maxY)
if (pt.y > maxY) {
maxY = pt.y; maxY = pt.y;
}
} }
return this.fromMinMax(minX, minY, maxX, maxY); return this.fromMinMax(minX, minY, maxX, maxY);
}; };
return Rectangle; return Rectangle;
}()); }(egret.Rectangle));
var Vector3 = (function () { var Vector3 = (function () {
function Vector3(x, y, z) { function Vector3(x, y, z) {
this.x = x; this.x = x;
@@ -4064,7 +4020,7 @@ var Polygon = (function (_super) {
}; };
Polygon.prototype.recalculateBounds = function (collider) { Polygon.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset; this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotationWithTransform) { if (collider.shouldColliderScaleAndRotateWithTransform) {
var hasUnitScale = true; var hasUnitScale = true;
var tempMat = void 0; var tempMat = void 0;
var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y); var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
@@ -4076,7 +4032,7 @@ var Polygon = (function (_super) {
this.center = scaledOffset; this.center = scaledOffset;
} }
if (collider.entity.rotation != 0) { if (collider.entity.rotation != 0) {
tempMat = Matrix2D.createRotation(collider.entity.rotation); tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; 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(); var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
@@ -4086,8 +4042,6 @@ var Polygon = (function (_super) {
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
this.isUnrotated = collider.entity.rotation == 0; this.isUnrotated = collider.entity.rotation == 0;
if (collider._isRotationDirty)
this._areEdgeNormalsDirty = true;
} }
this.position = Vector2.add(collider.entity.position, this.center); this.position = Vector2.add(collider.entity.position, this.center);
this.bounds = Rectangle.rectEncompassingPoints(this.points); this.bounds = Rectangle.rectEncompassingPoints(this.points);
@@ -4142,7 +4096,7 @@ var Box = (function (_super) {
}; };
Box.prototype.containsPoint = function (point) { Box.prototype.containsPoint = function (point) {
if (this.isUnrotated) if (this.isUnrotated)
return this.bounds.contains(point); return this.bounds.containsInVec(point);
return _super.prototype.containsPoint.call(this, point); return _super.prototype.containsPoint.call(this, point);
}; };
return Box; return Box;
@@ -4172,7 +4126,7 @@ var Circle = (function (_super) {
}; };
Circle.prototype.recalculateBounds = function (collider) { Circle.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset; this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotationWithTransform) { if (collider.shouldColliderScaleAndRotateWithTransform) {
var scale = collider.entity.scale; var scale = collider.entity.scale;
var hasUnitScale = scale.x == 1 && scale.y == 1; var hasUnitScale = scale.x == 1 && scale.y == 1;
var maxScale = Math.max(scale.x, scale.y); var maxScale = Math.max(scale.x, scale.y);
@@ -4379,7 +4333,7 @@ var ShapeCollisions = (function () {
ShapeCollisions.boxToBox = function (first, second) { ShapeCollisions.boxToBox = function (first, second) {
var result = new CollisionResult(); var result = new CollisionResult();
var minkowskiDiff = this.minkowskiDifference(first, second); var minkowskiDiff = this.minkowskiDifference(first, second);
if (minkowskiDiff.contains(new Vector2(0, 0))) { if (minkowskiDiff.containsInVec(new Vector2(0, 0))) {
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0) if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
return null; return null;
@@ -4401,6 +4355,7 @@ var SpatialHash = (function () {
function SpatialHash(cellSize) { function SpatialHash(cellSize) {
if (cellSize === void 0) { cellSize = 100; } if (cellSize === void 0) { cellSize = 100; }
this.gridBounds = new Rectangle(); this.gridBounds = new Rectangle();
this._overlapTestCircle = new Circle(0);
this._tempHashSet = []; this._tempHashSet = [];
this._cellDict = new NumberDictionary(); this._cellDict = new NumberDictionary();
this._cellSize = cellSize; this._cellSize = cellSize;
@@ -4426,10 +4381,10 @@ var SpatialHash = (function () {
collider.registeredPhysicsBounds = bounds; collider.registeredPhysicsBounds = bounds;
var p1 = this.cellCoords(bounds.x, bounds.y); var p1 = this.cellCoords(bounds.x, bounds.y);
var p2 = this.cellCoords(bounds.right, bounds.bottom); var p2 = this.cellCoords(bounds.right, bounds.bottom);
if (!this.gridBounds.contains(new Vector2(p1.x, p1.y))) { if (!this.gridBounds.containsInVec(new Vector2(p1.x, p1.y))) {
this.gridBounds = RectangleExt.union(this.gridBounds, p1); this.gridBounds = RectangleExt.union(this.gridBounds, p1);
} }
if (!this.gridBounds.contains(new Vector2(p2.x, p2.y))) { if (!this.gridBounds.containsInVec(new Vector2(p2.x, p2.y))) {
this.gridBounds = RectangleExt.union(this.gridBounds, p2); this.gridBounds = RectangleExt.union(this.gridBounds, p2);
} }
for (var x = p1.x; x <= p2.x; x++) { for (var x = p1.x; x <= p2.x; x++) {

File diff suppressed because one or more lines are too long

View File

@@ -15,13 +15,13 @@ class MainScene extends Scene {
bg.addComponent(new PlayerController()); bg.addComponent(new PlayerController());
bg.addComponent(new Mover()); bg.addComponent(new Mover());
bg.addComponent(new BoxCollider()); bg.addComponent(new BoxCollider());
bg.position = new Vector2(30, 30); bg.position = new Vector2(300, 300);
for (let i = 0; i < 1; i++) { for (let i = 0; i < 1; i++) {
let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png")); let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png"));
let player2 = this.createEntity("player2"); let player2 = this.createEntity("player2");
player2.addComponent(new SpriteRenderer()).setSprite(sprite); player2.addComponent(new SpriteRenderer()).setSprite(sprite);
player2.position = new Vector2(10, 10); player2.position = new Vector2(200, 200);
player2.addComponent(new BoxCollider()); player2.addComponent(new BoxCollider());
} }

View File

@@ -176,12 +176,12 @@ declare abstract class Component extends egret.DisplayObjectContainer {
onDisabled(): void; onDisabled(): void;
update(): void; update(): void;
debugRender(): void; debugRender(): void;
onEntityTransformChanged(comp: TransformComponent): void;
registerComponent(): void; registerComponent(): void;
deregisterComponent(): void; deregisterComponent(): void;
} }
declare class Entity extends egret.DisplayObjectContainer { declare class Entity extends egret.DisplayObjectContainer {
private static _idGenerator; private static _idGenerator;
private _position;
name: string; name: string;
readonly id: number; readonly id: number;
scene: Scene; scene: Scene;
@@ -194,6 +194,7 @@ declare class Entity extends egret.DisplayObjectContainer {
readonly isDestoryed: boolean; readonly isDestoryed: boolean;
position: Vector2; position: Vector2;
scale: Vector2; scale: Vector2;
rotation: number;
enabled: boolean; enabled: boolean;
setEnabled(isEnabled: boolean): this; setEnabled(isEnabled: boolean): this;
tag: number; tag: number;
@@ -210,6 +211,7 @@ declare class Entity extends egret.DisplayObjectContainer {
getOrCreateComponent<T extends Component>(type: T): T; getOrCreateComponent<T extends Component>(type: T): T;
getComponent<T extends Component>(type: any): T; getComponent<T extends Component>(type: any): T;
getComponents(typeName: string | any, componentList?: any): any; getComponents(typeName: string | any, componentList?: any): any;
private onEntityTransformChanged;
removeComponentForType<T extends Component>(type: any): boolean; removeComponentForType<T extends Component>(type: any): boolean;
removeComponent(component: Component): void; removeComponent(component: Component): void;
removeAllComponents(): void; removeAllComponents(): void;
@@ -218,6 +220,11 @@ declare class Entity extends egret.DisplayObjectContainer {
onRemovedFromScene(): void; onRemovedFromScene(): void;
destroy(): void; destroy(): void;
} }
declare enum TransformComponent {
rotation = 0,
scale = 1,
position = 2
}
declare class Scene extends egret.DisplayObjectContainer { declare class Scene extends egret.DisplayObjectContainer {
camera: Camera; camera: Camera;
readonly entities: EntityList; readonly entities: EntityList;
@@ -267,6 +274,7 @@ declare class Camera extends Component {
private _origin; private _origin;
private _minimumZoom; private _minimumZoom;
private _maximumZoom; private _maximumZoom;
private _position;
followLerp: number; followLerp: number;
deadzone: Rectangle; deadzone: Rectangle;
focusOffset: Vector2; focusOffset: Vector2;
@@ -282,6 +290,8 @@ declare class Camera extends Component {
maximumZoom: number; maximumZoom: number;
origin: Vector2; origin: Vector2;
position: Vector2; position: Vector2;
x: number;
y: number;
constructor(); constructor();
onSceneSizeChanged(newWidth: number, newHeight: number): void; onSceneSizeChanged(newWidth: number, newHeight: number): void;
setMinimumZoom(minZoom: number): Camera; setMinimumZoom(minZoom: number): Camera;
@@ -348,11 +358,8 @@ declare class SpriteAnimation {
constructor(sprites: Sprite[], frameRate: number); constructor(sprites: Sprite[], frameRate: number);
} }
declare class SpriteRenderer extends RenderableComponent { declare class SpriteRenderer extends RenderableComponent {
private _origin;
private _sprite; private _sprite;
protected bitmap: egret.Bitmap; protected bitmap: egret.Bitmap;
origin: Vector2;
setOrigin(origin: Vector2): this;
sprite: Sprite; sprite: Sprite;
setSprite(sprite: Sprite): SpriteRenderer; setSprite(sprite: Sprite): SpriteRenderer;
setColor(color: number): SpriteRenderer; setColor(color: number): SpriteRenderer;
@@ -420,11 +427,9 @@ declare abstract class Collider extends Component {
physicsLayer: number; physicsLayer: number;
isTrigger: boolean; isTrigger: boolean;
registeredPhysicsBounds: Rectangle; registeredPhysicsBounds: Rectangle;
shouldColliderScaleAndRotationWithTransform: boolean; shouldColliderScaleAndRotateWithTransform: boolean;
collidesWithLayers: number; collidesWithLayers: number;
_localOffsetLength: number; _localOffsetLength: number;
_isPositionDirty: boolean;
_isRotationDirty: boolean;
protected _isParentEntityAddedToScene: any; protected _isParentEntityAddedToScene: any;
protected _colliderRequiresAutoSizing: any; protected _colliderRequiresAutoSizing: any;
protected _localOffset: Vector2; protected _localOffset: Vector2;
@@ -440,7 +445,7 @@ declare abstract class Collider extends Component {
onRemovedFromEntity(): void; onRemovedFromEntity(): void;
onEnabled(): void; onEnabled(): void;
onDisabled(): void; onDisabled(): void;
update(): void; onEntityTransformChanged(comp: TransformComponent): void;
} }
declare class BoxCollider extends Collider { declare class BoxCollider extends Collider {
width: number; width: number;
@@ -516,6 +521,7 @@ declare class ComponentList {
deregisterAllComponents(): void; deregisterAllComponents(): void;
registerAllComponents(): void; registerAllComponents(): void;
updateLists(): void; updateLists(): void;
onEntityTransformChanged(comp: TransformComponent): void;
private handleRemove; private handleRemove;
getComponent<T extends Component>(type: any, onlyReturnInitializedComponents: boolean): T; getComponent<T extends Component>(type: any, onlyReturnInitializedComponents: boolean): T;
getComponents(typeName: string | any, components?: any): any; getComponents(typeName: string | any, components?: any): any;
@@ -758,29 +764,19 @@ declare class Matrix2D {
static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D; static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D;
determinant(): number; determinant(): number;
static invert(matrix: Matrix2D, result?: Matrix2D): Matrix2D; static invert(matrix: Matrix2D, result?: Matrix2D): Matrix2D;
static createTranslation(xPosition: number, yPosition: number, result?: Matrix2D): Matrix2D; static createTranslation(xPosition: number, yPosition: number): Matrix2D;
static createTranslationVector(position: Vector2): Matrix2D;
static createRotation(radians: number, result?: Matrix2D): Matrix2D; static createRotation(radians: number, result?: Matrix2D): Matrix2D;
static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D; static createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D;
toEgretMatrix(): egret.Matrix; toEgretMatrix(): egret.Matrix;
} }
declare class Rectangle { declare class Rectangle extends egret.Rectangle {
x: number;
y: number;
width: number;
height: number;
private _tempMat;
private _transformMat;
readonly max: Vector2; readonly max: Vector2;
readonly left: number;
readonly right: number;
readonly top: number;
readonly bottom: number;
readonly center: Vector2; readonly center: Vector2;
location: Vector2; location: Vector2;
size: Vector2; size: Vector2;
constructor(x?: number, y?: number, width?: number, height?: number); intersects(value: egret.Rectangle): boolean;
intersects(value: Rectangle): boolean; containsInVec(value: Vector2): boolean;
contains(value: Vector2): boolean;
containsRect(value: Rectangle): boolean; containsRect(value: Rectangle): boolean;
getHalfSize(): Vector2; getHalfSize(): Vector2;
static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle; static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle;
@@ -789,7 +785,6 @@ declare class Rectangle {
edgeNormal: Vector2; edgeNormal: Vector2;
}; };
getClosestPointOnBoundsToOrigin(): Vector2; getClosestPointOnBoundsToOrigin(): Vector2;
calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void;
static rectEncompassingPoints(points: Vector2[]): Rectangle; static rectEncompassingPoints(points: Vector2[]): Rectangle;
} }
declare class Vector3 { declare class Vector3 {

View File

@@ -917,6 +917,8 @@ var Component = (function (_super) {
}; };
Component.prototype.debugRender = function () { Component.prototype.debugRender = function () {
}; };
Component.prototype.onEntityTransformChanged = function (comp) {
};
Component.prototype.registerComponent = function () { Component.prototype.registerComponent = function () {
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false); this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
this.entity.scene.entityProcessors.onComponentAdded(this.entity); this.entity.scene.entityProcessors.onComponentAdded(this.entity);
@@ -931,7 +933,6 @@ var Entity = (function (_super) {
__extends(Entity, _super); __extends(Entity, _super);
function Entity(name) { function Entity(name) {
var _this = _super.call(this) || this; var _this = _super.call(this) || this;
_this._position = Vector2.zero;
_this._updateOrder = 0; _this._updateOrder = 0;
_this._enabled = true; _this._enabled = true;
_this._tag = 0; _this._tag = 0;
@@ -950,10 +951,12 @@ var Entity = (function (_super) {
}); });
Object.defineProperty(Entity.prototype, "position", { Object.defineProperty(Entity.prototype, "position", {
get: function () { get: function () {
return this._position; return new Vector2(this.x, this.y);
}, },
set: function (value) { set: function (value) {
this._position = value; this.$setX(value.x);
this.$setY(value.y);
this.onEntityTransformChanged(TransformComponent.position);
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -963,8 +966,17 @@ var Entity = (function (_super) {
return new Vector2(this.scaleX, this.scaleY); return new Vector2(this.scaleX, this.scaleY);
}, },
set: function (value) { set: function (value) {
this.scaleX = value.x; this.$setScaleX(value.x);
this.scaleY = value.y; this.$setScaleY(value.y);
this.onEntityTransformChanged(TransformComponent.scale);
},
enumerable: true,
configurable: true
});
Object.defineProperty(Entity.prototype, "rotation", {
set: function (value) {
this.$setRotation(value);
this.onEntityTransformChanged(TransformComponent.rotation);
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -1074,6 +1086,9 @@ var Entity = (function (_super) {
Entity.prototype.getComponents = function (typeName, componentList) { Entity.prototype.getComponents = function (typeName, componentList) {
return this.components.getComponents(typeName, componentList); return this.components.getComponents(typeName, componentList);
}; };
Entity.prototype.onEntityTransformChanged = function (comp) {
this.components.onEntityTransformChanged(comp);
};
Entity.prototype.removeComponentForType = function (type) { Entity.prototype.removeComponentForType = function (type) {
var comp = this.getComponent(type); var comp = this.getComponent(type);
if (comp) { if (comp) {
@@ -1110,6 +1125,12 @@ var Entity = (function (_super) {
}; };
return Entity; return Entity;
}(egret.DisplayObjectContainer)); }(egret.DisplayObjectContainer));
var TransformComponent;
(function (TransformComponent) {
TransformComponent[TransformComponent["rotation"] = 0] = "rotation";
TransformComponent[TransformComponent["scale"] = 1] = "scale";
TransformComponent[TransformComponent["position"] = 2] = "position";
})(TransformComponent || (TransformComponent = {}));
var Scene = (function (_super) { var Scene = (function (_super) {
__extends(Scene, _super); __extends(Scene, _super);
function Scene() { function Scene() {
@@ -1354,6 +1375,7 @@ var Camera = (function (_super) {
_this._origin = Vector2.zero; _this._origin = Vector2.zero;
_this._minimumZoom = 0.3; _this._minimumZoom = 0.3;
_this._maximumZoom = 3; _this._maximumZoom = 3;
_this._position = Vector2.zero;
_this.followLerp = 0.1; _this.followLerp = 0.1;
_this.deadzone = new Rectangle(); _this.deadzone = new Rectangle();
_this.focusOffset = new Vector2(); _this.focusOffset = new Vector2();
@@ -1415,10 +1437,30 @@ var Camera = (function (_super) {
}); });
Object.defineProperty(Camera.prototype, "position", { Object.defineProperty(Camera.prototype, "position", {
get: function () { get: function () {
return this.entity.position; return this._position;
}, },
set: function (value) { set: function (value) {
this.entity.position = value; this._position = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Camera.prototype, "x", {
get: function () {
return this._position.x;
},
set: function (value) {
this._position.x = value;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Camera.prototype, "y", {
get: function () {
return this._position.y;
},
set: function (value) {
this._position.y = value;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
@@ -1681,22 +1723,6 @@ var SpriteRenderer = (function (_super) {
function SpriteRenderer() { function SpriteRenderer() {
return _super !== null && _super.apply(this, arguments) || this; return _super !== null && _super.apply(this, arguments) || this;
} }
Object.defineProperty(SpriteRenderer.prototype, "origin", {
get: function () {
return this._origin;
},
set: function (value) {
this.setOrigin(value);
},
enumerable: true,
configurable: true
});
SpriteRenderer.prototype.setOrigin = function (origin) {
if (this._origin != origin) {
this._origin = origin;
}
return this;
};
Object.defineProperty(SpriteRenderer.prototype, "sprite", { Object.defineProperty(SpriteRenderer.prototype, "sprite", {
get: function () { get: function () {
return this._sprite; return this._sprite;
@@ -1710,8 +1736,10 @@ var SpriteRenderer = (function (_super) {
SpriteRenderer.prototype.setSprite = function (sprite) { SpriteRenderer.prototype.setSprite = function (sprite) {
this.removeChildren(); this.removeChildren();
this._sprite = sprite; this._sprite = sprite;
if (this._sprite) if (this._sprite) {
this._origin = this._sprite.origin; this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width;
this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height;
}
this.bitmap = new egret.Bitmap(sprite.texture2D); this.bitmap = new egret.Bitmap(sprite.texture2D);
this.addChild(this.bitmap); this.addChild(this.bitmap);
return this; return this;
@@ -1736,8 +1764,8 @@ var SpriteRenderer = (function (_super) {
return this.isVisible; return this.isVisible;
}; };
SpriteRenderer.prototype.render = function (camera) { SpriteRenderer.prototype.render = function (camera) {
this.x = this.entity.position.x - this.origin.x - camera.position.x + camera.origin.x; this.x = -camera.position.x + camera.origin.x;
this.y = this.entity.position.y - this.origin.y - camera.position.y + camera.origin.y; this.y = -camera.position.y + camera.origin.y;
}; };
SpriteRenderer.prototype.onRemovedFromEntity = function () { SpriteRenderer.prototype.onRemovedFromEntity = function () {
if (this.parent) if (this.parent)
@@ -1940,27 +1968,23 @@ var Collider = (function (_super) {
function Collider() { function Collider() {
var _this = _super !== null && _super.apply(this, arguments) || this; var _this = _super !== null && _super.apply(this, arguments) || this;
_this.physicsLayer = 1 << 0; _this.physicsLayer = 1 << 0;
_this.shouldColliderScaleAndRotationWithTransform = true; _this.registeredPhysicsBounds = new Rectangle();
_this.shouldColliderScaleAndRotateWithTransform = true;
_this.collidesWithLayers = Physics.allLayers; _this.collidesWithLayers = Physics.allLayers;
_this._isPositionDirty = true;
_this._isRotationDirty = true;
_this._localOffset = new Vector2(0, 0); _this._localOffset = new Vector2(0, 0);
return _this; return _this;
} }
Object.defineProperty(Collider.prototype, "bounds", { Object.defineProperty(Collider.prototype, "bounds", {
get: function () { get: function () {
if (this._isPositionDirty || this._isRotationDirty) { var bds = this.entity.getBounds();
this.shape.recalculateBounds(this); return new Rectangle(bds.x, bds.y, bds.width, bds.height);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(Collider.prototype, "localOffset", { Object.defineProperty(Collider.prototype, "localOffset", {
get: function () { get: function () {
return this._localOffset; return new Vector2(this.x, this.y);
}, },
set: function (value) { set: function (value) {
this.setLocalOffset(value); this.setLocalOffset(value);
@@ -1971,9 +1995,9 @@ var Collider = (function (_super) {
Collider.prototype.setLocalOffset = function (offset) { Collider.prototype.setLocalOffset = function (offset) {
if (this._localOffset != offset) { if (this._localOffset != offset) {
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset; this.$setX(offset.x);
this.$setY(offset.y);
this._localOffsetLength = this._localOffset.length(); this._localOffsetLength = this._localOffset.length();
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
} }
}; };
@@ -2006,17 +2030,15 @@ var Collider = (function (_super) {
if (!(this instanceof BoxCollider)) { if (!(this instanceof BoxCollider)) {
console.error("Only box and circle colliders can be created automatically"); console.error("Only box and circle colliders can be created automatically");
} }
var renderable = this.entity.getComponent(RenderableComponent); var bounds = this.entity.getBounds();
if (renderable) { var renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
var renderbaleBounds = renderable.bounds; var width = renderbaleBounds.width / this.entity.scale.x;
var width = renderbaleBounds.width / this.entity.scale.x; var height = renderbaleBounds.height / this.entity.scale.y;
var height = renderbaleBounds.height / this.entity.scale.y; if (this instanceof BoxCollider) {
if (this instanceof BoxCollider) { var boxCollider = this;
var boxCollider = this; boxCollider.width = width;
boxCollider.width = width; boxCollider.height = height;
boxCollider.height = height; this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
}
} }
} }
this._isParentEntityAddedToScene = true; this._isParentEntityAddedToScene = true;
@@ -2028,17 +2050,13 @@ var Collider = (function (_super) {
}; };
Collider.prototype.onEnabled = function () { Collider.prototype.onEnabled = function () {
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
this._isPositionDirty = this._isRotationDirty = true;
}; };
Collider.prototype.onDisabled = function () { Collider.prototype.onDisabled = function () {
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
}; };
Collider.prototype.update = function () { Collider.prototype.onEntityTransformChanged = function (comp) {
var spriteRenderer = this.entity.getComponent(SpriteRenderer); if (this._isColliderRegistered)
if (spriteRenderer) { Physics.updateCollider(this);
this.bounds.x = spriteRenderer.x;
this.bounds.y = spriteRenderer.y;
}
}; };
return Collider; return Collider;
}(Component)); }(Component));
@@ -2065,7 +2083,6 @@ var BoxCollider = (function (_super) {
var box = this.shape; var box = this.shape;
if (width != box.width) { if (width != box.width) {
box.updateBox(width, box.height); box.updateBox(width, box.height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -2086,7 +2103,6 @@ var BoxCollider = (function (_super) {
var box = this.shape; var box = this.shape;
if (height != box.height) { if (height != box.height) {
box.updateBox(box.width, height); box.updateBox(box.width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -2096,7 +2112,6 @@ var BoxCollider = (function (_super) {
var box = this.shape; var box = this.shape;
if (width != box.width || height != box.height) { if (width != box.width || height != box.height) {
box.updateBox(width, height); box.updateBox(width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -2407,6 +2422,16 @@ var ComponentList = (function () {
this._tempBufferList.length = 0; this._tempBufferList.length = 0;
} }
}; };
ComponentList.prototype.onEntityTransformChanged = function (comp) {
for (var i = 0; i < this._components.length; i++) {
if (this._components[i].enabled)
this._components[i].onEntityTransformChanged(comp);
}
for (var i = 0; i < this._componentsToAdd.length; i++) {
if (this._componentsToAdd[i].enabled)
this._componentsToAdd[i].onEntityTransformChanged(comp);
}
};
ComponentList.prototype.handleRemove = function (component) { ComponentList.prototype.handleRemove = function (component) {
if (component instanceof RenderableComponent) if (component instanceof RenderableComponent)
this._entity.scene.renderableComponents.remove(component); this._entity.scene.renderableComponents.remove(component);
@@ -3413,8 +3438,8 @@ var Matrix2D = (function () {
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det; result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
return result; return result;
}; };
Matrix2D.createTranslation = function (xPosition, yPosition, result) { Matrix2D.createTranslation = function (xPosition, yPosition) {
result = result ? result : new Matrix2D(); var result = new Matrix2D();
result.m11 = 1; result.m11 = 1;
result.m12 = 0; result.m12 = 0;
result.m21 = 0; result.m21 = 0;
@@ -3423,6 +3448,9 @@ var Matrix2D = (function () {
result.m32 = yPosition; result.m32 = yPosition;
return result; return result;
}; };
Matrix2D.createTranslationVector = function (position) {
return this.createTranslation(position.x, position.y);
};
Matrix2D.createRotation = function (radians, result) { Matrix2D.createRotation = function (radians, result) {
result = new Matrix2D(); result = new Matrix2D();
var val1 = Math.cos(radians); var val1 = Math.cos(radians);
@@ -3450,12 +3478,10 @@ var Matrix2D = (function () {
Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0); Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0);
return Matrix2D; return Matrix2D;
}()); }());
var Rectangle = (function () { var Rectangle = (function (_super) {
function Rectangle(x, y, width, height) { __extends(Rectangle, _super);
this.x = x ? x : 0; function Rectangle() {
this.y = y ? y : 0; return _super !== null && _super.apply(this, arguments) || this;
this.width = width ? width : 0;
this.height = height ? height : 0;
} }
Object.defineProperty(Rectangle.prototype, "max", { Object.defineProperty(Rectangle.prototype, "max", {
get: function () { get: function () {
@@ -3464,34 +3490,6 @@ var Rectangle = (function () {
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(Rectangle.prototype, "left", {
get: function () {
return this.x;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "right", {
get: function () {
return this.x + this.width;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "top", {
get: function () {
return this.y;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "bottom", {
get: function () {
return this.y + this.height;
},
enumerable: true,
configurable: true
});
Object.defineProperty(Rectangle.prototype, "center", { Object.defineProperty(Rectangle.prototype, "center", {
get: function () { get: function () {
return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
@@ -3527,7 +3525,7 @@ var Rectangle = (function () {
value.top < this.bottom && value.top < this.bottom &&
this.top < value.bottom; this.top < value.bottom;
}; };
Rectangle.prototype.contains = function (value) { Rectangle.prototype.containsInVec = function (value) {
return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && return ((((this.x <= value.x) && (value.x < (this.x + this.width))) &&
(this.y <= value.y)) && (this.y <= value.y)) &&
(value.y < (this.y + this.height))); (value.y < (this.y + this.height)));
@@ -3544,11 +3542,11 @@ var Rectangle = (function () {
return new Rectangle(minX, minY, maxX - minX, maxY - minY); return new Rectangle(minX, minY, maxX - minX, maxY - minY);
}; };
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) { Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) {
var edgeNormal = new Vector2(0, 0); var edgeNormal = Vector2.zero;
var res = new Vector2(0, 0); var res = new Vector2();
res.x = MathHelper.clamp(point.x, this.left, this.right); res.x = MathHelper.clamp(point.x, this.left, this.right);
res.y = MathHelper.clamp(point.y, this.top, this.bottom); res.y = MathHelper.clamp(point.y, this.top, this.bottom);
if (this.contains(res)) { if (this.containsInVec(res)) {
var dl = res.x - this.left; var dl = res.x - this.left;
var dr = this.right - res.x; var dr = this.right - res.x;
var dt = res.y - this.top; var dt = res.y - this.top;
@@ -3572,18 +3570,14 @@ var Rectangle = (function () {
} }
} }
else { else {
if (res.x == this.left) { if (res.x == this.left)
edgeNormal.x = -1; edgeNormal.x = -1;
} if (res.x == this.right)
if (res.x == this.right) {
edgeNormal.x = 1; edgeNormal.x = 1;
} if (res.y == this.top)
if (res.y == this.top) {
edgeNormal.y = -1; edgeNormal.y = -1;
} if (res.y == this.bottom)
if (res.y == this.bottom) {
edgeNormal.y = 1; edgeNormal.y = 1;
}
} }
return { res: res, edgeNormal: edgeNormal }; return { res: res, edgeNormal: edgeNormal };
}; };
@@ -3608,40 +3602,6 @@ var Rectangle = (function () {
} }
return boundsPoint; return boundsPoint;
}; };
Rectangle.prototype.calculateBounds = function (parentPosition, position, origin, scale, rotation, width, height) {
if (rotation == 0) {
this.x = parentPosition.x + position.x - origin.x * scale.x;
this.y = parentPosition.y + position.y - origin.y * scale.y;
this.width = width * scale.x;
this.height = height * scale.y;
}
else {
var worldPosX = parentPosition.x + position.x;
var worldPosY = parentPosition.y + position.y;
this._transformMat = Matrix2D.createTranslation(-worldPosX - origin.x, -worldPosY - origin.y);
this._tempMat = Matrix2D.createScale(scale.x, scale.y);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
this._tempMat = Matrix2D.createRotation(rotation);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
this._tempMat = Matrix2D.createTranslation(worldPosX, worldPosY);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
var topLeft = new Vector2(worldPosX, worldPosY);
var topRight = new Vector2(worldPosX + width, worldPosY);
var bottomLeft = new Vector2(worldPosX, worldPosY + height);
var bottomRight = new Vector2(worldPosX + width, worldPosY + height);
topLeft = Vector2Ext.transformR(topLeft, this._transformMat);
topRight = Vector2Ext.transformR(topRight, this._transformMat);
bottomLeft = Vector2Ext.transformR(bottomLeft, this._transformMat);
bottomRight = Vector2Ext.transformR(bottomRight, this._transformMat);
var minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
var maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
var minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
var maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
this.location = new Vector2(minX, minY);
this.width = maxX - minX;
this.height = maxY - minY;
}
};
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;
@@ -3649,23 +3609,19 @@ var Rectangle = (function () {
var maxY = Number.NEGATIVE_INFINITY; var maxY = Number.NEGATIVE_INFINITY;
for (var i = 0; i < points.length; i++) { for (var i = 0; i < points.length; i++) {
var pt = points[i]; var pt = points[i];
if (pt.x < minX) { if (pt.x < minX)
minX = pt.x; minX = pt.x;
} if (pt.x > maxX)
if (pt.x > maxX) {
maxX = pt.x; maxX = pt.x;
} if (pt.y < minY)
if (pt.y < minY) {
minY = pt.y; minY = pt.y;
} if (pt.y > maxY)
if (pt.y > maxY) {
maxY = pt.y; maxY = pt.y;
}
} }
return this.fromMinMax(minX, minY, maxX, maxY); return this.fromMinMax(minX, minY, maxX, maxY);
}; };
return Rectangle; return Rectangle;
}()); }(egret.Rectangle));
var Vector3 = (function () { var Vector3 = (function () {
function Vector3(x, y, z) { function Vector3(x, y, z) {
this.x = x; this.x = x;
@@ -4064,7 +4020,7 @@ var Polygon = (function (_super) {
}; };
Polygon.prototype.recalculateBounds = function (collider) { Polygon.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset; this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotationWithTransform) { if (collider.shouldColliderScaleAndRotateWithTransform) {
var hasUnitScale = true; var hasUnitScale = true;
var tempMat = void 0; var tempMat = void 0;
var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y); var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
@@ -4076,7 +4032,7 @@ var Polygon = (function (_super) {
this.center = scaledOffset; this.center = scaledOffset;
} }
if (collider.entity.rotation != 0) { if (collider.entity.rotation != 0) {
tempMat = Matrix2D.createRotation(collider.entity.rotation); tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg; 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(); var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
@@ -4086,8 +4042,6 @@ var Polygon = (function (_super) {
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
this.isUnrotated = collider.entity.rotation == 0; this.isUnrotated = collider.entity.rotation == 0;
if (collider._isRotationDirty)
this._areEdgeNormalsDirty = true;
} }
this.position = Vector2.add(collider.entity.position, this.center); this.position = Vector2.add(collider.entity.position, this.center);
this.bounds = Rectangle.rectEncompassingPoints(this.points); this.bounds = Rectangle.rectEncompassingPoints(this.points);
@@ -4142,7 +4096,7 @@ var Box = (function (_super) {
}; };
Box.prototype.containsPoint = function (point) { Box.prototype.containsPoint = function (point) {
if (this.isUnrotated) if (this.isUnrotated)
return this.bounds.contains(point); return this.bounds.containsInVec(point);
return _super.prototype.containsPoint.call(this, point); return _super.prototype.containsPoint.call(this, point);
}; };
return Box; return Box;
@@ -4172,7 +4126,7 @@ var Circle = (function (_super) {
}; };
Circle.prototype.recalculateBounds = function (collider) { Circle.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset; this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotationWithTransform) { if (collider.shouldColliderScaleAndRotateWithTransform) {
var scale = collider.entity.scale; var scale = collider.entity.scale;
var hasUnitScale = scale.x == 1 && scale.y == 1; var hasUnitScale = scale.x == 1 && scale.y == 1;
var maxScale = Math.max(scale.x, scale.y); var maxScale = Math.max(scale.x, scale.y);
@@ -4379,7 +4333,7 @@ var ShapeCollisions = (function () {
ShapeCollisions.boxToBox = function (first, second) { ShapeCollisions.boxToBox = function (first, second) {
var result = new CollisionResult(); var result = new CollisionResult();
var minkowskiDiff = this.minkowskiDifference(first, second); var minkowskiDiff = this.minkowskiDifference(first, second);
if (minkowskiDiff.contains(new Vector2(0, 0))) { if (minkowskiDiff.containsInVec(new Vector2(0, 0))) {
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0) if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
return null; return null;
@@ -4401,6 +4355,7 @@ var SpatialHash = (function () {
function SpatialHash(cellSize) { function SpatialHash(cellSize) {
if (cellSize === void 0) { cellSize = 100; } if (cellSize === void 0) { cellSize = 100; }
this.gridBounds = new Rectangle(); this.gridBounds = new Rectangle();
this._overlapTestCircle = new Circle(0);
this._tempHashSet = []; this._tempHashSet = [];
this._cellDict = new NumberDictionary(); this._cellDict = new NumberDictionary();
this._cellSize = cellSize; this._cellSize = cellSize;
@@ -4426,10 +4381,10 @@ var SpatialHash = (function () {
collider.registeredPhysicsBounds = bounds; collider.registeredPhysicsBounds = bounds;
var p1 = this.cellCoords(bounds.x, bounds.y); var p1 = this.cellCoords(bounds.x, bounds.y);
var p2 = this.cellCoords(bounds.right, bounds.bottom); var p2 = this.cellCoords(bounds.right, bounds.bottom);
if (!this.gridBounds.contains(new Vector2(p1.x, p1.y))) { if (!this.gridBounds.containsInVec(new Vector2(p1.x, p1.y))) {
this.gridBounds = RectangleExt.union(this.gridBounds, p1); this.gridBounds = RectangleExt.union(this.gridBounds, p1);
} }
if (!this.gridBounds.contains(new Vector2(p2.x, p2.y))) { if (!this.gridBounds.containsInVec(new Vector2(p2.x, p2.y))) {
this.gridBounds = RectangleExt.union(this.gridBounds, p2); this.gridBounds = RectangleExt.union(this.gridBounds, p2);
} }
for (var x = p1.x; x <= p2.x; x++) { for (var x = p1.x; x <= p2.x; x++) {

File diff suppressed because one or more lines are too long

View File

@@ -28,7 +28,6 @@ abstract class Component extends egret.DisplayObjectContainer {
} }
public initialize(){ public initialize(){
} }
public onAddedToEntity(){ public onAddedToEntity(){
@@ -55,6 +54,14 @@ abstract class Component extends egret.DisplayObjectContainer {
} }
/**
* 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。
* @param comp
*/
public onEntityTransformChanged(comp: TransformComponent){
}
/** 内部使用 运行时不应该调用 */ /** 内部使用 运行时不应该调用 */
public registerComponent(){ public registerComponent(){
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false); this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);

View File

@@ -6,6 +6,7 @@ class Camera extends Component {
private _minimumZoom = 0.3; private _minimumZoom = 0.3;
private _maximumZoom = 3; private _maximumZoom = 3;
private _position: Vector2 = Vector2.zero;
/** /**
* 如果相机模式为cameraWindow 则会进行缓动移动 * 如果相机模式为cameraWindow 则会进行缓动移动
* 该值为移动速度 * 该值为移动速度
@@ -67,11 +68,24 @@ class Camera extends Component {
} }
public get position(){ public get position(){
return this.entity.position; return this._position;
} }
public set position(value: Vector2){ public set position(value: Vector2){
this.entity.position = value; this._position = value;
}
public get x(){
return this._position.x;
}
public set x(value: number){
this._position.x = value;
}
public get y(){
return this._position.y;
}
public set y(value: number){
this._position.y = value;
} }
constructor() { constructor() {

View File

@@ -8,12 +8,16 @@ class BoxCollider extends Collider {
this.setWidth(value); this.setWidth(value);
} }
/**
* 设置BoxCollider的宽度
* @param width
*/
public setWidth(width: number): BoxCollider{ public setWidth(width: number): BoxCollider{
this._colliderRequiresAutoSizing = false; this._colliderRequiresAutoSizing = false;
let box = this.shape as Box; let box = this.shape as Box;
if (width != box.width){ if (width != box.width){
// 更新框,改变边界,如果我们需要更新物理系统中的边界
box.updateBox(width, box.height); box.updateBox(width, box.height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
@@ -29,17 +33,24 @@ class BoxCollider extends Collider {
this.setHeight(value); this.setHeight(value);
} }
/**
* 设置BoxCollider的高度
* @param height
*/
public setHeight(height: number){ public setHeight(height: number){
this._colliderRequiresAutoSizing = false; this._colliderRequiresAutoSizing = false;
let box = this.shape as Box; let box = this.shape as Box;
if (height != box.height){ if (height != box.height){
// 更新框,改变边界,如果我们需要更新物理系统中的边界
box.updateBox(box.width, height); box.updateBox(box.width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }
} }
/**
* 零参数构造函数要求RenderableComponent在实体上这样碰撞器可以在实体被添加到场景时调整自身的大小。
*/
constructor(){ constructor(){
super(); super();
@@ -52,8 +63,8 @@ class BoxCollider extends Collider {
this._colliderRequiresAutoSizing = false; this._colliderRequiresAutoSizing = false;
let box = this.shape as Box; let box = this.shape as Box;
if (width != box.width || height != box.height){ if (width != box.width || height != box.height){
// 更新框,改变边界,如果我们需要更新物理系统中的边界
box.updateBox(width, height); box.updateBox(width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene) if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this); Physics.updateCollider(this);
} }

View File

@@ -1,32 +1,41 @@
abstract class Collider extends Component{ abstract class Collider extends Component{
/** 对撞机的基本形状 */
public shape: Shape; public shape: Shape;
/** 在处理冲突时physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法。 */
public physicsLayer = 1 << 0; public physicsLayer = 1 << 0;
/** 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件 */
public isTrigger: boolean; public isTrigger: boolean;
public registeredPhysicsBounds: Rectangle; /**
public shouldColliderScaleAndRotationWithTransform = true; * 这个对撞机在物理系统注册时的边界。
* 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。
*/
public registeredPhysicsBounds: Rectangle = new Rectangle();
/** 如果为true碰撞器将根据附加的变换缩放和旋转 */
public shouldColliderScaleAndRotateWithTransform = true;
/** 默认为所有层。 */
public collidesWithLayers = Physics.allLayers; public collidesWithLayers = Physics.allLayers;
public _localOffsetLength: number; public _localOffsetLength: number;
public _isPositionDirty = true; /** 标记来跟踪我们的实体是否被添加到场景中 */
public _isRotationDirty = true;
protected _isParentEntityAddedToScene; protected _isParentEntityAddedToScene;
protected _colliderRequiresAutoSizing; protected _colliderRequiresAutoSizing;
protected _localOffset: Vector2 = new Vector2(0, 0); protected _localOffset: Vector2 = new Vector2(0, 0);
/** 标记来记录我们是否注册了物理系统 */
protected _isColliderRegistered; protected _isColliderRegistered;
public get bounds(): Rectangle { public get bounds(): Rectangle {
if (this._isPositionDirty || this._isRotationDirty){ // this.shape.recalculateBounds(this);
this.shape.recalculateBounds(this); let bds = this.entity.getBounds();
this._isPositionDirty = this._isRotationDirty = false; return new Rectangle(bds.x, bds.y, bds.width, bds.height);
}
return this.shape.bounds;
} }
public get localOffset(){ public get localOffset(){
return this._localOffset; return new Vector2(this.x, this.y);
} }
/**
* 将localOffset添加到实体。获取碰撞器的最终位置。这允许您向一个实体添加多个碰撞器并分别定位它们。
*/
public set localOffset(value: Vector2){ public set localOffset(value: Vector2){
this.setLocalOffset(value); this.setLocalOffset(value);
} }
@@ -34,20 +43,27 @@ abstract class Collider extends Component{
public setLocalOffset(offset: Vector2){ public setLocalOffset(offset: Vector2){
if (this._localOffset != offset){ if (this._localOffset != offset){
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset; this.$setX(offset.x);
this.$setY(offset.y);
this._localOffsetLength = this._localOffset.length(); this._localOffsetLength = this._localOffset.length();
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
} }
} }
/**
* 父实体会在不同的时间调用它(当添加到场景,启用,等等)
*/
public registerColliderWithPhysicsSystem(){ public registerColliderWithPhysicsSystem(){
// 如果在将我们添加到实体之前更改了origin等属性则实体可以为null
if (this._isParentEntityAddedToScene && !this._isColliderRegistered){ if (this._isParentEntityAddedToScene && !this._isColliderRegistered){
Physics.addCollider(this); Physics.addCollider(this);
this._isColliderRegistered = true; this._isColliderRegistered = true;
} }
} }
/**
* 父实体会在不同的时候调用它(从场景中移除,禁用,等等)
*/
public unregisterColliderWithPhysicsSystem(){ public unregisterColliderWithPhysicsSystem(){
if (this._isParentEntityAddedToScene && this._isColliderRegistered){ if (this._isParentEntityAddedToScene && this._isColliderRegistered){
Physics.removeCollider(this); Physics.removeCollider(this);
@@ -55,6 +71,10 @@ abstract class Collider extends Component{
this._isColliderRegistered = false; this._isColliderRegistered = false;
} }
/**
* 检查这个形状是否与物理系统中的其他对撞机重叠
* @param other
*/
public overlaps(other: Collider){ public overlaps(other: Collider){
return this.shape.overlaps(other.shape); return this.shape.overlaps(other.shape);
} }
@@ -85,22 +105,20 @@ abstract class Collider extends Component{
console.error("Only box and circle colliders can be created automatically"); console.error("Only box and circle colliders can be created automatically");
} }
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent); let bounds = this.entity.getBounds();
if (renderable){ let renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
let renderbaleBounds = renderable.bounds;
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染 // 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染
let width = renderbaleBounds.width / this.entity.scale.x; let width = renderbaleBounds.width / this.entity.scale.x;
let height = renderbaleBounds.height / this.entity.scale.y; let height = renderbaleBounds.height / this.entity.scale.y;
if (this instanceof BoxCollider){ if (this instanceof BoxCollider){
let boxCollider = this as BoxCollider; let boxCollider = this as BoxCollider;
boxCollider.width = width; boxCollider.width = width;
boxCollider.height = height; boxCollider.height = height;
// 获取渲染的中心将其转移到本地坐标并使用它作为碰撞器的localOffset // 获取渲染的中心将其转移到本地坐标并使用它作为碰撞器的localOffset
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position); this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
}
} }
} }
@@ -115,19 +133,14 @@ abstract class Collider extends Component{
public onEnabled(){ public onEnabled(){
this.registerColliderWithPhysicsSystem(); this.registerColliderWithPhysicsSystem();
this._isPositionDirty = this._isRotationDirty = true;
} }
public onDisabled(){ public onDisabled(){
this.unregisterColliderWithPhysicsSystem(); this.unregisterColliderWithPhysicsSystem();
} }
public update(){ public onEntityTransformChanged(comp: TransformComponent){
let spriteRenderer = this.entity.getComponent(SpriteRenderer); if (this._isColliderRegistered)
// 将显示目标设置为碰撞盒 Physics.updateCollider(this);
if (spriteRenderer){
this.bounds.x = spriteRenderer.x;
this.bounds.y = spriteRenderer.y;
}
} }
} }

View File

@@ -1,3 +1,10 @@
/**
* 辅助类说明了一种处理移动的方法,它考虑了包括触发器在内的所有冲突。
* ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调。
* 一个物体只能通过移动器移动。要正确报告触发器的move方法。
*
* 请注意多个移动者相互交互将多次调用ITriggerListener。
*/
class Mover extends Component { class Mover extends Component {
private _triggerHelper: ColliderTriggerHelper; private _triggerHelper: ColliderTriggerHelper;
@@ -5,6 +12,10 @@ class Mover extends Component {
this._triggerHelper = new ColliderTriggerHelper(this.entity); this._triggerHelper = new ColliderTriggerHelper(this.entity);
} }
/**
* 计算修改运动矢量的运动,以考虑移动时可能发生的碰撞
* @param motion
*/
public calculateMovement(motion: Vector2){ public calculateMovement(motion: Vector2){
let collisionResult = new CollisionResult(); let collisionResult = new CollisionResult();
@@ -16,9 +27,11 @@ class Mover extends Component {
for (let i = 0; i < colliders.length; i ++){ for (let i = 0; i < colliders.length; i ++){
let collider = colliders[i]; let collider = colliders[i];
// 不检测触发器
if (collider.isTrigger) if (collider.isTrigger)
continue; continue;
// 获取我们在新位置可能发生碰撞的任何东西
let bounds = collider.bounds; let bounds = collider.bounds;
bounds.x += motion.x; bounds.x += motion.x;
bounds.y += motion.y; bounds.y += motion.y;
@@ -28,13 +41,16 @@ class Mover extends Component {
for (let j = 0; j < neighbors.length; j ++){ for (let j = 0; j < neighbors.length; j ++){
let neighbor = neighbors[j]; let neighbor = neighbors[j];
// 不检测触发器
if (neighbor.isTrigger) if (neighbor.isTrigger)
continue; continue;
let _internalcollisionResult = collider.collidesWith(neighbor, motion); let _internalcollisionResult = collider.collidesWith(neighbor, motion);
if (_internalcollisionResult){ if (_internalcollisionResult){
// 如果碰撞 则退回之前的移动量
motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector); motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector);
// 如果我们碰到多个对象,为了简单起见,只取第一个。
if (_internalcollisionResult.collider){ if (_internalcollisionResult.collider){
collisionResult = _internalcollisionResult; collisionResult = _internalcollisionResult;
} }

View File

@@ -1,25 +1,12 @@
class SpriteRenderer extends RenderableComponent { class SpriteRenderer extends RenderableComponent {
private _origin: Vector2;
private _sprite: Sprite; private _sprite: Sprite;
protected bitmap: egret.Bitmap; protected bitmap: egret.Bitmap;
public get origin(){ /** 应该由这个精灵显示的精灵 */
return this._origin;
}
public set origin(value: Vector2){
this.setOrigin(value);
}
public setOrigin(origin: Vector2){
if (this._origin != origin){
this._origin = origin;
}
return this;
}
/** 应该由这个精灵显示的精灵。当设置时,精灵的原点也被设置为匹配精灵.origin。 */
public get sprite(): Sprite{ public get sprite(): Sprite{
return this._sprite; return this._sprite;
} }
/** 应该由这个精灵显示的精灵。当设置时,精灵的原点也被设置为匹配精灵.origin。 */ /** 应该由这个精灵显示的精灵 */
public set sprite(value: Sprite){ public set sprite(value: Sprite){
this.setSprite(value); this.setSprite(value);
} }
@@ -27,7 +14,10 @@ class SpriteRenderer extends RenderableComponent {
public setSprite(sprite: Sprite): SpriteRenderer{ public setSprite(sprite: Sprite): SpriteRenderer{
this.removeChildren(); this.removeChildren();
this._sprite = sprite; this._sprite = sprite;
if (this._sprite) this._origin = this._sprite.origin; if (this._sprite) {
this.anchorOffsetX = this._sprite.origin.x / this._sprite.sourceRect.width;
this.anchorOffsetY = this._sprite.origin.y / this._sprite.sourceRect.height;
}
this.bitmap = new egret.Bitmap(sprite.texture2D); this.bitmap = new egret.Bitmap(sprite.texture2D);
this.addChild(this.bitmap); this.addChild(this.bitmap);
@@ -58,8 +48,8 @@ class SpriteRenderer extends RenderableComponent {
/** 渲染处理 在每个模块中处理各自的渲染逻辑 */ /** 渲染处理 在每个模块中处理各自的渲染逻辑 */
public render(camera: Camera){ public render(camera: Camera){
this.x = this.entity.position.x - this.origin.x - camera.position.x + camera.origin.x; this.x = -camera.position.x + camera.origin.x;
this.y = this.entity.position.y - this.origin.y - camera.position.y + camera.origin.y; this.y = -camera.position.y + camera.origin.y;
} }
public onRemovedFromEntity(){ public onRemovedFromEntity(){

View File

@@ -1,7 +1,6 @@
class Entity extends egret.DisplayObjectContainer { class Entity extends egret.DisplayObjectContainer {
private static _idGenerator: number; private static _idGenerator: number;
private _position: Vector2 = Vector2.zero;
public name: string; public name: string;
public readonly id: number; public readonly id: number;
/** 当前实体所属的场景 */ /** 当前实体所属的场景 */
@@ -20,11 +19,13 @@ class Entity extends egret.DisplayObjectContainer {
} }
public get position(){ public get position(){
return this._position; return new Vector2(this.x, this.y);
} }
public set position(value: Vector2){ public set position(value: Vector2){
this._position = value; this.$setX(value.x);
this.$setY(value.y);
this.onEntityTransformChanged(TransformComponent.position);
} }
public get scale(){ public get scale(){
@@ -32,8 +33,14 @@ class Entity extends egret.DisplayObjectContainer {
} }
public set scale(value: Vector2){ public set scale(value: Vector2){
this.scaleX = value.x; this.$setScaleX(value.x);
this.scaleY = value.y; this.$setScaleY(value.y);
this.onEntityTransformChanged(TransformComponent.scale);
}
public set rotation(value: number){
this.$setRotation(value);
this.onEntityTransformChanged(TransformComponent.rotation);
} }
public get enabled(){ public get enabled(){
@@ -160,6 +167,10 @@ class Entity extends egret.DisplayObjectContainer {
return this.components.getComponents(typeName, componentList); return this.components.getComponents(typeName, componentList);
} }
private onEntityTransformChanged(comp: TransformComponent){
this.components.onEntityTransformChanged(comp);
}
public removeComponentForType<T extends Component>(type){ public removeComponentForType<T extends Component>(type){
let comp = this.getComponent<T>(type); let comp = this.getComponent<T>(type);
if (comp){ if (comp){
@@ -203,4 +214,10 @@ class Entity extends egret.DisplayObjectContainer {
(child as Component).entity.destroy(); (child as Component).entity.destroy();
} }
} }
}
enum TransformComponent {
rotation,
scale,
position
} }

View File

@@ -101,6 +101,18 @@ class ComponentList {
} }
} }
public onEntityTransformChanged(comp: TransformComponent){
for (let i = 0; i < this._components.length; i ++){
if (this._components[i].enabled)
this._components[i].onEntityTransformChanged(comp);
}
for (let i = 0; i < this._componentsToAdd.length; i ++){
if (this._componentsToAdd[i].enabled)
this._componentsToAdd[i].onEntityTransformChanged(comp);
}
}
private handleRemove(component: Component){ private handleRemove(component: Component){
if (component instanceof RenderableComponent) if (component instanceof RenderableComponent)
this._entity.scene.renderableComponents.remove(component); this._entity.scene.renderableComponents.remove(component);

View File

@@ -155,8 +155,13 @@ class Matrix2D {
return result; return result;
} }
public static createTranslation(xPosition: number, yPosition: number, result?: Matrix2D){ /**
result = result ? result : new Matrix2D(); * 创建一个新的tranlation
* @param xPosition
* @param yPosition
*/
public static createTranslation(xPosition: number, yPosition: number){
let result = new Matrix2D();
result.m11 = 1; result.m11 = 1;
result.m12 = 0; result.m12 = 0;
@@ -170,6 +175,14 @@ class Matrix2D {
return result; return result;
} }
/**
* 根据position 创建一个translation
* @param position
*/
public static createTranslationVector(position: Vector2){
return this.createTranslation(position.x, position.y);
}
public static createRotation(radians: number, result?: Matrix2D){ public static createRotation(radians: number, result?: Matrix2D){
result = new Matrix2D(); result = new Matrix2D();

View File

@@ -1,43 +1,21 @@
class Rectangle { class Rectangle extends egret.Rectangle {
public x: number;
public y: number;
public width: number;
public height: number;
private _tempMat: Matrix2D;
private _transformMat: Matrix2D;
/** /**
* 获取矩形的最大点,即右下角 * 获取矩形的最大点,即右下角
*/ */
public get max(){ public get max() {
return new Vector2(this.right, this.bottom); return new Vector2(this.right, this.bottom);
} }
public get left() { /** 中心点坐标 */
return this.x;
}
public get right() {
return this.x + this.width;
}
public get top() {
return this.y;
}
public get bottom() {
return this.y + this.height;
}
public get center() { public get center() {
return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2)); return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
} }
/** 左上角的坐标 */
public get location() { public get location() {
return new Vector2(this.x, this.y); return new Vector2(this.x, this.y);
} }
/** 左上角的坐标 */
public set location(value: Vector2) { public set location(value: Vector2) {
this.x = value.x; this.x = value.x;
this.y = value.y; this.y = value.y;
@@ -52,48 +30,66 @@ class Rectangle {
this.height = value.y; this.height = value.y;
} }
constructor(x?: number, y?: number, width?: number, height?: number) { /**
this.x = x ? x : 0; * 是否与另一个矩形相交
this.y = y ? y : 0; * @param value
this.width = width ? width : 0; */
this.height = height ? height : 0; public intersects(value: egret.Rectangle) {
}
public intersects(value: Rectangle) {
return value.left < this.right && return value.left < this.right &&
this.left < value.right && this.left < value.right &&
value.top < this.bottom && value.top < this.bottom &&
this.top < value.bottom; this.top < value.bottom;
} }
public contains(value: Vector2) { /**
* 判断点是否在矩形内
* @param value
*/
public containsInVec(value: Vector2) {
return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && return ((((this.x <= value.x) && (value.x < (this.x + this.width))) &&
(this.y <= value.y)) && (this.y <= value.y)) &&
(value.y < (this.y + this.height))); (value.y < (this.y + this.height)));
} }
/**
* 获取所提供的矩形是否在此矩形的边界内
* @param value
*/
public containsRect(value: Rectangle) { public containsRect(value: Rectangle) {
return ((((this.x <= value.x) && (value.x < (this.x + this.width))) && return ((((this.x <= value.x) && (value.x < (this.x + this.width))) &&
(this.y <= value.y)) && (this.y <= value.y)) &&
(value.y < (this.y + this.height))); (value.y < (this.y + this.height)));
} }
public getHalfSize(){ public getHalfSize() {
return new Vector2(this.width * 0.5, this.height * 0.5); return new Vector2(this.width * 0.5, this.height * 0.5);
} }
/**
* 创建一个矩形的最小/最大点(左上角,右下角的点)
* @param minX
* @param minY
* @param maxX
* @param maxY
*/
public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) { public static fromMinMax(minX: number, minY: number, maxX: number, maxY: number) {
return new Rectangle(minX, minY, maxX - minX, maxY - minY); return new Rectangle(minX, minY, maxX - minX, maxY - minY);
} }
/**
* 获取矩形边界上与给定点最近的点
* @param point
*/
public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } { public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } {
let edgeNormal = new Vector2(0, 0); let edgeNormal = Vector2.zero;
let res = new Vector2(0, 0); // 对于每个轴,如果点在盒子外面
let res = new Vector2();
res.x = MathHelper.clamp(point.x, this.left, this.right); res.x = MathHelper.clamp(point.x, this.left, this.right);
res.y = MathHelper.clamp(point.y, this.top, this.bottom); res.y = MathHelper.clamp(point.y, this.top, this.bottom);
if (this.contains(res)) { // 如果点在矩形内我们需要推res到边界因为它将在矩形内
if (this.containsInVec(res)) {
let dl = res.x - this.left; let dl = res.x - this.left;
let dr = this.right - res.x; let dr = this.right - res.x;
let dt = res.y - this.top; let dt = res.y - this.top;
@@ -114,41 +110,36 @@ class Rectangle {
edgeNormal.x = 1; edgeNormal.x = 1;
} }
} else { } else {
if (res.x == this.left) { if (res.x == this.left) edgeNormal.x = -1;
edgeNormal.x = -1; if (res.x == this.right) edgeNormal.x = 1;
} if (res.y == this.top) edgeNormal.y = -1;
if (res.x == this.right) { if (res.y == this.bottom) edgeNormal.y = 1;
edgeNormal.x = 1;
}
if (res.y == this.top) {
edgeNormal.y = -1;
}
if (res.y == this.bottom) {
edgeNormal.y = 1;
}
} }
return { res: res, edgeNormal: edgeNormal }; return { res: res, edgeNormal: edgeNormal };
} }
public getClosestPointOnBoundsToOrigin(){ /**
*
*/
public getClosestPointOnBoundsToOrigin() {
let max = this.max; let max = this.max;
let minDist = Math.abs(this.location.x); let minDist = Math.abs(this.location.x);
let boundsPoint = new Vector2(this.location.x, 0); let boundsPoint = new Vector2(this.location.x, 0);
if (Math.abs(max.x) < minDist){ if (Math.abs(max.x) < minDist) {
minDist = Math.abs(max.x); minDist = Math.abs(max.x);
boundsPoint.x = max.x; boundsPoint.x = max.x;
boundsPoint.y = 0; boundsPoint.y = 0;
} }
if (Math.abs(max.y) < minDist){ if (Math.abs(max.y) < minDist) {
minDist = Math.abs(max.y); minDist = Math.abs(max.y);
boundsPoint.x = 0; boundsPoint.x = 0;
boundsPoint.y = max.y; boundsPoint.y = max.y;
} }
if (Math.abs(this.location.y) < minDist){ if (Math.abs(this.location.y) < minDist) {
minDist = Math.abs(this.location.y); minDist = Math.abs(this.location.y);
boundsPoint.x = 0; boundsPoint.x = 0;
boundsPoint.y = this.location.y; boundsPoint.y = this.location.y;
@@ -156,52 +147,13 @@ class Rectangle {
return boundsPoint; return boundsPoint;
} }
public calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2,
rotation: number, width: number, height: number) {
if (rotation == 0) {
this.x = parentPosition.x + position.x - origin.x * scale.x;
this.y = parentPosition.y + position.y - origin.y * scale.y;
this.width = width * scale.x;
this.height = height * scale.y;
} else {
let worldPosX = parentPosition.x + position.x;
let worldPosY = parentPosition.y + position.y;
this._transformMat = Matrix2D.createTranslation(-worldPosX - origin.x, -worldPosY - origin.y);
this._tempMat = Matrix2D.createScale(scale.x, scale.y);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
this._tempMat = Matrix2D.createRotation(rotation);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
this._tempMat = Matrix2D.createTranslation(worldPosX, worldPosY);
this._transformMat = Matrix2D.multiply(this._transformMat, this._tempMat);
let topLeft = new Vector2(worldPosX, worldPosY);
let topRight = new Vector2(worldPosX + width, worldPosY);
let bottomLeft = new Vector2(worldPosX, worldPosY + height);
let bottomRight = new Vector2(worldPosX + width, worldPosY + height);
topLeft = Vector2Ext.transformR(topLeft, this._transformMat);
topRight = Vector2Ext.transformR(topRight, this._transformMat);
bottomLeft = Vector2Ext.transformR(bottomLeft, this._transformMat);
bottomRight = Vector2Ext.transformR(bottomRight, this._transformMat);
let minX = Math.min(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
let maxX = Math.max(topLeft.x, bottomRight.x, topRight.x, bottomLeft.x);
let minY = Math.min(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
let maxY = Math.max(topLeft.y, bottomRight.y, topRight.y, bottomLeft.y);
this.location = new Vector2(minX, minY);
this.width = maxX - minX;
this.height = maxY - minY;
}
}
/** /**
* 给定多边形的点,计算边界 * 给定多边形的点,计算边界
* @param points * @param points
*/ */
public static rectEncompassingPoints(points: Vector2[]) { public static rectEncompassingPoints(points: Vector2[]) {
// 我们需要求出x/y的最小值/最大值
let minX = Number.POSITIVE_INFINITY; let minX = Number.POSITIVE_INFINITY;
let minY = Number.POSITIVE_INFINITY; let minY = Number.POSITIVE_INFINITY;
let maxX = Number.NEGATIVE_INFINITY; let maxX = Number.NEGATIVE_INFINITY;
@@ -210,19 +162,11 @@ class Rectangle {
for (let i = 0; i < points.length; i++) { for (let i = 0; i < points.length; i++) {
let pt = points[i]; let pt = points[i];
if (pt.x < minX) { if (pt.x < minX) minX = pt.x;
minX = pt.x; if (pt.x > maxX) maxX = pt.x;
}
if (pt.x > maxX) {
maxX = pt.x;
}
if (pt.y < minY) { if (pt.y < minY) minY = pt.y;
minY = pt.y; if (pt.y > maxY) maxY = pt.y;
}
if (pt.y > maxY) {
maxY = pt.y;
}
} }
return this.fromMinMax(minX, minY, maxX, maxY); return this.fromMinMax(minX, minY, maxX, maxY);

View File

@@ -2,13 +2,16 @@ class Physics {
private static _spatialHash: SpatialHash; private static _spatialHash: SpatialHash;
/** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */ /** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */
public static spatialHashCellSize = 100; public static spatialHashCellSize = 100;
/** 接受layerMask的所有方法的默认值 */
public static readonly allLayers: number = -1; public static readonly allLayers: number = -1;
public static reset(){ public static reset(){
this._spatialHash = new SpatialHash(this.spatialHashCellSize); this._spatialHash = new SpatialHash(this.spatialHashCellSize);
} }
/**
* 从SpatialHash中移除所有碰撞器
*/
public static clear(){ public static clear(){
this._spatialHash.clear(); this._spatialHash.clear();
} }
@@ -26,14 +29,26 @@ class Physics {
return this._spatialHash.aabbBroadphase(rect, collider, layerMask); return this._spatialHash.aabbBroadphase(rect, collider, layerMask);
} }
/**
* 将对撞机添加到物理系统中
* @param collider
*/
public static addCollider(collider: Collider){ public static addCollider(collider: Collider){
Physics._spatialHash.register(collider); Physics._spatialHash.register(collider);
} }
/**
* 从物理系统中移除对撞机
* @param collider
*/
public static removeCollider(collider: Collider){ public static removeCollider(collider: Collider){
Physics._spatialHash.remove(collider); Physics._spatialHash.remove(collider);
} }
/**
* 更新物理系统中对撞机的位置。这实际上只是移除然后重新添加带有新边界的碰撞器
* @param collider
*/
public static updateCollider(collider: Collider){ public static updateCollider(collider: Collider){
this._spatialHash.remove(collider); this._spatialHash.remove(collider);
this._spatialHash.register(collider); this._spatialHash.register(collider);

View File

@@ -1,4 +1,7 @@
///<reference path="./Polygon.ts" /> ///<reference path="./Polygon.ts" />
/**
* 多边形的特殊情况。在进行SAT碰撞检查时我们只需要检查2个轴而不是8个轴
*/
class Box extends Polygon { class Box extends Polygon {
public width: number; public width: number;
public height: number; public height: number;
@@ -9,7 +12,13 @@ class Box extends Polygon {
this.height = height; this.height = height;
} }
/**
* 在一个盒子的形状中建立多边形需要的点的帮助方法
* @param width
* @param height
*/
private static buildBox(width: number, height: number): Vector2[]{ private static buildBox(width: number, height: number): Vector2[]{
// 我们在(0,0)的中心周围创建点
let halfWidth = width / 2; let halfWidth = width / 2;
let halfHeight = height / 2; let halfHeight = height / 2;
let verts = new Array(4); let verts = new Array(4);
@@ -21,11 +30,8 @@ class Box extends Polygon {
return verts; return verts;
} }
/**
*
* @param other
*/
public overlaps(other: Shape){ public overlaps(other: Shape){
// 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测
if (this.isUnrotated){ if (this.isUnrotated){
if (other instanceof Box && other.isUnrotated) if (other instanceof Box && other.isUnrotated)
return this.bounds.intersects(other.bounds); return this.bounds.intersects(other.bounds);
@@ -37,11 +43,8 @@ class Box extends Polygon {
return super.overlaps(other); return super.overlaps(other);
} }
/**
*
* @param other
*/
public collidesWithShape(other: Shape){ public collidesWithShape(other: Shape){
// 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测
if (this.isUnrotated && other instanceof Box && other.isUnrotated){ if (this.isUnrotated && other instanceof Box && other.isUnrotated){
return ShapeCollisions.boxToBox(this, other); return ShapeCollisions.boxToBox(this, other);
} }
@@ -51,10 +54,16 @@ class Box extends Polygon {
return super.collidesWithShape(other); return super.collidesWithShape(other);
} }
/**
* 更新框点,重新计算中心,设置宽度/高度
* @param width
* @param height
*/
public updateBox(width: number, height: number){ public updateBox(width: number, height: number){
this.width = width; this.width = width;
this.height = height; this.height = height;
// 我们在(0,0)的中心周围创建点
let halfWidth = width / 2; let halfWidth = width / 2;
let halfHeight = height / 2; let halfHeight = height / 2;
@@ -69,7 +78,7 @@ class Box extends Polygon {
public containsPoint(point: Vector2){ public containsPoint(point: Vector2){
if (this.isUnrotated) if (this.isUnrotated)
return this.bounds.contains(point); return this.bounds.containsInVec(point);
return super.containsPoint(point); return super.containsPoint(point);
} }

View File

@@ -32,7 +32,7 @@ class Circle extends Shape {
public recalculateBounds(collider: Collider) { public recalculateBounds(collider: Collider) {
this.center = collider.localOffset; this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotationWithTransform) { if (collider.shouldColliderScaleAndRotateWithTransform) {
let scale = collider.entity.scale; let scale = collider.entity.scale;
let hasUnitScale = scale.x == 1 && scale.y == 1; let hasUnitScale = scale.x == 1 && scale.y == 1;
let maxScale = Math.max(scale.x, scale.y); let maxScale = Math.max(scale.x, scale.y);

View File

@@ -103,6 +103,13 @@ class Polygon extends Shape {
return new Vector2(x / points.length, y / points.length); return new Vector2(x / points.length, y / points.length);
} }
/**
* 迭代多边形的所有边,并得到任意边上离点最近的点。
* 通过最近点的平方距离和它所在的边的法线返回。
* 点应该在多边形的空间中(点-多边形.位置)
* @param points
* @param point
*/
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint, distanceSquared, edgeNormal } { public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint, distanceSquared, edgeNormal } {
let distanceSquared = Number.MAX_VALUE; let distanceSquared = Number.MAX_VALUE;
let edgeNormal = new Vector2(0, 0); let edgeNormal = new Vector2(0, 0);
@@ -121,6 +128,7 @@ class Polygon extends Shape {
distanceSquared = tempDistanceSquared; distanceSquared = tempDistanceSquared;
closestPoint = closest; closestPoint = closest;
// 求直线的法线
let line = Vector2.subtract(points[j], points[i]); let line = Vector2.subtract(points[j], points[i]);
edgeNormal.x = -line.y; edgeNormal.x = -line.y;
edgeNormal.y = line.x; edgeNormal.y = line.x;
@@ -136,7 +144,13 @@ class Polygon extends Shape {
return ShapeCollisions.pointToPoly(point, this); return ShapeCollisions.pointToPoly(point, this);
} }
/**
* 本质上,这个算法所做的就是从一个点发射一条射线。
* 如果它与奇数条多边形边相交,我们就知道它在多边形内部。
* @param point
*/
public containsPoint(point: Vector2) { public containsPoint(point: Vector2) {
// 将点归一化到多边形坐标空间中
point = Vector2.subtract(point, this.position); point = Vector2.subtract(point, this.position);
let isInside = false; let isInside = false;
@@ -171,7 +185,7 @@ class Polygon extends Shape {
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心我们会从那开始 // 如果我们没有旋转或不关心TRS我们使用localOffset作为中心我们会从那开始
this.center = collider.localOffset; this.center = collider.localOffset;
if (collider.shouldColliderScaleAndRotationWithTransform){ if (collider.shouldColliderScaleAndRotateWithTransform){
let hasUnitScale = true; let hasUnitScale = true;
let tempMat: Matrix2D; let tempMat: Matrix2D;
let combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y); let combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
@@ -188,7 +202,7 @@ class Polygon extends Shape {
} }
if (collider.entity.rotation != 0){ if (collider.entity.rotation != 0){
tempMat = Matrix2D.createRotation(collider.entity.rotation); tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat); combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
// 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动我们的偏移使角度为0 // 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动我们的偏移使角度为0
@@ -204,10 +218,6 @@ class Polygon extends Shape {
// 最后变换原始点 // 最后变换原始点
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points); Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
this.isUnrotated = collider.entity.rotation == 0; this.isUnrotated = collider.entity.rotation == 0;
// 如果旋转的话,我们只需要重建边的法线
if (collider._isRotationDirty)
this._areEdgeNormalsDirty = true;
} }
this.position = Vector2.add(collider.entity.position, this.center); this.position = Vector2.add(collider.entity.position, this.center);

View File

@@ -274,7 +274,7 @@ class ShapeCollisions {
let result = new CollisionResult(); let result = new CollisionResult();
let minkowskiDiff = this.minkowskiDifference(first, second); let minkowskiDiff = this.minkowskiDifference(first, second);
if (minkowskiDiff.contains(new Vector2(0, 0))){ if (minkowskiDiff.containsInVec(new Vector2(0, 0))){
// 计算MTV。如果它是零我们就可以称它为非碰撞 // 计算MTV。如果它是零我们就可以称它为非碰撞
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin(); result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();

View File

@@ -2,10 +2,15 @@ class SpatialHash {
public gridBounds: Rectangle = new Rectangle(); public gridBounds: Rectangle = new Rectangle();
private _raycastParser: RaycastResultParser; private _raycastParser: RaycastResultParser;
/** 散列中每个单元格的大小 */
private _cellSize: number; private _cellSize: number;
/** 1除以单元格大小。缓存结果因为它被大量使用。 */
private _inverseCellSize: number; private _inverseCellSize: number;
private _overlapTestCircle: Circle; /** 缓存的循环用于重叠检查 */
private _overlapTestCircle: Circle = new Circle(0);
/** 用于返回冲突信息的共享HashSet */
private _tempHashSet: Collider[] = []; private _tempHashSet: Collider[] = [];
/** 保存所有数据的字典 */
private _cellDict: NumberDictionary = new NumberDictionary(); private _cellDict: NumberDictionary = new NumberDictionary();
constructor(cellSize: number = 100) { constructor(cellSize: number = 100) {
@@ -14,6 +19,10 @@ class SpatialHash {
this._raycastParser = new RaycastResultParser(); this._raycastParser = new RaycastResultParser();
} }
/**
* 从SpatialHash中删除对象
* @param collider
*/
public remove(collider: Collider) { public remove(collider: Collider) {
let bounds = collider.registeredPhysicsBounds; let bounds = collider.registeredPhysicsBounds;
let p1 = this.cellCoords(bounds.x, bounds.y); let p1 = this.cellCoords(bounds.x, bounds.y);
@@ -21,6 +30,7 @@ class SpatialHash {
for (let x = p1.x; x <= p2.x; x++) { for (let x = p1.x; x <= p2.x; x++) {
for (let y = p1.y; y <= p2.y; y++) { for (let y = p1.y; y <= p2.y; y++) {
// 单元格应该始终存在,因为这个碰撞器应该在所有查询的单元格中
let cell = this.cellAtPosition(x, y); let cell = this.cellAtPosition(x, y);
if (!cell) if (!cell)
console.error(`removing Collider [${collider}] from a cell that it is not present in`); console.error(`removing Collider [${collider}] from a cell that it is not present in`);
@@ -30,22 +40,28 @@ class SpatialHash {
} }
} }
/**
* 将对象添加到SpatialHash
* @param collider
*/
public register(collider: Collider) { public register(collider: Collider) {
let bounds = collider.bounds; let bounds = collider.bounds;
collider.registeredPhysicsBounds = bounds; collider.registeredPhysicsBounds = bounds;
let p1 = this.cellCoords(bounds.x, bounds.y); let p1 = this.cellCoords(bounds.x, bounds.y);
let p2 = this.cellCoords(bounds.right, bounds.bottom); let p2 = this.cellCoords(bounds.right, bounds.bottom);
if (!this.gridBounds.contains(new Vector2(p1.x, p1.y))) { // 更新边界以跟踪网格大小
if (!this.gridBounds.containsInVec(new Vector2(p1.x, p1.y))) {
this.gridBounds = RectangleExt.union(this.gridBounds, p1); this.gridBounds = RectangleExt.union(this.gridBounds, p1);
} }
if (!this.gridBounds.contains(new Vector2(p2.x, p2.y))) { if (!this.gridBounds.containsInVec(new Vector2(p2.x, p2.y))) {
this.gridBounds = RectangleExt.union(this.gridBounds, p2); this.gridBounds = RectangleExt.union(this.gridBounds, p2);
} }
for (let x = p1.x; x <= p2.x; x++) { for (let x = p1.x; x <= p2.x; x++) {
for (let y = p1.y; y <= p2.y; y++) { for (let y = p1.y; y <= p2.y; y++) {
// 如果没有单元格,我们需要创建它
let c = this.cellAtPosition(x, y, true); let c = this.cellAtPosition(x, y, true);
c.push(collider); c.push(collider);
} }
@@ -56,6 +72,13 @@ class SpatialHash {
this._cellDict.clear(); this._cellDict.clear();
} }
/**
* 获取位于指定圆内的所有碰撞器
* @param circleCenter
* @param radius
* @param results
* @param layerMask
*/
public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask) { public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask) {
let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2); let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
@@ -82,6 +105,12 @@ class SpatialHash {
return resultCounter; return resultCounter;
} }
/**
* 返回边框与单元格相交的所有对象
* @param bounds
* @param excludeCollider
* @param layerMask
*/
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) { public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) {
this._tempHashSet.length = 0; this._tempHashSet.length = 0;
@@ -94,9 +123,11 @@ class SpatialHash {
if (!cell) if (!cell)
continue; continue;
// 当cell不为空。循环并取回所有碰撞器
for (let i = 0; i < cell.length; i++) { for (let i = 0; i < cell.length; i++) {
let collider = cell[i]; let collider = cell[i];
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer)) if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer))
continue; continue;
@@ -111,6 +142,13 @@ class SpatialHash {
return {tempHashSet: this._tempHashSet, bounds: bounds}; return {tempHashSet: this._tempHashSet, bounds: bounds};
} }
/**
* 获取世界空间x,y值的单元格。
* 如果单元格为空且createCellIfEmpty为true则会创建一个新的单元格
* @param x
* @param y
* @param createCellIfEmpty
*/
private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false) { private cellAtPosition(x: number, y: number, createCellIfEmpty: boolean = false) {
let cell: Collider[] = this._cellDict.tryGetValue(x, y); let cell: Collider[] = this._cellDict.tryGetValue(x, y);
if (!cell) { if (!cell) {
@@ -122,6 +160,11 @@ class SpatialHash {
return cell; return cell;
} }
/**
* 获取单元格的x,y值作为世界空间的x,y值
* @param x
* @param y
*/
private cellCoords(x: number, y: number): Vector2 { private cellCoords(x: number, y: number): Vector2 {
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize)); return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
} }
@@ -131,6 +174,10 @@ class RaycastResultParser {
} }
/**
* 包装一个Unit32列表碰撞器字典
* 它的主要目的是将int、int x、y坐标散列到单个Uint32键中使用O(1)查找。
*/
class NumberDictionary { class NumberDictionary {
private _store: Map<number, Collider[]> = new Map<number, Collider[]>(); private _store: Map<number, Collider[]> = new Map<number, Collider[]>();
@@ -154,6 +201,10 @@ class NumberDictionary {
this._store.set(this.getKey(x, y), list); this._store.set(this.getKey(x, y), list);
} }
/**
* 使用蛮力方法从字典存储列表中移除碰撞器
* @param obj
*/
public remove(obj: Collider) { public remove(obj: Collider) {
this._store.forEach(list => { this._store.forEach(list => {
if (list.contains(obj)) if (list.contains(obj))
@@ -165,6 +216,9 @@ class NumberDictionary {
return this._store.get(this.getKey(x, y)); return this._store.get(this.getKey(x, y));
} }
/**
* 清除字典数据
*/
public clear() { public clear() {
this._store.clear(); this._store.clear();
} }

View File

@@ -43,6 +43,15 @@ class Vector2Ext {
return vec; return vec;
} }
/**
* 通过指定的矩阵对Vector2的数组中的向量应用变换并将结果放置在另一个数组中。
* @param sourceArray
* @param sourceIndex
* @param matrix
* @param destinationArray
* @param destinationIndex
* @param length
*/
public static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D, public static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D,
destinationArray: Vector2[], destinationIndex: number, length: number) { destinationArray: Vector2[], destinationIndex: number, length: number) {
for (let i = 0; i < length; i ++){ for (let i = 0; i < length; i ++){
@@ -60,6 +69,12 @@ class Vector2Ext {
return new Vector2(x, y); return new Vector2(x, y);
} }
/**
* 通过指定的矩阵对Vector2的数组中的所有向量应用变换并将结果放到另一个数组中。
* @param sourceArray
* @param matrix
* @param destinationArray
*/
public static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]) { public static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]) {
this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length); this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length);
} }