summaryrefslogtreecommitdiffstats
path: root/src/HTanks.hs
blob: dd60903990d827c4ccf15e2679681670d3a44800 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
{-# LANGUAGE PatternGuards #-}

import Game
import Level
import MainLoop
import Render
import Player
import CPUPlayer
import DefaultPlayer
import HWiidPlayer
import Simulation
import Tank
import Vector


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


main :: IO ()
main = do
  let theLevel = testLevel
  --humanPlayer <- newHWiidPlayer
  let humanPlayer = DefaultPlayer S.empty 0 0 False
  gl <- initGL $ glxDriver (levelWidth theLevel) (levelHeight theLevel)
  
  when (initialized gl) $ do
         currentTime <- getCurrentTime
         let gamestate = GameState {level = theLevel, tanks = [ Tank (Vertex 7.0 4.0) zeroV zeroV 1.5 (270*pi/180) False 3 1 5 1
                                                              , Tank (Vertex 4.0 4.0) zeroV zeroV 1.5 (270*pi/180) False 3 1 5 1
                                                              , Tank (Vertex 10.0 4.0) zeroV zeroV 1.5 (270*pi/180) False 3 1 5 1
                                                              ], bullets = []}
             mainstate = MainState {run = True, driver = SomeDriver gl, time = currentTime, players =
                                          [ SomePlayer humanPlayer
                                          , SomePlayer $ CPUPlayer $ fromAngle $ -pi/2
                                          , SomePlayer $ CPUPlayer $ fromAngle $ pi/2
                                          ], 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 ()