free-game 0.3.0.0 → 0.3.0.1
raw patch · 8 files changed
+84/−60 lines, 8 filesPVP ok
version bump matches the API change (PVP)
API changes (from Hackage documentation)
Files
- Graphics/FreeGame.hs +48/−8
- Graphics/FreeGame/Backends/GLFW.hs +2/−1
- Graphics/FreeGame/Base.hs +11/−9
- Graphics/FreeGame/Bitmap.hs +10/−6
- Graphics/FreeGame/Input.hs +0/−13
- Graphics/FreeGame/Util.hs +6/−2
- examples/test.hs +5/−5
- free-game.cabal +2/−16
Graphics/FreeGame.hs view
@@ -1,14 +1,54 @@-{-# LANGUAGE CPP #-} -module Graphics.FreeGame ( - module Graphics.FreeGame.Base - ,module Graphics.FreeGame.Bitmap - ,module Graphics.FreeGame.Input - ,module Graphics.FreeGame.Util - ,runGame +{-| +Module : Graphics.FreeGame +Copyright : (C) 2012 Fumiaki Kinoshita +License : BSD-style (see the file LICENSE) +Maintainer : Fumiaki Kinsohita <fumiexcel@gmail.com> + +free-game is a library that abstracts and purifies GUI applications. + +Small instruction: + + * load images by 'loadPictureFromFile'. + + * describe an application using 'drawPicture', 'askInput', 'tick', and so on, in Game monad. + + * apply 'runGame defaultGameParam' to run. + + * That's all! +-} +module Graphics.FreeGame + ( -- * Examples + -- $example + + -- * Note + -- $note + + -- * Reexports + module Graphics.FreeGame.Base, + module Graphics.FreeGame.Bitmap, + module Graphics.FreeGame.Input, + module Graphics.FreeGame.Util, + runGame ) where import Graphics.FreeGame.Base import Graphics.FreeGame.Bitmap import Graphics.FreeGame.Input import Graphics.FreeGame.Util -import Graphics.FreeGame.Backends.GLFW+import Graphics.FreeGame.Backends.GLFW + +{- $example + +> main = runGame defaultGameParam $ forever tick + +shows a window and does nothing. + +for more examples, see <https://github.com/fumieval/free-game/tree/master/examples>. + +-} + +{- $note + +* There are experimental implementation of text rendering('withRenderString'), but it often yields strange pictures. + +-}
Graphics/FreeGame/Backends/GLFW.hs view
@@ -54,11 +54,12 @@ [(0,0), (1.0,0), (1.0,1.0), (0,1.0)] GL.texture GL.Texture2D GL.$= GL.Disabled -drawPic (Rotate theta p) = GL.preservingMatrix $ GL.rotate (gf theta) (GL.Vector3 0 0 (-1)) >> drawPic p +drawPic (Rotate theta p) = GL.preservingMatrix $ GL.rotate (gf (-theta)) (GL.Vector3 0 0 1) >> drawPic p drawPic (Scale (Vec2 sx sy) p) = GL.preservingMatrix $ GL.scale (gf sx) (gf sy) 1 >> drawPic p drawPic (Translate (Vec2 tx ty) p) = GL.preservingMatrix $ GL.translate (GL.Vector3 (gf tx) (gf ty) 0) >> drawPic p drawPic (Pictures ps) = mapM_ drawPic ps +-- | Run 'Game' using OpenGL and GLFW. runGame :: GameParam -> Game a -> IO (Maybe a) runGame param game = do initialize
Graphics/FreeGame/Base.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE FlexibleContexts, FlexibleInstances #-} +{-# LANGUAGE FlexibleContexts #-} ----------------------------------------------------------------------------- -- | -- Module : Graphics.FreeGame.Base @@ -9,7 +9,7 @@ -- Stability : provisional -- Portability : non-portable -- --- Abstract structure that represents user interfaces +-- Abstract structures that represents user interfaces ---------------------------------------------------------------------------- module Graphics.FreeGame.Base ( @@ -38,6 +38,7 @@ type Game = Free GameAction +-- | A base for 'Game' monad. data GameAction cont = Tick cont | EmbedIO (IO cont) @@ -66,7 +67,7 @@ embedIO :: MonadFree GameAction m => IO a -> m a embedIO m = wrap $ EmbedIO $ liftM return m --- | Run a Game monad in the Game monad. resources (pictures, sounds) will be released when inner computation is done. +-- | Run a Game monad in a Game monad. resources (e.g. pictures) will be released when inner computation is done. bracket :: MonadFree GameAction m => Game a -> m a bracket m = wrap $ Bracket $ liftM return m @@ -74,11 +75,11 @@ drawPicture :: MonadFree GameAction m => Picture -> m () drawPicture pic = wrap $ DrawPicture pic (return ()) --- | Create 'Picture' from 'Bitmap'. +-- | Create a 'Picture' from 'Bitmap'. loadPicture :: MonadFree GameAction m => Bitmap -> m Picture loadPicture img = wrap $ LoadPicture img return --- | Is the specified key is pressed? +-- | Is the specified 'Key' is pressed? askInput :: MonadFree GameAction m => Key -> m Bool askInput key = wrap $ AskInput key return @@ -86,22 +87,22 @@ getMouseState :: MonadFree GameAction m => m MouseState getMouseState = wrap $ GetMouseState return --- | Apply the function to all pictures in 'DrawPicture'. +-- | Lift a picture transformation into transformation of 'GameAction' transPicture :: (Picture -> Picture) -> GameAction cont -> GameAction cont transPicture f (DrawPicture p cont) = DrawPicture (f p) cont transPicture _ x = x -- | A 2D Picture. data Picture - -- | An abstract image object. + -- | An abstract primitive image. = Image Unique -- | Combined picture from some pictures. | Pictures [Picture] - -- | Rotated picture counterclockwise by the given angle (in degrees). + -- | Rotated picture by the given angle (in degrees, counterclockwise). | Rotate Float Picture -- | Scaled picture. | Scale Vec2 Picture - -- | A picture moved by the given coordinate. + -- | A picture translated by the given coordinate. | Translate Vec2 Picture -- | Parameters of the application. @@ -112,5 +113,6 @@ ,windowed :: Bool } +-- | 640*480(windowed), 60fps defaultGameParam :: GameParam defaultGameParam = GameParam 60 (640,480) "free-game" True
Graphics/FreeGame/Bitmap.hs view
@@ -6,7 +6,7 @@ -- -- Maintainer : Fumiaki Kinsohita <fumiexcel@gmail.com> -- Stability : provisional --- Portability : portable +-- Portability : non-portable -- -- Manipulating bitmaps ---------------------------------------------------------------------------- @@ -20,26 +20,30 @@ import Data.Array.IArray as A import qualified Graphics.Rendering.TrueType.STB as TT -newtype Bitmap = Bitmap { bitmapData :: R.Array D DIM3 Word8 } +-- | Concrete bitmap data type +newtype Bitmap = Bitmap { + bitmapData :: R.Array D DIM3 Word8 -- ^ Bare the 'Bitmap''s internal representation (y * x * ARGB) + } -- | Get the size of the 'Bitmap'. bitmapSize :: Bitmap -> (Int, Int) bitmapSize bmp = let (Z :. h :. w :. _) = R.extent (bitmapData bmp) in (w, h) --- | Create 'Bitmap' from given path. +-- | Create a 'Bitmap' from the given file. loadBitmapFromFile :: FilePath -> IO Bitmap loadBitmapFromFile path = Bitmap <$> delay <$> imgData <$> either error id <$> readImageRGBA path --- | Extract bitmap from the specified range. +-- | Extract a 'Bitmap' from the specified range. cropBitmap :: Bitmap -- ^original bitmap -> (Int, Int) -- ^width and height -> (Int, Int) -- ^x and y -> Bitmap -- ^result cropBitmap (Bitmap img) (w, h) (x, y) = Bitmap $ extract (Z :. y :. x :. 0) (Z :. h :. w :. 4) img +-- | Font object newtype Font = Font TT.BitmapCache --- create 'Font' from given file. +-- | create a 'Font' from the given file. loadFont :: FilePath -> Float -> IO Font loadFont path size = do tt <- TT.loadTTF path @@ -50,7 +54,7 @@ let s = size/fromIntegral (x1-x0) Font <$> TT.newBitmapCache font False (s, s) --- render 'Bitmap' of given character by specified 'Font' and color(RGB). +-- | render 'Bitmap' of the character by specified 'Font' and color(RGB). charToBitmap :: Font -> (Word8, Word8, Word8) -> Char -> IO (Maybe (Bitmap, Float, Float, Float)) charToBitmap (Font cache) (red,green,blue) ch = do r <- TT.getCachedBitmap cache ch
Graphics/FreeGame/Input.hs view
@@ -1,16 +1,3 @@------------------------------------------------------------------------------ --- | --- Module : Graphics.FreeGame.Base --- Copyright : (C) 2012 Fumiaki Kinoshita --- License : BSD-style (see the file LICENSE) --- --- Maintainer : Fumiaki Kinsohita <fumiexcel@gmail.com> --- Stability : provisional --- Portability : non-portable --- --- Common key and mouse inputs ----------------------------------------------------------------------------- - module Graphics.FreeGame.Input where import Data.Vect
Graphics/FreeGame/Util.hs view
@@ -22,24 +22,27 @@ import Data.Vect import Data.Word --- | Run 'Game' as one frame. +-- | Run a 'Game' as one frame. untickGame :: Game a -> Game (Game a) untickGame (Pure a) = Pure (Pure a) untickGame (Free (Tick cont)) = Pure cont untickGame (Free fm) = Free $ fmap untickGame fm --- | Get a random value from the given range. +-- | Get a given range of value. randomness :: (Random r, MonadFree GameAction m) => (r, r) -> m r randomness r = embedIO $ randomRIO r +-- | Convert radians to degrees. degrees :: Float -> Float {-# INLINE degrees #-} degrees x = x / pi * 180 +-- | Convert degrees to radians. radians :: Float -> Float {-# INLINE radians #-} radians x = x / 180 * pi +-- | Render the string by given font and color, and pass it to the 'Game' computation. withRenderString :: Font -> (Word8, Word8, Word8) -> String -> (Picture -> Game a) -> Game a withRenderString font color str action = bracket $ render str 0 >>= action . Pictures where @@ -49,5 +52,6 @@ (:) <$> Translate (Vec2 (x + w + o) h) <$> loadPicture b <*> render cs (x + w) +-- | Create a 'Picture' from given file path. loadPictureFromFile :: FilePath -> Game Picture loadPictureFromFile = embedIO . loadBitmapFromFile >=> loadPicture
examples/test.hs view
@@ -4,10 +4,10 @@ import Control.Monad import Data.Vect -act :: (?pic :: Picture) => Vec2 -> Vec2 -> Bool -> Game () -act pos@(Vec2 x y) vel@(Vec2 dx dy) btn = do +act :: (?pic :: Picture) => Vec2 -> Vec2 -> Float -> Bool -> Game () +act pos@(Vec2 x y) vel@(Vec2 dx dy) angle btn = do - drawPicture $ Translate pos $ Rotate (degrees $ angle2 vel) ?pic + drawPicture $ Translate pos $ Rotate angle ?pic let dx' | x <= 0 = abs dx | x >= 640 = -(abs dx) @@ -21,14 +21,14 @@ then (&*3) <$> sinCos <$> randomness (0, 2 * pi) else return (Vec2 dx' dy') tick - act (pos &+ vel) vel' (leftButton mouse) + act (pos &+ vel) vel' (angle + 1) (leftButton mouse) initial :: (?pic :: Picture) => Game () initial = do x <- randomness (0,640) y <- randomness (0,480) a <- randomness (0, 2 * pi) - act (Vec2 x y) (sinCos a &* 4) False + act (Vec2 x y) (sinCos a &* 4) 0 False main = runGame defaultGameParam $ do pic <- loadPictureFromFile "logo.png"
free-game.cabal view
@@ -1,21 +1,7 @@ name: free-game -version: 0.3.0.0 +version: 0.3.0.1 synopsis: Create graphical applications for free. -description: - Create something graphical with useful free monads. - . - /Small instruction/ - . - * load your image by loadBitmapFromFile, embedIO, and loadPicture. - . - * describe an application using drawPicture, askInput, tick, and so on, in Game monad. - . - * apply `runGame defaultGameParam` to run. - . - * That's all! - . - There are experimental implementation of text rendering, but it yields strange pictures. - +description: closs-platform GUI library based on free monads. homepage: https://github.com/fumieval/free-game license: BSD3 license-file: LICENSE