Files
esengine/source/src/ECS/Components/Physics/Colliders/Collider.ts

115 lines
3.6 KiB
TypeScript
Raw Normal View History

2020-06-12 08:47:13 +08:00
abstract class Collider extends Component{
public shape: Shape;
public physicsLayer = 1 << 0;
public isTrigger: boolean;
2020-06-15 10:42:06 +08:00
public registeredPhysicsBounds: Rectangle;
2020-06-16 00:04:28 +08:00
public shouldColliderScaleAndRotationWithTransform = true;
public collidesWithLayers = Physics.allLayers;
2020-06-15 10:42:06 +08:00
2020-06-16 00:04:28 +08:00
public _localOffsetLength: number;
public _isPositionDirty = true;
public _isRotationDirty = true;
2020-06-15 10:42:06 +08:00
protected _isParentEntityAddedToScene;
protected _colliderRequiresAutoSizing;
2020-06-16 11:59:40 +08:00
protected _localOffset: Vector2 = new Vector2(0, 0);
protected _isColliderRegistered;
2020-06-12 08:47:13 +08:00
public get bounds(): Rectangle {
if (this._isPositionDirty || this._isRotationDirty){
this.shape.recalculateBounds(this);
this._isPositionDirty = this._isRotationDirty = false;
}
2020-06-12 08:47:13 +08:00
return this.shape.bounds;
}
2020-06-15 10:42:06 +08:00
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;
2020-06-16 00:04:28 +08:00
this._localOffsetLength = this._localOffset.length();
this._isPositionDirty = true;
this.registerColliderWithPhysicsSystem();
}
}
public registerColliderWithPhysicsSystem(){
if (this._isParentEntityAddedToScene && !this._isColliderRegistered){
Physics.addCollider(this);
this._isColliderRegistered = true;
}
}
public unregisterColliderWithPhysicsSystem(){
if (this._isParentEntityAddedToScene && this._isColliderRegistered){
Physics.removeCollider(this);
}
this._isColliderRegistered = false;
}
2020-06-16 00:04:28 +08:00
public overlaps(other: Collider){
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);
2020-06-16 20:22:22 +08:00
if (renderable){
let renderbaleBounds = renderable.bounds;
2020-06-29 15:41:02 +08:00
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;
2020-06-29 15:41:02 +08:00
this.localOffset = Vector2.subtract(renderbaleBounds.center, this.entity.position);
}
}
}
this._isParentEntityAddedToScene = true;
this.registerColliderWithPhysicsSystem();
}
2020-06-16 20:22:22 +08:00
public onRemovedFromEntity(){
this.unregisterColliderWithPhysicsSystem();
this._isParentEntityAddedToScene = false;
}
2020-06-16 00:04:28 +08:00
public onEnabled(){
this.registerColliderWithPhysicsSystem();
this._isPositionDirty = this._isRotationDirty = true;
}
public onDisabled(){
this.unregisterColliderWithPhysicsSystem();
2020-06-15 10:42:06 +08:00
}
2020-06-12 08:47:13 +08:00
}