Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- breakout prototype in haskell using SDL
- module Main where
- import Debug.Trace
- import Graphics.UI.SDL as SDL
- import Graphics.UI.SDL.Image as Image
- import Graphics.UI.SDL.Framerate as Framerate
- import Graphics.UI.SDL.Mixer as Mixer
- import Foreign
- import Data.Typeable
- import Data.Char
- import Data.IORef
- import Control.Monad
- import System.Environment
- import System.Exit
- import System.Random
- -- screenwidth = 640
- -- screenheight = 480
- screenwidth = 400
- screenheight = 400
- screendepth = 16
- screenmode = [SWSurface,Resizable]
- framerate = 60 -- (hz)
- batfriction = 0.2
- defbataccel = 2
- data Game = Game {
- running :: Bool,
- fpsmgr :: FPSManager,
- screenw :: Int,
- screenh :: Int,
- leftDown :: Bool,
- rightDown :: Bool,
- bat :: Bat,
- ball :: Ball
- }
- data Bat = Bat {
- batx :: Int,
- baty :: Int,
- batvx :: Int,
- batvy :: Int,
- batmaxspeed :: Int,
- bataccel :: Int,
- batw :: Int,
- bath :: Int
- }
- data Ball = Ball {
- ballx :: Int,
- bally :: Int,
- ballvx :: Int,
- ballvy :: Int,
- ballmaxspeed :: Int,
- ballw :: Int,
- ballh :: Int
- }
- main :: IO ()
- main = initialize >>= mainloop
- initialize :: IO Game
- initialize =
- do
- SDL.init [InitVideo,InitAudio]
- setVideoMode screenwidth screenheight screendepth screenmode
- setCaption "Breakout" ""
- enableUnicode True
- fpsmgr <- Framerate.new
- Framerate.init fpsmgr
- Framerate.set fpsmgr framerate
- return $ newGame fpsmgr
- newGame :: FPSManager -> Game
- newGame fpsmgr = Game True fpsmgr screenwidth screenheight False False newBat newBall
- newBat = Bat (div screenwidth 2) (screenheight-h-40) 0 0 10 defbataccel w h where w = 60; h = 10
- newBall = Ball 0 0 4 4 0 8 8
- mainloop :: Game -> IO ()
- mainloop game =
- do
- event <- pollEvent
- game' <- handleevent game event
- let game = step game'
- Framerate.delay $ fpsmgr game
- display game
- when (running game) $ do mainloop game
- handleevent :: Game -> Event -> IO Game
- handleevent game (Quit) = return game{running=False}
- handleevent game (KeyDown (Keysym SDLK_q _ _)) = return game{running=False}
- handleevent game (KeyDown (Keysym SDLK_LEFT _ _)) = return game{leftDown=True}
- handleevent game (KeyUp (Keysym SDLK_LEFT _ _)) = return game{leftDown=False}
- handleevent game (KeyDown (Keysym SDLK_RIGHT _ _)) = return game{rightDown=True}
- handleevent game (KeyUp (Keysym SDLK_RIGHT _ _)) = return game{rightDown=False}
- handleevent game (VideoResize w h) =
- do
- setVideoMode w h screendepth screenmode
- return game{screenw=w,screenh=h}
- handleevent game _ = return game
- step :: Game -> Game
- step game@(Game _ _ screenw screenh leftDown rightDown
- bat@(Bat batx baty batvx batvy batmaxspeed bataccel batw bath)
- ball@(Ball ballx bally ballvx ballvy ballmaxspeed ballw ballh)) =
- game{bat=bat', ball=ball'}
- where
- batvx' = if leftDown then (max (batvx-bataccel) (-batmaxspeed)) else batvx
- batvx'' = if rightDown then (min (batvx'+bataccel) (batmaxspeed)) else batvx'
- batvx''' = if (and [not leftDown, not rightDown]) then truncate(fromIntegral batvx'' * (1.0-batfriction)) else batvx''
- (batx',batvx'''') = incrementWithStop batx batvx''' 0 (screenw-batw)
- (baty',batvy') = (screenh-bath-40, 0)
- bat' = bat{batx=batx',baty=baty',batvx=batvx''',batvy=batvy'}
- (ballx',ballvx') = incrementWithBounce ballx ballvx 0 (screenw-ballw)
- (bally',ballvy') = if (and [ballx >= batx-ballw,
- ballx <= (batx+batw),
- bally >= (baty-ballh),
- bally <= baty,
- ballvy > 0])
- then incrementWithBounce bally ballvy 0 (baty-ballh)
- else incrementWithBounce bally ballvy 0 (screenh-ballh)
- ball' = if (bally+ballvy) >= (screenh-ballh)
- then newBall
- else ball{ballx=ballx',bally=bally',ballvx=ballvx',ballvy=ballvy'}
- incrementWithBounce :: Int -> Int -> Int -> Int -> (Int, Int)
- incrementWithBounce val inc lo hi =
- let v = val + inc in
- if v < lo then (lo+(lo-v), -inc)
- else if v > hi then (hi-(v-hi), -inc)
- else (v,inc)
- incrementWithStop val inc lo hi =
- let v = val + inc in
- if v < lo then (lo, -inc)
- else if v > hi then (hi, -inc)
- else (v,inc)
- display :: Game -> IO ()
- display (Game _ _ _ _ _ _
- (Bat batx baty _ _ _ _ batw bath)
- (Ball ballx bally _ _ _ ballw ballh)) =
- do
- screen <- getVideoSurface
- let format = surfaceGetPixelFormat screen
- red <- mapRGB format 0xFF 0 0
- green <- mapRGB format 0 0xFF 0
- black <- mapRGB format 0 0 0
- white <- mapRGB format 0xFF 0xFF 0xFF
- fillRect screen Nothing black
- fillRect screen (Just (Rect batx baty batw bath)) red
- fillRect screen (Just (Rect ballx bally ballw ballh)) white
- SDL.flip screen
- Wed Oct 27 04:26 2010 Time and Allocation Profiling Report (Final)
- breakoutp +RTS -p -RTS
- total time = 2.30 secs (115 ticks @ 20 ms)
- total alloc = 512,268 bytes (excludes profiling overheads)
- COST CENTRE MODULE %time %alloc
- display Main 93.0 34.8
- step Main 4.3 52.0
- mainloop Main 1.7 7.0
- incrementWithStop Main 0.0 1.6
- incrementWithBounce Main 0.0 3.2
- individual inherited
- COST CENTRE MODULE no. entries %time %alloc %time %alloc
- MAIN MAIN 1 0 0.0 0.0 100.0 100.0
- CAF MainWrapper 322 1 0.0 0.0 0.0 0.0
- CAF Main 321 22 0.0 0.0 99.1 99.9
- batfriction Main 344 1 0.0 0.0 0.0 0.0
- newBall Main 341 1 0.0 0.0 0.0 0.0
- newBat Main 340 1 0.0 0.0 0.0 0.0
- framerate Main 334 1 0.0 0.0 0.0 0.0
- screenmode Main 333 1 0.0 0.0 0.0 0.0
- screendepth Main 332 1 0.0 0.0 0.0 0.0
- screenheight Main 331 1 0.0 0.0 0.0 0.0
- screenwidth Main 330 1 0.0 0.0 0.0 0.0
- initialize Main 329 1 0.0 0.2 0.0 0.2
- newGame Main 335 1 0.0 0.0 0.0 0.0
- main Main 328 1 0.0 0.0 99.1 99.7
- mainloop Main 336 223 1.7 7.0 99.1 99.7
- running Main 349 0 0.0 0.5 0.0 0.5
- display Main 342 223 93.0 34.8 93.0 34.8
- step Main 339 223 4.3 52.0 4.3 56.7
- incrementWithBounce Main 348 446 0.0 3.2 0.0 3.2
- incrementWithStop Main 343 223 0.0 1.6 0.0 1.6
- fpsmgr Main 338 0 0.0 0.5 0.0 0.5
- handleevent Main 337 223 0.0 0.1 0.0 0.1
- CAF Graphics.UI.SDL.General 211 1 0.0 0.0 0.0 0.0
- CAF Graphics.UI.SDL.Events 207 1 0.9 0.0 0.9 0.0
- CAF Graphics.UI.SDL.Video 199 2 0.0 0.0 0.0 0.0
- main Main 345 0 0.0 0.0 0.0 0.0
- mainloop Main 346 0 0.0 0.0 0.0 0.0
- display Main 347 0 0.0 0.0 0.0 0.0
Add Comment
Please, Sign In to add comment