/// /** * 多边形的特殊情况。在进行SAT碰撞检查时,我们只需要检查2个轴而不是8个轴 */ class Box extends Polygon { 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; } public overlaps(other: Shape){ // 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测 if (other instanceof Box) return this.bounds.intersects(other.bounds); if (other instanceof Circle) return Collisions.isRectToCircle(this.bounds, other.position, other.radius); return super.overlaps(other); } public collidesWithShape(other: Shape){ // 特殊情况,这一个高性能方式实现,其他情况则使用polygon方法检测 if (other instanceof Box){ return ShapeCollisions.boxToBox(this, other); } // TODO: 让 minkowski 运行于 cricleToBox return super.collidesWithShape(other); } /** * 更新框点,重新计算中心,设置宽度/高度 * @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]; } /** * * @param point */ public containsPoint(point: Vector2){ return this.bounds.contains(point.x, point.y); } }