修复polygon数组错误 修复emit空注册报错

This commit is contained in:
yhh
2020-06-15 20:08:21 +08:00
parent c3120d791f
commit 5186bc0187
16 changed files with 398 additions and 32 deletions

View File

@@ -383,13 +383,23 @@ declare abstract class Collider extends Component {
registeredPhysicsBounds: Rectangle; registeredPhysicsBounds: Rectangle;
protected _isParentEntityAddedToScene: any; protected _isParentEntityAddedToScene: any;
protected _isPositionDirty: boolean; protected _isPositionDirty: boolean;
protected _isRotationDirty: boolean;
protected _colliderRequiresAutoSizing: any; protected _colliderRequiresAutoSizing: any;
protected _localOffset: Vector2;
protected _isColliderRegisterd: any;
readonly bounds: Rectangle; readonly bounds: Rectangle;
localOffset: Vector2;
setLocalOffset(offset: Vector2): void;
registerColliderWithPhysicsSystem(): void;
unregisterColliderWithPhysicsSystem(): void;
initialize(): void; initialize(): void;
} }
declare class BoxCollider extends Collider { declare class BoxCollider extends Collider {
width: number; width: number;
setWidth(width: number): BoxCollider; setWidth(width: number): BoxCollider;
height: number;
setHeight(height: number): void;
constructor();
} }
declare class EntitySystem { declare class EntitySystem {
private _scene; private _scene;
@@ -618,11 +628,15 @@ declare class Physics {
static readonly allLayers: number; static readonly allLayers: number;
static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number;
static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[]; static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[];
static addCollider(collider: Collider): void;
static removeCollider(collider: Collider): void;
static updateCollider(collider: Collider): void; static updateCollider(collider: Collider): void;
} }
declare abstract class Shape { declare abstract class Shape {
bounds: Rectangle; bounds: Rectangle;
position: Vector2; position: Vector2;
center: Vector2;
abstract recalculateBounds(collider: Collider): any;
abstract pointCollidesWithShape(point: Vector2): CollisionResult; abstract pointCollidesWithShape(point: Vector2): CollisionResult;
} }
declare class Polygon extends Shape { declare class Polygon extends Shape {
@@ -647,7 +661,8 @@ declare class Polygon extends Shape {
}; };
pointCollidesWithShape(point: Vector2): CollisionResult; pointCollidesWithShape(point: Vector2): CollisionResult;
containsPoint(point: Vector2): boolean; containsPoint(point: Vector2): boolean;
static buildSymmertricalPolygon(vertCount: number, radius: number): any; static buildSymmertricalPolygon(vertCount: number, radius: number): any[];
recalculateBounds(collider: Collider): void;
} }
declare class Box extends Polygon { declare class Box extends Polygon {
width: number; width: number;
@@ -661,6 +676,7 @@ declare class Circle extends Shape {
constructor(radius: number); constructor(radius: number);
pointCollidesWithShape(point: Vector2): CollisionResult; pointCollidesWithShape(point: Vector2): CollisionResult;
collidesWithShape(other: Shape): CollisionResult; collidesWithShape(other: Shape): CollisionResult;
recalculateBounds(collider: Collider): void;
} }
declare class CollisionResult { declare class CollisionResult {
minimumTranslationVector: Vector2; minimumTranslationVector: Vector2;
@@ -669,6 +685,7 @@ declare class CollisionResult {
} }
declare class ShapeCollisions { declare class ShapeCollisions {
static polygonToPolygon(first: Polygon, second: Polygon): void; static polygonToPolygon(first: Polygon, second: Polygon): void;
static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): void;
static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult; static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult;
static circleToRect(circle: Circle, box: Box): CollisionResult; static circleToRect(circle: Circle, box: Box): CollisionResult;
static pointToCicle(point: Vector2, circle: Circle): CollisionResult; static pointToCicle(point: Vector2, circle: Circle): CollisionResult;

View File

@@ -1787,15 +1787,50 @@ var Collider = (function (_super) {
var _this = _super !== null && _super.apply(this, arguments) || this; var _this = _super !== null && _super.apply(this, arguments) || this;
_this.physicsLayer = 1 << 0; _this.physicsLayer = 1 << 0;
_this._isPositionDirty = true; _this._isPositionDirty = true;
_this._isRotationDirty = true;
return _this; return _this;
} }
Object.defineProperty(Collider.prototype, "bounds", { Object.defineProperty(Collider.prototype, "bounds", {
get: function () { get: function () {
if (this._isPositionDirty || this._isRotationDirty) {
this.shape.recalculateBounds(this);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds; return this.shape.bounds;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(Collider.prototype, "localOffset", {
get: function () {
return this._localOffset;
},
set: function (value) {
this.setLocalOffset(value);
},
enumerable: true,
configurable: true
});
Collider.prototype.setLocalOffset = function (offset) {
if (this._localOffset != offset) {
this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset;
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem();
}
};
Collider.prototype.registerColliderWithPhysicsSystem = function () {
if (this._isParentEntityAddedToScene && !this._isColliderRegisterd) {
Physics.addCollider(this);
this._isColliderRegisterd = true;
}
};
Collider.prototype.unregisterColliderWithPhysicsSystem = function () {
if (this._isParentEntityAddedToScene && this._isColliderRegisterd) {
Physics.removeCollider(this);
}
this._isColliderRegisterd = false;
};
Collider.prototype.initialize = function () { Collider.prototype.initialize = function () {
}; };
return Collider; return Collider;
@@ -1803,7 +1838,10 @@ var Collider = (function (_super) {
var BoxCollider = (function (_super) { var BoxCollider = (function (_super) {
__extends(BoxCollider, _super); __extends(BoxCollider, _super);
function BoxCollider() { function BoxCollider() {
return _super !== null && _super.apply(this, arguments) || this; var _this = _super.call(this) || this;
_this.shape = new Box(1, 1);
_this._colliderRequiresAutoSizing = true;
return _this;
} }
Object.defineProperty(BoxCollider.prototype, "width", { Object.defineProperty(BoxCollider.prototype, "width", {
get: function () { get: function () {
@@ -1826,6 +1864,26 @@ var BoxCollider = (function (_super) {
} }
return this; return this;
}; };
Object.defineProperty(BoxCollider.prototype, "height", {
get: function () {
return this.shape.height;
},
set: function (value) {
this.setHeight(value);
},
enumerable: true,
configurable: true
});
BoxCollider.prototype.setHeight = function (height) {
this._colliderRequiresAutoSizing = false;
var box = this.shape;
if (height != box.height) {
box.updateBox(box.width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this);
}
};
return BoxCollider; return BoxCollider;
}(Collider)); }(Collider));
var EntitySystem = (function () { var EntitySystem = (function () {
@@ -2917,6 +2975,12 @@ var Physics = (function () {
if (layerMask === void 0) { layerMask = this.allLayers; } if (layerMask === void 0) { layerMask = this.allLayers; }
return this._spatialHash.aabbBroadphase(rect, null, layerMask); return this._spatialHash.aabbBroadphase(rect, null, layerMask);
}; };
Physics.addCollider = function (collider) {
Physics._spatialHash.register(collider);
};
Physics.removeCollider = function (collider) {
Physics._spatialHash.remove(collider);
};
Physics.updateCollider = function (collider) { Physics.updateCollider = function (collider) {
this._spatialHash.remove(collider); this._spatialHash.remove(collider);
this._spatialHash.register(collider); this._spatialHash.register(collider);
@@ -2950,7 +3014,7 @@ var Polygon = (function (_super) {
Polygon.prototype.buildEdgeNormals = function () { Polygon.prototype.buildEdgeNormals = function () {
var totalEdges = this.isBox ? 2 : this.points.length; var totalEdges = this.isBox ? 2 : this.points.length;
if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) if (this._edgeNormals == null || this._edgeNormals.length != totalEdges)
this._edgeNormals = new Vector2[totalEdges]; this._edgeNormals = new Array(totalEdges);
var p2; var p2;
for (var i = 0; i < totalEdges; i++) { for (var i = 0; i < totalEdges; i++) {
var p1 = this.points[i]; var p1 = this.points[i];
@@ -2966,7 +3030,7 @@ var Polygon = (function (_super) {
Polygon.prototype.setPoints = function (points) { Polygon.prototype.setPoints = function (points) {
this.points = points; this.points = points;
this.recalculateCenterAndEdgeNormals(); this.recalculateCenterAndEdgeNormals();
this._originalPoints = new Vector2[points.length]; this._originalPoints = new Array(points.length);
this._originalPoints = points; this._originalPoints = points;
}; };
Polygon.prototype.collidesWithShape = function (other) { Polygon.prototype.collidesWithShape = function (other) {
@@ -3023,13 +3087,16 @@ var Polygon = (function (_super) {
return isInside; return isInside;
}; };
Polygon.buildSymmertricalPolygon = function (vertCount, radius) { Polygon.buildSymmertricalPolygon = function (vertCount, radius) {
var verts = new Vector2[vertCount]; var verts = new Array(vertCount);
for (var i = 0; i < vertCount; i++) { for (var i = 0; i < vertCount; i++) {
var a = 2 * Math.PI * (i / vertCount); var a = 2 * Math.PI * (i / vertCount);
verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius); verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius);
} }
return verts; return verts;
}; };
Polygon.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset;
};
return Polygon; return Polygon;
}(Shape)); }(Shape));
var Box = (function (_super) { var Box = (function (_super) {
@@ -3071,8 +3138,16 @@ var Circle = (function (_super) {
if (other instanceof Box && other.isUnrotated) { if (other instanceof Box && other.isUnrotated) {
return ShapeCollisions.circleToRect(this, other); return ShapeCollisions.circleToRect(this, other);
} }
if (other instanceof Circle) {
}
if (other instanceof Polygon) {
return ShapeCollisions.circleToPolygon(this, other);
}
throw new Error("Collisions of Circle to " + other + " are not supported"); throw new Error("Collisions of Circle to " + other + " are not supported");
}; };
Circle.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset;
};
return Circle; return Circle;
}(Shape)); }(Shape));
var CollisionResult = (function () { var CollisionResult = (function () {
@@ -3092,6 +3167,34 @@ var ShapeCollisions = (function () {
var translationAxis = new Vector2(); var translationAxis = new Vector2();
var polygonOffset = Vector2.subtract(first.position, second.position); var polygonOffset = Vector2.subtract(first.position, second.position);
var axis; var axis;
for (var edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) {
if (edgeIndex < firstEdges.length) {
axis = firstEdges[edgeIndex];
}
else {
axis = secondEdges[edgeIndex - firstEdges.length];
}
var minA = 0;
var minB = 0;
var maxA = 0;
var maxB = 0;
var intervalDist = 0;
this.getInterval(axis, first, minA, maxA);
this.getInterval(axis, second, minB, maxB);
}
};
ShapeCollisions.getInterval = function (axis, polygon, min, max) {
var dot = Vector2.dot(polygon.points[0], axis);
min = max = dot;
for (var i = 1; i < polygon.points.length; i++) {
dot = Vector2.dot(polygon.points[i], axis);
if (dot < min) {
min = dot;
}
else if (dot > max) {
max = dot;
}
}
}; };
ShapeCollisions.circleToPolygon = function (circle, polygon) { ShapeCollisions.circleToPolygon = function (circle, polygon) {
var result = new CollisionResult(); var result = new CollisionResult();
@@ -3293,8 +3396,10 @@ var Emitter = (function () {
}; };
Emitter.prototype.emit = function (eventType, data) { Emitter.prototype.emit = function (eventType, data) {
var list = this._messageTable.get(eventType); var list = this._messageTable.get(eventType);
for (var i = list.length - 1; i >= 0; i--) if (list) {
list[i](data); for (var i = list.length - 1; i >= 0; i--)
list[i](data);
}
}; };
return Emitter; return Emitter;
}()); }());

File diff suppressed because one or more lines are too long

View File

@@ -105,7 +105,7 @@ class Main extends eui.UILayer {
new Vector2(0, 10), new Vector2(0, 10),
new Vector2(0, 0)])); new Vector2(0, 0)]));
player.addComponent(new SpawnComponent(EnemyType.worm)); player.addComponent(new SpawnComponent(EnemyType.worm));
// console.log(player.transform.position); player.addComponent(new BoxCollider());
Main.emitter.addObserver(CoreEmitterType.Update, ()=>{ Main.emitter.addObserver(CoreEmitterType.Update, ()=>{
console.log("update emitter"); console.log("update emitter");

View File

@@ -383,13 +383,23 @@ declare abstract class Collider extends Component {
registeredPhysicsBounds: Rectangle; registeredPhysicsBounds: Rectangle;
protected _isParentEntityAddedToScene: any; protected _isParentEntityAddedToScene: any;
protected _isPositionDirty: boolean; protected _isPositionDirty: boolean;
protected _isRotationDirty: boolean;
protected _colliderRequiresAutoSizing: any; protected _colliderRequiresAutoSizing: any;
protected _localOffset: Vector2;
protected _isColliderRegisterd: any;
readonly bounds: Rectangle; readonly bounds: Rectangle;
localOffset: Vector2;
setLocalOffset(offset: Vector2): void;
registerColliderWithPhysicsSystem(): void;
unregisterColliderWithPhysicsSystem(): void;
initialize(): void; initialize(): void;
} }
declare class BoxCollider extends Collider { declare class BoxCollider extends Collider {
width: number; width: number;
setWidth(width: number): BoxCollider; setWidth(width: number): BoxCollider;
height: number;
setHeight(height: number): void;
constructor();
} }
declare class EntitySystem { declare class EntitySystem {
private _scene; private _scene;
@@ -618,11 +628,15 @@ declare class Physics {
static readonly allLayers: number; static readonly allLayers: number;
static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number; static overlapCircleAll(center: Vector2, randius: number, results: any[], layerMask?: number): number;
static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[]; static boxcastBroadphase(rect: Rectangle, layerMask?: number): Collider[];
static addCollider(collider: Collider): void;
static removeCollider(collider: Collider): void;
static updateCollider(collider: Collider): void; static updateCollider(collider: Collider): void;
} }
declare abstract class Shape { declare abstract class Shape {
bounds: Rectangle; bounds: Rectangle;
position: Vector2; position: Vector2;
center: Vector2;
abstract recalculateBounds(collider: Collider): any;
abstract pointCollidesWithShape(point: Vector2): CollisionResult; abstract pointCollidesWithShape(point: Vector2): CollisionResult;
} }
declare class Polygon extends Shape { declare class Polygon extends Shape {
@@ -647,7 +661,8 @@ declare class Polygon extends Shape {
}; };
pointCollidesWithShape(point: Vector2): CollisionResult; pointCollidesWithShape(point: Vector2): CollisionResult;
containsPoint(point: Vector2): boolean; containsPoint(point: Vector2): boolean;
static buildSymmertricalPolygon(vertCount: number, radius: number): any; static buildSymmertricalPolygon(vertCount: number, radius: number): any[];
recalculateBounds(collider: Collider): void;
} }
declare class Box extends Polygon { declare class Box extends Polygon {
width: number; width: number;
@@ -661,6 +676,7 @@ declare class Circle extends Shape {
constructor(radius: number); constructor(radius: number);
pointCollidesWithShape(point: Vector2): CollisionResult; pointCollidesWithShape(point: Vector2): CollisionResult;
collidesWithShape(other: Shape): CollisionResult; collidesWithShape(other: Shape): CollisionResult;
recalculateBounds(collider: Collider): void;
} }
declare class CollisionResult { declare class CollisionResult {
minimumTranslationVector: Vector2; minimumTranslationVector: Vector2;
@@ -669,6 +685,7 @@ declare class CollisionResult {
} }
declare class ShapeCollisions { declare class ShapeCollisions {
static polygonToPolygon(first: Polygon, second: Polygon): void; static polygonToPolygon(first: Polygon, second: Polygon): void;
static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number): void;
static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult; static circleToPolygon(circle: Circle, polygon: Polygon): CollisionResult;
static circleToRect(circle: Circle, box: Box): CollisionResult; static circleToRect(circle: Circle, box: Box): CollisionResult;
static pointToCicle(point: Vector2, circle: Circle): CollisionResult; static pointToCicle(point: Vector2, circle: Circle): CollisionResult;

View File

@@ -1787,15 +1787,50 @@ var Collider = (function (_super) {
var _this = _super !== null && _super.apply(this, arguments) || this; var _this = _super !== null && _super.apply(this, arguments) || this;
_this.physicsLayer = 1 << 0; _this.physicsLayer = 1 << 0;
_this._isPositionDirty = true; _this._isPositionDirty = true;
_this._isRotationDirty = true;
return _this; return _this;
} }
Object.defineProperty(Collider.prototype, "bounds", { Object.defineProperty(Collider.prototype, "bounds", {
get: function () { get: function () {
if (this._isPositionDirty || this._isRotationDirty) {
this.shape.recalculateBounds(this);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds; return this.shape.bounds;
}, },
enumerable: true, enumerable: true,
configurable: true configurable: true
}); });
Object.defineProperty(Collider.prototype, "localOffset", {
get: function () {
return this._localOffset;
},
set: function (value) {
this.setLocalOffset(value);
},
enumerable: true,
configurable: true
});
Collider.prototype.setLocalOffset = function (offset) {
if (this._localOffset != offset) {
this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset;
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem();
}
};
Collider.prototype.registerColliderWithPhysicsSystem = function () {
if (this._isParentEntityAddedToScene && !this._isColliderRegisterd) {
Physics.addCollider(this);
this._isColliderRegisterd = true;
}
};
Collider.prototype.unregisterColliderWithPhysicsSystem = function () {
if (this._isParentEntityAddedToScene && this._isColliderRegisterd) {
Physics.removeCollider(this);
}
this._isColliderRegisterd = false;
};
Collider.prototype.initialize = function () { Collider.prototype.initialize = function () {
}; };
return Collider; return Collider;
@@ -1803,7 +1838,10 @@ var Collider = (function (_super) {
var BoxCollider = (function (_super) { var BoxCollider = (function (_super) {
__extends(BoxCollider, _super); __extends(BoxCollider, _super);
function BoxCollider() { function BoxCollider() {
return _super !== null && _super.apply(this, arguments) || this; var _this = _super.call(this) || this;
_this.shape = new Box(1, 1);
_this._colliderRequiresAutoSizing = true;
return _this;
} }
Object.defineProperty(BoxCollider.prototype, "width", { Object.defineProperty(BoxCollider.prototype, "width", {
get: function () { get: function () {
@@ -1826,6 +1864,26 @@ var BoxCollider = (function (_super) {
} }
return this; return this;
}; };
Object.defineProperty(BoxCollider.prototype, "height", {
get: function () {
return this.shape.height;
},
set: function (value) {
this.setHeight(value);
},
enumerable: true,
configurable: true
});
BoxCollider.prototype.setHeight = function (height) {
this._colliderRequiresAutoSizing = false;
var box = this.shape;
if (height != box.height) {
box.updateBox(box.width, height);
this._isPositionDirty = true;
if (this.entity && this._isParentEntityAddedToScene)
Physics.updateCollider(this);
}
};
return BoxCollider; return BoxCollider;
}(Collider)); }(Collider));
var EntitySystem = (function () { var EntitySystem = (function () {
@@ -2917,6 +2975,12 @@ var Physics = (function () {
if (layerMask === void 0) { layerMask = this.allLayers; } if (layerMask === void 0) { layerMask = this.allLayers; }
return this._spatialHash.aabbBroadphase(rect, null, layerMask); return this._spatialHash.aabbBroadphase(rect, null, layerMask);
}; };
Physics.addCollider = function (collider) {
Physics._spatialHash.register(collider);
};
Physics.removeCollider = function (collider) {
Physics._spatialHash.remove(collider);
};
Physics.updateCollider = function (collider) { Physics.updateCollider = function (collider) {
this._spatialHash.remove(collider); this._spatialHash.remove(collider);
this._spatialHash.register(collider); this._spatialHash.register(collider);
@@ -2950,7 +3014,7 @@ var Polygon = (function (_super) {
Polygon.prototype.buildEdgeNormals = function () { Polygon.prototype.buildEdgeNormals = function () {
var totalEdges = this.isBox ? 2 : this.points.length; var totalEdges = this.isBox ? 2 : this.points.length;
if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) if (this._edgeNormals == null || this._edgeNormals.length != totalEdges)
this._edgeNormals = new Vector2[totalEdges]; this._edgeNormals = new Array(totalEdges);
var p2; var p2;
for (var i = 0; i < totalEdges; i++) { for (var i = 0; i < totalEdges; i++) {
var p1 = this.points[i]; var p1 = this.points[i];
@@ -2966,7 +3030,7 @@ var Polygon = (function (_super) {
Polygon.prototype.setPoints = function (points) { Polygon.prototype.setPoints = function (points) {
this.points = points; this.points = points;
this.recalculateCenterAndEdgeNormals(); this.recalculateCenterAndEdgeNormals();
this._originalPoints = new Vector2[points.length]; this._originalPoints = new Array(points.length);
this._originalPoints = points; this._originalPoints = points;
}; };
Polygon.prototype.collidesWithShape = function (other) { Polygon.prototype.collidesWithShape = function (other) {
@@ -3023,13 +3087,16 @@ var Polygon = (function (_super) {
return isInside; return isInside;
}; };
Polygon.buildSymmertricalPolygon = function (vertCount, radius) { Polygon.buildSymmertricalPolygon = function (vertCount, radius) {
var verts = new Vector2[vertCount]; var verts = new Array(vertCount);
for (var i = 0; i < vertCount; i++) { for (var i = 0; i < vertCount; i++) {
var a = 2 * Math.PI * (i / vertCount); var a = 2 * Math.PI * (i / vertCount);
verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius); verts[i] = new Vector2(Math.cos(a), Math.sin(a) * radius);
} }
return verts; return verts;
}; };
Polygon.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset;
};
return Polygon; return Polygon;
}(Shape)); }(Shape));
var Box = (function (_super) { var Box = (function (_super) {
@@ -3071,8 +3138,16 @@ var Circle = (function (_super) {
if (other instanceof Box && other.isUnrotated) { if (other instanceof Box && other.isUnrotated) {
return ShapeCollisions.circleToRect(this, other); return ShapeCollisions.circleToRect(this, other);
} }
if (other instanceof Circle) {
}
if (other instanceof Polygon) {
return ShapeCollisions.circleToPolygon(this, other);
}
throw new Error("Collisions of Circle to " + other + " are not supported"); throw new Error("Collisions of Circle to " + other + " are not supported");
}; };
Circle.prototype.recalculateBounds = function (collider) {
this.center = collider.localOffset;
};
return Circle; return Circle;
}(Shape)); }(Shape));
var CollisionResult = (function () { var CollisionResult = (function () {
@@ -3092,6 +3167,34 @@ var ShapeCollisions = (function () {
var translationAxis = new Vector2(); var translationAxis = new Vector2();
var polygonOffset = Vector2.subtract(first.position, second.position); var polygonOffset = Vector2.subtract(first.position, second.position);
var axis; var axis;
for (var edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex++) {
if (edgeIndex < firstEdges.length) {
axis = firstEdges[edgeIndex];
}
else {
axis = secondEdges[edgeIndex - firstEdges.length];
}
var minA = 0;
var minB = 0;
var maxA = 0;
var maxB = 0;
var intervalDist = 0;
this.getInterval(axis, first, minA, maxA);
this.getInterval(axis, second, minB, maxB);
}
};
ShapeCollisions.getInterval = function (axis, polygon, min, max) {
var dot = Vector2.dot(polygon.points[0], axis);
min = max = dot;
for (var i = 1; i < polygon.points.length; i++) {
dot = Vector2.dot(polygon.points[i], axis);
if (dot < min) {
min = dot;
}
else if (dot > max) {
max = dot;
}
}
}; };
ShapeCollisions.circleToPolygon = function (circle, polygon) { ShapeCollisions.circleToPolygon = function (circle, polygon) {
var result = new CollisionResult(); var result = new CollisionResult();
@@ -3293,8 +3396,10 @@ var Emitter = (function () {
}; };
Emitter.prototype.emit = function (eventType, data) { Emitter.prototype.emit = function (eventType, data) {
var list = this._messageTable.get(eventType); var list = this._messageTable.get(eventType);
for (var i = list.length - 1; i >= 0; i--) if (list) {
list[i](data); for (var i = list.length - 1; i >= 0; i--)
list[i](data);
}
}; };
return Emitter; return Emitter;
}()); }());

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,5 @@
///<reference path="./Collider.ts" /> ///<reference path="./Collider.ts" />
class BoxCollider extends Collider { class BoxCollider extends Collider {
public get width(){ public get width(){
return (this.shape as Box).width; return (this.shape as Box).width;
} }
@@ -21,4 +20,30 @@ class BoxCollider extends Collider {
return this; return this;
} }
public get height(){
return (this.shape as Box).height;
}
public set height(value: number){
this.setHeight(value);
}
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);
}
}
constructor(){
super();
this.shape = new Box(1, 1);
this._colliderRequiresAutoSizing = true;
}
} }

View File

@@ -6,12 +6,51 @@ abstract class Collider extends Component{
protected _isParentEntityAddedToScene; protected _isParentEntityAddedToScene;
protected _isPositionDirty = true; protected _isPositionDirty = true;
protected _isRotationDirty = true;
protected _colliderRequiresAutoSizing; protected _colliderRequiresAutoSizing;
protected _localOffset: Vector2;
protected _isColliderRegisterd;
public get bounds(): Rectangle { public get bounds(): Rectangle {
if (this._isPositionDirty || this._isRotationDirty){
this.shape.recalculateBounds(this);
this._isPositionDirty = this._isRotationDirty = false;
}
return this.shape.bounds; return this.shape.bounds;
} }
public get localOffset(){
return this._localOffset;
}
public set localOffset(value: Vector2){
this.setLocalOffset(value);
}
public setLocalOffset(offset: Vector2){
if (this._localOffset != offset){
this.unregisterColliderWithPhysicsSystem();
this._localOffset = offset;
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem();
}
}
public registerColliderWithPhysicsSystem(){
if (this._isParentEntityAddedToScene && !this._isColliderRegisterd){
Physics.addCollider(this);
this._isColliderRegisterd = true;
}
}
public unregisterColliderWithPhysicsSystem(){
if (this._isParentEntityAddedToScene && this._isColliderRegisterd){
Physics.removeCollider(this);
}
this._isColliderRegisterd = false;
}
public initialize() { public initialize() {
} }
} }

View File

@@ -11,6 +11,14 @@ class Physics {
return this._spatialHash.aabbBroadphase(rect, null, layerMask); return this._spatialHash.aabbBroadphase(rect, null, layerMask);
} }
public static addCollider(collider: Collider){
Physics._spatialHash.register(collider);
}
public static removeCollider(collider: Collider){
Physics._spatialHash.remove(collider);
}
public static updateCollider(collider: Collider){ public static updateCollider(collider: Collider){
this._spatialHash.remove(collider); this._spatialHash.remove(collider);
this._spatialHash.register(collider); this._spatialHash.register(collider);

View File

@@ -18,6 +18,18 @@ class Circle extends Shape {
return ShapeCollisions.circleToRect(this, other as Box); return ShapeCollisions.circleToRect(this, other as Box);
} }
if (other instanceof Circle){
// TODO CIRCLETOCIRCLE
}
if (other instanceof Polygon){
return ShapeCollisions.circleToPolygon(this, other);
}
throw new Error(`Collisions of Circle to ${other} are not supported`); throw new Error(`Collisions of Circle to ${other} are not supported`);
} }
public recalculateBounds(collider: Collider) {
this.center = collider.localOffset;
}
} }

View File

@@ -22,7 +22,7 @@ class Polygon extends Shape {
private buildEdgeNormals(){ private buildEdgeNormals(){
let totalEdges = this.isBox ? 2 : this.points.length; let totalEdges = this.isBox ? 2 : this.points.length;
if (this._edgeNormals == null || this._edgeNormals.length != totalEdges) if (this._edgeNormals == null || this._edgeNormals.length != totalEdges)
this._edgeNormals = new Vector2[totalEdges]; this._edgeNormals = new Array(totalEdges);
let p2: Vector2; let p2: Vector2;
for (let i = 0; i < totalEdges; i ++){ for (let i = 0; i < totalEdges; i ++){
@@ -42,7 +42,7 @@ class Polygon extends Shape {
this.points = points; this.points = points;
this.recalculateCenterAndEdgeNormals(); this.recalculateCenterAndEdgeNormals();
this._originalPoints = new Vector2[points.length]; this._originalPoints = new Array(points.length);
this._originalPoints = points; this._originalPoints = points;
} }
@@ -116,7 +116,7 @@ class Polygon extends Shape {
} }
public static buildSymmertricalPolygon(vertCount: number, radius: number) { public static buildSymmertricalPolygon(vertCount: number, radius: number) {
let verts = new Vector2[vertCount]; let verts = new Array(vertCount);
for (let i = 0; i < vertCount; i++) { for (let i = 0; i < vertCount; i++) {
let a = 2 * Math.PI * (i / vertCount); let a = 2 * Math.PI * (i / vertCount);
@@ -125,4 +125,8 @@ class Polygon extends Shape {
return verts; return verts;
} }
public recalculateBounds(collider: Collider) {
this.center = collider.localOffset;
}
} }

View File

@@ -1,6 +1,8 @@
abstract class Shape { abstract class Shape {
public bounds: Rectangle; public bounds: Rectangle;
public position: Vector2; public position: Vector2;
public center: Vector2;
public abstract recalculateBounds(collider: Collider);
public abstract pointCollidesWithShape(point: Vector2): CollisionResult; public abstract pointCollidesWithShape(point: Vector2): CollisionResult;
} }

View File

@@ -10,6 +10,35 @@ class ShapeCollisions {
let polygonOffset = Vector2.subtract(first.position, second.position); let polygonOffset = Vector2.subtract(first.position, second.position);
let axis: Vector2; let axis: Vector2;
for (let edgeIndex = 0; edgeIndex < firstEdges.length + secondEdges.length; edgeIndex ++){
if (edgeIndex < firstEdges.length){
axis = firstEdges[edgeIndex];
} else {
axis = secondEdges[edgeIndex - firstEdges.length];
}
let minA = 0;
let minB = 0;
let maxA = 0;
let maxB = 0;
let intervalDist = 0;
this.getInterval(axis, first, minA, maxA);
this.getInterval(axis, second, minB, maxB);
}
}
public static getInterval(axis: Vector2, polygon: Polygon, min: number, max: number){
let dot = Vector2.dot(polygon.points[0], axis);
min = max = dot;
for (let i = 1; i < polygon.points.length; i++){
dot = Vector2.dot(polygon.points[i], axis);
if (dot < min){
min = dot;
}else if(dot > max){
max = dot;
}
}
} }
public static circleToPolygon(circle: Circle, polygon: Polygon){ public static circleToPolygon(circle: Circle, polygon: Polygon){

View File

@@ -23,7 +23,9 @@ class Emitter<T> {
public emit(eventType: T, data: any){ public emit(eventType: T, data: any){
let list: Function[] = this._messageTable.get(eventType); let list: Function[] = this._messageTable.get(eventType);
for (let i = list.length - 1; i >= 0; i --) if (list){
list[i](data); for (let i = list.length - 1; i >= 0; i --)
list[i](data);
}
} }
} }

View File

@@ -1,12 +1,13 @@
class WebGLUtils { class WebGLUtils {
public static getWebGL(): WebGLRenderingContext{ public static getWebGL(): WebGLRenderingContext {
if (egret.WebGLUtils.checkCanUseWebGL()) if (egret.WebGLUtils.checkCanUseWebGL())
return document.querySelector("canvas").getContext("webgl"); return document.querySelector("canvas").getContext("webgl");
throw new Error("cannot get webgl"); throw new Error("cannot get webgl");
} }
public static drawUserIndexPrimitives<T>(primitiveType: number, vertexData: T[], vertexOffset: number, numVertices: number, indexData: number[], indexOffset: number, primitiveCount: number){ public static drawUserIndexPrimitives<T>(primitiveType: number, vertexData: T[], vertexOffset: number,
numVertices: number, indexData: number[], indexOffset: number, primitiveCount: number) {
let GL = this.getWebGL(); let GL = this.getWebGL();
GL.bindBuffer(GL.ARRAY_BUFFER, 0); GL.bindBuffer(GL.ARRAY_BUFFER, 0);
@@ -14,16 +15,16 @@ class WebGLUtils {
GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, 0); GL.bindBuffer(GL.ELEMENT_ARRAY_BUFFER, 0);
this.checkGLError(); this.checkGLError();
GL.drawElements(primitiveType, GL.drawElements(primitiveType,
this.getElementCountArray(primitiveType, primitiveCount), this.getElementCountArray(primitiveType, primitiveCount),
GL.UNSIGNED_SHORT, GL.UNSIGNED_SHORT,
indexOffset * 2); indexOffset * 2);
this.checkGLError(); this.checkGLError();
} }
private static getElementCountArray(primitiveType: number, primitiveCount: number){ private static getElementCountArray(primitiveType: number, primitiveCount: number) {
let GL = this.getWebGL(); let GL = this.getWebGL();
switch (primitiveType){ switch (primitiveType) {
case GL.LINES: case GL.LINES:
return primitiveCount * 2; return primitiveCount * 2;
case GL.LINE_STRIP: case GL.LINE_STRIP:
@@ -37,10 +38,10 @@ class WebGLUtils {
throw new Error("not support"); throw new Error("not support");
} }
public static checkGLError(){ public static checkGLError() {
let GL = this.getWebGL(); let GL = this.getWebGL();
let error = GL.getError(); let error = GL.getError();
if (error != GL.NO_ERROR){ if (error != GL.NO_ERROR) {
throw new Error("GL.GetError() returned" + error); throw new Error("GL.GetError() returned" + error);
} }
} }