Nice tank-border collision detection

This commit is contained in:
Matthias Schiffer 2010-03-09 22:36:22 +01:00
parent f3d9814ad5
commit e85dc20a48
4 changed files with 65 additions and 16 deletions

View file

@ -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