import { distance } from 'common/util' ; import Sprite , { RectSprite , CircleSprite } from './sprite' ; export default class Collide { constructor ( ) { if ( this instanceof Collide ) { return this ; } return new Collide ( ) ; } public isCandidateForCollide ( sprite , otherSprite ) { return sprite . visible && otherSprite . visible && sprite !== otherSprite ; } public didCollide ( sprite , otherSprite ) { let sType = sprite . type ; let oType = otherSprite . type ; if ( sType === 'rect' && oType === 'rect' ) { return this . didRectCollide ( sprite as RectSprite , otherSprite as RectSprite ) ; } else if ( sType === 'circle' && oType === 'circle' ) { return this . didCircleCollide ( sprite as CircleSprite , otherSprite as CircleSprite ) ; } else if ( sType === 'rect' ) { return this . didRectWidthCircleCollide ( sprite as RectSprite , otherSprite as CircleSprite ) ; } else { return this . didRectWidthCircleCollide ( otherSprite as RectSprite , sprite as CircleSprite ) ; } } private didRectCollide ( sprite , otherSprite ) { let horizontal = sprite . left + sprite . width > otherSprite . left && sprite . left < otherSprite . left + otherSprite . width ; let vertical = sprite . top < otherSprite . top + otherSprite . height && sprite . top + sprite . height > otherSprite . top ; return horizontal && vertical ; } private didCircleCollide ( sprite , otherSprite ) { return distance ( sprite . x , sprite . y , otherSprite . x , otherSprite . y ) < sprite . radius + otherSprite . radius ; } private didRectWidthCircleCollide ( rectSprite , circleSprite ) { let closePoint = { x : undefined , y : undefined } ; if ( circleSprite . x < rectSprite . left ) { closePoint . x = rectSprite . left ; } else if ( circleSprite . x < rectSprite . left + rectSprite . width ) { closePoint . x = circleSprite . x ; } else { closePoint . x = rectSprite . left + rectSprite . width ; } if ( circleSprite . y < rectSprite . top ) { closePoint . y = rectSprite . top ; } else if ( circleSprite . y < rectSprite . top + rectSprite . height ) { closePoint . y = circleSprite . y ; } else { closePoint . y = rectSprite . top + rectSprite . height ; } return distance ( circleSprite . x , circleSprite . y , closePoint . x , closePoint . y ) < circleSprite . radius ; } }