Added bullet/bullet collision
This commit is contained in:
parent
90b8d87e02
commit
98ae7f48c5
2 changed files with 25 additions and 5 deletions
|
@ -1,7 +1,9 @@
|
||||||
module Collision ( collisionTankBorder
|
module Collision ( collisionTankBorder
|
||||||
|
, collisionBulletBullet
|
||||||
) where
|
) where
|
||||||
|
|
||||||
import Tank
|
import Tank
|
||||||
|
import Game
|
||||||
|
|
||||||
import Data.Fixed
|
import Data.Fixed
|
||||||
import Data.Ratio
|
import Data.Ratio
|
||||||
|
@ -12,6 +14,9 @@ tankWidth = 0.95
|
||||||
tankLength :: Micro
|
tankLength :: Micro
|
||||||
tankLength = 0.95
|
tankLength = 0.95
|
||||||
|
|
||||||
|
bulletDiameter :: Micro
|
||||||
|
bulletDiameter = 0.2
|
||||||
|
|
||||||
collisionTankBorder :: Micro -> Micro -> Tank -> Tank
|
collisionTankBorder :: Micro -> Micro -> Tank -> Tank
|
||||||
collisionTankBorder lw lh tank = tank {tankX = newx, tankY = newy}
|
collisionTankBorder lw lh tank = tank {tankX = newx, tankY = newy}
|
||||||
where
|
where
|
||||||
|
@ -39,3 +44,8 @@ collisionTankBorder lw lh tank = tank {tankX = newx, tankY = newy}
|
||||||
|
|
||||||
newx = (tankX tank) + dx
|
newx = (tankX tank) + dx
|
||||||
newy = (tankY tank) + dy
|
newy = (tankY tank) + dy
|
||||||
|
|
||||||
|
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
|
|
@ -121,12 +121,22 @@ simulationStep = do
|
||||||
|
|
||||||
modify $ \state -> state {players = p}
|
modify $ \state -> state {players = p}
|
||||||
lift $ modify $ \state ->
|
lift $ modify $ \state ->
|
||||||
let thebullets = map (runState $ updateBullet state) $ newbullets ++ bullets state
|
let thebullets = map (runState $ updateBullet state) $ bullets state
|
||||||
thetanks = map (\(tank, n) -> tank {tankBulletsLeft = (tankBulletsLeft tank) + (countLostTankBullets n thebullets)}) $ zip newtanks [0..]
|
leftbullets = collideBullets $ zipWith (\(left, bullet') bullet -> (left, bullet, bullet')) thebullets $ bullets state
|
||||||
in state {tanks = thetanks, bullets = map snd . filter fst $ thebullets}
|
thetanks = map (\(tank, n) -> tank {tankBulletsLeft = (tankBulletsLeft tank) + (countLostTankBullets n leftbullets)}) $ zip newtanks [0..]
|
||||||
|
in state {tanks = thetanks, bullets = newbullets ++ (map snd . filter fst $ leftbullets)}
|
||||||
|
|
||||||
where
|
where
|
||||||
updateTank' game (player, tank) = let (p, angle, move, aangle, bullet) = playerUpdate player tank
|
collideBullets [] = []
|
||||||
|
collideBullets ((left, bullet, bullet'):bs) = let (c, ls) = collideBullet bullet bullet' bs
|
||||||
|
in (left && not c, bullet'):(collideBullets ls)
|
||||||
|
collideBullet bullet bullet' bs = let cs = map (\(left, b, b') -> (left, collisionBulletBullet (bullet, bullet') (b, b'), b, b')) bs
|
||||||
|
collided = any (\(_,c,_,_) -> c) cs
|
||||||
|
left = map (\(left, c, b, b') -> (left && not c, b, b')) $ cs
|
||||||
|
in (collided, left)
|
||||||
|
|
||||||
|
updateTank' game (player, tank) = let (p, angle, move, aangle, shoot) = playerUpdate player tank
|
||||||
t = execState (updateTank game angle move aangle) tank
|
t = execState (updateTank game angle move aangle) tank
|
||||||
in (p, t, bullet)
|
in (p, t, shoot)
|
||||||
countLostTankBullets n (x:xs) = (if ((not . fst $ x) && (n == (bulletTank . snd $ x))) then 1 else 0) + (countLostTankBullets n xs)
|
countLostTankBullets n (x:xs) = (if ((not . fst $ x) && (n == (bulletTank . snd $ x))) then 1 else 0) + (countLostTankBullets n xs)
|
||||||
countLostTankBullets n [] = 0
|
countLostTankBullets n [] = 0
|
||||||
|
|
Reference in a new issue