packages feed

fallingblocks-0.1.2: main.hs

import Paths_fallingblocks
import Graphics.UI.SDL as SDL
import Graphics.UI.SDL.TTF as TTF

import Graphics.UI.SDL.Mixer as Mix

import Game
import Shape
import Helpers
import Board 

import GameController
import SplashController

import GameState

import Random (randomRIO)
import Data.Maybe (isNothing)

import GraphicsInfo

main = do
  SDL.init [InitEverything]
  setVideoMode 400 400 32 []
  TTF.init

  setCaption "Falling Blocks!" "Falling Blocks!" 

  mworked <- openAudio 44100 AudioS16Sys 2 4096
  music <- loadMUS =<< getDataFileName "music.mp3"
  
  playMusic music (-1)

  gi <- makeGraphics

  enableKeyRepeat 500 30

  c <- getRandomType
  n <- getRandomType
  gameLoop (GameState gi (newGame c n) 0 True music handleSplashEvents renderSplashScreen True)


gameLoop :: GameState -> IO ()
gameLoop gsfirst = do
  gs <- addPiece gsfirst

  --getEvents - would like to get all events from pollEvent
  events <- getEvents pollEvent []

  --handle input
  let gs' = handleEvents events gs

  --delay - probably want something a bit more
  --        complex here to handle refresh rate
  delay 10

  doRender gs'

  if (keepGoing gs')
    then gameLoop $ tickAndMoveIfNeeded gs'
    else cleanUp gs'

cleanUp :: GameState -> IO ()
cleanUp gs = do
  cleanupGraphics $ grInfo gs
  freeMusic $ mus gs
  closeAudio
  TTF.quit
  SDL.quit



getRandomType :: IO ShapeType 
getRandomType = do
  randomRIO (0,6) >>= \i ->
      return (toEnum i::ShapeType)

addPiece :: GameState -> IO GameState
addPiece gsfirst =
  if isNothing . nextBlock $ game gsfirst
   then randomRIO (0,6) >>= \i -> 
       return $ gsfirst {game = addBlock (game gsfirst) (toEnum i::ShapeType)}
   else return gsfirst

tickAndMoveIfNeeded :: GameState -> GameState
tickAndMoveIfNeeded gs = if ticks gs > t && (stillRunning $ game gs) && (not $ paused gs)
                         then gs { game = move (game gs) MoveDown,
                                   ticks = 0 }
                         else gs { ticks = (ticks gs) + 1 }
    where t = 40 - floor (modifier)
          modifier = 2.3 * (fromIntegral level) :: Float
          level = curLevel $ game gs


-- collects a list of all outstanding events from SDL
getEvents :: IO Event -> [Event] -> IO [Event]
getEvents pEvent es = do
  e <- pEvent
  let hasEvent = e /= NoEvent
  if hasEvent
   then getEvents pEvent (e:es)
   else return (reverse es)