Nice tank-border collision detection
This commit is contained in:
parent
f3d9814ad5
commit
e85dc20a48
4 changed files with 65 additions and 16 deletions
|
@ -1,6 +1,7 @@
|
|||
module Simulation ( simulationStep
|
||||
) where
|
||||
|
||||
import Collision
|
||||
import Game
|
||||
import Level
|
||||
import MainLoop
|
||||
|
@ -47,8 +48,8 @@ updateAngle angle = do
|
|||
modify $ \tank -> tank {tankDir = newangle180}
|
||||
|
||||
|
||||
updateTank :: Maybe Micro -> Bool -> Maybe Micro -> State Tank ()
|
||||
updateTank angle move aangle = do
|
||||
updateTank :: GameState -> Maybe Micro -> Bool -> Maybe Micro -> State Tank ()
|
||||
updateTank game angle move aangle = do
|
||||
when (isJust angle) $
|
||||
updateAngle $ fromJust angle
|
||||
|
||||
|
@ -56,19 +57,24 @@ updateTank angle move aangle = do
|
|||
modify $ \tank -> tank {tankAim = fromJust aangle}
|
||||
|
||||
when move $ do
|
||||
tdir <- gets tankDir
|
||||
tspeed <- gets tankSpeed
|
||||
moved <- gets tankMoving
|
||||
tank <- get
|
||||
let tdir = tankDir tank
|
||||
tspeed = tankSpeed tank
|
||||
moved = tankMoving tank
|
||||
|
||||
when (isNothing angle || (isJust angle && (tdir == fromJust angle)) || moved) $ do
|
||||
let anglej = (fromRational . toRational $ tdir)*pi/180
|
||||
x = tspeed * fromRational (round ((cos anglej)*1000)%1000000)
|
||||
y = tspeed * fromRational (round ((sin anglej)*1000)%1000000)
|
||||
dx = tspeed * fromRational (round ((cos anglej)*1000)%1000000)
|
||||
dy = tspeed * fromRational (round ((sin anglej)*1000)%1000000)
|
||||
|
||||
modify $ \tank -> tank {tankX = x + tankX tank, tankY = y + tankY tank, tankMoving = True}
|
||||
put tank {tankX = dx + tankX tank, tankY = dy + tankY tank, tankMoving = True}
|
||||
|
||||
when (not move) $ do
|
||||
modify $ \tank -> tank {tankMoving = False}
|
||||
|
||||
let lw = fromIntegral . levelWidth . level $ game
|
||||
lh = fromIntegral . levelHeight . level $ game
|
||||
modify $ collisionTankBorder lw lh
|
||||
|
||||
|
||||
updateBullet :: GameState -> State Bullet Bool
|
||||
|
@ -96,9 +102,10 @@ updateBullet game = do
|
|||
simulationStep :: Main ()
|
||||
simulationStep = do
|
||||
oldplayers <- gets players
|
||||
oldtanks <- lift $ gets tanks
|
||||
game <- lift get
|
||||
let oldtanks = tanks game
|
||||
|
||||
let (p, t, s) = unzip3 $ map updateTank' $ zip oldplayers oldtanks
|
||||
let (p, t, s) = unzip3 $ map (updateTank' game) $ zip oldplayers oldtanks
|
||||
ts = zip3 t s [0..]
|
||||
shootingtanks = map (\(tank, _, n) -> (tank, n)) $ filter (\(tank, shoot, _) -> shoot && (tankBulletsLeft tank) > 0) $ ts
|
||||
newtanks = map (\(tank, shoot, _) -> if (shoot && (tankBulletsLeft tank) > 0) then tank {tankBulletsLeft = (tankBulletsLeft tank) - 1} else tank) $ ts
|
||||
|
@ -117,8 +124,8 @@ simulationStep = do
|
|||
thetanks = map (\(tank, n) -> tank {tankBulletsLeft = (tankBulletsLeft tank) + (countLostTankBullets n thebullets)}) $ zip newtanks [0..]
|
||||
in state {tanks = thetanks, bullets = map snd . filter fst $ thebullets}
|
||||
where
|
||||
updateTank' (player, tank) = let (p, angle, move, aangle, bullet) = playerUpdate player tank
|
||||
t = execState (updateTank angle move aangle) tank
|
||||
in (p, t, bullet)
|
||||
updateTank' game (player, tank) = let (p, angle, move, aangle, bullet) = playerUpdate player tank
|
||||
t = execState (updateTank game angle move aangle) tank
|
||||
in (p, t, bullet)
|
||||
countLostTankBullets n (x:xs) = (if ((not . fst $ x) && (n == (bulletTank . snd $ x))) then 1 else 0) + (countLostTankBullets n xs)
|
||||
countLostTankBullets n [] = 0
|
||||
|
|
Reference in a new issue