新增mover移动器组件 用于处理itriggerListener接口碰撞信息

This commit is contained in:
yhh
2020-06-16 11:22:37 +08:00
parent 75301f7776
commit 8b21edc65f
22 changed files with 671 additions and 46 deletions

View File

@@ -46,4 +46,17 @@ class BoxCollider extends Collider {
this.shape = new Box(1, 1);
this._colliderRequiresAutoSizing = true;
}
public setSize(width: number, height: number){
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);
}
return this;
}
}

View File

@@ -7,9 +7,9 @@ abstract class Collider extends Component{
public collidesWithLayers = Physics.allLayers;
public _localOffsetLength: number;
public _isPositionDirty = true;
public _isRotationDirty = true;
protected _isParentEntityAddedToScene;
protected _isPositionDirty = true;
protected _isRotationDirty = true;
protected _colliderRequiresAutoSizing;
protected _localOffset: Vector2;
protected _isColliderRegisterd;
@@ -59,6 +59,46 @@ abstract class Collider extends Component{
return this.shape.overlaps(other.shape);
}
public collidesWith(collider: Collider, motion: Vector2){
let oldPosition = this.shape.position;
this.shape.position = Vector2.add(this.shape.position, motion);
let result = this.shape.collidesWithShape(collider.shape);
if (result)
result.collider = collider;
this.shape.position = oldPosition;
return result;
}
public onAddedToEntity(){
if (this._colliderRequiresAutoSizing){
if (!(this instanceof BoxCollider)){
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 width = renderbaleBounds.width / this.entity.transform.scale.x;
let height = renderbaleBounds.height / this.entity.transform.scale.y;
if (this instanceof BoxCollider){
let boxCollider = this as BoxCollider;
boxCollider.width = width;
boxCollider.height = height;
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.transform.position);
}
}
}
this._isParentEntityAddedToScene = true;
this.registerColliderWithPhysicsSystem();
}
public onEntityTransformChanged(comp: ComponentTransform){
switch (comp){
case ComponentTransform.position:

View File

@@ -0,0 +1,62 @@
class Mover extends Component {
private _triggerHelper: ColliderTriggerHelper;
public onAddedToEntity(){
this._triggerHelper = new ColliderTriggerHelper(this.entity);
}
public calculateMovement(motion: Vector2){
let collisionResult = new CollisionResult();
if (!this.entity.getComponent(Collider) || !this._triggerHelper){
return null;
}
let colliders: Collider[] = this.entity.getComponents(Collider);
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);
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;
}
}
}
}
ListPool.free(colliders);
return collisionResult;
}
public applyMovement(motion: Vector2){
this.entity.transform.position = Vector2.add(this.entity.transform.position, motion);
if (this._triggerHelper)
this._triggerHelper.update();
}
public move(motion: Vector2){
let collisionResult = this.calculateMovement(motion);
this.applyMovement(motion);
return collisionResult;
}
}