This repository has been archived on 2025-03-03. You can view files and clone it, but cannot push or open issues or pull requests.
htanks/src/HTanks.hs

92 lines
2.6 KiB
Haskell

{-# LANGUAGE PatternGuards #-}
import Game
import Level
import MainLoop
import Render
import Player
import CPUPlayer
import DefaultPlayer
import HWiidPlayer
import Simulation
import Tank
import GLDriver
import GLX
import Control.Monad.State
import Data.Maybe
import qualified Data.Map as M
import qualified Data.Set as S
import Data.Time
import Data.Obj3D
import Data.Obj3D.GL
main :: IO ()
main = do
let theLevel = testLevel
hwiidPlayer <- newHWiidPlayer
gl <- initGL $ glxDriver (levelWidth theLevel) (levelHeight theLevel)
when (initialized gl) $ do
currentTime <- getCurrentTime
let gamestate = GameState {level = theLevel, tanks = [ Tank 5.0 5.0 0 0 1.5 270 False 3 1 5 1
, Tank 5.0 3.5 0 0 1.5 270 False 3 1 5 1
], bullets = []}
mainstate = MainState {run = True, driver = SomeDriver gl, time = currentTime, players =
[ --SomePlayer $ DefaultPlayer S.empty 0 0 False
SomePlayer $ hwiidPlayer
, SomePlayer $ CPUPlayer 0
], textures = M.empty, models = M.empty, gameState = gamestate}
runMain mainstate $ do
setup
mainLoop
deinitGL gl
minFrameTime :: NominalDiffTime
minFrameTime = 0.02
mainLoop :: Main ()
mainLoop = do
gl <- gets driver
t <- gets time
handleEvents
render
liftIO $ swapBuffers gl
rtime <- liftIO getCurrentTime
let drender = diffUTCTime rtime t
when (drender < minFrameTime) $
liftIO $ usleep gl $ truncate $ 1e6*(minFrameTime - drender)
currenttime <- liftIO getCurrentTime
let d = round $ 1e2*(diffUTCTime currenttime t)
replicateM_ d simulationStep
let newtime = addUTCTime ((1e-2)*(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 ()