packages feed

4Blocks-0.2: Interface/WindowUpdate.hs

module Interface.WindowUpdate ( updateWindowWithPlayerAction,
                                updateWindowWithGravityDelay )

where

import Core.Game
import Core.Commands

import Control.Monad.State
import Control.Concurrent
import Graphics.UI.Gtk
import Data.IORef

import Debug.Trace

-------------------------------------------------------------------------------------------------------------------------
-- Updating of the Game Window with an action performed by the player and with an action performed periodically       
updateWindowWithPlayerAction :: DrawingArea -> MVar Game -> State Game Bool -> IO ()
updateWindowWithPlayerAction drawArea gameMVar move 
  = do oldGame <- takeMVar gameMVar
       let newGame = execState move oldGame
       widgetQueueDraw drawArea
       putMVar gameMVar newGame
       return ()
       
updateWindowWithGravityDelay :: DrawingArea -> MVar Game -> IO ()
updateWindowWithGravityDelay drawArea gameMVar
  = do -- retrieve game state
       oldGame <- takeMVar gameMVar
           -- attempt to move brick down
       let (result,moveDownGame) = runState shift_brick_down oldGame
           -- if it is not possible to move brick down lock it in place and...
           newGame = if result
                        then moveDownGame
                        else execState lock_clear_next_brick moveDownGame
            -- calculate new delay
           newDelay = (calculateGravityDelay.getGravityFromGame) newGame
       -- save new game state
       putMVar gameMVar newGame
       -- create a new one-time update for the screen by calling oneself
       timeoutAdd (updateWindowWithGravityDelay drawArea gameMVar >> return False) newDelay
       
       return ()
-------------------------------------------------------------------------------------------------------------------------
-- Delay Calculations
calculateGravityDelay :: Int -> Int
calculateGravityDelay g
  | g > 0     = 1000 `div` g
  | otherwise = ((abs g) + 1) * 1000
  
calculateComputerPlayDelay :: Int
calculateComputerPlayDelay = 10