summaryrefslogtreecommitdiffstats
path: root/HTanks.hs
diff options
context:
space:
mode:
Diffstat (limited to 'HTanks.hs')
-rw-r--r--HTanks.hs69
1 files changed, 56 insertions, 13 deletions
diff --git a/HTanks.hs b/HTanks.hs
index a6ade4f..22b8309 100644
--- a/HTanks.hs
+++ b/HTanks.hs
@@ -10,6 +10,7 @@ import GLX
import Control.Concurrent (threadDelay)
import Control.Monad.State
+import Data.Fixed
import Data.Maybe
import qualified Data.Map as M
import Data.Ratio
@@ -40,7 +41,7 @@ main = do
when (initialized gl) $ do
currentTime <- getCurrentTime
let mainState = MainState {run = True, driver = SomeDriver gl, time = currentTime, keyset = S.empty}
- gameState = GameState {level = testLevel, tanks = [Tank 0.0 0.0 0 0 2], textures = M.empty}
+ gameState = GameState {level = testLevel, tanks = [Tank 0.0 0.0 0 0 2 360 False], textures = M.empty}
runGame gameState $ do
setup 800 600
@@ -70,7 +71,6 @@ mainLoop = do
let d = round $ 1e3*(diffUTCTime currenttime t)
replicateM_ d simulationStep
- --liftIO $ print $ d
let newtime = addUTCTime ((1e-3)*(fromIntegral d)) t
@@ -80,27 +80,70 @@ mainLoop = do
when runnext mainLoop
-simulationStep :: Main ()
-simulationStep = do
+playerMovement :: Main (Maybe Micro, Bool)
+playerMovement = do
keys <- gets keyset
let x = (if (S.member KeyLeft keys) then (-1) else 0) + (if (S.member KeyRight keys) then 1 else 0)
y = (if (S.member KeyDown keys) then (-1) else 0) + (if (S.member KeyUp keys) then 1 else 0)
- let lengthsq = ((x*x)+(y*y))
+ if (x /= 0 || y /= 0)
+ then return (Just $ fromRational $ round ((atan2 y x)*1000000*180/pi)%1000000, True)
+ else return (Nothing, False)
+
+
+simulationStep :: Main ()
+simulationStep = do
+ (angle, move) <- playerMovement
- when (lengthsq /= 0) $ do
- let length = sqrt lengthsq
+ when (isJust angle) $ do
+ tank <- lift $ gets (head . tanks)
+ let oldangle = dir tank
- oldtank <- lift $ gets (head . tanks)
+ let diff = fromJust angle - oldangle
+ let diff360 = if (diff > 180)
+ then (diff-360)
+ else if (diff <= -180)
+ then (diff+360)
+ else diff
- let dx = (speed oldtank) * fromRational (round (x*1000/length)%1000000)
- dy = (speed oldtank) * fromRational (round (y*1000/length)%1000000)
+ let (diff180, angle180) = if (diff360 > 90)
+ then (diff360-180, oldangle+180)
+ else if (diff360 <= -90)
+ then (diff360+180, oldangle-180)
+ else (diff360, oldangle)
- let tank = oldtank {posx = dx + posx oldtank, posy = dy + posy oldtank, dir = fromRational $ round ((atan2 y x)*1000000*180/pi)%1000000}
+ let tspeed = (turnspeed tank)/1000
+ let turn = if (diff180 > tspeed)
+ then tspeed
+ else if (diff180 < -tspeed)
+ then (-tspeed)
+ else diff180
- lift $ modify $ \state -> state {tanks = tank:(tail . tanks $ state)}
-
+ let newangle = angle180 + turn
+
+ let newangle180 = if (newangle > 180)
+ then (newangle-360)
+ else if (newangle <= -180)
+ then (newangle+360)
+ else newangle
+
+ lift $ modify $ \state -> state {tanks = (tank {dir = newangle180}):(tail . tanks $ state)}
+
+ when move $ do
+ tank <- lift $ gets (head . tanks)
+ let moved = moving tank
+
+ when (isNothing angle || (isJust angle && (dir tank == fromJust angle)) || moved) $ do
+ let angle = (fromRational . toRational $ dir tank)*pi/180
+ x = (speed tank) * fromRational (round ((cos angle)*1000)%1000000)
+ y = (speed tank) * fromRational (round ((sin angle)*1000)%1000000)
+
+ lift $ modify $ \state -> state {tanks = (tank {posx = x + posx tank, posy = y + posy tank, moving = True}):(tail . tanks $ state)}
+
+ when (not move) $ do
+ tank <- lift $ gets (head . tanks)
+ lift $ modify $ \state -> state {tanks = (tank {moving = False}):(tail . tanks $ state)}
handleEvents :: Main ()
handleEvents = do