88 lines
2.4 KiB
Haskell
88 lines
2.4 KiB
Haskell
{-# LANGUAGE PatternGuards #-}
|
|
|
|
import Game
|
|
import Level
|
|
import MainLoop
|
|
import Render
|
|
import Player
|
|
import CPUPlayer
|
|
import DefaultPlayer
|
|
import Simulation
|
|
import Tank
|
|
|
|
import GLDriver
|
|
import GLX
|
|
|
|
import Control.Concurrent (threadDelay)
|
|
import Control.Monad.State
|
|
import Data.Maybe
|
|
import qualified Data.Map as M
|
|
import qualified Data.Set as S
|
|
import Data.Time
|
|
|
|
|
|
main :: IO ()
|
|
main = do
|
|
let theLevel = testLevel
|
|
gl <- initGL $ glxDriver (levelWidth theLevel) (levelHeight theLevel)
|
|
|
|
when (initialized gl) $ do
|
|
currentTime <- getCurrentTime
|
|
let mainState = MainState {run = True, driver = SomeDriver gl, time = currentTime, players =
|
|
[ SomePlayer $ DefaultPlayer S.empty 0 0 False
|
|
, SomePlayer $ CPUPlayer 0
|
|
]}
|
|
gameState = GameState {level = theLevel, tanks = [ Tank 5.0 5.0 0 0 2 270 False 3 2 5
|
|
, Tank 5.0 3.5 0 0 2 270 False 3 2 5
|
|
], bullets = [], textures = M.empty}
|
|
|
|
runGame gameState $ do
|
|
setup
|
|
runMain mainState mainLoop
|
|
|
|
deinitGL gl
|
|
|
|
minFrameTime :: NominalDiffTime
|
|
minFrameTime = 0.01
|
|
|
|
mainLoop :: Main ()
|
|
mainLoop = do
|
|
gl <- gets driver
|
|
t <- gets time
|
|
handleEvents
|
|
|
|
lift render
|
|
|
|
liftIO $ swapBuffers gl
|
|
|
|
rtime <- liftIO getCurrentTime
|
|
let drender = diffUTCTime rtime t
|
|
when (drender < minFrameTime) $
|
|
liftIO $ threadDelay $ truncate $ 1e6*(minFrameTime - drender)
|
|
|
|
currenttime <- liftIO getCurrentTime
|
|
let d = round $ 1e3*(diffUTCTime currenttime t)
|
|
|
|
replicateM_ d simulationStep
|
|
|
|
let newtime = addUTCTime ((1e-3)*(fromIntegral d)) t
|
|
|
|
modify $ \state -> state {time = newtime}
|
|
|
|
runnext <- gets run
|
|
when runnext mainLoop
|
|
|
|
|
|
handleEvents :: Main ()
|
|
handleEvents = do
|
|
(newgl, event) <- gets driver >>= liftIO . nextEvent
|
|
modify $ \state -> state {driver = newgl}
|
|
when (isJust event) $ do
|
|
Main.handleEvent $ fromJust event
|
|
modify $ \state -> state {players = map (\p -> Player.handleEvent p $ fromJust event) $ players state}
|
|
handleEvents
|
|
|
|
handleEvent :: SomeEvent -> Main ()
|
|
handleEvent ev
|
|
| Just QuitEvent <- fromEvent ev = modify $ \state -> state {run = False}
|
|
| otherwise = return ()
|