性能优化
This commit is contained in:
@@ -157,29 +157,33 @@ module es {
|
||||
|
||||
// 捞取我们在新的位置上可能会碰撞到的任何东西
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(this._collider, this._collider.bounds, this._collider.collidesWithLayers.value);
|
||||
for (const neighbor of neighbors) {
|
||||
if (!neighbor)
|
||||
continue;
|
||||
|
||||
// 如果邻近的对撞机是同一个实体,则忽略它
|
||||
if (neighbor.entity.equals(this.entity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this._collider.collidesWithNonMotion(neighbor, collisionResult)) {
|
||||
// 如果附近有一个ArcadeRigidbody,我们就会处理完整的碰撞响应。如果没有,我们会根据附近是不可移动的来计算事情
|
||||
let neighborRigidbody = neighbor.entity.getComponent(ArcadeRigidbody);
|
||||
if (neighborRigidbody != null) {
|
||||
this.processOverlap(neighborRigidbody, collisionResult.minimumTranslationVector);
|
||||
this.processCollision(neighborRigidbody, collisionResult.minimumTranslationVector);
|
||||
} else {
|
||||
// 没有ArcadeRigidbody,所以我们假设它是不动的,只移动我们自己的
|
||||
this.entity.position = this.entity.position.sub(collisionResult.minimumTranslationVector);
|
||||
const relativeVelocity = this.calculateResponseVelocity(this.velocity, collisionResult.minimumTranslationVector);
|
||||
this.velocity.addEqual(relativeVelocity);
|
||||
if (neighbors.length > 0) {
|
||||
for (let i = 0; i < neighbors.length; i ++) {
|
||||
const neighbor = neighbors[i];
|
||||
if (!neighbor)
|
||||
continue;
|
||||
|
||||
// 如果邻近的对撞机是同一个实体,则忽略它
|
||||
if (neighbor.entity.equals(this.entity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (this._collider.collidesWithNonMotion(neighbor, collisionResult)) {
|
||||
// 如果附近有一个ArcadeRigidbody,我们就会处理完整的碰撞响应。如果没有,我们会根据附近是不可移动的来计算事情
|
||||
let neighborRigidbody = neighbor.entity.getComponent(ArcadeRigidbody);
|
||||
if (neighborRigidbody != null) {
|
||||
this.processOverlap(neighborRigidbody, collisionResult.minimumTranslationVector);
|
||||
this.processCollision(neighborRigidbody, collisionResult.minimumTranslationVector);
|
||||
} else {
|
||||
// 没有ArcadeRigidbody,所以我们假设它是不动的,只移动我们自己的
|
||||
this.entity.position = this.entity.position.sub(collisionResult.minimumTranslationVector);
|
||||
const relativeVelocity = this.calculateResponseVelocity(this.velocity, collisionResult.minimumTranslationVector);
|
||||
this.velocity.addEqual(relativeVelocity);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -228,23 +228,26 @@ module es {
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(this, colliderBounds, this.collidesWithLayers.value);
|
||||
|
||||
// 更改形状位置,使其处于移动后的位置,以便我们检查是否有重叠
|
||||
let oldPosition = this.shape.position.clone();
|
||||
let oldPosition = this.shape.position;
|
||||
this.shape.position = Vector2.add(this.shape.position, motion);
|
||||
|
||||
let didCollide = false;
|
||||
for (let neighbor of neighbors) {
|
||||
if (neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
if (this.collidesWithNonMotion(neighbor, result)) {
|
||||
motion = motion.sub(result.minimumTranslationVector);
|
||||
this.shape.position = this.shape.position.sub(result.minimumTranslationVector);
|
||||
didCollide = true;
|
||||
if (neighbors.length > 0) {
|
||||
for (let i = 0; i < neighbors.length; i ++ ){
|
||||
const neighbor = neighbors[i];
|
||||
if (neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
if (this.collidesWithNonMotion(neighbor, result)) {
|
||||
motion = motion.sub(result.minimumTranslationVector);
|
||||
this.shape.position = this.shape.position.sub(result.minimumTranslationVector);
|
||||
didCollide = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 将形状位置返回到检查之前的位置
|
||||
this.shape.position = oldPosition.clone();
|
||||
this.shape.position = oldPosition;
|
||||
|
||||
return didCollide;
|
||||
}
|
||||
|
||||
@@ -23,9 +23,12 @@ module es {
|
||||
|
||||
export class TriggerListenerHelper {
|
||||
public static getITriggerListener(entity: Entity, components: ITriggerListener[]){
|
||||
for (let component of entity.components._components) {
|
||||
if (isITriggerListener(component)) {
|
||||
components.push(component);
|
||||
if (entity.components._components.length > 0) {
|
||||
for (let i = 0; i < entity.components._components.length; i ++) {
|
||||
const component = entity.components._components[i];
|
||||
if (isITriggerListener(component)) {
|
||||
components.push(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,58 +20,66 @@ module es {
|
||||
*/
|
||||
public calculateMovement(motion: Vector2, collisionResult: CollisionResult): boolean {
|
||||
let collider = null;
|
||||
for (let i = 0; i < this.entity.components.buffer.length; i++) {
|
||||
let component = this.entity.components.buffer[i];
|
||||
if (component instanceof Collider) {
|
||||
collider = component;
|
||||
break;
|
||||
if (this.entity.components.buffer.length > 0)
|
||||
for (let i = 0; i < this.entity.components.buffer.length; i++) {
|
||||
let component = this.entity.components.buffer[i];
|
||||
if (component instanceof Collider) {
|
||||
collider = component;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (collider == null || this._triggerHelper == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 移动所有的非触发碰撞器并获得最近的碰撞
|
||||
let colliders: Collider[] = [];
|
||||
for (let i = 0; i < this.entity.components.buffer.length; i ++) {
|
||||
let component = this.entity.components.buffer[i];
|
||||
if (component instanceof Collider) {
|
||||
colliders.push(component);
|
||||
if (this.entity.components.buffer.length > 0)
|
||||
for (let i = 0; i < this.entity.components.buffer.length; i ++) {
|
||||
let component = this.entity.components.buffer[i];
|
||||
if (component instanceof Collider) {
|
||||
colliders.push(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (let i = 0; i < colliders.length; i++) {
|
||||
let collider = colliders[i];
|
||||
|
||||
// 不检测触发器 在我们移动后会重新访问它
|
||||
if (collider.isTrigger)
|
||||
continue;
|
||||
|
||||
// 获取我们在新位置可能发生碰撞的任何东西
|
||||
let bounds = collider.bounds.clone();
|
||||
bounds.x += motion.x;
|
||||
bounds.y += motion.y;
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers.value);
|
||||
|
||||
for (let neighbor of neighbors) {
|
||||
// 不检测触发器
|
||||
if (neighbor.isTrigger)
|
||||
return;
|
||||
|
||||
let _internalcollisionResult: CollisionResult = new CollisionResult();
|
||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
||||
// 如果碰撞 则退回之前的移动量
|
||||
motion.subEqual(_internalcollisionResult.minimumTranslationVector);
|
||||
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
||||
if (_internalcollisionResult.collider != null) {
|
||||
collisionResult.collider = _internalcollisionResult.collider;
|
||||
collisionResult.minimumTranslationVector = _internalcollisionResult.minimumTranslationVector;
|
||||
collisionResult.normal = _internalcollisionResult.normal;
|
||||
collisionResult.point = _internalcollisionResult.point;
|
||||
if (colliders.length > 0) {
|
||||
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;
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, bounds, collider.collidesWithLayers.value);
|
||||
|
||||
if (neighbors.length > 0) {
|
||||
for (let i = 0; i < neighbors.length; i ++) {
|
||||
const neighbor = neighbors[i];
|
||||
// 不检测触发器
|
||||
if (neighbor.isTrigger)
|
||||
return;
|
||||
|
||||
let _internalcollisionResult: CollisionResult = new CollisionResult();
|
||||
if (collider.collidesWith(neighbor, motion, _internalcollisionResult)) {
|
||||
// 如果碰撞 则退回之前的移动量
|
||||
motion.subEqual(_internalcollisionResult.minimumTranslationVector);
|
||||
// 如果我们碰到多个对象,为了简单起见,只取第一个。
|
||||
if (_internalcollisionResult.collider != null) {
|
||||
collisionResult.collider = _internalcollisionResult.collider;
|
||||
collisionResult.minimumTranslationVector = _internalcollisionResult.minimumTranslationVector;
|
||||
collisionResult.normal = _internalcollisionResult.normal;
|
||||
collisionResult.point = _internalcollisionResult.point;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ListPool.free(Collider, colliders);
|
||||
|
||||
return collisionResult.collider != null;
|
||||
|
||||
@@ -23,38 +23,44 @@ module es {
|
||||
// 对所有实体.colliders进行重叠检查,这些实体.colliders是触发器,与所有宽相碰撞器,无论是否触发器。
|
||||
// 任何重叠都会导致触发事件
|
||||
let colliders: Collider[] = this.getColliders();
|
||||
for (let i = 0; i < colliders.length; i++) {
|
||||
let collider = colliders[i];
|
||||
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, collider.bounds, collider.collidesWithLayers.value);
|
||||
for (let j = 0; j < neighbors.length; j++) {
|
||||
let neighbor = neighbors[j];
|
||||
// 我们至少需要一个碰撞器作为触发器
|
||||
if (!collider.isTrigger && !neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
if (collider.overlaps(neighbor)) {
|
||||
const pair = new Pair<Collider>(collider, neighbor);
|
||||
|
||||
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
||||
const shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
||||
!this._previousTriggerIntersections.has(pair);
|
||||
|
||||
if (shouldReportTriggerEvent) {
|
||||
if (neighbor.castSortOrder >= Collider.lateSortOrder) {
|
||||
lateColliders.push(pair);
|
||||
} else {
|
||||
this.notifyTriggerListeners(pair, true);
|
||||
if (colliders.length > 0) {
|
||||
for (let i = 0; i < colliders.length; i++) {
|
||||
let collider = colliders[i];
|
||||
|
||||
let neighbors = Physics.boxcastBroadphaseExcludingSelf(collider, collider.bounds, collider.collidesWithLayers.value);
|
||||
for (let j = 0; j < neighbors.length; j++) {
|
||||
let neighbor = neighbors[j];
|
||||
// 我们至少需要一个碰撞器作为触发器
|
||||
if (!collider.isTrigger && !neighbor.isTrigger)
|
||||
continue;
|
||||
|
||||
if (collider.overlaps(neighbor)) {
|
||||
const pair = new Pair<Collider>(collider, neighbor);
|
||||
|
||||
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
|
||||
const shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
|
||||
!this._previousTriggerIntersections.has(pair);
|
||||
|
||||
if (shouldReportTriggerEvent) {
|
||||
if (neighbor.castSortOrder >= Collider.lateSortOrder) {
|
||||
lateColliders.push(pair);
|
||||
} else {
|
||||
this.notifyTriggerListeners(pair, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
this._activeTriggerIntersections.add(pair);
|
||||
|
||||
this._activeTriggerIntersections.add(pair);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
for (const pair of lateColliders) {
|
||||
this.notifyTriggerListeners(pair, true);
|
||||
if (lateColliders.length > 0) {
|
||||
for (let i = 0; i < lateColliders.length; i ++) {
|
||||
const pair = lateColliders[i];
|
||||
this.notifyTriggerListeners(pair, true);
|
||||
}
|
||||
}
|
||||
|
||||
this.checkForExitedColliders();
|
||||
@@ -62,12 +68,13 @@ module es {
|
||||
|
||||
private getColliders() {
|
||||
const colliders: Collider[] = [];
|
||||
for (let i = 0; i < this._entity.components.buffer.length; i ++) {
|
||||
const component = this._entity.components.buffer[i];
|
||||
if (component instanceof Collider) {
|
||||
colliders.push(component);
|
||||
if (this._entity.components.buffer.length > 0)
|
||||
for (let i = 0; i < this._entity.components.buffer.length; i ++) {
|
||||
const component = this._entity.components.buffer[i];
|
||||
if (component instanceof Collider) {
|
||||
colliders.push(component);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return colliders;
|
||||
}
|
||||
@@ -91,28 +98,32 @@ module es {
|
||||
|
||||
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
|
||||
TriggerListenerHelper.getITriggerListener(collisionPair.first.entity, this._tempTriggerList);
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
if (isEntering) {
|
||||
this._tempTriggerList[i].onTriggerEnter(collisionPair.second, collisionPair.first);
|
||||
} else {
|
||||
this._tempTriggerList[i].onTriggerExit(collisionPair.second, collisionPair.first);
|
||||
}
|
||||
|
||||
this._tempTriggerList.length = 0;
|
||||
|
||||
if (collisionPair.second.entity) {
|
||||
TriggerListenerHelper.getITriggerListener(collisionPair.second.entity, this._tempTriggerList);
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
if (isEntering) {
|
||||
this._tempTriggerList[i].onTriggerEnter(collisionPair.first, collisionPair.second);
|
||||
} else {
|
||||
this._tempTriggerList[i].onTriggerExit(collisionPair.first, collisionPair.second);
|
||||
}
|
||||
if (this._tempTriggerList.length > 0)
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
const trigger = this._tempTriggerList[i];
|
||||
if (isEntering) {
|
||||
trigger.onTriggerEnter(collisionPair.second, collisionPair.first);
|
||||
} else {
|
||||
trigger.onTriggerExit(collisionPair.second, collisionPair.first);
|
||||
}
|
||||
|
||||
this._tempTriggerList.length = 0;
|
||||
|
||||
if (collisionPair.second.entity) {
|
||||
TriggerListenerHelper.getITriggerListener(collisionPair.second.entity, this._tempTriggerList);
|
||||
if (this._tempTriggerList.length > 0)
|
||||
for (let i = 0; i < this._tempTriggerList.length; i++) {
|
||||
const trigger = this._tempTriggerList[i];
|
||||
if (isEntering) {
|
||||
trigger.onTriggerEnter(collisionPair.first, collisionPair.second);
|
||||
} else {
|
||||
trigger.onTriggerExit(collisionPair.first, collisionPair.second);
|
||||
}
|
||||
}
|
||||
|
||||
this._tempTriggerList.length = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -113,15 +113,17 @@ module es {
|
||||
continue;
|
||||
|
||||
// 当cell不为空。循环并取回所有碰撞器
|
||||
for (let i = 0; i < cell.length; i++) {
|
||||
const collider = cell[i];
|
||||
|
||||
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
|
||||
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer.value))
|
||||
continue;
|
||||
|
||||
if (bounds.intersects(collider.bounds)) {
|
||||
this._tempHashSet.add(collider);
|
||||
if (cell.length > 0) {
|
||||
for (let i = 0; i < cell.length; i++) {
|
||||
const collider = cell[i];
|
||||
|
||||
// 如果它是自身或者如果它不匹配我们的层掩码 跳过这个碰撞器
|
||||
if (collider == excludeCollider || !Flags.isFlagSet(layerMask, collider.physicsLayer.value))
|
||||
continue;
|
||||
|
||||
if (bounds.intersects(collider.bounds)) {
|
||||
this._tempHashSet.add(collider);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -215,7 +217,9 @@ module es {
|
||||
|
||||
let resultCounter = 0;
|
||||
let potentials = this.aabbBroadphase(rect, null, layerMask);
|
||||
for (let collider of potentials) {
|
||||
|
||||
for (let i = 0; i < potentials.length; i ++) {
|
||||
const collider = potentials[i];
|
||||
if (collider instanceof BoxCollider) {
|
||||
results[resultCounter] = collider;
|
||||
resultCounter++;
|
||||
@@ -255,7 +259,8 @@ module es {
|
||||
|
||||
let resultCounter = 0;
|
||||
const potentials = this.aabbBroadphase(bounds, null, layerMask);
|
||||
for (let collider of potentials) {
|
||||
for (let i = 0; i < potentials.length; i ++) {
|
||||
const collider = potentials[i];
|
||||
if (collider instanceof BoxCollider) {
|
||||
if (collider.shape.overlaps(this._overlapTestCircle)) {
|
||||
results[resultCounter] = collider;
|
||||
@@ -324,9 +329,8 @@ module es {
|
||||
*/
|
||||
public remove(obj: T) {
|
||||
this._store.forEach(list => {
|
||||
let linqList = new es.List(list);
|
||||
if (linqList.contains(obj))
|
||||
linqList.remove(obj);
|
||||
let index = list.indexOf(obj);
|
||||
list.splice(index, 1);
|
||||
})
|
||||
}
|
||||
|
||||
@@ -383,7 +387,7 @@ module es {
|
||||
const potential = cell[i];
|
||||
|
||||
// 管理我们已经处理过的碰撞器
|
||||
if (new es.List(this._checkedColliders).contains(potential))
|
||||
if (this._checkedColliders.indexOf(potential) != -1)
|
||||
continue;
|
||||
|
||||
this._checkedColliders.push(potential);
|
||||
|
||||
@@ -31,14 +31,20 @@ module es {
|
||||
|
||||
public union(other: PairSet<T>) {
|
||||
const otherAll = other.all;
|
||||
for (const elem of otherAll) {
|
||||
this.add(elem);
|
||||
}
|
||||
|
||||
if (otherAll.length > 0)
|
||||
for (let i = 0; i < otherAll.length; i ++) {
|
||||
const elem = otherAll[i];
|
||||
this.add(elem);
|
||||
}
|
||||
}
|
||||
|
||||
public except(other: PairSet<T>) {
|
||||
const otherAll = other.all;
|
||||
for (const elem of otherAll) {
|
||||
|
||||
if (otherAll.length > 0)
|
||||
for (let i = 0; i < otherAll.length; i ++) {
|
||||
const elem = otherAll[i];
|
||||
this.remove(elem);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user