优化triggerListener与ArrayUtils

This commit is contained in:
yhh
2020-11-26 17:26:49 +08:00
parent de3f7bff60
commit ae2cfdafdd
15 changed files with 418 additions and 261 deletions

View File

@@ -4,10 +4,10 @@ module es {
*/
export class ColliderTriggerHelper {
private _entity: Entity;
/** 存储当前帧中发生的所有活动交对 */
private _activeTriggerIntersections: Pair<Collider>[] = [];
/** 存储前一帧的交对,以便我们可以在移动帧后检测出 */
private _previousTriggerIntersections: Pair<Collider>[] = [];
/** 存储当前帧中发生的所有活动交对 */
private _activeTriggerIntersections: Set<Pair<Collider>> = new Set();
/** 存储前一帧的交对,这样我们可以在移动这一帧后检测到退出 */
private _previousTriggerIntersections: Set<Pair<Collider>> = new Set();
private _tempTriggerList: ITriggerListener[] = [];
constructor(entity: Entity) {
@@ -15,32 +15,34 @@ module es {
}
/**
* 实体被移动后应该调用更新。它会处理碰撞器重叠的任何itriggerlistener。
* update应该在实体被移动后被调用它将处理任何与Colllider重叠的ITriggerListeners
* 它将处理任何与Collider重叠的ITriggerListeners。
*/
public update() {
// 对所有实体.colliders进行重叠检查这些实体.colliders是触发器与所有宽相碰撞器无论是否触发器。
// 任何重叠都会导致触发事件
let colliders = this._entity.getComponents(Collider);
for (let i = 0; i < colliders.length; i++) {
let collider = colliders[i];
let neighbors = Physics.boxcastBroadphase(collider.bounds, collider.collidesWithLayers);
for (let j = 0; j < neighbors.length; j++) {
for (let j = 0; j < neighbors.size; j++) {
let neighbor = neighbors[j];
// 我们至少需要一个碰撞器作为触发器
if (!collider.isTrigger && !neighbor.isTrigger)
continue;
if (collider.overlaps(neighbor)) {
let pair = new Pair<Collider>(collider, neighbor);
let shouldReportTriggerEvent = this._activeTriggerIntersections.findIndex(value => {
return value.first == pair.first && value.second == pair.second;
}) == -1 && this._previousTriggerIntersections.findIndex(value => {
return value.first == pair.first && value.second == pair.second;
}) == -1;
// 如果我们的某一个集合中已经有了这个对子(前一个或当前的触发交叉点),就不要调用输入事件了
let shouldReportTriggerEvent = !this._activeTriggerIntersections.has(pair) &&
!this._previousTriggerIntersections.has(pair);
if (shouldReportTriggerEvent)
this.notifyTriggerListeners(pair, true);
if (!this._activeTriggerIntersections.contains(pair))
this._activeTriggerIntersections.push(pair);
this._activeTriggerIntersections.add(pair);
}
}
}
@@ -51,31 +53,42 @@ module es {
}
private checkForExitedColliders() {
for (let i = 0; i < this._activeTriggerIntersections.length; i++) {
let index = this._previousTriggerIntersections.findIndex(value => {
if (value.first == this._activeTriggerIntersections[i].first && value.second == this._activeTriggerIntersections[i].second)
return true;
// 删除所有与此帧交互的触发器,留下我们退出的触发器
this.excepthWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
return false;
});
if (index != -1)
this._previousTriggerIntersections.removeAt(index);
}
for (let i = 0; i < this._previousTriggerIntersections.length; i++) {
for (let i = 0; i < this._previousTriggerIntersections.size; i++) {
this.notifyTriggerListeners(this._previousTriggerIntersections[i], false)
}
this._previousTriggerIntersections.length = 0;
for (let i = 0; i < this._activeTriggerIntersections.length; i++) {
if (!this._previousTriggerIntersections.contains(this._activeTriggerIntersections[i])) {
this._previousTriggerIntersections.push(this._activeTriggerIntersections[i]);
this._previousTriggerIntersections.clear();
// 添加所有当前激活的触发器
this.unionWith(this._previousTriggerIntersections, this._activeTriggerIntersections);
// 清空活动集,为下一帧做准备
this._activeTriggerIntersections.clear();
}
private excepthWith(previous: Set<Pair<Collider>>, active: Set<Pair<Collider>>){
for (let i = 0; i < previous.size; i ++){
let previousDATA: Pair<Collider> = previous[i];
for (let j = 0; j < active.size; j ++){
let activeDATA: Pair<Collider> = active[j];
if (activeDATA.equals(previousDATA))
previous.delete(previousDATA);
}
}
this._activeTriggerIntersections.length = 0;
}
private unionWith(previous: Set<Pair<Collider>>, active: Set<Pair<Collider>>) {
for (let i = 0; i < this._activeTriggerIntersections.size; i ++) {
if (!this._previousTriggerIntersections.has(this._activeTriggerIntersections[i]))
this._previousTriggerIntersections.add(this._activeTriggerIntersections[i]);
}
}
private notifyTriggerListeners(collisionPair: Pair<Collider>, isEntering: boolean) {
collisionPair.first.entity.getComponents("ITriggerListener", this._tempTriggerList);
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);
@@ -86,7 +99,7 @@ module es {
this._tempTriggerList.length = 0;
if (collisionPair.second.entity) {
collisionPair.second.entity.getComponents("ITriggerListener", this._tempTriggerList);
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);