Added bullet/tank collision; reduced tick count
This commit is contained in:
parent
a1294859c7
commit
5c34cd6941
5 changed files with 41 additions and 11 deletions
|
@ -10,6 +10,7 @@ import Tank
|
|||
|
||||
import Control.Monad.State
|
||||
import Data.Fixed
|
||||
import Data.List
|
||||
import Data.Maybe
|
||||
import Data.Ratio
|
||||
|
||||
|
@ -17,7 +18,7 @@ import Data.Ratio
|
|||
updateAngle :: Micro -> State Tank ()
|
||||
updateAngle angle = do
|
||||
oldangle <- gets tankDir
|
||||
tspeed <- gets tankTurnspeed >>= return . (/1000)
|
||||
tspeed <- liftM (/100) $ gets tankTurnspeed
|
||||
|
||||
let diff = angle - oldangle
|
||||
let diff360 = if (diff > 180)
|
||||
|
@ -65,8 +66,8 @@ updateTank game angle move aangle = do
|
|||
|
||||
when (isNothing angle || (isJust angle && (tdir == fromJust angle)) || moved) $ do
|
||||
let anglej = (fromRational . toRational $ tdir)*pi/180
|
||||
dx = tspeed * fromRational (round ((cos anglej)*1000)%1000000)
|
||||
dy = tspeed * fromRational (round ((sin anglej)*1000)%1000000)
|
||||
dx = tspeed * fromRational (round ((cos anglej)*1000)%100000)
|
||||
dy = tspeed * fromRational (round ((sin anglej)*1000)%100000)
|
||||
|
||||
put tank {tankX = dx + tankX tank, tankY = dy + tankY tank, tankMoving = True}
|
||||
|
||||
|
@ -83,8 +84,8 @@ updateBullet game = do
|
|||
bullet <- get
|
||||
let angle = (fromRational . toRational . bulletDir $ bullet)*pi/180
|
||||
speed = bulletSpeed bullet
|
||||
dx = speed * fromRational (round ((cos angle)*1000)%1000000)
|
||||
dy = speed * fromRational (round ((sin angle)*1000)%1000000)
|
||||
dx = speed * fromRational (round ((cos angle)*1000)%100000)
|
||||
dy = speed * fromRational (round ((sin angle)*1000)%100000)
|
||||
x = dx + bulletX bullet
|
||||
y = dy + bulletY bullet
|
||||
lw = fromIntegral . levelWidth . level $ game
|
||||
|
@ -123,8 +124,12 @@ simulationStep = do
|
|||
lift $ modify $ \state ->
|
||||
let thebullets = map (runState $ updateBullet state) $ bullets state
|
||||
leftbullets = collideBullets $ zipWith (\(left, bullet') bullet -> (left, bullet, bullet')) thebullets $ bullets state
|
||||
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)}
|
||||
bt = hitBullets $ liftM2 (\(b, (_, b')) (t, t') -> (b, b', t, t')) (zip (bullets state) leftbullets) (zip (tanks state) newtanks)
|
||||
leftbullets2 = map (\(left, bullet) -> (left && (all (\(c, b, _) -> (b /= bullet) || (not c)) bt), bullet)) leftbullets
|
||||
|
||||
thetanks = map (\(tank, n) -> tank {tankBulletsLeft = (tankBulletsLeft tank) + (countLostTankBullets n leftbullets2)}) $ zip newtanks [0..]
|
||||
|
||||
in state {tanks = thetanks, bullets = newbullets ++ (map snd . filter fst $ leftbullets2)}
|
||||
|
||||
where
|
||||
collideBullets [] = []
|
||||
|
@ -135,6 +140,10 @@ simulationStep = do
|
|||
left = map (\(left, c, b, b') -> (left && not c, b, b')) $ cs
|
||||
in (collided, left)
|
||||
|
||||
hitBullets :: [(Bullet, Bullet, Tank, Tank)] -> [(Bool, Bullet, Tank)]
|
||||
hitBullets [] = []
|
||||
hitBullets ((b, b', t, t'):xs) = (collisionBulletTank (b, b') (t, t'), b', t'):(hitBullets xs)
|
||||
|
||||
updateTank' game (player, tank) = let (p, angle, move, aangle, shoot) = playerUpdate player tank
|
||||
t = execState (updateTank game angle move aangle) tank
|
||||
in (p, t, shoot)
|
||||
|
|
Reference in a new issue