Files
esengine/source/src/Physics/Shapes/Box.ts
2021-04-28 14:43:48 +08:00

94 lines
3.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
///<reference path="./Polygon.ts" />
module es {
/**
* 多边形的特殊情况。在进行SAT碰撞检查时我们只需要检查2个轴而不是8个轴
*/
export class Box extends Polygon {
public width: number;
public height: number;
constructor(width: number, height: number) {
super(Box.buildBox(width, height), true);
this.width = width;
this.height = height;
}
/**
* 在一个盒子的形状中建立多边形需要的点的帮助方法
* @param width
* @param height
*/
private static buildBox(width: number, height: number): Vector2[] {
// 我们在(0,0)的中心周围创建点
let halfWidth = width / 2;
let halfHeight = height / 2;
let verts = new Array(4);
verts[0] = new Vector2(-halfWidth, -halfHeight);
verts[1] = new Vector2(halfWidth, -halfHeight);
verts[2] = new Vector2(halfWidth, halfHeight);
verts[3] = new Vector2(-halfWidth, halfHeight);
return verts;
}
/**
* 更新框点,重新计算中心,设置宽度/高度
* @param width
* @param height
*/
public updateBox(width: number, height: number) {
this.width = width;
this.height = height;
// 我们在(0,0)的中心周围创建点
let halfWidth = width / 2;
let halfHeight = height / 2;
this.points[0] = new Vector2(-halfWidth, -halfHeight);
this.points[1] = new Vector2(halfWidth, -halfHeight);
this.points[2] = new Vector2(halfWidth, halfHeight);
this.points[3] = new Vector2(-halfWidth, halfHeight);
for (let i = 0; i < this.points.length; i++)
this._originalPoints[i] = this.points[i];
}
public overlaps(other: Shape) {
// 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测
if (this.isUnrotated) {
if (other instanceof Box && other.isUnrotated)
return this.bounds.intersects(other.bounds);
if (other instanceof Circle)
return Collisions.rectToCircle(this.bounds, other.position, other.radius);
}
return super.overlaps(other);
}
public collidesWithShape(other: Shape, result: CollisionResult): boolean {
// 特殊情况这一个高性能方式实现其他情况则使用polygon方法检测
if (other instanceof Box && (other as Box).isUnrotated) {
return ShapeCollisionsBox.boxToBox(this, other, result);
}
// TODO: 让 minkowski 运行于 cricleToBox
return super.collidesWithShape(other, result);
}
public containsPoint(point: Vector2) {
if (this.isUnrotated)
return this.bounds.contains(point.x, point.y);
return super.containsPoint(point);
}
public pointCollidesWithShape(point: es.Vector2, result: es.CollisionResult): boolean {
if (this.isUnrotated)
return ShapeCollisionsPoint.pointToBox(point, this, result);
return super.pointCollidesWithShape(point, result);
}
}
}