Reflect bullets at the level border

This commit is contained in:
Matthias Schiffer 2010-03-09 06:45:02 +01:00
parent 89e87826a8
commit 4993b2ef07
2 changed files with 32 additions and 23 deletions

View file

@ -17,13 +17,13 @@ import qualified Data.Map as M
data Tank = Tank data Tank = Tank
{ tankX :: !Micro { tankX :: !Micro
, tankY :: !Micro , tankY :: !Micro
, tankDir :: !Micro , tankDir :: !Micro
, tankAim :: !Micro , tankAim :: !Micro
, tankSpeed :: !Micro , tankSpeed :: !Micro
, tankTurnspeed :: !Micro , tankTurnspeed :: !Micro
, tankMoving :: !Bool , tankMoving :: !Bool
, tankBulletSpeed :: !Micro , tankBulletSpeed :: !Micro
, tankBulletBounces :: !Int , tankBulletBounces :: !Int
, tankBulletsLeft :: !Int , tankBulletsLeft :: !Int
@ -41,7 +41,7 @@ data Bullet = Bullet
data GameState = GameState data GameState = GameState
{ level :: !Level { level :: !Level
, tanks :: ![Tank] , tanks :: ![Tank]
, bullets :: ![Bullet] , bullets :: ![Bullet]
, textures :: !(M.Map Texture TextureObject) , textures :: !(M.Map Texture TextureObject)
} deriving (Show) } deriving (Show)

View file

@ -147,14 +147,23 @@ updateTank angle move aangle = do
modify $ \tank -> tank {tankMoving = False} modify $ \tank -> tank {tankMoving = False}
updateBullet :: State Bullet () updateBullet :: GameState -> State Bullet ()
updateBullet = do updateBullet game = do
angle <- gets bulletDir >>= return . (/180) . (*pi) . fromRational . toRational bullet <- get
speed <- gets bulletSpeed let angle = (fromRational . toRational . bulletDir $ bullet)*pi/180
let dx = speed * fromRational (round ((cos angle)*1000)%1000000) speed = bulletSpeed bullet
dx = speed * fromRational (round ((cos angle)*1000)%1000000)
dy = speed * fromRational (round ((sin angle)*1000)%1000000) dy = speed * fromRational (round ((sin angle)*1000)%1000000)
x = dx + bulletX bullet
y = dy + bulletY bullet
lw = fromIntegral . levelWidth . level $ game
lh = fromIntegral . levelHeight . level $ game
dir = bulletDir bullet
modify $ \bullet -> bullet {bulletX = dx + bulletX bullet, bulletY = dy + bulletY bullet} (newx, dir2) = if x < 0 then (-x, (signum dir)*180 - dir) else if x > lw then (2*lw-x, (signum dir)*180 - dir) else (x, dir)
(newy, dir3) = if y < 0 then (-y, -dir2) else if y > lh then (2*lh-y, -dir2) else (y, dir2)
put bullet {bulletX = newx, bulletY = newy, bulletDir = dir3}
simulationStep :: Main () simulationStep :: Main ()
@ -167,17 +176,17 @@ simulationStep = do
bulletingtanks = map (\(tank, _, n) -> (tank, n)) $ filter (\(tank, bullet, _) -> bullet && (tankBulletsLeft tank) > 0) $ ts bulletingtanks = map (\(tank, _, n) -> (tank, n)) $ filter (\(tank, bullet, _) -> bullet && (tankBulletsLeft tank) > 0) $ ts
newtanks = map (\(tank, bullet, _) -> if bullet then tank {tankBulletsLeft = (tankBulletsLeft tank) - 1} else tank) $ ts newtanks = map (\(tank, bullet, _) -> if bullet then tank {tankBulletsLeft = (tankBulletsLeft tank) - 1} else tank) $ ts
newbullets = map (\(tank, n) -> Bullet newbullets = map (\(tank, n) -> Bullet
{ bulletX = tankX tank { bulletX = tankX tank
, bulletY = tankY tank , bulletY = tankY tank
, bulletDir = tankAim tank , bulletDir = tankAim tank
, bulletSpeed = tankBulletSpeed tank , bulletSpeed = tankBulletSpeed tank
, bulletBouncesLeft = tankBulletBounces tank , bulletBouncesLeft = tankBulletBounces tank
, bulletTank = n , bulletTank = n
}) bulletingtanks }) bulletingtanks
modify $ \state -> state {players = p} modify $ \state -> state {players = p}
lift $ modify $ \state -> state {tanks = newtanks, bullets = map (execState updateBullet) (newbullets ++ bullets state)} lift $ modify $ \state -> state {tanks = newtanks, bullets = map (execState $ updateBullet state) (newbullets ++ bullets state)}
where where
updateTank' (player, tank) = let (p, angle, move, aangle, bullet) = playerUpdate player tank updateTank' (player, tank) = let (p, angle, move, aangle, bullet) = playerUpdate player tank
t = execState (updateTank angle move aangle) tank t = execState (updateTank angle move aangle) tank