module Collision ( collisionTankBorder , collisionBulletBullet , collisionBulletTank ) where import Tank import Game import Transformable import qualified Vector as V import Data.VectorSpace tankWidth :: Coord tankWidth = 0.4 tankLength :: Coord tankLength = 0.95 bulletDiameter :: Coord bulletDiameter = 0.05 collisionTankBorder :: Coord -> Coord -> Tank -> Tank collisionTankBorder lw lh tank = V.Vector dx dy >< tank where corners = [ V.Vector (tankLength/2) (tankWidth/2) , V.Vector (-tankLength/2) (tankWidth/2) , V.Vector (-tankLength/2) (-tankWidth/2) , V.Vector (tankLength/2) (-tankWidth/2) ] rotp v = tankDir tank >< v transp v = v >< tankPos tank points = map (transp . rotp) corners minx = minimum $ map V.vertexX points maxx = maximum $ map V.vertexX points miny = minimum $ map V.vertexY points maxy = maximum $ map V.vertexY points dx = if minx < 0 then (-minx) else if maxx > lw then (-maxx+lw) else 0 dy = if miny < 0 then (-miny) else if maxy > lh then (-maxy+lh) else 0 collisionBulletBullet :: (Bullet, Bullet) -> (Bullet, Bullet) -> Bool collisionBulletBullet (b1, b1') (b2, b2') = distancesq < (bulletDiameter^2) where distancesq = (bulletX b1' - bulletX b2')^2 + (bulletY b1' - bulletY b2')^2 collisionBulletTank :: (Bullet, Bullet) -> (Tank, Tank) -> Bool collisionBulletTank (b, b') (tank, tank') = (not ((between bx minx maxx) && (between by miny maxy))) && ((between bx' minx maxx) && (between by' miny maxy)) where between x a b = x >= a && x <= b rotp t v = tankDir t >:< v transp t v = V.diffV (tankPos t) v V.Vector bx by = (rotp tank) . (transp tank) $ bulletPos b V.Vector bx' by' = (rotp tank') . (transp tank') $ bulletPos b' minx = -(tankLength+bulletDiameter)/2 maxx = (tankLength+bulletDiameter)/2 miny = -(tankWidth+bulletDiameter)/2 maxy = (tankWidth+bulletDiameter)/2 collisionTankTank :: ((Tank, Tank), (Tank, Tank)) -> (Tank, Tank) collisionTankTank ((t1, t1'), (t2, t2')) = (t1'', t2'') where t1'' = t1' t2'' = t2'