Merge branch 'develop' of https://github.com/esengine/egret-framework into develop
This commit is contained in:
@@ -27,7 +27,7 @@
|
||||
data-entry-class="Main"
|
||||
data-orientation="auto"
|
||||
data-scale-mode="fixedWidth"
|
||||
data-frame-rate="30"
|
||||
data-frame-rate="60"
|
||||
data-content-width="640"
|
||||
data-content-height="1136"
|
||||
data-multi-fingered="2"
|
||||
|
||||
151
demo/libs/framework/framework.d.ts
vendored
151
demo/libs/framework/framework.d.ts
vendored
@@ -32,22 +32,22 @@ declare class AStarNode<T> extends PriorityQueueNode {
|
||||
data: T;
|
||||
constructor(data: T);
|
||||
}
|
||||
declare class AstarGridGraph implements IAstarGraph<Point> {
|
||||
dirs: Point[];
|
||||
walls: Point[];
|
||||
weightedNodes: Point[];
|
||||
declare class AstarGridGraph implements IAstarGraph<Vector2> {
|
||||
dirs: Vector2[];
|
||||
walls: Vector2[];
|
||||
weightedNodes: Vector2[];
|
||||
defaultWeight: number;
|
||||
weightedNodeWeight: number;
|
||||
private _width;
|
||||
private _height;
|
||||
private _neighbors;
|
||||
constructor(width: number, height: number);
|
||||
isNodeInBounds(node: Point): boolean;
|
||||
isNodePassable(node: Point): boolean;
|
||||
search(start: Point, goal: Point): Point[];
|
||||
getNeighbors(node: Point): Point[];
|
||||
cost(from: Point, to: Point): number;
|
||||
heuristic(node: Point, goal: Point): number;
|
||||
isNodeInBounds(node: Vector2): boolean;
|
||||
isNodePassable(node: Vector2): boolean;
|
||||
search(start: Vector2, goal: Vector2): Vector2[];
|
||||
getNeighbors(node: Vector2): Vector2[];
|
||||
cost(from: Vector2, to: Vector2): number;
|
||||
heuristic(node: Vector2, goal: Vector2): number;
|
||||
}
|
||||
interface IAstarGraph<T> {
|
||||
getNeighbors(node: T): Array<T>;
|
||||
@@ -84,34 +84,57 @@ declare class UnweightedGraph<T> implements IUnweightedGraph<T> {
|
||||
addEdgesForNode(node: T, edges: T[]): this;
|
||||
getNeighbors(node: T): T[];
|
||||
}
|
||||
declare class Point {
|
||||
declare class Vector2 {
|
||||
x: number;
|
||||
y: number;
|
||||
private static readonly unitYVector;
|
||||
private static readonly unitXVector;
|
||||
private static readonly unitVector2;
|
||||
private static readonly zeroVector2;
|
||||
static readonly zero: Vector2;
|
||||
static readonly one: Vector2;
|
||||
static readonly unitX: Vector2;
|
||||
static readonly unitY: Vector2;
|
||||
constructor(x?: number, y?: number);
|
||||
static add(value1: Vector2, value2: Vector2): Vector2;
|
||||
static divide(value1: Vector2, value2: Vector2): Vector2;
|
||||
static multiply(value1: Vector2, value2: Vector2): Vector2;
|
||||
static subtract(value1: Vector2, value2: Vector2): Vector2;
|
||||
normalize(): void;
|
||||
length(): number;
|
||||
round(): Vector2;
|
||||
static normalize(value: Vector2): Vector2;
|
||||
static dot(value1: Vector2, value2: Vector2): number;
|
||||
static distanceSquared(value1: Vector2, value2: Vector2): number;
|
||||
static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2;
|
||||
static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2;
|
||||
static transform(position: Vector2, matrix: Matrix2D): Vector2;
|
||||
static distance(value1: Vector2, value2: Vector2): number;
|
||||
static negate(value: Vector2): Vector2;
|
||||
}
|
||||
declare class UnweightedGridGraph implements IUnweightedGraph<Point> {
|
||||
declare class UnweightedGridGraph implements IUnweightedGraph<Vector2> {
|
||||
private static readonly CARDINAL_DIRS;
|
||||
private static readonly COMPASS_DIRS;
|
||||
walls: Point[];
|
||||
walls: Vector2[];
|
||||
private _width;
|
||||
private _hegiht;
|
||||
private _dirs;
|
||||
private _neighbors;
|
||||
constructor(width: number, height: number, allowDiagonalSearch?: boolean);
|
||||
isNodeInBounds(node: Point): boolean;
|
||||
isNodePassable(node: Point): boolean;
|
||||
getNeighbors(node: Point): Point[];
|
||||
search(start: Point, goal: Point): Point[];
|
||||
isNodeInBounds(node: Vector2): boolean;
|
||||
isNodePassable(node: Vector2): boolean;
|
||||
getNeighbors(node: Vector2): Vector2[];
|
||||
search(start: Vector2, goal: Vector2): Vector2[];
|
||||
}
|
||||
interface IWeightedGraph<T> {
|
||||
getNeighbors(node: T): T[];
|
||||
cost(from: T, to: T): number;
|
||||
}
|
||||
declare class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
static readonly CARDINAL_DIRS: Point[];
|
||||
declare class WeightedGridGraph implements IWeightedGraph<Vector2> {
|
||||
static readonly CARDINAL_DIRS: Vector2[];
|
||||
private static readonly COMPASS_DIRS;
|
||||
walls: Point[];
|
||||
weightedNodes: Point[];
|
||||
walls: Vector2[];
|
||||
weightedNodes: Vector2[];
|
||||
defaultWeight: number;
|
||||
weightedNodeWeight: number;
|
||||
private _width;
|
||||
@@ -119,11 +142,11 @@ declare class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
private _dirs;
|
||||
private _neighbors;
|
||||
constructor(width: number, height: number, allowDiagonalSearch?: boolean);
|
||||
isNodeInBounds(node: Point): boolean;
|
||||
isNodePassable(node: Point): boolean;
|
||||
search(start: Point, goal: Point): Point[];
|
||||
getNeighbors(node: Point): Point[];
|
||||
cost(from: Point, to: Point): number;
|
||||
isNodeInBounds(node: Vector2): boolean;
|
||||
isNodePassable(node: Vector2): boolean;
|
||||
search(start: Vector2, goal: Vector2): Vector2[];
|
||||
getNeighbors(node: Vector2): Vector2[];
|
||||
cost(from: Vector2, to: Vector2): number;
|
||||
}
|
||||
declare class WeightedNode<T> extends PriorityQueueNode {
|
||||
data: T;
|
||||
@@ -153,12 +176,12 @@ declare abstract class Component extends egret.DisplayObjectContainer {
|
||||
onDisabled(): void;
|
||||
update(): void;
|
||||
debugRender(): void;
|
||||
onEntityTransformChanged(comp: TransformComponent): void;
|
||||
registerComponent(): void;
|
||||
deregisterComponent(): void;
|
||||
}
|
||||
declare class Entity extends egret.DisplayObjectContainer {
|
||||
private static _idGenerator;
|
||||
private _position;
|
||||
name: string;
|
||||
readonly id: number;
|
||||
scene: Scene;
|
||||
@@ -171,6 +194,7 @@ declare class Entity extends egret.DisplayObjectContainer {
|
||||
readonly isDestoryed: boolean;
|
||||
position: Vector2;
|
||||
scale: Vector2;
|
||||
rotation: number;
|
||||
enabled: boolean;
|
||||
setEnabled(isEnabled: boolean): this;
|
||||
tag: number;
|
||||
@@ -187,6 +211,7 @@ declare class Entity extends egret.DisplayObjectContainer {
|
||||
getOrCreateComponent<T extends Component>(type: T): T;
|
||||
getComponent<T extends Component>(type: any): T;
|
||||
getComponents(typeName: string | any, componentList?: any): any;
|
||||
private onEntityTransformChanged;
|
||||
removeComponentForType<T extends Component>(type: any): boolean;
|
||||
removeComponent(component: Component): void;
|
||||
removeAllComponents(): void;
|
||||
@@ -195,6 +220,11 @@ declare class Entity extends egret.DisplayObjectContainer {
|
||||
onRemovedFromScene(): void;
|
||||
destroy(): void;
|
||||
}
|
||||
declare enum TransformComponent {
|
||||
rotation = 0,
|
||||
scale = 1,
|
||||
position = 2
|
||||
}
|
||||
declare class Scene extends egret.DisplayObjectContainer {
|
||||
camera: Camera;
|
||||
readonly entities: EntityList;
|
||||
@@ -244,6 +274,7 @@ declare class Camera extends Component {
|
||||
private _origin;
|
||||
private _minimumZoom;
|
||||
private _maximumZoom;
|
||||
private _position;
|
||||
followLerp: number;
|
||||
deadzone: Rectangle;
|
||||
focusOffset: Vector2;
|
||||
@@ -259,6 +290,8 @@ declare class Camera extends Component {
|
||||
maximumZoom: number;
|
||||
origin: Vector2;
|
||||
position: Vector2;
|
||||
x: number;
|
||||
y: number;
|
||||
constructor();
|
||||
onSceneSizeChanged(newWidth: number, newHeight: number): void;
|
||||
setMinimumZoom(minZoom: number): Camera;
|
||||
@@ -312,11 +345,8 @@ declare class Mesh extends RenderableComponent {
|
||||
reset(): void;
|
||||
}
|
||||
declare class SpriteRenderer extends RenderableComponent {
|
||||
private _origin;
|
||||
private _sprite;
|
||||
protected bitmap: egret.Bitmap;
|
||||
origin: Vector2;
|
||||
setOrigin(origin: Vector2): this;
|
||||
sprite: Sprite;
|
||||
setSprite(sprite: Sprite): SpriteRenderer;
|
||||
setColor(color: number): SpriteRenderer;
|
||||
@@ -406,11 +436,9 @@ declare abstract class Collider extends Component {
|
||||
physicsLayer: number;
|
||||
isTrigger: boolean;
|
||||
registeredPhysicsBounds: Rectangle;
|
||||
shouldColliderScaleAndRotationWithTransform: boolean;
|
||||
shouldColliderScaleAndRotateWithTransform: boolean;
|
||||
collidesWithLayers: number;
|
||||
_localOffsetLength: number;
|
||||
_isPositionDirty: boolean;
|
||||
_isRotationDirty: boolean;
|
||||
protected _isParentEntityAddedToScene: any;
|
||||
protected _colliderRequiresAutoSizing: any;
|
||||
protected _localOffset: Vector2;
|
||||
@@ -426,6 +454,7 @@ declare abstract class Collider extends Component {
|
||||
onRemovedFromEntity(): void;
|
||||
onEnabled(): void;
|
||||
onDisabled(): void;
|
||||
onEntityTransformChanged(comp: TransformComponent): void;
|
||||
}
|
||||
declare class BoxCollider extends Collider {
|
||||
width: number;
|
||||
@@ -501,6 +530,7 @@ declare class ComponentList {
|
||||
deregisterAllComponents(): void;
|
||||
registerAllComponents(): void;
|
||||
updateLists(): void;
|
||||
onEntityTransformChanged(comp: TransformComponent): void;
|
||||
private handleRemove;
|
||||
getComponent<T extends Component>(type: any, onlyReturnInitializedComponents: boolean): T;
|
||||
getComponents(typeName: string | any, components?: any): any;
|
||||
@@ -743,68 +773,29 @@ declare class Matrix2D {
|
||||
static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D;
|
||||
determinant(): number;
|
||||
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 createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D;
|
||||
toEgretMatrix(): egret.Matrix;
|
||||
}
|
||||
declare class Rectangle {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
private _tempMat;
|
||||
private _transformMat;
|
||||
declare class Rectangle extends egret.Rectangle {
|
||||
readonly max: Vector2;
|
||||
readonly left: number;
|
||||
readonly right: number;
|
||||
readonly top: number;
|
||||
readonly bottom: number;
|
||||
readonly center: Vector2;
|
||||
location: Vector2;
|
||||
size: Vector2;
|
||||
constructor(x?: number, y?: number, width?: number, height?: number);
|
||||
intersects(value: Rectangle): boolean;
|
||||
contains(value: Vector2): boolean;
|
||||
intersects(value: egret.Rectangle): boolean;
|
||||
containsInVec(value: Vector2): boolean;
|
||||
containsRect(value: Rectangle): boolean;
|
||||
getHalfSize(): Vector2;
|
||||
static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle;
|
||||
getClosestPointOnRectangleBorderToPoint(point: Point): {
|
||||
getClosestPointOnRectangleBorderToPoint(point: Vector2): {
|
||||
res: Vector2;
|
||||
edgeNormal: Vector2;
|
||||
};
|
||||
getClosestPointOnBoundsToOrigin(): Vector2;
|
||||
calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void;
|
||||
static rectEncompassingPoints(points: Vector2[]): Rectangle;
|
||||
}
|
||||
declare class Vector2 {
|
||||
x: number;
|
||||
y: number;
|
||||
private static readonly unitYVector;
|
||||
private static readonly unitXVector;
|
||||
private static readonly unitVector2;
|
||||
private static readonly zeroVector2;
|
||||
static readonly zero: Vector2;
|
||||
static readonly one: Vector2;
|
||||
static readonly unitX: Vector2;
|
||||
static readonly unitY: Vector2;
|
||||
constructor(x?: number, y?: number);
|
||||
static add(value1: Vector2, value2: Vector2): Vector2;
|
||||
static divide(value1: Vector2, value2: Vector2): Vector2;
|
||||
static multiply(value1: Vector2, value2: Vector2): Vector2;
|
||||
static subtract(value1: Vector2, value2: Vector2): Vector2;
|
||||
normalize(): void;
|
||||
length(): number;
|
||||
round(): Vector2;
|
||||
static normalize(value: Vector2): Vector2;
|
||||
static dot(value1: Vector2, value2: Vector2): number;
|
||||
static distanceSquared(value1: Vector2, value2: Vector2): number;
|
||||
static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2;
|
||||
static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2;
|
||||
static transform(position: Vector2, matrix: Matrix2D): Vector2;
|
||||
static distance(value1: Vector2, value2: Vector2): number;
|
||||
static negate(value: Vector2): Vector2;
|
||||
}
|
||||
declare class Vector3 {
|
||||
x: number;
|
||||
y: number;
|
||||
@@ -937,7 +928,7 @@ declare class ShapeCollisions {
|
||||
static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2;
|
||||
static pointToPoly(point: Vector2, poly: Polygon): CollisionResult;
|
||||
static circleToCircle(first: Circle, second: Circle): CollisionResult;
|
||||
static boxToBox(first: Box, second: Box): false | CollisionResult;
|
||||
static boxToBox(first: Box, second: Box): CollisionResult;
|
||||
private static minkowskiDifference;
|
||||
}
|
||||
declare class SpatialHash {
|
||||
@@ -1044,7 +1035,7 @@ declare class Pair<T> {
|
||||
equals(other: Pair<T>): boolean;
|
||||
}
|
||||
declare class RectangleExt {
|
||||
static union(first: Rectangle, point: Point): Rectangle;
|
||||
static union(first: Rectangle, point: Vector2): Rectangle;
|
||||
static unionR(value1: Rectangle, value2: Rectangle): Rectangle;
|
||||
}
|
||||
declare class Triangulator {
|
||||
|
||||
@@ -361,10 +361,10 @@ var AStarNode = (function (_super) {
|
||||
var AstarGridGraph = (function () {
|
||||
function AstarGridGraph(width, height) {
|
||||
this.dirs = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, 1)
|
||||
];
|
||||
this.walls = [];
|
||||
this.weightedNodes = [];
|
||||
@@ -387,7 +387,7 @@ var AstarGridGraph = (function () {
|
||||
var _this = this;
|
||||
this._neighbors.length = 0;
|
||||
this.dirs.forEach(function (dir) {
|
||||
var next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
var next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (_this.isNodeInBounds(next) && _this.isNodePassable(next))
|
||||
_this._neighbors.push(next);
|
||||
});
|
||||
@@ -583,12 +583,113 @@ var UnweightedGraph = (function () {
|
||||
};
|
||||
return UnweightedGraph;
|
||||
}());
|
||||
var Point = (function () {
|
||||
function Point(x, y) {
|
||||
var Vector2 = (function () {
|
||||
function Vector2(x, y) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : this.x;
|
||||
}
|
||||
return Point;
|
||||
Object.defineProperty(Vector2, "zero", {
|
||||
get: function () {
|
||||
return Vector2.zeroVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "one", {
|
||||
get: function () {
|
||||
return Vector2.unitVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitX", {
|
||||
get: function () {
|
||||
return Vector2.unitXVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitY", {
|
||||
get: function () {
|
||||
return Vector2.unitYVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Vector2.add = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x + value2.x;
|
||||
result.y = value1.y + value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.divide = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x / value2.x;
|
||||
result.y = value1.y / value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.multiply = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x * value2.x;
|
||||
result.y = value1.y * value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.subtract = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x - value2.x;
|
||||
result.y = value1.y - value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.prototype.normalize = function () {
|
||||
var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
};
|
||||
Vector2.prototype.length = function () {
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
};
|
||||
Vector2.prototype.round = function () {
|
||||
return new Vector2(Math.round(this.x), Math.round(this.y));
|
||||
};
|
||||
Vector2.normalize = function (value) {
|
||||
var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y));
|
||||
value.x *= val;
|
||||
value.y *= val;
|
||||
return value;
|
||||
};
|
||||
Vector2.dot = function (value1, value2) {
|
||||
return (value1.x * value2.x) + (value1.y * value2.y);
|
||||
};
|
||||
Vector2.distanceSquared = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return (v1 * v1) + (v2 * v2);
|
||||
};
|
||||
Vector2.clamp = function (value1, min, max) {
|
||||
return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), MathHelper.clamp(value1.y, min.y, max.y));
|
||||
};
|
||||
Vector2.lerp = function (value1, value2, amount) {
|
||||
return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount));
|
||||
};
|
||||
Vector2.transform = function (position, matrix) {
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
};
|
||||
Vector2.distance = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return Math.sqrt((v1 * v1) + (v2 * v2));
|
||||
};
|
||||
Vector2.negate = function (value) {
|
||||
var result = new Vector2();
|
||||
result.x = -value.x;
|
||||
result.y = -value.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.unitYVector = new Vector2(0, 1);
|
||||
Vector2.unitXVector = new Vector2(1, 0);
|
||||
Vector2.unitVector2 = new Vector2(1, 1);
|
||||
Vector2.zeroVector2 = new Vector2(0, 0);
|
||||
return Vector2;
|
||||
}());
|
||||
var UnweightedGridGraph = (function () {
|
||||
function UnweightedGridGraph(width, height, allowDiagonalSearch) {
|
||||
@@ -609,7 +710,7 @@ var UnweightedGridGraph = (function () {
|
||||
var _this = this;
|
||||
this._neighbors.length = 0;
|
||||
this._dirs.forEach(function (dir) {
|
||||
var next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
var next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (_this.isNodeInBounds(next) && _this.isNodePassable(next))
|
||||
_this._neighbors.push(next);
|
||||
});
|
||||
@@ -619,20 +720,20 @@ var UnweightedGridGraph = (function () {
|
||||
return BreadthFirstPathfinder.search(this, start, goal);
|
||||
};
|
||||
UnweightedGridGraph.CARDINAL_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, -1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, -1)
|
||||
];
|
||||
UnweightedGridGraph.COMPASS_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(1, -1),
|
||||
new Point(0, -1),
|
||||
new Point(-1, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(-1, 1),
|
||||
new Point(0, 1),
|
||||
new Point(1, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, -1),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(-1, 1),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
];
|
||||
return UnweightedGridGraph;
|
||||
}());
|
||||
@@ -661,7 +762,7 @@ var WeightedGridGraph = (function () {
|
||||
var _this = this;
|
||||
this._neighbors.length = 0;
|
||||
this._dirs.forEach(function (dir) {
|
||||
var next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
var next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (_this.isNodeInBounds(next) && _this.isNodePassable(next))
|
||||
_this._neighbors.push(next);
|
||||
});
|
||||
@@ -671,20 +772,20 @@ var WeightedGridGraph = (function () {
|
||||
return this.weightedNodes.find(function (t) { return JSON.stringify(t) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
};
|
||||
WeightedGridGraph.CARDINAL_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, 1)
|
||||
];
|
||||
WeightedGridGraph.COMPASS_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(1, -1),
|
||||
new Point(0, -1),
|
||||
new Point(-1, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(-1, 1),
|
||||
new Point(0, 1),
|
||||
new Point(1, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, -1),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(-1, 1),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
];
|
||||
return WeightedGridGraph;
|
||||
}());
|
||||
@@ -816,6 +917,8 @@ var Component = (function (_super) {
|
||||
};
|
||||
Component.prototype.debugRender = function () {
|
||||
};
|
||||
Component.prototype.onEntityTransformChanged = function (comp) {
|
||||
};
|
||||
Component.prototype.registerComponent = function () {
|
||||
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
|
||||
this.entity.scene.entityProcessors.onComponentAdded(this.entity);
|
||||
@@ -830,7 +933,6 @@ var Entity = (function (_super) {
|
||||
__extends(Entity, _super);
|
||||
function Entity(name) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this._position = Vector2.zero;
|
||||
_this._updateOrder = 0;
|
||||
_this._enabled = true;
|
||||
_this._tag = 0;
|
||||
@@ -849,10 +951,12 @@ var Entity = (function (_super) {
|
||||
});
|
||||
Object.defineProperty(Entity.prototype, "position", {
|
||||
get: function () {
|
||||
return this._position;
|
||||
return new Vector2(this.x, this.y);
|
||||
},
|
||||
set: function (value) {
|
||||
this._position = value;
|
||||
this.$setX(value.x);
|
||||
this.$setY(value.y);
|
||||
this.onEntityTransformChanged(TransformComponent.position);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
@@ -862,8 +966,17 @@ var Entity = (function (_super) {
|
||||
return new Vector2(this.scaleX, this.scaleY);
|
||||
},
|
||||
set: function (value) {
|
||||
this.scaleX = value.x;
|
||||
this.scaleY = value.y;
|
||||
this.$setScaleX(value.x);
|
||||
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,
|
||||
configurable: true
|
||||
@@ -973,6 +1086,9 @@ var Entity = (function (_super) {
|
||||
Entity.prototype.getComponents = function (typeName, componentList) {
|
||||
return this.components.getComponents(typeName, componentList);
|
||||
};
|
||||
Entity.prototype.onEntityTransformChanged = function (comp) {
|
||||
this.components.onEntityTransformChanged(comp);
|
||||
};
|
||||
Entity.prototype.removeComponentForType = function (type) {
|
||||
var comp = this.getComponent(type);
|
||||
if (comp) {
|
||||
@@ -1009,6 +1125,12 @@ var Entity = (function (_super) {
|
||||
};
|
||||
return Entity;
|
||||
}(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) {
|
||||
__extends(Scene, _super);
|
||||
function Scene() {
|
||||
@@ -1112,6 +1234,8 @@ var Scene = (function (_super) {
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
this.unload();
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
};
|
||||
Scene.prototype.onStart = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
@@ -1251,6 +1375,7 @@ var Camera = (function (_super) {
|
||||
_this._origin = Vector2.zero;
|
||||
_this._minimumZoom = 0.3;
|
||||
_this._maximumZoom = 3;
|
||||
_this._position = Vector2.zero;
|
||||
_this.followLerp = 0.1;
|
||||
_this.deadzone = new Rectangle();
|
||||
_this.focusOffset = new Vector2();
|
||||
@@ -1312,10 +1437,30 @@ var Camera = (function (_super) {
|
||||
});
|
||||
Object.defineProperty(Camera.prototype, "position", {
|
||||
get: function () {
|
||||
return this.entity.position;
|
||||
return this._position;
|
||||
},
|
||||
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,
|
||||
configurable: true
|
||||
@@ -1553,22 +1698,6 @@ var SpriteRenderer = (function (_super) {
|
||||
function SpriteRenderer() {
|
||||
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", {
|
||||
get: function () {
|
||||
return this._sprite;
|
||||
@@ -1582,8 +1711,10 @@ var SpriteRenderer = (function (_super) {
|
||||
SpriteRenderer.prototype.setSprite = function (sprite) {
|
||||
this.removeChildren();
|
||||
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.addChild(this.bitmap);
|
||||
return this;
|
||||
@@ -1608,8 +1739,8 @@ var SpriteRenderer = (function (_super) {
|
||||
return this.isVisible;
|
||||
};
|
||||
SpriteRenderer.prototype.render = function (camera) {
|
||||
this.x = this.entity.position.x - this.origin.x - camera.position.x + camera.origin.x;
|
||||
this.y = this.entity.position.y - this.origin.y - camera.position.y + camera.origin.y;
|
||||
this.x = -camera.position.x + camera.origin.x;
|
||||
this.y = -camera.position.y + camera.origin.y;
|
||||
};
|
||||
SpriteRenderer.prototype.onRemovedFromEntity = function () {
|
||||
if (this.parent)
|
||||
@@ -1874,27 +2005,23 @@ var Collider = (function (_super) {
|
||||
function Collider() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.physicsLayer = 1 << 0;
|
||||
_this.shouldColliderScaleAndRotationWithTransform = true;
|
||||
_this.registeredPhysicsBounds = new Rectangle();
|
||||
_this.shouldColliderScaleAndRotateWithTransform = true;
|
||||
_this.collidesWithLayers = Physics.allLayers;
|
||||
_this._isPositionDirty = true;
|
||||
_this._isRotationDirty = true;
|
||||
_this._localOffset = new Vector2(0, 0);
|
||||
return _this;
|
||||
}
|
||||
Object.defineProperty(Collider.prototype, "bounds", {
|
||||
get: function () {
|
||||
if (this._isPositionDirty || this._isRotationDirty) {
|
||||
this.shape.recalculateBounds(this);
|
||||
this._isPositionDirty = this._isRotationDirty = false;
|
||||
}
|
||||
return this.shape.bounds;
|
||||
var bds = this.entity.getBounds();
|
||||
return new Rectangle(bds.x, bds.y, bds.width, bds.height);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Collider.prototype, "localOffset", {
|
||||
get: function () {
|
||||
return this._localOffset;
|
||||
return new Vector2(this.x, this.y);
|
||||
},
|
||||
set: function (value) {
|
||||
this.setLocalOffset(value);
|
||||
@@ -1905,9 +2032,9 @@ var Collider = (function (_super) {
|
||||
Collider.prototype.setLocalOffset = function (offset) {
|
||||
if (this._localOffset != offset) {
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
this._localOffset = offset;
|
||||
this.$setX(offset.x);
|
||||
this.$setY(offset.y);
|
||||
this._localOffsetLength = this._localOffset.length();
|
||||
this._isPositionDirty = true;
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
}
|
||||
};
|
||||
@@ -1940,17 +2067,15 @@ var Collider = (function (_super) {
|
||||
if (!(this instanceof BoxCollider)) {
|
||||
console.error("Only box and circle colliders can be created automatically");
|
||||
}
|
||||
var renderable = this.entity.getComponent(RenderableComponent);
|
||||
if (renderable) {
|
||||
var renderbaleBounds = renderable.bounds;
|
||||
var width = renderbaleBounds.width / this.entity.scale.x;
|
||||
var height = renderbaleBounds.height / this.entity.scale.y;
|
||||
if (this instanceof BoxCollider) {
|
||||
var boxCollider = this;
|
||||
boxCollider.width = width;
|
||||
boxCollider.height = height;
|
||||
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
|
||||
}
|
||||
var bounds = this.entity.getBounds();
|
||||
var renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
var width = renderbaleBounds.width / this.entity.scale.x;
|
||||
var height = renderbaleBounds.height / this.entity.scale.y;
|
||||
if (this instanceof BoxCollider) {
|
||||
var boxCollider = this;
|
||||
boxCollider.width = width;
|
||||
boxCollider.height = height;
|
||||
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
|
||||
}
|
||||
}
|
||||
this._isParentEntityAddedToScene = true;
|
||||
@@ -1962,11 +2087,14 @@ var Collider = (function (_super) {
|
||||
};
|
||||
Collider.prototype.onEnabled = function () {
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
this._isPositionDirty = this._isRotationDirty = true;
|
||||
};
|
||||
Collider.prototype.onDisabled = function () {
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
};
|
||||
Collider.prototype.onEntityTransformChanged = function (comp) {
|
||||
if (this._isColliderRegistered)
|
||||
Physics.updateCollider(this);
|
||||
};
|
||||
return Collider;
|
||||
}(Component));
|
||||
var BoxCollider = (function (_super) {
|
||||
@@ -1992,7 +2120,6 @@ var BoxCollider = (function (_super) {
|
||||
var box = this.shape;
|
||||
if (width != box.width) {
|
||||
box.updateBox(width, box.height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -2013,7 +2140,6 @@ var BoxCollider = (function (_super) {
|
||||
var box = this.shape;
|
||||
if (height != box.height) {
|
||||
box.updateBox(box.width, height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -2023,7 +2149,6 @@ var BoxCollider = (function (_super) {
|
||||
var box = this.shape;
|
||||
if (width != box.width || height != box.height) {
|
||||
box.updateBox(width, height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -2334,6 +2459,16 @@ var ComponentList = (function () {
|
||||
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) {
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
@@ -3340,8 +3475,8 @@ var Matrix2D = (function () {
|
||||
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
|
||||
return result;
|
||||
};
|
||||
Matrix2D.createTranslation = function (xPosition, yPosition, result) {
|
||||
result = result ? result : new Matrix2D();
|
||||
Matrix2D.createTranslation = function (xPosition, yPosition) {
|
||||
var result = new Matrix2D();
|
||||
result.m11 = 1;
|
||||
result.m12 = 0;
|
||||
result.m21 = 0;
|
||||
@@ -3350,6 +3485,9 @@ var Matrix2D = (function () {
|
||||
result.m32 = yPosition;
|
||||
return result;
|
||||
};
|
||||
Matrix2D.createTranslationVector = function (position) {
|
||||
return this.createTranslation(position.x, position.y);
|
||||
};
|
||||
Matrix2D.createRotation = function (radians, result) {
|
||||
result = new Matrix2D();
|
||||
var val1 = Math.cos(radians);
|
||||
@@ -3377,12 +3515,10 @@ var Matrix2D = (function () {
|
||||
Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0);
|
||||
return Matrix2D;
|
||||
}());
|
||||
var Rectangle = (function () {
|
||||
function Rectangle(x, y, width, height) {
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : 0;
|
||||
this.width = width ? width : 0;
|
||||
this.height = height ? height : 0;
|
||||
var Rectangle = (function (_super) {
|
||||
__extends(Rectangle, _super);
|
||||
function Rectangle() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Object.defineProperty(Rectangle.prototype, "max", {
|
||||
get: function () {
|
||||
@@ -3391,34 +3527,6 @@ var Rectangle = (function () {
|
||||
enumerable: 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", {
|
||||
get: function () {
|
||||
return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
|
||||
@@ -3454,7 +3562,7 @@ var Rectangle = (function () {
|
||||
value.top < this.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))) &&
|
||||
(this.y <= value.y)) &&
|
||||
(value.y < (this.y + this.height)));
|
||||
@@ -3471,11 +3579,11 @@ var Rectangle = (function () {
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
};
|
||||
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) {
|
||||
var edgeNormal = new Vector2(0, 0);
|
||||
var res = new Vector2(0, 0);
|
||||
var edgeNormal = Vector2.zero;
|
||||
var res = new Vector2();
|
||||
res.x = MathHelper.clamp(point.x, this.left, this.right);
|
||||
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 dr = this.right - res.x;
|
||||
var dt = res.y - this.top;
|
||||
@@ -3499,18 +3607,14 @@ var Rectangle = (function () {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (res.x == this.left) {
|
||||
if (res.x == this.left)
|
||||
edgeNormal.x = -1;
|
||||
}
|
||||
if (res.x == this.right) {
|
||||
if (res.x == this.right)
|
||||
edgeNormal.x = 1;
|
||||
}
|
||||
if (res.y == this.top) {
|
||||
if (res.y == this.top)
|
||||
edgeNormal.y = -1;
|
||||
}
|
||||
if (res.y == this.bottom) {
|
||||
if (res.y == this.bottom)
|
||||
edgeNormal.y = 1;
|
||||
}
|
||||
}
|
||||
return { res: res, edgeNormal: edgeNormal };
|
||||
};
|
||||
@@ -3535,40 +3639,6 @@ var Rectangle = (function () {
|
||||
}
|
||||
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) {
|
||||
var minX = Number.POSITIVE_INFINITY;
|
||||
var minY = Number.POSITIVE_INFINITY;
|
||||
@@ -3576,131 +3646,19 @@ var Rectangle = (function () {
|
||||
var maxY = Number.NEGATIVE_INFINITY;
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var pt = points[i];
|
||||
if (pt.x < minX) {
|
||||
if (pt.x < minX)
|
||||
minX = pt.x;
|
||||
}
|
||||
if (pt.x > maxX) {
|
||||
if (pt.x > maxX)
|
||||
maxX = pt.x;
|
||||
}
|
||||
if (pt.y < minY) {
|
||||
if (pt.y < minY)
|
||||
minY = pt.y;
|
||||
}
|
||||
if (pt.y > maxY) {
|
||||
if (pt.y > maxY)
|
||||
maxY = pt.y;
|
||||
}
|
||||
}
|
||||
return this.fromMinMax(minX, minY, maxX, maxY);
|
||||
};
|
||||
return Rectangle;
|
||||
}());
|
||||
var Vector2 = (function () {
|
||||
function Vector2(x, y) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : this.x;
|
||||
}
|
||||
Object.defineProperty(Vector2, "zero", {
|
||||
get: function () {
|
||||
return Vector2.zeroVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "one", {
|
||||
get: function () {
|
||||
return Vector2.unitVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitX", {
|
||||
get: function () {
|
||||
return Vector2.unitXVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitY", {
|
||||
get: function () {
|
||||
return Vector2.unitYVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Vector2.add = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x + value2.x;
|
||||
result.y = value1.y + value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.divide = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x / value2.x;
|
||||
result.y = value1.y / value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.multiply = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x * value2.x;
|
||||
result.y = value1.y * value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.subtract = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x - value2.x;
|
||||
result.y = value1.y - value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.prototype.normalize = function () {
|
||||
var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
};
|
||||
Vector2.prototype.length = function () {
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
};
|
||||
Vector2.prototype.round = function () {
|
||||
return new Vector2(Math.round(this.x), Math.round(this.y));
|
||||
};
|
||||
Vector2.normalize = function (value) {
|
||||
var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y));
|
||||
value.x *= val;
|
||||
value.y *= val;
|
||||
return value;
|
||||
};
|
||||
Vector2.dot = function (value1, value2) {
|
||||
return (value1.x * value2.x) + (value1.y * value2.y);
|
||||
};
|
||||
Vector2.distanceSquared = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return (v1 * v1) + (v2 * v2);
|
||||
};
|
||||
Vector2.clamp = function (value1, min, max) {
|
||||
return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), MathHelper.clamp(value1.y, min.y, max.y));
|
||||
};
|
||||
Vector2.lerp = function (value1, value2, amount) {
|
||||
return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount));
|
||||
};
|
||||
Vector2.transform = function (position, matrix) {
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
};
|
||||
Vector2.distance = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return Math.sqrt((v1 * v1) + (v2 * v2));
|
||||
};
|
||||
Vector2.negate = function (value) {
|
||||
var result = new Vector2();
|
||||
result.x = -value.x;
|
||||
result.y = -value.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.unitYVector = new Vector2(0, 1);
|
||||
Vector2.unitXVector = new Vector2(1, 0);
|
||||
Vector2.unitVector2 = new Vector2(1, 1);
|
||||
Vector2.zeroVector2 = new Vector2(0, 0);
|
||||
return Vector2;
|
||||
}());
|
||||
}(egret.Rectangle));
|
||||
var Vector3 = (function () {
|
||||
function Vector3(x, y, z) {
|
||||
this.x = x;
|
||||
@@ -4099,7 +4057,7 @@ var Polygon = (function (_super) {
|
||||
};
|
||||
Polygon.prototype.recalculateBounds = function (collider) {
|
||||
this.center = collider.localOffset;
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform) {
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||
var hasUnitScale = true;
|
||||
var tempMat = void 0;
|
||||
var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
|
||||
@@ -4111,7 +4069,7 @@ var Polygon = (function (_super) {
|
||||
this.center = scaledOffset;
|
||||
}
|
||||
if (collider.entity.rotation != 0) {
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation);
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg;
|
||||
var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
|
||||
@@ -4121,8 +4079,6 @@ var Polygon = (function (_super) {
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
|
||||
this.isUnrotated = collider.entity.rotation == 0;
|
||||
if (collider._isRotationDirty)
|
||||
this._areEdgeNormalsDirty = true;
|
||||
}
|
||||
this.position = Vector2.add(collider.entity.position, this.center);
|
||||
this.bounds = Rectangle.rectEncompassingPoints(this.points);
|
||||
@@ -4177,7 +4133,7 @@ var Box = (function (_super) {
|
||||
};
|
||||
Box.prototype.containsPoint = function (point) {
|
||||
if (this.isUnrotated)
|
||||
return this.bounds.contains(point);
|
||||
return this.bounds.containsInVec(point);
|
||||
return _super.prototype.containsPoint.call(this, point);
|
||||
};
|
||||
return Box;
|
||||
@@ -4207,7 +4163,7 @@ var Circle = (function (_super) {
|
||||
};
|
||||
Circle.prototype.recalculateBounds = function (collider) {
|
||||
this.center = collider.localOffset;
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform) {
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||
var scale = collider.entity.scale;
|
||||
var hasUnitScale = scale.x == 1 && scale.y == 1;
|
||||
var maxScale = Math.max(scale.x, scale.y);
|
||||
@@ -4291,7 +4247,7 @@ var ShapeCollisions = (function () {
|
||||
}
|
||||
}
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis), new Vector2(minIntervalDistance));
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance));
|
||||
return result;
|
||||
};
|
||||
ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) {
|
||||
@@ -4414,10 +4370,10 @@ var ShapeCollisions = (function () {
|
||||
ShapeCollisions.boxToBox = function (first, second) {
|
||||
var result = new CollisionResult();
|
||||
var minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(new Vector2(0, 0))) {
|
||||
if (minkowskiDiff.containsInVec(new Vector2(0, 0))) {
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
if (result.minimumTranslationVector == Vector2.zero)
|
||||
return false;
|
||||
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
|
||||
return null;
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
return result;
|
||||
@@ -4436,6 +4392,7 @@ var SpatialHash = (function () {
|
||||
function SpatialHash(cellSize) {
|
||||
if (cellSize === void 0) { cellSize = 100; }
|
||||
this.gridBounds = new Rectangle();
|
||||
this._overlapTestCircle = new Circle(0);
|
||||
this._tempHashSet = [];
|
||||
this._cellDict = new NumberDictionary();
|
||||
this._cellSize = cellSize;
|
||||
@@ -4461,10 +4418,10 @@ var SpatialHash = (function () {
|
||||
collider.registeredPhysicsBounds = bounds;
|
||||
var p1 = this.cellCoords(bounds.x, bounds.y);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
for (var x = p1.x; x <= p2.x; x++) {
|
||||
@@ -4533,7 +4490,7 @@ var SpatialHash = (function () {
|
||||
return cell;
|
||||
};
|
||||
SpatialHash.prototype.cellCoords = function (x, y) {
|
||||
return new Point(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
};
|
||||
return SpatialHash;
|
||||
}());
|
||||
|
||||
2
demo/libs/framework/framework.min.js
vendored
2
demo/libs/framework/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -15,13 +15,13 @@ class MainScene extends Scene {
|
||||
bg.addComponent(new PlayerController());
|
||||
bg.addComponent(new Mover());
|
||||
bg.addComponent(new BoxCollider());
|
||||
bg.position = new Vector2(Math.random() * 200, Math.random() * 200);
|
||||
bg.position = new Vector2(300, 300);
|
||||
|
||||
for (let i = 0; i < 100; i++) {
|
||||
for (let i = 0; i < 1; i++) {
|
||||
let sprite = new Sprite(RES.getRes("checkbox_select_disabled_png"));
|
||||
let player2 = this.createEntity("player2");
|
||||
player2.addComponent(new SpriteRenderer()).setSprite(sprite);
|
||||
player2.position = new Vector2(Math.random() * 100 * i, Math.random() * 100 * i);
|
||||
player2.position = new Vector2(200, 200);
|
||||
player2.addComponent(new BoxCollider());
|
||||
}
|
||||
|
||||
@@ -63,24 +63,24 @@ class MainScene extends Scene {
|
||||
public dijkstraTest() {
|
||||
let graph = new WeightedGridGraph(20, 20);
|
||||
|
||||
graph.weightedNodes.push(new Point(3, 3));
|
||||
graph.weightedNodes.push(new Point(3, 4));
|
||||
graph.weightedNodes.push(new Point(4, 3));
|
||||
graph.weightedNodes.push(new Point(4, 4));
|
||||
graph.weightedNodes.push(new Vector2(3, 3));
|
||||
graph.weightedNodes.push(new Vector2(3, 4));
|
||||
graph.weightedNodes.push(new Vector2(4, 3));
|
||||
graph.weightedNodes.push(new Vector2(4, 4));
|
||||
|
||||
let path = graph.search(new Point(3, 4), new Point(15, 17));
|
||||
let path = graph.search(new Vector2(3, 4), new Vector2(15, 17));
|
||||
console.log(path);
|
||||
}
|
||||
|
||||
public astarTest() {
|
||||
let graph = new AstarGridGraph(20, 20);
|
||||
|
||||
graph.weightedNodes.push(new Point(3, 3));
|
||||
graph.weightedNodes.push(new Point(3, 4));
|
||||
graph.weightedNodes.push(new Point(4, 3));
|
||||
graph.weightedNodes.push(new Point(4, 4));
|
||||
graph.weightedNodes.push(new Vector2(3, 3));
|
||||
graph.weightedNodes.push(new Vector2(3, 4));
|
||||
graph.weightedNodes.push(new Vector2(4, 3));
|
||||
graph.weightedNodes.push(new Vector2(4, 4));
|
||||
|
||||
let path = graph.search(new Point(3, 4), new Point(15, 17));
|
||||
let path = graph.search(new Vector2(3, 4), new Vector2(15, 17));
|
||||
console.log(path);
|
||||
}
|
||||
}
|
||||
@@ -34,23 +34,23 @@ class PlayerController extends Component {
|
||||
return;
|
||||
|
||||
if (this.down){
|
||||
let camera = SceneManager.scene.camera;
|
||||
let moveLeft: number = 0;
|
||||
let moveRight: number = 0;
|
||||
let speed = 200;
|
||||
let worldPos = Input.touchPosition;
|
||||
if (worldPos.x < this.spriteRenderer.x){
|
||||
moveLeft = -1;
|
||||
} else if(worldPos.x > this.spriteRenderer.x){
|
||||
moveLeft = 1;
|
||||
}
|
||||
// let camera = SceneManager.scene.camera;
|
||||
// let moveLeft: number = 0;
|
||||
// let moveRight: number = 0;
|
||||
// let speed = 100;
|
||||
// let worldPos = Input.touchPosition;
|
||||
// if (worldPos.x < this.spriteRenderer.x){
|
||||
// moveLeft = -1;
|
||||
// } else if(worldPos.x > this.spriteRenderer.x){
|
||||
// moveLeft = 1;
|
||||
// }
|
||||
|
||||
if (worldPos.y < this.spriteRenderer.y){
|
||||
moveRight = -1;
|
||||
} else if(worldPos.y > this.spriteRenderer.y){
|
||||
moveRight = 1;
|
||||
}
|
||||
this.mover.move(new Vector2(moveLeft * speed * Time.deltaTime, moveRight * speed * Time.deltaTime));
|
||||
// if (worldPos.y < this.spriteRenderer.y){
|
||||
// moveRight = -1;
|
||||
// } else if(worldPos.y > this.spriteRenderer.y){
|
||||
// moveRight = 1;
|
||||
// }
|
||||
this.mover.move(new Vector2(-1, -1));
|
||||
}
|
||||
}
|
||||
}
|
||||
151
source/bin/framework.d.ts
vendored
151
source/bin/framework.d.ts
vendored
@@ -32,22 +32,22 @@ declare class AStarNode<T> extends PriorityQueueNode {
|
||||
data: T;
|
||||
constructor(data: T);
|
||||
}
|
||||
declare class AstarGridGraph implements IAstarGraph<Point> {
|
||||
dirs: Point[];
|
||||
walls: Point[];
|
||||
weightedNodes: Point[];
|
||||
declare class AstarGridGraph implements IAstarGraph<Vector2> {
|
||||
dirs: Vector2[];
|
||||
walls: Vector2[];
|
||||
weightedNodes: Vector2[];
|
||||
defaultWeight: number;
|
||||
weightedNodeWeight: number;
|
||||
private _width;
|
||||
private _height;
|
||||
private _neighbors;
|
||||
constructor(width: number, height: number);
|
||||
isNodeInBounds(node: Point): boolean;
|
||||
isNodePassable(node: Point): boolean;
|
||||
search(start: Point, goal: Point): Point[];
|
||||
getNeighbors(node: Point): Point[];
|
||||
cost(from: Point, to: Point): number;
|
||||
heuristic(node: Point, goal: Point): number;
|
||||
isNodeInBounds(node: Vector2): boolean;
|
||||
isNodePassable(node: Vector2): boolean;
|
||||
search(start: Vector2, goal: Vector2): Vector2[];
|
||||
getNeighbors(node: Vector2): Vector2[];
|
||||
cost(from: Vector2, to: Vector2): number;
|
||||
heuristic(node: Vector2, goal: Vector2): number;
|
||||
}
|
||||
interface IAstarGraph<T> {
|
||||
getNeighbors(node: T): Array<T>;
|
||||
@@ -84,34 +84,57 @@ declare class UnweightedGraph<T> implements IUnweightedGraph<T> {
|
||||
addEdgesForNode(node: T, edges: T[]): this;
|
||||
getNeighbors(node: T): T[];
|
||||
}
|
||||
declare class Point {
|
||||
declare class Vector2 {
|
||||
x: number;
|
||||
y: number;
|
||||
private static readonly unitYVector;
|
||||
private static readonly unitXVector;
|
||||
private static readonly unitVector2;
|
||||
private static readonly zeroVector2;
|
||||
static readonly zero: Vector2;
|
||||
static readonly one: Vector2;
|
||||
static readonly unitX: Vector2;
|
||||
static readonly unitY: Vector2;
|
||||
constructor(x?: number, y?: number);
|
||||
static add(value1: Vector2, value2: Vector2): Vector2;
|
||||
static divide(value1: Vector2, value2: Vector2): Vector2;
|
||||
static multiply(value1: Vector2, value2: Vector2): Vector2;
|
||||
static subtract(value1: Vector2, value2: Vector2): Vector2;
|
||||
normalize(): void;
|
||||
length(): number;
|
||||
round(): Vector2;
|
||||
static normalize(value: Vector2): Vector2;
|
||||
static dot(value1: Vector2, value2: Vector2): number;
|
||||
static distanceSquared(value1: Vector2, value2: Vector2): number;
|
||||
static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2;
|
||||
static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2;
|
||||
static transform(position: Vector2, matrix: Matrix2D): Vector2;
|
||||
static distance(value1: Vector2, value2: Vector2): number;
|
||||
static negate(value: Vector2): Vector2;
|
||||
}
|
||||
declare class UnweightedGridGraph implements IUnweightedGraph<Point> {
|
||||
declare class UnweightedGridGraph implements IUnweightedGraph<Vector2> {
|
||||
private static readonly CARDINAL_DIRS;
|
||||
private static readonly COMPASS_DIRS;
|
||||
walls: Point[];
|
||||
walls: Vector2[];
|
||||
private _width;
|
||||
private _hegiht;
|
||||
private _dirs;
|
||||
private _neighbors;
|
||||
constructor(width: number, height: number, allowDiagonalSearch?: boolean);
|
||||
isNodeInBounds(node: Point): boolean;
|
||||
isNodePassable(node: Point): boolean;
|
||||
getNeighbors(node: Point): Point[];
|
||||
search(start: Point, goal: Point): Point[];
|
||||
isNodeInBounds(node: Vector2): boolean;
|
||||
isNodePassable(node: Vector2): boolean;
|
||||
getNeighbors(node: Vector2): Vector2[];
|
||||
search(start: Vector2, goal: Vector2): Vector2[];
|
||||
}
|
||||
interface IWeightedGraph<T> {
|
||||
getNeighbors(node: T): T[];
|
||||
cost(from: T, to: T): number;
|
||||
}
|
||||
declare class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
static readonly CARDINAL_DIRS: Point[];
|
||||
declare class WeightedGridGraph implements IWeightedGraph<Vector2> {
|
||||
static readonly CARDINAL_DIRS: Vector2[];
|
||||
private static readonly COMPASS_DIRS;
|
||||
walls: Point[];
|
||||
weightedNodes: Point[];
|
||||
walls: Vector2[];
|
||||
weightedNodes: Vector2[];
|
||||
defaultWeight: number;
|
||||
weightedNodeWeight: number;
|
||||
private _width;
|
||||
@@ -119,11 +142,11 @@ declare class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
private _dirs;
|
||||
private _neighbors;
|
||||
constructor(width: number, height: number, allowDiagonalSearch?: boolean);
|
||||
isNodeInBounds(node: Point): boolean;
|
||||
isNodePassable(node: Point): boolean;
|
||||
search(start: Point, goal: Point): Point[];
|
||||
getNeighbors(node: Point): Point[];
|
||||
cost(from: Point, to: Point): number;
|
||||
isNodeInBounds(node: Vector2): boolean;
|
||||
isNodePassable(node: Vector2): boolean;
|
||||
search(start: Vector2, goal: Vector2): Vector2[];
|
||||
getNeighbors(node: Vector2): Vector2[];
|
||||
cost(from: Vector2, to: Vector2): number;
|
||||
}
|
||||
declare class WeightedNode<T> extends PriorityQueueNode {
|
||||
data: T;
|
||||
@@ -153,12 +176,12 @@ declare abstract class Component extends egret.DisplayObjectContainer {
|
||||
onDisabled(): void;
|
||||
update(): void;
|
||||
debugRender(): void;
|
||||
onEntityTransformChanged(comp: TransformComponent): void;
|
||||
registerComponent(): void;
|
||||
deregisterComponent(): void;
|
||||
}
|
||||
declare class Entity extends egret.DisplayObjectContainer {
|
||||
private static _idGenerator;
|
||||
private _position;
|
||||
name: string;
|
||||
readonly id: number;
|
||||
scene: Scene;
|
||||
@@ -171,6 +194,7 @@ declare class Entity extends egret.DisplayObjectContainer {
|
||||
readonly isDestoryed: boolean;
|
||||
position: Vector2;
|
||||
scale: Vector2;
|
||||
rotation: number;
|
||||
enabled: boolean;
|
||||
setEnabled(isEnabled: boolean): this;
|
||||
tag: number;
|
||||
@@ -187,6 +211,7 @@ declare class Entity extends egret.DisplayObjectContainer {
|
||||
getOrCreateComponent<T extends Component>(type: T): T;
|
||||
getComponent<T extends Component>(type: any): T;
|
||||
getComponents(typeName: string | any, componentList?: any): any;
|
||||
private onEntityTransformChanged;
|
||||
removeComponentForType<T extends Component>(type: any): boolean;
|
||||
removeComponent(component: Component): void;
|
||||
removeAllComponents(): void;
|
||||
@@ -195,6 +220,11 @@ declare class Entity extends egret.DisplayObjectContainer {
|
||||
onRemovedFromScene(): void;
|
||||
destroy(): void;
|
||||
}
|
||||
declare enum TransformComponent {
|
||||
rotation = 0,
|
||||
scale = 1,
|
||||
position = 2
|
||||
}
|
||||
declare class Scene extends egret.DisplayObjectContainer {
|
||||
camera: Camera;
|
||||
readonly entities: EntityList;
|
||||
@@ -244,6 +274,7 @@ declare class Camera extends Component {
|
||||
private _origin;
|
||||
private _minimumZoom;
|
||||
private _maximumZoom;
|
||||
private _position;
|
||||
followLerp: number;
|
||||
deadzone: Rectangle;
|
||||
focusOffset: Vector2;
|
||||
@@ -259,6 +290,8 @@ declare class Camera extends Component {
|
||||
maximumZoom: number;
|
||||
origin: Vector2;
|
||||
position: Vector2;
|
||||
x: number;
|
||||
y: number;
|
||||
constructor();
|
||||
onSceneSizeChanged(newWidth: number, newHeight: number): void;
|
||||
setMinimumZoom(minZoom: number): Camera;
|
||||
@@ -312,11 +345,8 @@ declare class Mesh extends RenderableComponent {
|
||||
reset(): void;
|
||||
}
|
||||
declare class SpriteRenderer extends RenderableComponent {
|
||||
private _origin;
|
||||
private _sprite;
|
||||
protected bitmap: egret.Bitmap;
|
||||
origin: Vector2;
|
||||
setOrigin(origin: Vector2): this;
|
||||
sprite: Sprite;
|
||||
setSprite(sprite: Sprite): SpriteRenderer;
|
||||
setColor(color: number): SpriteRenderer;
|
||||
@@ -406,11 +436,9 @@ declare abstract class Collider extends Component {
|
||||
physicsLayer: number;
|
||||
isTrigger: boolean;
|
||||
registeredPhysicsBounds: Rectangle;
|
||||
shouldColliderScaleAndRotationWithTransform: boolean;
|
||||
shouldColliderScaleAndRotateWithTransform: boolean;
|
||||
collidesWithLayers: number;
|
||||
_localOffsetLength: number;
|
||||
_isPositionDirty: boolean;
|
||||
_isRotationDirty: boolean;
|
||||
protected _isParentEntityAddedToScene: any;
|
||||
protected _colliderRequiresAutoSizing: any;
|
||||
protected _localOffset: Vector2;
|
||||
@@ -426,6 +454,7 @@ declare abstract class Collider extends Component {
|
||||
onRemovedFromEntity(): void;
|
||||
onEnabled(): void;
|
||||
onDisabled(): void;
|
||||
onEntityTransformChanged(comp: TransformComponent): void;
|
||||
}
|
||||
declare class BoxCollider extends Collider {
|
||||
width: number;
|
||||
@@ -501,6 +530,7 @@ declare class ComponentList {
|
||||
deregisterAllComponents(): void;
|
||||
registerAllComponents(): void;
|
||||
updateLists(): void;
|
||||
onEntityTransformChanged(comp: TransformComponent): void;
|
||||
private handleRemove;
|
||||
getComponent<T extends Component>(type: any, onlyReturnInitializedComponents: boolean): T;
|
||||
getComponents(typeName: string | any, components?: any): any;
|
||||
@@ -743,68 +773,29 @@ declare class Matrix2D {
|
||||
static multiplyTranslation(matrix: Matrix2D, x: number, y: number): Matrix2D;
|
||||
determinant(): number;
|
||||
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 createScale(xScale: number, yScale: number, result?: Matrix2D): Matrix2D;
|
||||
toEgretMatrix(): egret.Matrix;
|
||||
}
|
||||
declare class Rectangle {
|
||||
x: number;
|
||||
y: number;
|
||||
width: number;
|
||||
height: number;
|
||||
private _tempMat;
|
||||
private _transformMat;
|
||||
declare class Rectangle extends egret.Rectangle {
|
||||
readonly max: Vector2;
|
||||
readonly left: number;
|
||||
readonly right: number;
|
||||
readonly top: number;
|
||||
readonly bottom: number;
|
||||
readonly center: Vector2;
|
||||
location: Vector2;
|
||||
size: Vector2;
|
||||
constructor(x?: number, y?: number, width?: number, height?: number);
|
||||
intersects(value: Rectangle): boolean;
|
||||
contains(value: Vector2): boolean;
|
||||
intersects(value: egret.Rectangle): boolean;
|
||||
containsInVec(value: Vector2): boolean;
|
||||
containsRect(value: Rectangle): boolean;
|
||||
getHalfSize(): Vector2;
|
||||
static fromMinMax(minX: number, minY: number, maxX: number, maxY: number): Rectangle;
|
||||
getClosestPointOnRectangleBorderToPoint(point: Point): {
|
||||
getClosestPointOnRectangleBorderToPoint(point: Vector2): {
|
||||
res: Vector2;
|
||||
edgeNormal: Vector2;
|
||||
};
|
||||
getClosestPointOnBoundsToOrigin(): Vector2;
|
||||
calculateBounds(parentPosition: Vector2, position: Vector2, origin: Vector2, scale: Vector2, rotation: number, width: number, height: number): void;
|
||||
static rectEncompassingPoints(points: Vector2[]): Rectangle;
|
||||
}
|
||||
declare class Vector2 {
|
||||
x: number;
|
||||
y: number;
|
||||
private static readonly unitYVector;
|
||||
private static readonly unitXVector;
|
||||
private static readonly unitVector2;
|
||||
private static readonly zeroVector2;
|
||||
static readonly zero: Vector2;
|
||||
static readonly one: Vector2;
|
||||
static readonly unitX: Vector2;
|
||||
static readonly unitY: Vector2;
|
||||
constructor(x?: number, y?: number);
|
||||
static add(value1: Vector2, value2: Vector2): Vector2;
|
||||
static divide(value1: Vector2, value2: Vector2): Vector2;
|
||||
static multiply(value1: Vector2, value2: Vector2): Vector2;
|
||||
static subtract(value1: Vector2, value2: Vector2): Vector2;
|
||||
normalize(): void;
|
||||
length(): number;
|
||||
round(): Vector2;
|
||||
static normalize(value: Vector2): Vector2;
|
||||
static dot(value1: Vector2, value2: Vector2): number;
|
||||
static distanceSquared(value1: Vector2, value2: Vector2): number;
|
||||
static clamp(value1: Vector2, min: Vector2, max: Vector2): Vector2;
|
||||
static lerp(value1: Vector2, value2: Vector2, amount: number): Vector2;
|
||||
static transform(position: Vector2, matrix: Matrix2D): Vector2;
|
||||
static distance(value1: Vector2, value2: Vector2): number;
|
||||
static negate(value: Vector2): Vector2;
|
||||
}
|
||||
declare class Vector3 {
|
||||
x: number;
|
||||
y: number;
|
||||
@@ -937,7 +928,7 @@ declare class ShapeCollisions {
|
||||
static closestPointOnLine(lineA: Vector2, lineB: Vector2, closestTo: Vector2): Vector2;
|
||||
static pointToPoly(point: Vector2, poly: Polygon): CollisionResult;
|
||||
static circleToCircle(first: Circle, second: Circle): CollisionResult;
|
||||
static boxToBox(first: Box, second: Box): false | CollisionResult;
|
||||
static boxToBox(first: Box, second: Box): CollisionResult;
|
||||
private static minkowskiDifference;
|
||||
}
|
||||
declare class SpatialHash {
|
||||
@@ -1044,7 +1035,7 @@ declare class Pair<T> {
|
||||
equals(other: Pair<T>): boolean;
|
||||
}
|
||||
declare class RectangleExt {
|
||||
static union(first: Rectangle, point: Point): Rectangle;
|
||||
static union(first: Rectangle, point: Vector2): Rectangle;
|
||||
static unionR(value1: Rectangle, value2: Rectangle): Rectangle;
|
||||
}
|
||||
declare class Triangulator {
|
||||
|
||||
@@ -361,10 +361,10 @@ var AStarNode = (function (_super) {
|
||||
var AstarGridGraph = (function () {
|
||||
function AstarGridGraph(width, height) {
|
||||
this.dirs = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, 1)
|
||||
];
|
||||
this.walls = [];
|
||||
this.weightedNodes = [];
|
||||
@@ -387,7 +387,7 @@ var AstarGridGraph = (function () {
|
||||
var _this = this;
|
||||
this._neighbors.length = 0;
|
||||
this.dirs.forEach(function (dir) {
|
||||
var next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
var next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (_this.isNodeInBounds(next) && _this.isNodePassable(next))
|
||||
_this._neighbors.push(next);
|
||||
});
|
||||
@@ -583,12 +583,113 @@ var UnweightedGraph = (function () {
|
||||
};
|
||||
return UnweightedGraph;
|
||||
}());
|
||||
var Point = (function () {
|
||||
function Point(x, y) {
|
||||
var Vector2 = (function () {
|
||||
function Vector2(x, y) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : this.x;
|
||||
}
|
||||
return Point;
|
||||
Object.defineProperty(Vector2, "zero", {
|
||||
get: function () {
|
||||
return Vector2.zeroVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "one", {
|
||||
get: function () {
|
||||
return Vector2.unitVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitX", {
|
||||
get: function () {
|
||||
return Vector2.unitXVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitY", {
|
||||
get: function () {
|
||||
return Vector2.unitYVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Vector2.add = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x + value2.x;
|
||||
result.y = value1.y + value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.divide = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x / value2.x;
|
||||
result.y = value1.y / value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.multiply = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x * value2.x;
|
||||
result.y = value1.y * value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.subtract = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x - value2.x;
|
||||
result.y = value1.y - value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.prototype.normalize = function () {
|
||||
var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
};
|
||||
Vector2.prototype.length = function () {
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
};
|
||||
Vector2.prototype.round = function () {
|
||||
return new Vector2(Math.round(this.x), Math.round(this.y));
|
||||
};
|
||||
Vector2.normalize = function (value) {
|
||||
var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y));
|
||||
value.x *= val;
|
||||
value.y *= val;
|
||||
return value;
|
||||
};
|
||||
Vector2.dot = function (value1, value2) {
|
||||
return (value1.x * value2.x) + (value1.y * value2.y);
|
||||
};
|
||||
Vector2.distanceSquared = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return (v1 * v1) + (v2 * v2);
|
||||
};
|
||||
Vector2.clamp = function (value1, min, max) {
|
||||
return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), MathHelper.clamp(value1.y, min.y, max.y));
|
||||
};
|
||||
Vector2.lerp = function (value1, value2, amount) {
|
||||
return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount));
|
||||
};
|
||||
Vector2.transform = function (position, matrix) {
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
};
|
||||
Vector2.distance = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return Math.sqrt((v1 * v1) + (v2 * v2));
|
||||
};
|
||||
Vector2.negate = function (value) {
|
||||
var result = new Vector2();
|
||||
result.x = -value.x;
|
||||
result.y = -value.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.unitYVector = new Vector2(0, 1);
|
||||
Vector2.unitXVector = new Vector2(1, 0);
|
||||
Vector2.unitVector2 = new Vector2(1, 1);
|
||||
Vector2.zeroVector2 = new Vector2(0, 0);
|
||||
return Vector2;
|
||||
}());
|
||||
var UnweightedGridGraph = (function () {
|
||||
function UnweightedGridGraph(width, height, allowDiagonalSearch) {
|
||||
@@ -609,7 +710,7 @@ var UnweightedGridGraph = (function () {
|
||||
var _this = this;
|
||||
this._neighbors.length = 0;
|
||||
this._dirs.forEach(function (dir) {
|
||||
var next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
var next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (_this.isNodeInBounds(next) && _this.isNodePassable(next))
|
||||
_this._neighbors.push(next);
|
||||
});
|
||||
@@ -619,20 +720,20 @@ var UnweightedGridGraph = (function () {
|
||||
return BreadthFirstPathfinder.search(this, start, goal);
|
||||
};
|
||||
UnweightedGridGraph.CARDINAL_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, -1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, -1)
|
||||
];
|
||||
UnweightedGridGraph.COMPASS_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(1, -1),
|
||||
new Point(0, -1),
|
||||
new Point(-1, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(-1, 1),
|
||||
new Point(0, 1),
|
||||
new Point(1, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, -1),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(-1, 1),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
];
|
||||
return UnweightedGridGraph;
|
||||
}());
|
||||
@@ -661,7 +762,7 @@ var WeightedGridGraph = (function () {
|
||||
var _this = this;
|
||||
this._neighbors.length = 0;
|
||||
this._dirs.forEach(function (dir) {
|
||||
var next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
var next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (_this.isNodeInBounds(next) && _this.isNodePassable(next))
|
||||
_this._neighbors.push(next);
|
||||
});
|
||||
@@ -671,20 +772,20 @@ var WeightedGridGraph = (function () {
|
||||
return this.weightedNodes.find(function (t) { return JSON.stringify(t) == JSON.stringify(to); }) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
};
|
||||
WeightedGridGraph.CARDINAL_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, 1)
|
||||
];
|
||||
WeightedGridGraph.COMPASS_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(1, -1),
|
||||
new Point(0, -1),
|
||||
new Point(-1, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(-1, 1),
|
||||
new Point(0, 1),
|
||||
new Point(1, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, -1),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(-1, 1),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
];
|
||||
return WeightedGridGraph;
|
||||
}());
|
||||
@@ -816,6 +917,8 @@ var Component = (function (_super) {
|
||||
};
|
||||
Component.prototype.debugRender = function () {
|
||||
};
|
||||
Component.prototype.onEntityTransformChanged = function (comp) {
|
||||
};
|
||||
Component.prototype.registerComponent = function () {
|
||||
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
|
||||
this.entity.scene.entityProcessors.onComponentAdded(this.entity);
|
||||
@@ -830,7 +933,6 @@ var Entity = (function (_super) {
|
||||
__extends(Entity, _super);
|
||||
function Entity(name) {
|
||||
var _this = _super.call(this) || this;
|
||||
_this._position = Vector2.zero;
|
||||
_this._updateOrder = 0;
|
||||
_this._enabled = true;
|
||||
_this._tag = 0;
|
||||
@@ -849,10 +951,12 @@ var Entity = (function (_super) {
|
||||
});
|
||||
Object.defineProperty(Entity.prototype, "position", {
|
||||
get: function () {
|
||||
return this._position;
|
||||
return new Vector2(this.x, this.y);
|
||||
},
|
||||
set: function (value) {
|
||||
this._position = value;
|
||||
this.$setX(value.x);
|
||||
this.$setY(value.y);
|
||||
this.onEntityTransformChanged(TransformComponent.position);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
@@ -862,8 +966,17 @@ var Entity = (function (_super) {
|
||||
return new Vector2(this.scaleX, this.scaleY);
|
||||
},
|
||||
set: function (value) {
|
||||
this.scaleX = value.x;
|
||||
this.scaleY = value.y;
|
||||
this.$setScaleX(value.x);
|
||||
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,
|
||||
configurable: true
|
||||
@@ -973,6 +1086,9 @@ var Entity = (function (_super) {
|
||||
Entity.prototype.getComponents = function (typeName, componentList) {
|
||||
return this.components.getComponents(typeName, componentList);
|
||||
};
|
||||
Entity.prototype.onEntityTransformChanged = function (comp) {
|
||||
this.components.onEntityTransformChanged(comp);
|
||||
};
|
||||
Entity.prototype.removeComponentForType = function (type) {
|
||||
var comp = this.getComponent(type);
|
||||
if (comp) {
|
||||
@@ -1009,6 +1125,12 @@ var Entity = (function (_super) {
|
||||
};
|
||||
return Entity;
|
||||
}(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) {
|
||||
__extends(Scene, _super);
|
||||
function Scene() {
|
||||
@@ -1112,6 +1234,8 @@ var Scene = (function (_super) {
|
||||
if (this.entityProcessors)
|
||||
this.entityProcessors.end();
|
||||
this.unload();
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
};
|
||||
Scene.prototype.onStart = function () {
|
||||
return __awaiter(this, void 0, void 0, function () {
|
||||
@@ -1251,6 +1375,7 @@ var Camera = (function (_super) {
|
||||
_this._origin = Vector2.zero;
|
||||
_this._minimumZoom = 0.3;
|
||||
_this._maximumZoom = 3;
|
||||
_this._position = Vector2.zero;
|
||||
_this.followLerp = 0.1;
|
||||
_this.deadzone = new Rectangle();
|
||||
_this.focusOffset = new Vector2();
|
||||
@@ -1312,10 +1437,30 @@ var Camera = (function (_super) {
|
||||
});
|
||||
Object.defineProperty(Camera.prototype, "position", {
|
||||
get: function () {
|
||||
return this.entity.position;
|
||||
return this._position;
|
||||
},
|
||||
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,
|
||||
configurable: true
|
||||
@@ -1553,22 +1698,6 @@ var SpriteRenderer = (function (_super) {
|
||||
function SpriteRenderer() {
|
||||
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", {
|
||||
get: function () {
|
||||
return this._sprite;
|
||||
@@ -1582,8 +1711,10 @@ var SpriteRenderer = (function (_super) {
|
||||
SpriteRenderer.prototype.setSprite = function (sprite) {
|
||||
this.removeChildren();
|
||||
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.addChild(this.bitmap);
|
||||
return this;
|
||||
@@ -1608,8 +1739,8 @@ var SpriteRenderer = (function (_super) {
|
||||
return this.isVisible;
|
||||
};
|
||||
SpriteRenderer.prototype.render = function (camera) {
|
||||
this.x = this.entity.position.x - this.origin.x - camera.position.x + camera.origin.x;
|
||||
this.y = this.entity.position.y - this.origin.y - camera.position.y + camera.origin.y;
|
||||
this.x = -camera.position.x + camera.origin.x;
|
||||
this.y = -camera.position.y + camera.origin.y;
|
||||
};
|
||||
SpriteRenderer.prototype.onRemovedFromEntity = function () {
|
||||
if (this.parent)
|
||||
@@ -1874,27 +2005,23 @@ var Collider = (function (_super) {
|
||||
function Collider() {
|
||||
var _this = _super !== null && _super.apply(this, arguments) || this;
|
||||
_this.physicsLayer = 1 << 0;
|
||||
_this.shouldColliderScaleAndRotationWithTransform = true;
|
||||
_this.registeredPhysicsBounds = new Rectangle();
|
||||
_this.shouldColliderScaleAndRotateWithTransform = true;
|
||||
_this.collidesWithLayers = Physics.allLayers;
|
||||
_this._isPositionDirty = true;
|
||||
_this._isRotationDirty = true;
|
||||
_this._localOffset = new Vector2(0, 0);
|
||||
return _this;
|
||||
}
|
||||
Object.defineProperty(Collider.prototype, "bounds", {
|
||||
get: function () {
|
||||
if (this._isPositionDirty || this._isRotationDirty) {
|
||||
this.shape.recalculateBounds(this);
|
||||
this._isPositionDirty = this._isRotationDirty = false;
|
||||
}
|
||||
return this.shape.bounds;
|
||||
var bds = this.entity.getBounds();
|
||||
return new Rectangle(bds.x, bds.y, bds.width, bds.height);
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Collider.prototype, "localOffset", {
|
||||
get: function () {
|
||||
return this._localOffset;
|
||||
return new Vector2(this.x, this.y);
|
||||
},
|
||||
set: function (value) {
|
||||
this.setLocalOffset(value);
|
||||
@@ -1905,9 +2032,9 @@ var Collider = (function (_super) {
|
||||
Collider.prototype.setLocalOffset = function (offset) {
|
||||
if (this._localOffset != offset) {
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
this._localOffset = offset;
|
||||
this.$setX(offset.x);
|
||||
this.$setY(offset.y);
|
||||
this._localOffsetLength = this._localOffset.length();
|
||||
this._isPositionDirty = true;
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
}
|
||||
};
|
||||
@@ -1940,17 +2067,15 @@ var Collider = (function (_super) {
|
||||
if (!(this instanceof BoxCollider)) {
|
||||
console.error("Only box and circle colliders can be created automatically");
|
||||
}
|
||||
var renderable = this.entity.getComponent(RenderableComponent);
|
||||
if (renderable) {
|
||||
var renderbaleBounds = renderable.bounds;
|
||||
var width = renderbaleBounds.width / this.entity.scale.x;
|
||||
var height = renderbaleBounds.height / this.entity.scale.y;
|
||||
if (this instanceof BoxCollider) {
|
||||
var boxCollider = this;
|
||||
boxCollider.width = width;
|
||||
boxCollider.height = height;
|
||||
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
|
||||
}
|
||||
var bounds = this.entity.getBounds();
|
||||
var renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
var width = renderbaleBounds.width / this.entity.scale.x;
|
||||
var height = renderbaleBounds.height / this.entity.scale.y;
|
||||
if (this instanceof BoxCollider) {
|
||||
var boxCollider = this;
|
||||
boxCollider.width = width;
|
||||
boxCollider.height = height;
|
||||
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
|
||||
}
|
||||
}
|
||||
this._isParentEntityAddedToScene = true;
|
||||
@@ -1962,11 +2087,14 @@ var Collider = (function (_super) {
|
||||
};
|
||||
Collider.prototype.onEnabled = function () {
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
this._isPositionDirty = this._isRotationDirty = true;
|
||||
};
|
||||
Collider.prototype.onDisabled = function () {
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
};
|
||||
Collider.prototype.onEntityTransformChanged = function (comp) {
|
||||
if (this._isColliderRegistered)
|
||||
Physics.updateCollider(this);
|
||||
};
|
||||
return Collider;
|
||||
}(Component));
|
||||
var BoxCollider = (function (_super) {
|
||||
@@ -1992,7 +2120,6 @@ var BoxCollider = (function (_super) {
|
||||
var box = this.shape;
|
||||
if (width != box.width) {
|
||||
box.updateBox(width, box.height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -2013,7 +2140,6 @@ var BoxCollider = (function (_super) {
|
||||
var box = this.shape;
|
||||
if (height != box.height) {
|
||||
box.updateBox(box.width, height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -2023,7 +2149,6 @@ var BoxCollider = (function (_super) {
|
||||
var box = this.shape;
|
||||
if (width != box.width || height != box.height) {
|
||||
box.updateBox(width, height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -2334,6 +2459,16 @@ var ComponentList = (function () {
|
||||
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) {
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
@@ -3340,8 +3475,8 @@ var Matrix2D = (function () {
|
||||
result.m32 = -(matrix.m32 * matrix.m11 - matrix.m31 * matrix.m12) * det;
|
||||
return result;
|
||||
};
|
||||
Matrix2D.createTranslation = function (xPosition, yPosition, result) {
|
||||
result = result ? result : new Matrix2D();
|
||||
Matrix2D.createTranslation = function (xPosition, yPosition) {
|
||||
var result = new Matrix2D();
|
||||
result.m11 = 1;
|
||||
result.m12 = 0;
|
||||
result.m21 = 0;
|
||||
@@ -3350,6 +3485,9 @@ var Matrix2D = (function () {
|
||||
result.m32 = yPosition;
|
||||
return result;
|
||||
};
|
||||
Matrix2D.createTranslationVector = function (position) {
|
||||
return this.createTranslation(position.x, position.y);
|
||||
};
|
||||
Matrix2D.createRotation = function (radians, result) {
|
||||
result = new Matrix2D();
|
||||
var val1 = Math.cos(radians);
|
||||
@@ -3377,12 +3515,10 @@ var Matrix2D = (function () {
|
||||
Matrix2D._identity = new Matrix2D(1, 0, 0, 1, 0, 0);
|
||||
return Matrix2D;
|
||||
}());
|
||||
var Rectangle = (function () {
|
||||
function Rectangle(x, y, width, height) {
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : 0;
|
||||
this.width = width ? width : 0;
|
||||
this.height = height ? height : 0;
|
||||
var Rectangle = (function (_super) {
|
||||
__extends(Rectangle, _super);
|
||||
function Rectangle() {
|
||||
return _super !== null && _super.apply(this, arguments) || this;
|
||||
}
|
||||
Object.defineProperty(Rectangle.prototype, "max", {
|
||||
get: function () {
|
||||
@@ -3391,34 +3527,6 @@ var Rectangle = (function () {
|
||||
enumerable: 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", {
|
||||
get: function () {
|
||||
return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
|
||||
@@ -3454,7 +3562,7 @@ var Rectangle = (function () {
|
||||
value.top < this.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))) &&
|
||||
(this.y <= value.y)) &&
|
||||
(value.y < (this.y + this.height)));
|
||||
@@ -3471,11 +3579,11 @@ var Rectangle = (function () {
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
};
|
||||
Rectangle.prototype.getClosestPointOnRectangleBorderToPoint = function (point) {
|
||||
var edgeNormal = new Vector2(0, 0);
|
||||
var res = new Vector2(0, 0);
|
||||
var edgeNormal = Vector2.zero;
|
||||
var res = new Vector2();
|
||||
res.x = MathHelper.clamp(point.x, this.left, this.right);
|
||||
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 dr = this.right - res.x;
|
||||
var dt = res.y - this.top;
|
||||
@@ -3499,18 +3607,14 @@ var Rectangle = (function () {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (res.x == this.left) {
|
||||
if (res.x == this.left)
|
||||
edgeNormal.x = -1;
|
||||
}
|
||||
if (res.x == this.right) {
|
||||
if (res.x == this.right)
|
||||
edgeNormal.x = 1;
|
||||
}
|
||||
if (res.y == this.top) {
|
||||
if (res.y == this.top)
|
||||
edgeNormal.y = -1;
|
||||
}
|
||||
if (res.y == this.bottom) {
|
||||
if (res.y == this.bottom)
|
||||
edgeNormal.y = 1;
|
||||
}
|
||||
}
|
||||
return { res: res, edgeNormal: edgeNormal };
|
||||
};
|
||||
@@ -3535,40 +3639,6 @@ var Rectangle = (function () {
|
||||
}
|
||||
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) {
|
||||
var minX = Number.POSITIVE_INFINITY;
|
||||
var minY = Number.POSITIVE_INFINITY;
|
||||
@@ -3576,131 +3646,19 @@ var Rectangle = (function () {
|
||||
var maxY = Number.NEGATIVE_INFINITY;
|
||||
for (var i = 0; i < points.length; i++) {
|
||||
var pt = points[i];
|
||||
if (pt.x < minX) {
|
||||
if (pt.x < minX)
|
||||
minX = pt.x;
|
||||
}
|
||||
if (pt.x > maxX) {
|
||||
if (pt.x > maxX)
|
||||
maxX = pt.x;
|
||||
}
|
||||
if (pt.y < minY) {
|
||||
if (pt.y < minY)
|
||||
minY = pt.y;
|
||||
}
|
||||
if (pt.y > maxY) {
|
||||
if (pt.y > maxY)
|
||||
maxY = pt.y;
|
||||
}
|
||||
}
|
||||
return this.fromMinMax(minX, minY, maxX, maxY);
|
||||
};
|
||||
return Rectangle;
|
||||
}());
|
||||
var Vector2 = (function () {
|
||||
function Vector2(x, y) {
|
||||
this.x = 0;
|
||||
this.y = 0;
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : this.x;
|
||||
}
|
||||
Object.defineProperty(Vector2, "zero", {
|
||||
get: function () {
|
||||
return Vector2.zeroVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "one", {
|
||||
get: function () {
|
||||
return Vector2.unitVector2;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitX", {
|
||||
get: function () {
|
||||
return Vector2.unitXVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Object.defineProperty(Vector2, "unitY", {
|
||||
get: function () {
|
||||
return Vector2.unitYVector;
|
||||
},
|
||||
enumerable: true,
|
||||
configurable: true
|
||||
});
|
||||
Vector2.add = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x + value2.x;
|
||||
result.y = value1.y + value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.divide = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x / value2.x;
|
||||
result.y = value1.y / value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.multiply = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x * value2.x;
|
||||
result.y = value1.y * value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.subtract = function (value1, value2) {
|
||||
var result = new Vector2(0, 0);
|
||||
result.x = value1.x - value2.x;
|
||||
result.y = value1.y - value2.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.prototype.normalize = function () {
|
||||
var val = 1 / Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
this.x *= val;
|
||||
this.y *= val;
|
||||
};
|
||||
Vector2.prototype.length = function () {
|
||||
return Math.sqrt((this.x * this.x) + (this.y * this.y));
|
||||
};
|
||||
Vector2.prototype.round = function () {
|
||||
return new Vector2(Math.round(this.x), Math.round(this.y));
|
||||
};
|
||||
Vector2.normalize = function (value) {
|
||||
var val = 1 / Math.sqrt((value.x * value.x) + (value.y * value.y));
|
||||
value.x *= val;
|
||||
value.y *= val;
|
||||
return value;
|
||||
};
|
||||
Vector2.dot = function (value1, value2) {
|
||||
return (value1.x * value2.x) + (value1.y * value2.y);
|
||||
};
|
||||
Vector2.distanceSquared = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return (v1 * v1) + (v2 * v2);
|
||||
};
|
||||
Vector2.clamp = function (value1, min, max) {
|
||||
return new Vector2(MathHelper.clamp(value1.x, min.x, max.x), MathHelper.clamp(value1.y, min.y, max.y));
|
||||
};
|
||||
Vector2.lerp = function (value1, value2, amount) {
|
||||
return new Vector2(MathHelper.lerp(value1.x, value2.x, amount), MathHelper.lerp(value1.y, value2.y, amount));
|
||||
};
|
||||
Vector2.transform = function (position, matrix) {
|
||||
return new Vector2((position.x * matrix.m11) + (position.y * matrix.m21), (position.x * matrix.m12) + (position.y * matrix.m22));
|
||||
};
|
||||
Vector2.distance = function (value1, value2) {
|
||||
var v1 = value1.x - value2.x, v2 = value1.y - value2.y;
|
||||
return Math.sqrt((v1 * v1) + (v2 * v2));
|
||||
};
|
||||
Vector2.negate = function (value) {
|
||||
var result = new Vector2();
|
||||
result.x = -value.x;
|
||||
result.y = -value.y;
|
||||
return result;
|
||||
};
|
||||
Vector2.unitYVector = new Vector2(0, 1);
|
||||
Vector2.unitXVector = new Vector2(1, 0);
|
||||
Vector2.unitVector2 = new Vector2(1, 1);
|
||||
Vector2.zeroVector2 = new Vector2(0, 0);
|
||||
return Vector2;
|
||||
}());
|
||||
}(egret.Rectangle));
|
||||
var Vector3 = (function () {
|
||||
function Vector3(x, y, z) {
|
||||
this.x = x;
|
||||
@@ -4099,7 +4057,7 @@ var Polygon = (function (_super) {
|
||||
};
|
||||
Polygon.prototype.recalculateBounds = function (collider) {
|
||||
this.center = collider.localOffset;
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform) {
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||
var hasUnitScale = true;
|
||||
var tempMat = void 0;
|
||||
var combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
|
||||
@@ -4111,7 +4069,7 @@ var Polygon = (function (_super) {
|
||||
this.center = scaledOffset;
|
||||
}
|
||||
if (collider.entity.rotation != 0) {
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation);
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
var offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg;
|
||||
var offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
|
||||
@@ -4121,8 +4079,6 @@ var Polygon = (function (_super) {
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
|
||||
this.isUnrotated = collider.entity.rotation == 0;
|
||||
if (collider._isRotationDirty)
|
||||
this._areEdgeNormalsDirty = true;
|
||||
}
|
||||
this.position = Vector2.add(collider.entity.position, this.center);
|
||||
this.bounds = Rectangle.rectEncompassingPoints(this.points);
|
||||
@@ -4177,7 +4133,7 @@ var Box = (function (_super) {
|
||||
};
|
||||
Box.prototype.containsPoint = function (point) {
|
||||
if (this.isUnrotated)
|
||||
return this.bounds.contains(point);
|
||||
return this.bounds.containsInVec(point);
|
||||
return _super.prototype.containsPoint.call(this, point);
|
||||
};
|
||||
return Box;
|
||||
@@ -4207,7 +4163,7 @@ var Circle = (function (_super) {
|
||||
};
|
||||
Circle.prototype.recalculateBounds = function (collider) {
|
||||
this.center = collider.localOffset;
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform) {
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||
var scale = collider.entity.scale;
|
||||
var hasUnitScale = scale.x == 1 && scale.y == 1;
|
||||
var maxScale = Math.max(scale.x, scale.y);
|
||||
@@ -4291,7 +4247,7 @@ var ShapeCollisions = (function () {
|
||||
}
|
||||
}
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis), new Vector2(minIntervalDistance));
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance));
|
||||
return result;
|
||||
};
|
||||
ShapeCollisions.intervalDistance = function (minA, maxA, minB, maxB) {
|
||||
@@ -4414,10 +4370,10 @@ var ShapeCollisions = (function () {
|
||||
ShapeCollisions.boxToBox = function (first, second) {
|
||||
var result = new CollisionResult();
|
||||
var minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(new Vector2(0, 0))) {
|
||||
if (minkowskiDiff.containsInVec(new Vector2(0, 0))) {
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
if (result.minimumTranslationVector == Vector2.zero)
|
||||
return false;
|
||||
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
|
||||
return null;
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
return result;
|
||||
@@ -4436,6 +4392,7 @@ var SpatialHash = (function () {
|
||||
function SpatialHash(cellSize) {
|
||||
if (cellSize === void 0) { cellSize = 100; }
|
||||
this.gridBounds = new Rectangle();
|
||||
this._overlapTestCircle = new Circle(0);
|
||||
this._tempHashSet = [];
|
||||
this._cellDict = new NumberDictionary();
|
||||
this._cellSize = cellSize;
|
||||
@@ -4461,10 +4418,10 @@ var SpatialHash = (function () {
|
||||
collider.registeredPhysicsBounds = bounds;
|
||||
var p1 = this.cellCoords(bounds.x, bounds.y);
|
||||
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);
|
||||
}
|
||||
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);
|
||||
}
|
||||
for (var x = p1.x; x <= p2.x; x++) {
|
||||
@@ -4533,7 +4490,7 @@ var SpatialHash = (function () {
|
||||
return cell;
|
||||
};
|
||||
SpatialHash.prototype.cellCoords = function (x, y) {
|
||||
return new Point(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
return new Vector2(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
};
|
||||
return SpatialHash;
|
||||
}());
|
||||
|
||||
2
source/bin/framework.min.js
vendored
2
source/bin/framework.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -2,22 +2,22 @@
|
||||
* 基本静态网格图与A*一起使用
|
||||
* 将walls添加到walls HashSet,并将加权节点添加到weightedNodes
|
||||
*/
|
||||
class AstarGridGraph implements IAstarGraph<Point> {
|
||||
public dirs: Point[] = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1)
|
||||
class AstarGridGraph implements IAstarGraph<Vector2> {
|
||||
public dirs: Vector2[] = [
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, 1)
|
||||
];
|
||||
|
||||
public walls: Point[] = [];
|
||||
public weightedNodes: Point[] = [];
|
||||
public walls: Vector2[] = [];
|
||||
public weightedNodes: Vector2[] = [];
|
||||
public defaultWeight: number = 1;
|
||||
public weightedNodeWeight = 5;
|
||||
|
||||
private _width;
|
||||
private _height;
|
||||
private _neighbors: Point[] = new Array(4);
|
||||
private _neighbors: Vector2[] = new Array(4);
|
||||
|
||||
constructor(width: number, height: number){
|
||||
this._width = width;
|
||||
@@ -28,7 +28,7 @@ class AstarGridGraph implements IAstarGraph<Point> {
|
||||
* 确保节点在网格图的边界内
|
||||
* @param node
|
||||
*/
|
||||
public isNodeInBounds(node: Point): boolean {
|
||||
public isNodeInBounds(node: Vector2): boolean {
|
||||
return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height;
|
||||
}
|
||||
|
||||
@@ -36,19 +36,19 @@ class AstarGridGraph implements IAstarGraph<Point> {
|
||||
* 检查节点是否可以通过。墙壁是不可逾越的。
|
||||
* @param node
|
||||
*/
|
||||
public isNodePassable(node: Point): boolean {
|
||||
public isNodePassable(node: Vector2): boolean {
|
||||
return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node));
|
||||
}
|
||||
|
||||
public search(start: Point, goal: Point){
|
||||
public search(start: Vector2, goal: Vector2){
|
||||
return AStarPathfinder.search(this, start, goal);
|
||||
}
|
||||
|
||||
public getNeighbors(node: Point): Point[] {
|
||||
public getNeighbors(node: Vector2): Vector2[] {
|
||||
this._neighbors.length = 0;
|
||||
|
||||
this.dirs.forEach(dir => {
|
||||
let next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
let next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (this.isNodeInBounds(next) && this.isNodePassable(next))
|
||||
this._neighbors.push(next);
|
||||
});
|
||||
@@ -56,11 +56,11 @@ class AstarGridGraph implements IAstarGraph<Point> {
|
||||
return this._neighbors;
|
||||
}
|
||||
|
||||
public cost(from: Point, to: Point): number {
|
||||
public cost(from: Vector2, to: Vector2): number {
|
||||
return this.weightedNodes.find((p)=> JSON.stringify(p) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
}
|
||||
|
||||
public heuristic(node: Point, goal: Point) {
|
||||
public heuristic(node: Vector2, goal: Vector2) {
|
||||
return Math.abs(node.x - goal.x) + Math.abs(node.y - goal.y);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
///<reference path="../../../Math/Point.ts" />
|
||||
///<reference path="../../../Math/Vector2.ts" />
|
||||
/**
|
||||
* 基本的未加权网格图形用于BreadthFirstPathfinder
|
||||
*/
|
||||
class UnweightedGridGraph implements IUnweightedGraph<Point> {
|
||||
private static readonly CARDINAL_DIRS: Point[] = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, -1)
|
||||
class UnweightedGridGraph implements IUnweightedGraph<Vector2> {
|
||||
private static readonly CARDINAL_DIRS: Vector2[] = [
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, -1)
|
||||
];
|
||||
|
||||
private static readonly COMPASS_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(1, -1),
|
||||
new Point(0, -1),
|
||||
new Point(-1, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(-1, 1),
|
||||
new Point(0, 1),
|
||||
new Point(1, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, -1),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(-1, 1),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
];
|
||||
|
||||
public walls: Point[] = [];
|
||||
public walls: Vector2[] = [];
|
||||
|
||||
private _width: number;
|
||||
private _hegiht: number;
|
||||
|
||||
private _dirs: Point[];
|
||||
private _neighbors: Point[] = new Array(4);
|
||||
private _dirs: Vector2[];
|
||||
private _neighbors: Vector2[] = new Array(4);
|
||||
|
||||
constructor(width: number, height: number, allowDiagonalSearch: boolean = false) {
|
||||
this._width = width;
|
||||
@@ -35,19 +35,19 @@ class UnweightedGridGraph implements IUnweightedGraph<Point> {
|
||||
this._dirs = allowDiagonalSearch ? UnweightedGridGraph.COMPASS_DIRS : UnweightedGridGraph.CARDINAL_DIRS;
|
||||
}
|
||||
|
||||
public isNodeInBounds(node: Point): boolean {
|
||||
public isNodeInBounds(node: Vector2): boolean {
|
||||
return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._hegiht;
|
||||
}
|
||||
|
||||
public isNodePassable(node: Point): boolean {
|
||||
public isNodePassable(node: Vector2): boolean {
|
||||
return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node));
|
||||
}
|
||||
|
||||
public getNeighbors(node: Point) {
|
||||
public getNeighbors(node: Vector2) {
|
||||
this._neighbors.length = 0;
|
||||
|
||||
this._dirs.forEach(dir => {
|
||||
let next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
let next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (this.isNodeInBounds(next) && this.isNodePassable(next))
|
||||
this._neighbors.push(next);
|
||||
});
|
||||
@@ -55,7 +55,7 @@ class UnweightedGridGraph implements IUnweightedGraph<Point> {
|
||||
return this._neighbors;
|
||||
}
|
||||
|
||||
public search(start: Point, goal: Point): Point[] {
|
||||
public search(start: Vector2, goal: Vector2): Vector2[] {
|
||||
return BreadthFirstPathfinder.search(this, start, goal);
|
||||
}
|
||||
}
|
||||
@@ -1,35 +1,35 @@
|
||||
///<reference path="../../../Math/Point.ts" />
|
||||
///<reference path="../../../Math/Vector2.ts" />
|
||||
/**
|
||||
* 支持一种加权节点的基本网格图
|
||||
*/
|
||||
class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
class WeightedGridGraph implements IWeightedGraph<Vector2> {
|
||||
public static readonly CARDINAL_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(0, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(0, 1)
|
||||
new Vector2(1, 0),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(0, 1)
|
||||
];
|
||||
|
||||
private static readonly COMPASS_DIRS = [
|
||||
new Point(1, 0),
|
||||
new Point(1, -1),
|
||||
new Point(0, -1),
|
||||
new Point(-1, -1),
|
||||
new Point(-1, 0),
|
||||
new Point(-1, 1),
|
||||
new Point(0, 1),
|
||||
new Point(1, 1),
|
||||
new Vector2(1, 0),
|
||||
new Vector2(1, -1),
|
||||
new Vector2(0, -1),
|
||||
new Vector2(-1, -1),
|
||||
new Vector2(-1, 0),
|
||||
new Vector2(-1, 1),
|
||||
new Vector2(0, 1),
|
||||
new Vector2(1, 1),
|
||||
];
|
||||
|
||||
public walls: Point[] = [];
|
||||
public weightedNodes: Point[] = [];
|
||||
public walls: Vector2[] = [];
|
||||
public weightedNodes: Vector2[] = [];
|
||||
public defaultWeight = 1;
|
||||
public weightedNodeWeight = 5;
|
||||
|
||||
private _width: number;
|
||||
private _height: number;
|
||||
private _dirs: Point[];
|
||||
private _neighbors: Point[] = new Array(4);
|
||||
private _dirs: Vector2[];
|
||||
private _neighbors: Vector2[] = new Array(4);
|
||||
|
||||
constructor(width: number, height: number, allowDiagonalSearch: boolean = false){
|
||||
this._width = width;
|
||||
@@ -37,23 +37,23 @@ class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
this._dirs = allowDiagonalSearch ? WeightedGridGraph.COMPASS_DIRS : WeightedGridGraph.CARDINAL_DIRS;
|
||||
}
|
||||
|
||||
public isNodeInBounds(node: Point){
|
||||
public isNodeInBounds(node: Vector2){
|
||||
return 0 <= node.x && node.x < this._width && 0 <= node.y && node.y < this._height;
|
||||
}
|
||||
|
||||
public isNodePassable(node: Point): boolean {
|
||||
public isNodePassable(node: Vector2): boolean {
|
||||
return !this.walls.firstOrDefault(wall => JSON.stringify(wall) == JSON.stringify(node));
|
||||
}
|
||||
|
||||
public search(start: Point, goal: Point){
|
||||
public search(start: Vector2, goal: Vector2){
|
||||
return WeightedPathfinder.search(this, start, goal);
|
||||
}
|
||||
|
||||
public getNeighbors(node: Point): Point[]{
|
||||
public getNeighbors(node: Vector2): Vector2[]{
|
||||
this._neighbors.length = 0;
|
||||
|
||||
this._dirs.forEach(dir => {
|
||||
let next = new Point(node.x + dir.x, node.y + dir.y);
|
||||
let next = new Vector2(node.x + dir.x, node.y + dir.y);
|
||||
if (this.isNodeInBounds(next) && this.isNodePassable(next))
|
||||
this._neighbors.push(next);
|
||||
});
|
||||
@@ -61,7 +61,7 @@ class WeightedGridGraph implements IWeightedGraph<Point> {
|
||||
return this._neighbors;
|
||||
}
|
||||
|
||||
public cost(from: Point, to: Point): number{
|
||||
public cost(from: Vector2, to: Vector2): number{
|
||||
return this.weightedNodes.find(t => JSON.stringify(t) == JSON.stringify(to)) ? this.weightedNodeWeight : this.defaultWeight;
|
||||
}
|
||||
}
|
||||
@@ -28,7 +28,6 @@ abstract class Component extends egret.DisplayObjectContainer {
|
||||
}
|
||||
|
||||
public initialize(){
|
||||
|
||||
}
|
||||
|
||||
public onAddedToEntity(){
|
||||
@@ -55,6 +54,14 @@ abstract class Component extends egret.DisplayObjectContainer {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* 当实体的位置改变时调用。这允许组件知道它们由于父实体的移动而移动了。
|
||||
* @param comp
|
||||
*/
|
||||
public onEntityTransformChanged(comp: TransformComponent){
|
||||
|
||||
}
|
||||
|
||||
/** 内部使用 运行时不应该调用 */
|
||||
public registerComponent(){
|
||||
this.entity.componentBits.set(ComponentTypeManager.getIndexFor(this), false);
|
||||
|
||||
@@ -6,6 +6,7 @@ class Camera extends Component {
|
||||
private _minimumZoom = 0.3;
|
||||
private _maximumZoom = 3;
|
||||
|
||||
private _position: Vector2 = Vector2.zero;
|
||||
/**
|
||||
* 如果相机模式为cameraWindow 则会进行缓动移动
|
||||
* 该值为移动速度
|
||||
@@ -67,11 +68,24 @@ class Camera extends Component {
|
||||
}
|
||||
|
||||
public get position(){
|
||||
return this.entity.position;
|
||||
return this._position;
|
||||
}
|
||||
|
||||
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() {
|
||||
|
||||
@@ -8,12 +8,16 @@ class BoxCollider extends Collider {
|
||||
this.setWidth(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置BoxCollider的宽度
|
||||
* @param width
|
||||
*/
|
||||
public setWidth(width: number): BoxCollider{
|
||||
this._colliderRequiresAutoSizing = false;
|
||||
let box = this.shape as Box;
|
||||
if (width != box.width){
|
||||
// 更新框,改变边界,如果我们需要更新物理系统中的边界
|
||||
box.updateBox(width, box.height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
@@ -29,17 +33,24 @@ class BoxCollider extends Collider {
|
||||
this.setHeight(value);
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置BoxCollider的高度
|
||||
* @param height
|
||||
*/
|
||||
public setHeight(height: number){
|
||||
this._colliderRequiresAutoSizing = false;
|
||||
let box = this.shape as Box;
|
||||
if (height != box.height){
|
||||
// 更新框,改变边界,如果我们需要更新物理系统中的边界
|
||||
box.updateBox(box.width, height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 零参数构造函数要求RenderableComponent在实体上,这样碰撞器可以在实体被添加到场景时调整自身的大小。
|
||||
*/
|
||||
constructor(){
|
||||
super();
|
||||
|
||||
@@ -52,8 +63,8 @@ class BoxCollider extends Collider {
|
||||
this._colliderRequiresAutoSizing = false;
|
||||
let box = this.shape as Box;
|
||||
if (width != box.width || height != box.height){
|
||||
// 更新框,改变边界,如果我们需要更新物理系统中的边界
|
||||
box.updateBox(width, height);
|
||||
this._isPositionDirty = true;
|
||||
if (this.entity && this._isParentEntityAddedToScene)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
|
||||
@@ -1,32 +1,41 @@
|
||||
abstract class Collider extends Component{
|
||||
/** 对撞机的基本形状 */
|
||||
public shape: Shape;
|
||||
/** 在处理冲突时,physicsLayer可以用作过滤器。Flags类有帮助位掩码的方法。 */
|
||||
public physicsLayer = 1 << 0;
|
||||
/** 如果这个碰撞器是一个触发器,它将不会引起碰撞,但它仍然会触发事件 */
|
||||
public isTrigger: boolean;
|
||||
public registeredPhysicsBounds: Rectangle;
|
||||
public shouldColliderScaleAndRotationWithTransform = true;
|
||||
/**
|
||||
* 这个对撞机在物理系统注册时的边界。
|
||||
* 存储这个允许我们始终能够安全地从物理系统中移除对撞机,即使它在试图移除它之前已经被移动了。
|
||||
*/
|
||||
public registeredPhysicsBounds: Rectangle = new Rectangle();
|
||||
/** 如果为true,碰撞器将根据附加的变换缩放和旋转 */
|
||||
public shouldColliderScaleAndRotateWithTransform = true;
|
||||
/** 默认为所有层。 */
|
||||
public collidesWithLayers = Physics.allLayers;
|
||||
|
||||
public _localOffsetLength: number;
|
||||
public _isPositionDirty = true;
|
||||
public _isRotationDirty = true;
|
||||
/** 标记来跟踪我们的实体是否被添加到场景中 */
|
||||
protected _isParentEntityAddedToScene;
|
||||
protected _colliderRequiresAutoSizing;
|
||||
protected _localOffset: Vector2 = new Vector2(0, 0);
|
||||
/** 标记来记录我们是否注册了物理系统 */
|
||||
protected _isColliderRegistered;
|
||||
|
||||
public get bounds(): Rectangle {
|
||||
if (this._isPositionDirty || this._isRotationDirty){
|
||||
this.shape.recalculateBounds(this);
|
||||
this._isPositionDirty = this._isRotationDirty = false;
|
||||
}
|
||||
|
||||
return this.shape.bounds;
|
||||
// this.shape.recalculateBounds(this);
|
||||
let bds = this.entity.getBounds();
|
||||
return new Rectangle(bds.x, bds.y, bds.width, bds.height);
|
||||
}
|
||||
|
||||
public get localOffset(){
|
||||
return this._localOffset;
|
||||
return new Vector2(this.x, this.y);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将localOffset添加到实体。获取碰撞器的最终位置。这允许您向一个实体添加多个碰撞器并分别定位它们。
|
||||
*/
|
||||
public set localOffset(value: Vector2){
|
||||
this.setLocalOffset(value);
|
||||
}
|
||||
@@ -34,20 +43,27 @@ abstract class Collider extends Component{
|
||||
public setLocalOffset(offset: Vector2){
|
||||
if (this._localOffset != offset){
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
this._localOffset = offset;
|
||||
this.$setX(offset.x);
|
||||
this.$setY(offset.y);
|
||||
this._localOffsetLength = this._localOffset.length();
|
||||
this._isPositionDirty = true;
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 父实体会在不同的时间调用它(当添加到场景,启用,等等)
|
||||
*/
|
||||
public registerColliderWithPhysicsSystem(){
|
||||
// 如果在将我们添加到实体之前更改了origin等属性,则实体可以为null
|
||||
if (this._isParentEntityAddedToScene && !this._isColliderRegistered){
|
||||
Physics.addCollider(this);
|
||||
this._isColliderRegistered = true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 父实体会在不同的时候调用它(从场景中移除,禁用,等等)
|
||||
*/
|
||||
public unregisterColliderWithPhysicsSystem(){
|
||||
if (this._isParentEntityAddedToScene && this._isColliderRegistered){
|
||||
Physics.removeCollider(this);
|
||||
@@ -55,11 +71,21 @@ abstract class Collider extends Component{
|
||||
this._isColliderRegistered = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查这个形状是否与物理系统中的其他对撞机重叠
|
||||
* @param other
|
||||
*/
|
||||
public overlaps(other: Collider){
|
||||
return this.shape.overlaps(other.shape);
|
||||
}
|
||||
|
||||
/**
|
||||
* 检查这个与运动应用的碰撞器(移动向量)是否与碰撞器碰撞。如果是这样,将返回true,并且结果将填充碰撞数据。
|
||||
* @param collider
|
||||
* @param motion
|
||||
*/
|
||||
public collidesWith(collider: Collider, motion: Vector2){
|
||||
// 改变形状的位置,使它在移动后的位置,这样我们可以检查重叠
|
||||
let oldPosition = this.shape.position;
|
||||
this.shape.position = Vector2.add(this.shape.position, motion);
|
||||
|
||||
@@ -67,6 +93,7 @@ abstract class Collider extends Component{
|
||||
if (result)
|
||||
result.collider = collider;
|
||||
|
||||
// 将图形位置返回到检查前的位置
|
||||
this.shape.position = oldPosition;
|
||||
|
||||
return result;
|
||||
@@ -78,20 +105,20 @@ abstract class Collider extends Component{
|
||||
console.error("Only box and circle colliders can be created automatically");
|
||||
}
|
||||
|
||||
let renderable = this.entity.getComponent<RenderableComponent>(RenderableComponent);
|
||||
if (renderable){
|
||||
let renderbaleBounds = renderable.bounds;
|
||||
let bounds = this.entity.getBounds();
|
||||
let renderbaleBounds = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
|
||||
|
||||
let width = renderbaleBounds.width / this.entity.scale.x;
|
||||
let height = renderbaleBounds.height / this.entity.scale.y;
|
||||
// 这里我们需要大小*反尺度,因为当我们自动调整碰撞器的大小时,它需要没有缩放的渲染
|
||||
let width = renderbaleBounds.width / this.entity.scale.x;
|
||||
let height = renderbaleBounds.height / this.entity.scale.y;
|
||||
|
||||
if (this instanceof BoxCollider){
|
||||
let boxCollider = this as BoxCollider;
|
||||
boxCollider.width = width;
|
||||
boxCollider.height = height;
|
||||
if (this instanceof BoxCollider){
|
||||
let boxCollider = this as BoxCollider;
|
||||
boxCollider.width = width;
|
||||
boxCollider.height = height;
|
||||
|
||||
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
|
||||
}
|
||||
// 获取渲染的中心,将其转移到本地坐标,并使用它作为碰撞器的localOffset
|
||||
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,10 +133,14 @@ abstract class Collider extends Component{
|
||||
|
||||
public onEnabled(){
|
||||
this.registerColliderWithPhysicsSystem();
|
||||
this._isPositionDirty = this._isRotationDirty = true;
|
||||
}
|
||||
|
||||
public onDisabled(){
|
||||
this.unregisterColliderWithPhysicsSystem();
|
||||
}
|
||||
|
||||
public onEntityTransformChanged(comp: TransformComponent){
|
||||
if (this._isColliderRegistered)
|
||||
Physics.updateCollider(this);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,10 @@
|
||||
/**
|
||||
* 辅助类说明了一种处理移动的方法,它考虑了包括触发器在内的所有冲突。
|
||||
* ITriggerListener接口用于管理对移动过程中违反的任何触发器的回调。
|
||||
* 一个物体只能通过移动器移动。要正确报告触发器的move方法。
|
||||
*
|
||||
* 请注意,多个移动者相互交互将多次调用ITriggerListener。
|
||||
*/
|
||||
class Mover extends Component {
|
||||
private _triggerHelper: ColliderTriggerHelper;
|
||||
|
||||
@@ -5,6 +12,10 @@ class Mover extends Component {
|
||||
this._triggerHelper = new ColliderTriggerHelper(this.entity);
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算修改运动矢量的运动,以考虑移动时可能发生的碰撞
|
||||
* @param motion
|
||||
*/
|
||||
public calculateMovement(motion: Vector2){
|
||||
let collisionResult = new CollisionResult();
|
||||
|
||||
@@ -16,9 +27,11 @@ class Mover extends Component {
|
||||
for (let i = 0; i < colliders.length; i ++){
|
||||
let collider = colliders[i];
|
||||
|
||||
// 不检测触发器
|
||||
if (collider.isTrigger)
|
||||
continue;
|
||||
|
||||
// 获取我们在新位置可能发生碰撞的任何东西
|
||||
let bounds = collider.bounds;
|
||||
bounds.x += motion.x;
|
||||
bounds.y += motion.y;
|
||||
@@ -28,13 +41,16 @@ class Mover extends Component {
|
||||
|
||||
for (let j = 0; j < neighbors.length; j ++){
|
||||
let neighbor = neighbors[j];
|
||||
// 不检测触发器
|
||||
if (neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
let _internalcollisionResult = collider.collidesWith(neighbor, motion);
|
||||
if (_internalcollisionResult){
|
||||
// 如果碰撞 则退回之前的移动量
|
||||
motion = Vector2.subtract(motion, _internalcollisionResult.minimumTranslationVector);
|
||||
|
||||
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
||||
if (_internalcollisionResult.collider){
|
||||
collisionResult = _internalcollisionResult;
|
||||
}
|
||||
|
||||
@@ -1,25 +1,12 @@
|
||||
class SpriteRenderer extends RenderableComponent {
|
||||
private _origin: Vector2;
|
||||
private _sprite: Sprite;
|
||||
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{
|
||||
return this._sprite;
|
||||
}
|
||||
/** 应该由这个精灵显示的精灵。当设置时,精灵的原点也被设置为匹配精灵.origin。 */
|
||||
/** 应该由这个精灵显示的精灵 */
|
||||
public set sprite(value: Sprite){
|
||||
this.setSprite(value);
|
||||
}
|
||||
@@ -27,7 +14,10 @@ class SpriteRenderer extends RenderableComponent {
|
||||
public setSprite(sprite: Sprite): SpriteRenderer{
|
||||
this.removeChildren();
|
||||
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.addChild(this.bitmap);
|
||||
|
||||
@@ -58,8 +48,8 @@ class SpriteRenderer extends RenderableComponent {
|
||||
|
||||
/** 渲染处理 在每个模块中处理各自的渲染逻辑 */
|
||||
public render(camera: Camera){
|
||||
this.x = this.entity.position.x - this.origin.x - camera.position.x + camera.origin.x;
|
||||
this.y = this.entity.position.y - this.origin.y - camera.position.y + camera.origin.y;
|
||||
this.x = -camera.position.x + camera.origin.x;
|
||||
this.y = -camera.position.y + camera.origin.y;
|
||||
}
|
||||
|
||||
public onRemovedFromEntity(){
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
class Entity extends egret.DisplayObjectContainer {
|
||||
private static _idGenerator: number;
|
||||
|
||||
private _position: Vector2 = Vector2.zero;
|
||||
public name: string;
|
||||
public readonly id: number;
|
||||
/** 当前实体所属的场景 */
|
||||
@@ -20,11 +19,13 @@ class Entity extends egret.DisplayObjectContainer {
|
||||
}
|
||||
|
||||
public get position(){
|
||||
return this._position;
|
||||
return new Vector2(this.x, this.y);
|
||||
}
|
||||
|
||||
public set position(value: Vector2){
|
||||
this._position = value;
|
||||
this.$setX(value.x);
|
||||
this.$setY(value.y);
|
||||
this.onEntityTransformChanged(TransformComponent.position);
|
||||
}
|
||||
|
||||
public get scale(){
|
||||
@@ -32,8 +33,14 @@ class Entity extends egret.DisplayObjectContainer {
|
||||
}
|
||||
|
||||
public set scale(value: Vector2){
|
||||
this.scaleX = value.x;
|
||||
this.scaleY = value.y;
|
||||
this.$setScaleX(value.x);
|
||||
this.$setScaleY(value.y);
|
||||
this.onEntityTransformChanged(TransformComponent.scale);
|
||||
}
|
||||
|
||||
public set rotation(value: number){
|
||||
this.$setRotation(value);
|
||||
this.onEntityTransformChanged(TransformComponent.rotation);
|
||||
}
|
||||
|
||||
public get enabled(){
|
||||
@@ -160,6 +167,10 @@ class Entity extends egret.DisplayObjectContainer {
|
||||
return this.components.getComponents(typeName, componentList);
|
||||
}
|
||||
|
||||
private onEntityTransformChanged(comp: TransformComponent){
|
||||
this.components.onEntityTransformChanged(comp);
|
||||
}
|
||||
|
||||
public removeComponentForType<T extends Component>(type){
|
||||
let comp = this.getComponent<T>(type);
|
||||
if (comp){
|
||||
@@ -203,4 +214,10 @@ class Entity extends egret.DisplayObjectContainer {
|
||||
(child as Component).entity.destroy();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enum TransformComponent {
|
||||
rotation,
|
||||
scale,
|
||||
position
|
||||
}
|
||||
@@ -144,6 +144,9 @@ class Scene extends egret.DisplayObjectContainer {
|
||||
this.entityProcessors.end();
|
||||
|
||||
this.unload();
|
||||
|
||||
if (this.parent)
|
||||
this.parent.removeChild(this);
|
||||
}
|
||||
|
||||
protected async onStart() {
|
||||
|
||||
@@ -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){
|
||||
if (component instanceof RenderableComponent)
|
||||
this._entity.scene.renderableComponents.remove(component);
|
||||
|
||||
@@ -155,8 +155,13 @@ class Matrix2D {
|
||||
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.m12 = 0;
|
||||
@@ -170,6 +175,14 @@ class Matrix2D {
|
||||
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){
|
||||
result = new Matrix2D();
|
||||
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
class Point {
|
||||
public x: number;
|
||||
public y: number;
|
||||
|
||||
constructor(x?: number, y?: number){
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : this.x;
|
||||
}
|
||||
}
|
||||
@@ -1,43 +1,21 @@
|
||||
class Rectangle {
|
||||
public x: number;
|
||||
public y: number;
|
||||
public width: number;
|
||||
public height: number;
|
||||
|
||||
private _tempMat: Matrix2D;
|
||||
private _transformMat: Matrix2D;
|
||||
|
||||
class Rectangle extends egret.Rectangle {
|
||||
/**
|
||||
* 获取矩形的最大点,即右下角
|
||||
*/
|
||||
public get max(){
|
||||
public get max() {
|
||||
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() {
|
||||
return new Vector2(this.x + (this.width / 2), this.y + (this.height / 2));
|
||||
}
|
||||
|
||||
/** 左上角的坐标 */
|
||||
public get location() {
|
||||
return new Vector2(this.x, this.y);
|
||||
}
|
||||
|
||||
/** 左上角的坐标 */
|
||||
public set location(value: Vector2) {
|
||||
this.x = value.x;
|
||||
this.y = value.y;
|
||||
@@ -52,48 +30,66 @@ class Rectangle {
|
||||
this.height = value.y;
|
||||
}
|
||||
|
||||
constructor(x?: number, y?: number, width?: number, height?: number) {
|
||||
this.x = x ? x : 0;
|
||||
this.y = y ? y : 0;
|
||||
this.width = width ? width : 0;
|
||||
this.height = height ? height : 0;
|
||||
}
|
||||
|
||||
public intersects(value: Rectangle) {
|
||||
/**
|
||||
* 是否与另一个矩形相交
|
||||
* @param value
|
||||
*/
|
||||
public intersects(value: egret.Rectangle) {
|
||||
return value.left < this.right &&
|
||||
this.left < value.right &&
|
||||
value.top < this.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))) &&
|
||||
(this.y <= value.y)) &&
|
||||
(value.y < (this.y + this.height)));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取所提供的矩形是否在此矩形的边界内
|
||||
* @param value
|
||||
*/
|
||||
public containsRect(value: Rectangle) {
|
||||
return ((((this.x <= value.x) && (value.x < (this.x + this.width))) &&
|
||||
(this.y <= value.y)) &&
|
||||
(value.y < (this.y + this.height)));
|
||||
}
|
||||
|
||||
public getHalfSize(){
|
||||
public getHalfSize() {
|
||||
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) {
|
||||
return new Rectangle(minX, minY, maxX - minX, maxY - minY);
|
||||
}
|
||||
|
||||
public getClosestPointOnRectangleBorderToPoint(point: Point): { res: Vector2, edgeNormal: Vector2 } {
|
||||
let edgeNormal = new Vector2(0, 0);
|
||||
/**
|
||||
* 获取矩形边界上与给定点最近的点
|
||||
* @param point
|
||||
*/
|
||||
public getClosestPointOnRectangleBorderToPoint(point: Vector2): { res: Vector2, edgeNormal: Vector2 } {
|
||||
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.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 dr = this.right - res.x;
|
||||
let dt = res.y - this.top;
|
||||
@@ -114,41 +110,36 @@ class Rectangle {
|
||||
edgeNormal.x = 1;
|
||||
}
|
||||
} else {
|
||||
if (res.x == this.left) {
|
||||
edgeNormal.x = -1;
|
||||
}
|
||||
if (res.x == this.right) {
|
||||
edgeNormal.x = 1;
|
||||
}
|
||||
if (res.y == this.top) {
|
||||
edgeNormal.y = -1;
|
||||
}
|
||||
if (res.y == this.bottom) {
|
||||
edgeNormal.y = 1;
|
||||
}
|
||||
if (res.x == this.left) edgeNormal.x = -1;
|
||||
if (res.x == this.right) edgeNormal.x = 1;
|
||||
if (res.y == this.top) edgeNormal.y = -1;
|
||||
if (res.y == this.bottom) edgeNormal.y = 1;
|
||||
}
|
||||
|
||||
return { res: res, edgeNormal: edgeNormal };
|
||||
}
|
||||
|
||||
public getClosestPointOnBoundsToOrigin(){
|
||||
/**
|
||||
*
|
||||
*/
|
||||
public getClosestPointOnBoundsToOrigin() {
|
||||
let max = this.max;
|
||||
let minDist = Math.abs(this.location.x);
|
||||
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);
|
||||
boundsPoint.x = max.x;
|
||||
boundsPoint.y = 0;
|
||||
}
|
||||
|
||||
if (Math.abs(max.y) < minDist){
|
||||
|
||||
if (Math.abs(max.y) < minDist) {
|
||||
minDist = Math.abs(max.y);
|
||||
boundsPoint.x = 0;
|
||||
boundsPoint.y = max.y;
|
||||
}
|
||||
|
||||
if (Math.abs(this.location.y) < minDist){
|
||||
if (Math.abs(this.location.y) < minDist) {
|
||||
minDist = Math.abs(this.location.y);
|
||||
boundsPoint.x = 0;
|
||||
boundsPoint.y = this.location.y;
|
||||
@@ -156,52 +147,13 @@ class Rectangle {
|
||||
|
||||
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
|
||||
*/
|
||||
public static rectEncompassingPoints(points: Vector2[]) {
|
||||
// 我们需要求出x/y的最小值/最大值
|
||||
let minX = Number.POSITIVE_INFINITY;
|
||||
let minY = Number.POSITIVE_INFINITY;
|
||||
let maxX = Number.NEGATIVE_INFINITY;
|
||||
@@ -210,19 +162,11 @@ class Rectangle {
|
||||
for (let i = 0; i < points.length; i++) {
|
||||
let pt = points[i];
|
||||
|
||||
if (pt.x < minX) {
|
||||
minX = pt.x;
|
||||
}
|
||||
if (pt.x > maxX) {
|
||||
maxX = pt.x;
|
||||
}
|
||||
if (pt.x < minX) minX = pt.x;
|
||||
if (pt.x > maxX) maxX = pt.x;
|
||||
|
||||
if (pt.y < minY) {
|
||||
minY = pt.y;
|
||||
}
|
||||
if (pt.y > maxY) {
|
||||
maxY = pt.y;
|
||||
}
|
||||
if (pt.y < minY) minY = pt.y;
|
||||
if (pt.y > maxY) maxY = pt.y;
|
||||
}
|
||||
|
||||
return this.fromMinMax(minX, minY, maxX, maxY);
|
||||
|
||||
@@ -2,13 +2,16 @@ class Physics {
|
||||
private static _spatialHash: SpatialHash;
|
||||
/** 调用reset并创建一个新的SpatialHash时使用的单元格大小 */
|
||||
public static spatialHashCellSize = 100;
|
||||
|
||||
/** 接受layerMask的所有方法的默认值 */
|
||||
public static readonly allLayers: number = -1;
|
||||
|
||||
public static reset(){
|
||||
this._spatialHash = new SpatialHash(this.spatialHashCellSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从SpatialHash中移除所有碰撞器
|
||||
*/
|
||||
public static clear(){
|
||||
this._spatialHash.clear();
|
||||
}
|
||||
@@ -26,14 +29,26 @@ class Physics {
|
||||
return this._spatialHash.aabbBroadphase(rect, collider, layerMask);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将对撞机添加到物理系统中
|
||||
* @param collider
|
||||
*/
|
||||
public static addCollider(collider: Collider){
|
||||
Physics._spatialHash.register(collider);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从物理系统中移除对撞机
|
||||
* @param collider
|
||||
*/
|
||||
public static removeCollider(collider: Collider){
|
||||
Physics._spatialHash.remove(collider);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新物理系统中对撞机的位置。这实际上只是移除然后重新添加带有新边界的碰撞器
|
||||
* @param collider
|
||||
*/
|
||||
public static updateCollider(collider: Collider){
|
||||
this._spatialHash.remove(collider);
|
||||
this._spatialHash.register(collider);
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
///<reference path="./Polygon.ts" />
|
||||
/**
|
||||
* 多边形的特殊情况。在进行SAT碰撞检查时,我们只需要检查2个轴而不是8个轴
|
||||
*/
|
||||
class Box extends Polygon {
|
||||
public width: number;
|
||||
public height: number;
|
||||
@@ -9,7 +12,13 @@ class Box extends Polygon {
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
/**
|
||||
* 在一个盒子的形状中建立多边形需要的点的帮助方法
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
private static buildBox(width: number, height: number): Vector2[]{
|
||||
// 我们在(0,0)的中心周围创建点
|
||||
let halfWidth = width / 2;
|
||||
let halfHeight = height / 2;
|
||||
let verts = new Array(4);
|
||||
@@ -21,11 +30,8 @@ class Box extends Polygon {
|
||||
return verts;
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public overlaps(other: Shape){
|
||||
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
||||
if (this.isUnrotated){
|
||||
if (other instanceof Box && other.isUnrotated)
|
||||
return this.bounds.intersects(other.bounds);
|
||||
@@ -37,11 +43,8 @@ class Box extends Polygon {
|
||||
return super.overlaps(other);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param other
|
||||
*/
|
||||
public collidesWithShape(other: Shape){
|
||||
// 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测
|
||||
if (this.isUnrotated && other instanceof Box && other.isUnrotated){
|
||||
return ShapeCollisions.boxToBox(this, other);
|
||||
}
|
||||
@@ -51,10 +54,16 @@ class Box extends Polygon {
|
||||
return super.collidesWithShape(other);
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新框点,重新计算中心,设置宽度/高度
|
||||
* @param width
|
||||
* @param height
|
||||
*/
|
||||
public updateBox(width: number, height: number){
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
|
||||
// 我们在(0,0)的中心周围创建点
|
||||
let halfWidth = width / 2;
|
||||
let halfHeight = height / 2;
|
||||
|
||||
@@ -69,7 +78,7 @@ class Box extends Polygon {
|
||||
|
||||
public containsPoint(point: Vector2){
|
||||
if (this.isUnrotated)
|
||||
return this.bounds.contains(point);
|
||||
return this.bounds.containsInVec(point);
|
||||
|
||||
return super.containsPoint(point);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class Circle extends Shape {
|
||||
public recalculateBounds(collider: Collider) {
|
||||
this.center = collider.localOffset;
|
||||
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform) {
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform) {
|
||||
let scale = collider.entity.scale;
|
||||
let hasUnitScale = scale.x == 1 && scale.y == 1;
|
||||
let maxScale = Math.max(scale.x, scale.y);
|
||||
|
||||
@@ -103,6 +103,13 @@ class Polygon extends Shape {
|
||||
return new Vector2(x / points.length, y / points.length);
|
||||
}
|
||||
|
||||
/**
|
||||
* 迭代多边形的所有边,并得到任意边上离点最近的点。
|
||||
* 通过最近点的平方距离和它所在的边的法线返回。
|
||||
* 点应该在多边形的空间中(点-多边形.位置)
|
||||
* @param points
|
||||
* @param point
|
||||
*/
|
||||
public static getClosestPointOnPolygonToPoint(points: Vector2[], point: Vector2): { closestPoint, distanceSquared, edgeNormal } {
|
||||
let distanceSquared = Number.MAX_VALUE;
|
||||
let edgeNormal = new Vector2(0, 0);
|
||||
@@ -121,6 +128,7 @@ class Polygon extends Shape {
|
||||
distanceSquared = tempDistanceSquared;
|
||||
closestPoint = closest;
|
||||
|
||||
// 求直线的法线
|
||||
let line = Vector2.subtract(points[j], points[i]);
|
||||
edgeNormal.x = -line.y;
|
||||
edgeNormal.y = line.x;
|
||||
@@ -136,7 +144,13 @@ class Polygon extends Shape {
|
||||
return ShapeCollisions.pointToPoly(point, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* 本质上,这个算法所做的就是从一个点发射一条射线。
|
||||
* 如果它与奇数条多边形边相交,我们就知道它在多边形内部。
|
||||
* @param point
|
||||
*/
|
||||
public containsPoint(point: Vector2) {
|
||||
// 将点归一化到多边形坐标空间中
|
||||
point = Vector2.subtract(point, this.position);
|
||||
|
||||
let isInside = false;
|
||||
@@ -168,9 +182,10 @@ class Polygon extends Shape {
|
||||
}
|
||||
|
||||
public recalculateBounds(collider: Collider) {
|
||||
// 如果我们没有旋转或不关心TRS我们使用localOffset作为中心,我们会从那开始
|
||||
this.center = collider.localOffset;
|
||||
|
||||
if (collider.shouldColliderScaleAndRotationWithTransform){
|
||||
if (collider.shouldColliderScaleAndRotateWithTransform){
|
||||
let hasUnitScale = true;
|
||||
let tempMat: Matrix2D;
|
||||
let combinedMatrix = Matrix2D.createTranslation(-this._polygonCenter.x, -this._polygonCenter.y);
|
||||
@@ -180,14 +195,18 @@ class Polygon extends Shape {
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
|
||||
hasUnitScale = false;
|
||||
|
||||
// 缩放偏移量并将其设置为中心。如果我们有旋转,它会在下面重置
|
||||
let scaledOffset = Vector2.multiply(collider.localOffset, collider.entity.scale);
|
||||
this.center = scaledOffset;
|
||||
}
|
||||
|
||||
if (collider.entity.rotation != 0){
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation);
|
||||
tempMat = Matrix2D.createRotation(collider.entity.rotation, tempMat);
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
|
||||
// 为了处理偏移原点的旋转我们只需要将圆心在(0,0)附近移动我们的偏移使角度为0
|
||||
// 我们还需要处理这里的比例所以我们先对偏移进行缩放以得到合适的长度。
|
||||
let offsetAngle = Math.atan2(collider.localOffset.y, collider.localOffset.x) * MathHelper.Rad2Deg;
|
||||
let offsetLength = hasUnitScale ? collider._localOffsetLength : (Vector2.multiply(collider.localOffset, collider.entity.scale)).length();
|
||||
this.center = MathHelper.pointOnCirlce(Vector2.zero, offsetLength, MathHelper.toDegrees(collider.entity.rotation) + offsetAngle);
|
||||
@@ -196,11 +215,9 @@ class Polygon extends Shape {
|
||||
tempMat = Matrix2D.createTranslation(this._polygonCenter.x, this._polygonCenter.y);
|
||||
combinedMatrix = Matrix2D.multiply(combinedMatrix, tempMat);
|
||||
|
||||
// 最后变换原始点
|
||||
Vector2Ext.transform(this._originalPoints, combinedMatrix, this.points);
|
||||
this.isUnrotated = collider.entity.rotation == 0;
|
||||
|
||||
if (collider._isRotationDirty)
|
||||
this._areEdgeNormalsDirty = true;
|
||||
}
|
||||
|
||||
this.position = Vector2.add(collider.entity.position, this.center);
|
||||
|
||||
@@ -15,13 +15,17 @@ class ShapeCollisions {
|
||||
let polygonOffset = Vector2.subtract(first.position, second.position);
|
||||
let axis: Vector2;
|
||||
|
||||
// 循环穿过两个多边形的所有边
|
||||
for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) {
|
||||
// 1. 找出当前多边形是否相交
|
||||
// 多边形的归一化轴垂直于缓存给我们的当前边
|
||||
if (edgeIndex < firstEdges.length) {
|
||||
axis = firstEdges[edgeIndex];
|
||||
} else {
|
||||
axis = secondEdges[edgeIndex - firstEdges.length];
|
||||
}
|
||||
|
||||
// 求多边形在当前轴上的投影
|
||||
let minA = 0;
|
||||
let minB = 0;
|
||||
let maxA = 0;
|
||||
@@ -34,17 +38,24 @@ class ShapeCollisions {
|
||||
minB = tb.min;
|
||||
maxB = tb.max;
|
||||
|
||||
// 将区间设为第二个多边形的空间。由轴上投影的位置差偏移。
|
||||
let relativeIntervalOffset = Vector2.dot(polygonOffset, axis);
|
||||
minA += relativeIntervalOffset;
|
||||
maxA += relativeIntervalOffset;
|
||||
|
||||
// 检查多边形投影是否正在相交
|
||||
intervalDist = this.intervalDistance(minA, maxA, minB, maxB);
|
||||
if (intervalDist > 0)
|
||||
isIntersecting = false;
|
||||
|
||||
// 对于多对多数据类型转换,添加一个Vector2?参数称为deltaMovement。为了提高速度,我们这里不使用它
|
||||
// TODO: 现在找出多边形是否会相交。只要检查速度就行了
|
||||
|
||||
// 如果多边形不相交,也不会相交,退出循环
|
||||
if (!isIntersecting)
|
||||
return null;
|
||||
|
||||
// 检查当前间隔距离是否为最小值。如果是,则存储间隔距离和当前距离。这将用于计算最小平移向量
|
||||
intervalDist = Math.abs(intervalDist);
|
||||
if (intervalDist < minIntervalDistance) {
|
||||
minIntervalDistance = intervalDist;
|
||||
@@ -55,8 +66,9 @@ class ShapeCollisions {
|
||||
}
|
||||
}
|
||||
|
||||
// 利用最小平移向量对多边形进行推入。
|
||||
result.normal = translationAxis;
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis), new Vector2(minIntervalDistance));
|
||||
result.minimumTranslationVector = Vector2.multiply(new Vector2(-translationAxis.x, -translationAxis.y), new Vector2(minIntervalDistance));
|
||||
|
||||
return result;
|
||||
}
|
||||
@@ -262,11 +274,12 @@ class ShapeCollisions {
|
||||
let result = new CollisionResult();
|
||||
|
||||
let minkowskiDiff = this.minkowskiDifference(first, second);
|
||||
if (minkowskiDiff.contains(new Vector2(0, 0))){
|
||||
if (minkowskiDiff.containsInVec(new Vector2(0, 0))){
|
||||
// 计算MTV。如果它是零,我们就可以称它为非碰撞
|
||||
result.minimumTranslationVector = minkowskiDiff.getClosestPointOnBoundsToOrigin();
|
||||
|
||||
if (result.minimumTranslationVector == Vector2.zero)
|
||||
return false;
|
||||
if (result.minimumTranslationVector.x == 0 && result.minimumTranslationVector.y == 0)
|
||||
return null;
|
||||
|
||||
result.normal = new Vector2(-result.minimumTranslationVector.x, -result.minimumTranslationVector.y);
|
||||
result.normal.normalize();
|
||||
@@ -278,6 +291,8 @@ class ShapeCollisions {
|
||||
}
|
||||
|
||||
private static minkowskiDifference(first: Box, second: Box){
|
||||
// 我们需要第一个框的左上角
|
||||
// 碰撞器只会修改运动的位置所以我们需要用位置来计算出运动是什么。
|
||||
let positionOffset = Vector2.subtract(first.position, Vector2.add(first.bounds.location, Vector2.divide(first.bounds.size, new Vector2(2))));
|
||||
let topLeft = Vector2.subtract(Vector2.add(first.bounds.location, positionOffset), second.bounds.max);
|
||||
let fullSize = Vector2.add(first.bounds.size, second.bounds.size);
|
||||
|
||||
@@ -2,10 +2,15 @@ class SpatialHash {
|
||||
public gridBounds: Rectangle = new Rectangle();
|
||||
|
||||
private _raycastParser: RaycastResultParser;
|
||||
/** 散列中每个单元格的大小 */
|
||||
private _cellSize: number;
|
||||
/** 1除以单元格大小。缓存结果,因为它被大量使用。 */
|
||||
private _inverseCellSize: number;
|
||||
private _overlapTestCircle: Circle;
|
||||
/** 缓存的循环用于重叠检查 */
|
||||
private _overlapTestCircle: Circle = new Circle(0);
|
||||
/** 用于返回冲突信息的共享HashSet */
|
||||
private _tempHashSet: Collider[] = [];
|
||||
/** 保存所有数据的字典 */
|
||||
private _cellDict: NumberDictionary = new NumberDictionary();
|
||||
|
||||
constructor(cellSize: number = 100) {
|
||||
@@ -14,6 +19,10 @@ class SpatialHash {
|
||||
this._raycastParser = new RaycastResultParser();
|
||||
}
|
||||
|
||||
/**
|
||||
* 从SpatialHash中删除对象
|
||||
* @param collider
|
||||
*/
|
||||
public remove(collider: Collider) {
|
||||
let bounds = collider.registeredPhysicsBounds;
|
||||
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 y = p1.y; y <= p2.y; y++) {
|
||||
// 单元格应该始终存在,因为这个碰撞器应该在所有查询的单元格中
|
||||
let cell = this.cellAtPosition(x, y);
|
||||
if (!cell)
|
||||
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) {
|
||||
let bounds = collider.bounds;
|
||||
collider.registeredPhysicsBounds = bounds;
|
||||
let p1 = this.cellCoords(bounds.x, bounds.y);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
for (let x = p1.x; x <= p2.x; x++) {
|
||||
for (let y = p1.y; y <= p2.y; y++) {
|
||||
// 如果没有单元格,我们需要创建它
|
||||
let c = this.cellAtPosition(x, y, true);
|
||||
c.push(collider);
|
||||
}
|
||||
@@ -56,6 +72,13 @@ class SpatialHash {
|
||||
this._cellDict.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取位于指定圆内的所有碰撞器
|
||||
* @param circleCenter
|
||||
* @param radius
|
||||
* @param results
|
||||
* @param layerMask
|
||||
*/
|
||||
public overlapCircle(circleCenter: Vector2, radius: number, results: Collider[], layerMask) {
|
||||
let bounds = new Rectangle(circleCenter.x - radius, circleCenter.y - radius, radius * 2, radius * 2);
|
||||
|
||||
@@ -82,6 +105,12 @@ class SpatialHash {
|
||||
return resultCounter;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回边框与单元格相交的所有对象
|
||||
* @param bounds
|
||||
* @param excludeCollider
|
||||
* @param layerMask
|
||||
*/
|
||||
public aabbBroadphase(bounds: Rectangle, excludeCollider: Collider, layerMask: number) {
|
||||
this._tempHashSet.length = 0;
|
||||
|
||||
@@ -94,9 +123,11 @@ class SpatialHash {
|
||||
if (!cell)
|
||||
continue;
|
||||
|
||||
// 当cell不为空。循环并取回所有碰撞器
|
||||
for (let i = 0; i < cell.length; i++) {
|
||||
let collider = cell[i];
|
||||
|
||||
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
|
||||
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer))
|
||||
continue;
|
||||
|
||||
@@ -111,6 +142,13 @@ class SpatialHash {
|
||||
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) {
|
||||
let cell: Collider[] = this._cellDict.tryGetValue(x, y);
|
||||
if (!cell) {
|
||||
@@ -122,8 +160,13 @@ class SpatialHash {
|
||||
return cell;
|
||||
}
|
||||
|
||||
private cellCoords(x: number, y: number): Point {
|
||||
return new Point(Math.floor(x * this._inverseCellSize), Math.floor(y * this._inverseCellSize));
|
||||
/**
|
||||
* 获取单元格的x,y值作为世界空间的x,y值
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
private cellCoords(x: number, y: number): Vector2 {
|
||||
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 {
|
||||
private _store: Map<number, Collider[]> = new Map<number, Collider[]>();
|
||||
|
||||
@@ -154,6 +201,10 @@ class NumberDictionary {
|
||||
this._store.set(this.getKey(x, y), list);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用蛮力方法从字典存储列表中移除碰撞器
|
||||
* @param obj
|
||||
*/
|
||||
public remove(obj: Collider) {
|
||||
this._store.forEach(list => {
|
||||
if (list.contains(obj))
|
||||
@@ -165,6 +216,9 @@ class NumberDictionary {
|
||||
return this._store.get(this.getKey(x, y));
|
||||
}
|
||||
|
||||
/**
|
||||
* 清除字典数据
|
||||
*/
|
||||
public clear() {
|
||||
this._store.clear();
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
class RectangleExt {
|
||||
public static union(first: Rectangle, point: Point){
|
||||
public static union(first: Rectangle, point: Vector2){
|
||||
let rect = new Rectangle(point.x, point.y, 0, 0);
|
||||
return this.unionR(first, rect);
|
||||
}
|
||||
|
||||
@@ -43,6 +43,15 @@ class Vector2Ext {
|
||||
return vec;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过指定的矩阵对Vector2的数组中的向量应用变换,并将结果放置在另一个数组中。
|
||||
* @param sourceArray
|
||||
* @param sourceIndex
|
||||
* @param matrix
|
||||
* @param destinationArray
|
||||
* @param destinationIndex
|
||||
* @param length
|
||||
*/
|
||||
public static transformA(sourceArray: Vector2[], sourceIndex: number, matrix: Matrix2D,
|
||||
destinationArray: Vector2[], destinationIndex: number, length: number) {
|
||||
for (let i = 0; i < length; i ++){
|
||||
@@ -60,6 +69,12 @@ class Vector2Ext {
|
||||
return new Vector2(x, y);
|
||||
}
|
||||
|
||||
/**
|
||||
* 通过指定的矩阵对Vector2的数组中的所有向量应用变换,并将结果放到另一个数组中。
|
||||
* @param sourceArray
|
||||
* @param matrix
|
||||
* @param destinationArray
|
||||
*/
|
||||
public static transform(sourceArray: Vector2[], matrix: Matrix2D, destinationArray: Vector2[]) {
|
||||
this.transformA(sourceArray, 0, matrix, destinationArray, 0, sourceArray.length);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user