FunGEn 0.3 → 0.4
raw patch · 11 files changed
+361/−274 lines, 11 filesdep −haskell98PVP ok
version bump matches the API change (PVP)
Dependencies removed: haskell98
API changes (from Hackage documentation)
- Graphics.UI.Fungen.Input: type InputConfig t s u v = (Key, KeyEvent, IOGame t s u v ())
- Graphics.UI.Fungen.UserInput: Char :: Char -> Key
- Graphics.UI.Fungen.UserInput: MouseButton :: MouseButton -> Key
- Graphics.UI.Fungen.UserInput: Press :: KeyEvent
- Graphics.UI.Fungen.UserInput: Release :: KeyEvent
- Graphics.UI.Fungen.UserInput: SpecialKey :: SpecialKey -> Key
- Graphics.UI.Fungen.UserInput: StillDown :: KeyEvent
- Graphics.UI.Fungen.UserInput: data Key :: *
- Graphics.UI.Fungen.UserInput: data KeyEvent
- Graphics.UI.Fungen.UserInput: initUserInput :: IO (KeyBinder, StillDownHandler)
- Graphics.UI.Fungen.UserInput: instance Eq KeyEvent
- Graphics.UI.Fungen.UserInput: type KeyBinder = Key -> KeyEvent -> Maybe (IO ()) -> IO ()
- Graphics.UI.Fungen.UserInput: type StillDownHandler = IO ()
+ Graphics.UI.Fungen.Input: KeyUnknown :: Int -> SpecialKey
+ Graphics.UI.Fungen.Input: Modifiers :: KeyState -> KeyState -> KeyState -> Modifiers
+ Graphics.UI.Fungen.Input: Position :: !GLint -> !GLint -> Position
+ Graphics.UI.Fungen.Input: alt :: Modifiers -> KeyState
+ Graphics.UI.Fungen.Input: ctrl :: Modifiers -> KeyState
+ Graphics.UI.Fungen.Input: data Modifiers :: *
+ Graphics.UI.Fungen.Input: data Position :: *
+ Graphics.UI.Fungen.Input: shift :: Modifiers -> KeyState
+ Graphics.UI.Fungen.Input: type InputBinding t s u v = (Key, KeyEvent, InputHandler t s u v)
+ Graphics.UI.Fungen.Input: type InputHandler t s u v = Modifiers -> Position -> IOGame t s u v ()
+ Graphics.UI.GLUT.Input: Char :: Char -> Key
+ Graphics.UI.GLUT.Input: MouseButton :: MouseButton -> Key
+ Graphics.UI.GLUT.Input: Press :: KeyEvent
+ Graphics.UI.GLUT.Input: Release :: KeyEvent
+ Graphics.UI.GLUT.Input: SpecialKey :: SpecialKey -> Key
+ Graphics.UI.GLUT.Input: StillDown :: KeyEvent
+ Graphics.UI.GLUT.Input: data Key :: *
+ Graphics.UI.GLUT.Input: data KeyEvent
+ Graphics.UI.GLUT.Input: initGLUTInput :: IO (KeyBinder, StillDownHandler)
+ Graphics.UI.GLUT.Input: instance Eq KeyEvent
+ Graphics.UI.GLUT.Input: type InputHandler = Modifiers -> Position -> IO ()
+ Graphics.UI.GLUT.Input: type KeyBinder = Key -> KeyEvent -> Maybe InputHandler -> IO ()
+ Graphics.UI.GLUT.Input: type StillDownHandler = IO ()
- Graphics.UI.Fungen.Init: funInit :: WindowConfig -> GameMap v -> [(ObjectManager s)] -> u -> t -> [InputConfig t s u v] -> IOGame t s u v () -> RefreshType -> FilePictureList -> IO ()
+ Graphics.UI.Fungen.Init: funInit :: WindowConfig -> GameMap v -> [(ObjectManager s)] -> u -> t -> [InputBinding t s u v] -> IOGame t s u v () -> RefreshType -> FilePictureList -> IO ()
- Graphics.UI.Fungen.Input: funBinding :: [InputConfig t s u v] -> Game t s u v -> IO (KeyBinder, StillDownHandler)
+ Graphics.UI.Fungen.Input: funBinding :: [InputBinding t s u v] -> Game t s u v -> IO (KeyBinder, StillDownHandler)
Files
- FunGEn.cabal +14/−15
- Graphics/UI/Fungen/Game.hs +34/−2
- Graphics/UI/Fungen/Init.hs +1/−1
- Graphics/UI/Fungen/Input.hs +15/−8
- Graphics/UI/Fungen/Timer.hs +1/−1
- Graphics/UI/Fungen/UserInput.hs +0/−82
- Graphics/UI/GLUT/Input.hs +102/−0
- LICENSE +1/−1
- README.md +175/−143
- examples/pong/pong.hs +10/−13
- examples/worms/worms.hs +8/−8
FunGEn.cabal view
@@ -1,18 +1,18 @@ name: FunGEn -version: 0.3 -copyright: (C) 2002 Andre Furtado <awbf@cin.ufpe.br>, (C) 2008 Miloslav Raus <666wman@gmail.com>, (C) 2008,2011 Simon Michael <simon@joyful.com> +version: 0.4 +copyright: (C) 2002 Andre Furtado <awbf@cin.ufpe.br> license: BSD3 license-file: LICENSE author: Andre Furtado <awbf@cin.ufpe.br> maintainer: Simon Michael <simon@joyful.com> -homepage: http://darcsden.com/simon/fungen +homepage: http://joyful.com/fungen category: Game synopsis: FUNctional Game ENgine description: Multi-platform 2D game engine built on top of OpenGL & GLUT -stability: experimental +stability: alpha cabal-version: >= 1.6 build-type: Simple -tested-with: GHC==6.12 +tested-with: GHC==7.6.3 extra-source-files: README.md, examples/pong/hit.wav, examples/pong/pong.hs, examples/pong/tex.bmp, examples/worms/border1.bmp, examples/worms/border2.bmp, examples/worms/border3.bmp, examples/worms/congratulations.bmp, examples/worms/food.bmp, examples/worms/free1.bmp, @@ -22,15 +22,14 @@ examples/worms/level3.bmp, examples/worms/segment.bmp, examples/worms/worms.hs library - exposed-modules: Graphics.UI.Fungen, - Graphics.UI.Fungen.Types, Graphics.UI.Fungen.Util, Graphics.UI.Fungen.Loader, - Graphics.UI.Fungen.Objects, Graphics.UI.Fungen.Map, Graphics.UI.Fungen.Game, - Graphics.UI.Fungen.Display, Graphics.UI.Fungen.Input, Graphics.UI.Fungen.Timer, - Graphics.UI.Fungen.Text, Graphics.UI.Fungen.Init, Graphics.UI.Fungen.UserInput + exposed-modules: Graphics.UI.Fungen, + Graphics.UI.Fungen.Types, Graphics.UI.Fungen.Util, Graphics.UI.Fungen.Loader, + Graphics.UI.Fungen.Objects, Graphics.UI.Fungen.Map, Graphics.UI.Fungen.Game, + Graphics.UI.Fungen.Display, Graphics.UI.Fungen.Input, Graphics.UI.Fungen.Timer, + Graphics.UI.Fungen.Text, Graphics.UI.Fungen.Init, Graphics.UI.GLUT.Input build-depends: - base == 4.* - ,OpenGL - ,GLUT - ,haskell98 - ,random + base == 4.* + ,OpenGL + ,GLUT + ,random
Graphics/UI/Fungen/Game.hs view
@@ -68,7 +68,39 @@ -- -- * v is the type of the map tile special attribute, in case we use a Tile Map as the background of our game -- --- A game consists of: +-- For a mnemonic, uh... +-- +-- * t - /T/op-level game attribute type, +-- +-- * s - /S/prite object attribute type, +-- +-- * u - /U/pdating game state type, +-- +-- * v - /V/icinity (map tile) attribute type. +-- +-- A Game consists of the following attributes, accessible via the +-- accessor functions below: +-- +-- * @gameMap :: IORef (GameMap v) -- a map (background)@ +-- +-- * @gameState :: IORef u -- initial game state@ +-- +-- * @gameFlags :: IORef GameFlags -- initial game flags@ +-- +-- * @objManagers :: IORef [(ObjectManager s)] -- some object managers@ +-- +-- * @textList :: IORef [Text] -- some texts@ +-- +-- * @quadricObj :: QuadricPrimitive -- a quadric thing@ +-- +-- * @windowConfig :: IORef WindowConfig -- a config for the main window@ +-- +-- * @gameAttribute :: IORef t -- a game attribute@ +-- +-- * @pictureList :: IORef [TextureObject] -- some pictures@ +-- +-- * @fpsInfo :: IORef (Int,Int,Float) -- only for debugging@ +-- data Game t s u v = Game { gameMap :: IORef (GameMap v), -- ^ a map (background) gameState :: IORef u, -- ^ initial game state @@ -82,7 +114,7 @@ fpsInfo :: IORef (Int,Int,Float) -- only for debugging } --- | A game action has the type @IOGame t s u v a@, where t, s, u and v +-- | A game action (IOGame) has the type @IOGame t s u v a@, where t, s, u and v -- are as for Game and a is the type returned by each action of the game -- (such as the Int for "IO Int"). The name IOGame was chosen to remind -- that each action deals with a Game, but an IO operation can also be
Graphics/UI/Fungen/Init.hs view
@@ -28,7 +28,7 @@ import Graphics.Rendering.OpenGL import Graphics.UI.GLUT -funInit :: WindowConfig -> GameMap v -> [(ObjectManager s)] -> u -> t -> [InputConfig t s u v] -> IOGame t s u v () -> RefreshType -> FilePictureList -> IO () +funInit :: WindowConfig -> GameMap v -> [(ObjectManager s)] -> u -> t -> [InputBinding t s u v] -> IOGame t s u v () -> RefreshType -> FilePictureList -> IO () funInit winConfig@((px,py),(sx,sy),t) userMap objectGroups gState gAttrib i gameCicle r picList = do initialize "FunGen app" [] createWindow t -- (return ()) [ Double, RGBA ]
Graphics/UI/Fungen/Input.hs view
@@ -14,22 +14,29 @@ -} module Graphics.UI.Fungen.Input ( - InputConfig, - Key(..), KeyEvent(..), SpecialKey(..), MouseButton(..), + InputBinding, InputHandler, + Key(..), KeyEvent(..), SpecialKey(..), MouseButton(..), Modifiers(..), Position(..), funBinding ) where import Graphics.UI.Fungen.Game -import Graphics.UI.Fungen.UserInput import Graphics.UI.GLUT +import Graphics.UI.GLUT.Input (KeyEvent(..), KeyBinder, StillDownHandler, initGLUTInput) -type InputConfig t s u v = (Key,KeyEvent,IOGame t s u v ()) +-- | A FunGEn input handler (which we use instead of GLUTInput's) is +-- an IOGame (game action) that takes two extra arguments: the current +-- keyboard modifiers state, and the current mouse position. (For a StillDown +-- event, these will be the original state and position from the Press event.) +type InputHandler t s u v = Modifiers -> Position -> IOGame t s u v () -funBinding :: [InputConfig t s u v] -> Game t s u v -> IO (KeyBinder, StillDownHandler) +-- | A mapping from an input event to an input handler. +type InputBinding t s u v = (Key, KeyEvent, InputHandler t s u v) + +funBinding :: [InputBinding t s u v] -> Game t s u v -> IO (KeyBinder, StillDownHandler) funBinding inputs g = do - (bindKey, stillDown) <- initUserInput + (bindKey, stillDown) <- initGLUTInput mapM (userBinding g bindKey) inputs return (bindKey, stillDown) -userBinding :: Game t s u v -> KeyBinder -> InputConfig t s u v -> IO () -userBinding g bindKey (key,keyEvent,gameAction) = bindKey key keyEvent (Just (runIOGameM gameAction g))+userBinding :: Game t s u v -> KeyBinder -> InputBinding t s u v -> IO () +userBinding g bindKey (key, keyEvent, inputHandler) = bindKey key keyEvent (Just (\mods pos -> runIOGameM (inputHandler mods pos) g))
Graphics/UI/Fungen/Timer.hs view
@@ -18,8 +18,8 @@ setRefresh ) where -import Graphics.UI.Fungen.UserInput import Graphics.UI.GLUT +import Graphics.UI.GLUT.Input data RefreshType = Idle
− Graphics/UI/Fungen/UserInput.hs
@@ -1,82 +0,0 @@-{- | - GLUT-based keyboard/mouse handling - Sven Panne 2000. mailto:Sven.Panne@informatik.uni-muenchen.de --} - -module Graphics.UI.Fungen.UserInput ( - Key(..), KeyEvent(..), KeyBinder, StillDownHandler, initUserInput -) where - -import Data.IORef(IORef, newIORef, readIORef, modifyIORef) -import Data.List(delete) -import Graphics.UI.GLUT - ---------------------------------------------------------------------------- - -data KeyEvent = Press | StillDown | Release deriving Eq - ---------------------------------------------------------------------------- - -type KeyTable = IORef [Key] - -newKeyTable :: IO KeyTable -newKeyTable = newIORef [] - -getKeys :: KeyTable -> IO [Key] -getKeys = readIORef - -insertIntoKeyTable :: KeyTable -> Key -> IO () -insertIntoKeyTable keyTab key = modifyIORef keyTab (key:) - -deleteFromKeyTable :: KeyTable -> Key -> IO () -deleteFromKeyTable keyTab key = modifyIORef keyTab (delete key) - ---------------------------------------------------------------------------- - -type KeyBinder = Key -> KeyEvent -> Maybe (IO ()) -> IO () - --- TODO: Improve type -type BindingTable = IORef [((Key,KeyEvent), IO ())] - -newBindingTable :: IO BindingTable -newBindingTable = newIORef [] - -bindKey :: BindingTable -> KeyBinder -bindKey bindingTable key event Nothing = - modifyIORef bindingTable (\t -> [ e | e@(b,a) <- t, b /= (key, event)]) -bindKey bindingTable key event (Just action) = do - bindKey bindingTable key event Nothing - modifyIORef bindingTable (((key, event), action) :) - -execAction :: BindingTable -> Key -> KeyEvent -> IO () -execAction bindingTable key event = - readIORef bindingTable >>= (maybe (return ()) id . lookup (key, event)) - ---------------------------------------------------------------------------- - -type StillDownHandler = IO () - -stillDown :: BindingTable -> KeyTable -> StillDownHandler -stillDown bindingTable pressedKeys = - getKeys pressedKeys >>= mapM_ (\k -> execAction bindingTable k StillDown) - ---------------------------------------------------------------------------- - -initUserInput :: IO (KeyBinder, StillDownHandler) -initUserInput = do - -- Using "setKeyRepeat KeyRepeatOff" would be a little bit more - -- efficient, but has two disadvantages: It is not yet implemented - -- for M$ and it changes the global state of X11. - globalKeyRepeat $= GlobalKeyRepeatOff - bindingTable <- newBindingTable - pressedKeys <- newKeyTable - let keyPress k = do insertIntoKeyTable pressedKeys k - execAction bindingTable k Press - keyRelease k = do deleteFromKeyTable pressedKeys k - execAction bindingTable k Release - keyboardMouse k Down _ _ = keyPress k - keyboardMouse k Up _ _ = keyRelease k - keyboardMouseCallback $= Just keyboardMouse - return (bindKey bindingTable, stillDown bindingTable pressedKeys) - -
+ Graphics/UI/GLUT/Input.hs view
@@ -0,0 +1,102 @@+{- | +GLUT-based keyboard/mouse handling. + +Sven Panne 2000 <Sven.Panne@informatik.uni-muenchen.de> + +This provides a "still down" event in addition to GLUT's key/mouse +button up/down events, and manages bindings from input events to actions. + +-} + +module Graphics.UI.GLUT.Input ( + Key(..), KeyEvent(..), KeyBinder, InputHandler, StillDownHandler, initGLUTInput +) where + +import Data.IORef(IORef, newIORef, readIORef, modifyIORef) +import Data.List(deleteBy) +import Graphics.UI.GLUT + +--------------------------------------------------------------------------- + +data KeyEvent = Press | StillDown | Release deriving Eq + +--------------------------------------------------------------------------- + +-- | A mutable list of keys (or mouse buttons), along with modifier +-- state and mouse position. +type KeyTable = IORef [(Key, Modifiers, Position)] + +newKeyTable :: IO KeyTable +newKeyTable = newIORef [] + +getKeys :: KeyTable -> IO [(Key, Modifiers, Position)] +getKeys = readIORef + +insertIntoKeyTable :: KeyTable -> Key -> Modifiers -> Position -> IO () +insertIntoKeyTable keyTab key mods pos = modifyIORef keyTab ((key,mods,pos):) + +deleteFromKeyTable :: KeyTable -> Key -> IO () +deleteFromKeyTable keyTab key = modifyIORef keyTab (deleteBy (\(k,_,_) (l,_,_) -> k==l) (key, nullmods, nullpos)) + where nullmods = Modifiers Up Up Up + nullpos = Position 0 0 + +--------------------------------------------------------------------------- + +type InputHandler = Modifiers -> Position -> IO () + +type KeyBinder = Key -> KeyEvent -> Maybe InputHandler -> IO () + +-- TODO: Improve type + +-- | A mutable list of mappings from key/mousebutton up/down/stilldown +-- events to IO actions. +type BindingTable = IORef [((Key,KeyEvent), InputHandler)] + +newBindingTable :: IO BindingTable +newBindingTable = newIORef [] + +bindKey :: BindingTable -> KeyBinder +bindKey bindingTable key event Nothing = + modifyIORef bindingTable (\t -> [ e | e@(b,a) <- t, b /= (key, event)]) +bindKey bindingTable key event (Just action) = do + bindKey bindingTable key event Nothing + modifyIORef bindingTable (((key, event), action) :) + +execAction :: BindingTable -> Key -> KeyEvent -> Modifiers -> Position -> IO () +execAction bindingTable key event mods pos = + readIORef bindingTable >>= (maybe (return ()) (\a -> a mods pos) . lookup (key, event)) + +--------------------------------------------------------------------------- + +type StillDownHandler = IO () + +stillDown :: BindingTable -> KeyTable -> StillDownHandler +stillDown bindingTable pressedKeys = + getKeys pressedKeys >>= mapM_ (\(k,mods,pos) -> execAction bindingTable k StillDown mods pos) + +--------------------------------------------------------------------------- + +-- | Initialise the input system, which keeps a list of input event to +-- action bindings and executes the the proper actions automatically. +-- Returns a function for adding bindings, and another which should be +-- called periodically (eg from refresh) to trigger still-down actions. +initGLUTInput :: IO (KeyBinder, StillDownHandler) +initGLUTInput = do + -- Using "setKeyRepeat KeyRepeatOff" would be a little bit more + -- efficient, but has two disadvantages: It is not yet implemented + -- for M$ and it changes the global state of X11. + globalKeyRepeat $= GlobalKeyRepeatOff + bindingTable <- newBindingTable + pressedKeys <- newKeyTable + let keyPress k mods pos = do + insertIntoKeyTable pressedKeys k mods pos + execAction bindingTable k Press mods pos + keyRelease k mods pos = do + deleteFromKeyTable pressedKeys k + execAction bindingTable k Release mods pos + keyboardMouse k Down mods pos = keyPress k mods pos + keyboardMouse k Up mods pos = keyRelease k mods pos + keyboardMouseCallback $= Just keyboardMouse + return (bindKey bindingTable, stillDown bindingTable pressedKeys) + +
LICENSE view
@@ -1,6 +1,6 @@ Copyright (C) 2002 Andre Furtado <awbf@cin.ufpe.br> Copyright (C) 2008 Miloslav Raus <666wman@gmail.com>-Copyright (C) 2008,2011 Simon Michael <simon@joyful.com>+Copyright (C) 2008,2011-2013 Simon Michael <simon@joyful.com> All rights reserved.
README.md view
@@ -1,143 +1,175 @@-# FunGEN - Functional Game Engine - -FunGEn (Functional Game Engine) is a BSD-licensed 2D platform-independent -game engine implemented in and for Haskell, using HOpenGL. It is intended -to help game programmers in the game development process, in a faster and -automated way. Actually, FunGEn supports: - -- Initialization, updating, removing, rendering and grouping routines for game objects; -- Definition of a game background (or map), including texture-based maps and tile maps; -- Reading and intepretation of the player's keyboard input; -- Collision detection; -- Time-based functions and pre-defined game actions; -- Loading and displaying of 24-bit bitmap files; -- Debugging and game performance evaluation facilities; -- Sound support (actually for windows platforms only... :-[ ); -- Hope to expand this list soon :-] - -This README includes most of the docs from the original site, lightly updated. -There is also a [tutorial](TUTORIAL.html). - -Original home: [http://www.cin.ufpe.br/\~haskell/fungen](http://www.cin.ufpe.br/\~haskell/fungen) - -Latest code: [http://darcsden.com/simon/fungen](http://darcsden.com/simon/fungen) - -Latest haddock: [http://joyful.com/repos/fungen/dist/doc/html/FunGEn/](http://joyful.com/repos/fungen/dist/doc/html/fungen/) - -Hackage: [http://hackage.haskell.org/package/FunGEn](http://hackage.haskell.org/package/FunGEn) - -Copyright: [LICENSE](./LICENSE) - -## History - -* Cabalised ghc 6.12-compatible 0.3 released on darcsden & hackage by Simon Michael (2011/02) - -* Cabalised ghc 6.10-compatible 0.1 released on hackage by Miloslav Raus (2008/09) - - *Tested under Win32 & Linux/Intel. Known glitches: Flickering under - linux (at least on my shitty laptop). Weird pong paddle behavior under - Win32.* - -* Repo-ised ghc 6.8-compatible update by Simon Michael (2008/02) - -* 0.1 released by Andre Furtado (2002) - - *Current Status:Some feedback indicated that the first version of - FunGEn was not as "functional" as it was desired: some game issues - were still being dealt through an imperative fashion. This way, the - authors of this project decided to change the game engine philosophy: - programmers should describe a game as a set of "specifications" rather - than defining its behavior imperatively. One plausible alternative for - accomplishing this task is porting the Clean Game Library (CGL) to - Haskell, adding some FunGEn specific features. Hence, this is the - actual status of the FunGEn project: it is being rebuilt in order to - provide game programming mechanisms following the CGL concepts. This - really demands some time, but the authors expect a new version to be - released soon.* - - *FunGEn v1.0 can be downloaded here. (PLEASE NOTE: this is the very - first version of FunGEn, and it was released just to get some feedback - from game programmers. You are strongly invited to tell your game - programming experiences with FunGEn, helping us to release a - definitive, stable version). Ok, after this disclaimer, please fell - yourself free to take a quick tour in the site; it contains a lot of - useful information for those who are really interested in trying a new - game programming experience. Nice coding...* - -## Credits - -FunGEn was created by a Computation Science graduation student, at the -Informatics Center (CIn) of the Federal University of Pernambuco (UFPE), -as part of a Scientific Iniciation (PIBIC/CNPq) research project (Creating -a Game Platform Using Haskell), oriented by lecturer Andre Santos (PhD, -1995, University of Glasgow). He was responsible for figuring out a lot of -FunGEn implementation details. - -I would like to thank also the following people who contributed for the development of FunGEn: - -- Sven Panne -- Jay Cox -- Geber Ramalho -- Carlos Andre Pessoa -- Charles Madeira -- Monique Monteiro -- The people at the Haskell mailing lists - -FunGEn can be distributed freely, in the hope that it will be useful, but -WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY -or FITNESS FOR A PARTICULAR PURPOSE. I would thank you if you cite my name -and this site if you are going to use FunGEn for other things besides home -programming. - -## To do - -Andre's 2002 list: - -Here you have a list of some upcoming FunGEn features, and some other -desired features (but with no implementation prevision yet). - -- Support map scrolling (coming soon); -- Support mouse input management (coming soon); -- Make a polygon map definition avaiable (coming soon); -- Make sound avaible to non-Win32 platforms; -- Create, if possible, some operators to avoid the excessive (x <- ...) syntax; -- Support auto-animated objects; -- Create a GLUT independent font support (or perhaps extend it); -- Improve the installation process; -- Upgrade FunGEn to be both a 2D (bidimensional) and 2D 1/2 (bi and a half dimensional) engine; -- Create a map editor/generator (possibly in other language, or using the brand new Haskell GUI...); -- Take courage to start thinking about the 3D world... - -Would you like to suggest a feature? Feel free to do it. Would you like to -implement a feature? Please do it! Keep in touch. - -## FAQ - -**What is a game engine?** - -A game engine can be considered as a library that provides game facilities -to a game programmer. When using a game engine, the programmer must -specify when the game events happen, rather than how they are -implemented. A same functionality may have its implementation varying from -platform to platform, in the case the engine is platform-independent. The -main advantage of a game engine is that it can be reused to the -development of many different kind of games, in an automated way, saving a -lot of programming time. - -**Why Haskell?** - -We believe that Haskell is a great language to develop games, because of -its high level of abstraction and the generation of a more concise, -elegant and shorter code. This is great for code maintenance and -understanding. Combining the power of Haskell with the facilities provided -by game engines seems a promising project. You can find more info on -Haskell in its official site. - -**What is HOpenGL?** - -HOpenGL stands for Haskell Open Graphics Library. Actually, it is a -binding to one of the most famous graphics libraries around the world -(OpenGL) and its auxiliary toolkit (GLUT). In other words, it makes -possible to call OpenGL/GLUT routines (which were written in the C -language) when programming in Haskell. You can find more info on HOpenGL -in my HOpenGL Tutorial site, or in its official site. +<style>+.a {+ font-weight:bold;+ color:red;+ font-size:200%;+}+.b {+ font-weight:normal;+ color:#bbb;+ font-size:smaller;+}+</style>++# <span class="a">Fun<span class="b">ctional</span> G<span class="b">ame</span> En<span class="b">gine</span></span>++FunGEn (Functional Game Engine) is a cross-platform, BSD-licensed,+OpenGL-based 2D game engine written in Haskell. It is intended to help+game programmers make games in a faster and more automated way. FunGEn+supports:++- Initialization, updating, removing, rendering and grouping routines for game objects;+- Definition of a game background (or map), including texture-based maps and tile maps;+- Reading and intepretation of the player's keyboard input;+- Collision detection;+- Time-based functions and pre-defined game actions;+- Loading and displaying of 24-bit bitmap files;+- Debugging and game performance evaluation facilities;+- Sound support (actually for windows platforms only... :-[ );+- Hope to expand this list soon :-]++Home: [http://joyful.com/fungen](http://joyful.com/fungen) +Docs: [Original docs](old-site/index.html), moved here from the [old site](http://www.cin.ufpe.br/~haskell/fungen). <!-- Another version of the [pong tutorial](TUTORIAL.html). --> A [video of the worms demo](http://www.youtube.com/watch?v=XRG9H0oC2Fw). +Hackage & API docs: [http://hackage.haskell.org/package/FunGEn](http://hackage.haskell.org/package/FunGEn) +Latest code: [http://hub.darcs.net/simon/fungen](http://hub.darcs.net/simon/fungen) +Discussion & help: [#haskell-game](irc://irc.freenode.net/#haskell-game) or [haskell-cafe](http://www.haskell.org/haskellwiki/Mailing_lists) ++## Getting started++ cabal install FunGEn++## FAQ++**What is a game engine?**++A game engine can be considered as a library that provides game facilities+to a game programmer. When using a game engine, the programmer must+specify when the game events happen, rather than how they are+implemented. A same functionality may have its implementation varying from+platform to platform, in the case the engine is platform-independent. The+main advantage of a game engine is that it can be reused to the+development of many different kind of games, in an automated way, saving a+lot of programming time.++**Why Haskell?**++We believe that Haskell is a great language to develop games, because of+its high level of abstraction and the generation of a more concise,+elegant and shorter code. This is great for code maintenance and+understanding. Combining the power of Haskell with the facilities provided+by game engines seems a promising project. You can find more info on+Haskell in its official site.++**What is HOpenGL?**++HOpenGL stands for Haskell Open Graphics Library. Actually, it is a+binding to one of the most famous graphics libraries around the world+(OpenGL) and its auxiliary toolkit (GLUT). In other words, it makes+possible to call OpenGL/GLUT routines (which were written in the C+language) when programming in Haskell. You can find more info on HOpenGL+in my HOpenGL Tutorial site, or in its official site.++## Release notes++### 0.4 (2013/08/05)++* a new hakyll-based website, incorporating the old site+* input handlers now receive mouse position and modifier state+ (inspired by Pradeep Kumar). See fungentest.hs for examples.+* more haddocks++### 0.3 (2011/02/13)+GHC 6.12-compatible 0.3 [released](http://thread.gmane.org/gmane.comp.lang.haskell.cafe/86330) on darcsden & hackage by Simon Michael:++- updated for GHC 6.12 & base 4+- module names simplified+- beginning of haddockification+- docs moved into repo+- published to darcsden, hackage, wiki, haskell-cafe, #haskell-game, reddit++### 0.1-hackage (2008/09/17)+GHC 6.10-compatible 0.1 released on hackage by Miloslav Raus:++- updated for GHC 6.10+- cabalised+- Tested under Win32 & Linux/Intel. Known glitches: Flickering under linux+ (at least on my shitty laptop). Weird pong paddle behavior under Win32.++### GHC 6.8 update (2008/02/26)+GHC 6.8-compatible update by Simon Michael:++- updated for GHC 6.8+- slight tweaks to examples+- public darcs repo++### 0.1 (2002)+First public release by Andre Furtado:++- FunGEn v1.0 can be downloaded here. (PLEASE NOTE: this is the very first+ version of FunGEn, and it was released just to get some feedback from+ game programmers. You are strongly invited to tell your game programming+ experiences with FunGEn, helping us to release a definitive, stable+ version). Ok, after this disclaimer, please fell yourself free to take a+ quick tour in the site; it contains a lot of useful information for+ those who are really interested in trying a new game programming+ experience. Nice coding...++- Current Status: Some feedback indicated that the first version of FunGEn+ was not as "functional" as it was desired: some game issues were still+ being dealt through an imperative fashion. This way, the authors of this+ project decided to change the game engine philosophy: programmers should+ describe a game as a set of "specifications" rather than defining its+ behavior imperatively. One plausible alternative for accomplishing this+ task is porting the Clean Game Library (CGL) to Haskell, adding some+ FunGEn specific features. Hence, this is the actual status of the FunGEn+ project: it is being rebuilt in order to provide game programming+ mechanisms following the CGL concepts. This really demands some time,+ but the authors expect a new version to be released soon.++## Contributing++Andre's 2002 todo list:++Here you have a list of some upcoming FunGEn features, and some other+desired features (but with no implementation prevision yet).++- Support map scrolling (coming soon);+- Support mouse input management (coming soon);+- Make a polygon map definition avaiable (coming soon);+- Make sound avaible to non-Win32 platforms;+- Create, if possible, some operators to avoid the excessive (x <- ...) syntax;+- Support auto-animated objects;+- Create a GLUT independent font support (or perhaps extend it);+- Improve the installation process;+- Upgrade FunGEn to be both a 2D (bidimensional) and 2D 1/2 (bi and a half dimensional) engine;+- Create a map editor/generator (possibly in other language, or using the brand new Haskell GUI...);+- Take courage to start thinking about the 3D world...++Would you like to suggest a feature? Feel free to do it. Would you like to+implement a feature? Please do it! Keep in touch.++## Credits++FunGEn was created by Andre Furtado, Computation Science graduation+student at the Informatics Center (CIn) of the Federal University of+Pernambuco (UFPE), as part of a Scientific Iniciation (PIBIC/CNPq)+research project (Creating a Game Platform Using Haskell), oriented by+lecturer Andre Santos (PhD, 1995, University of Glasgow), who was+responsible for figuring out a lot of FunGEn implementation details.++I would like to thank also the following people who contributed for the development of FunGEn:++- Sven Panne+- Jay Cox+- Geber Ramalho+- Carlos Andre Pessoa+- Charles Madeira+- Monique Monteiro+- The people at the Haskell mailing lists++FunGEn can be distributed freely, in the hope that it will be useful, but+WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY+or FITNESS FOR A PARTICULAR PURPOSE. I would thank you if you cite my name+and this site if you are going to use FunGEn for other things besides home+programming.+
examples/pong/pong.hs view
@@ -17,9 +17,6 @@ data GameAttribute = Score Int -type PongObject = GameObject () -type PongAction a = IOGame GameAttribute () () () a - width = 400 height = 400 w = fromIntegral width :: GLdouble @@ -33,23 +30,23 @@ bar = objectGroup "barGroup" [createBar] ball = objectGroup "ballGroup" [createBall] initScore = Score 0 - input = [(SpecialKey KeyRight, StillDown, moveBarToRight), - (SpecialKey KeyLeft, StillDown, moveBarToLeft)] - + input = [(SpecialKey KeyRight, StillDown, moveBarToRight) + ,(SpecialKey KeyLeft, StillDown, moveBarToLeft) + ] funInit winConfig gameMap [bar,ball] () initScore input gameCycle (Timer 30) bmpList -createBall :: PongObject +createBall :: GameObject () createBall = let ballPic = Basic (Circle 6.0 0.0 1.0 0.0 Filled) in object "ball" ballPic False (w/2,h/2) (-8,8) () -createBar :: PongObject +createBar :: GameObject () createBar = let barBound = [(-25,-6),(25,-6),(25,6),(-25,6)] barPic = Basic (Polyg barBound 1.0 1.0 1.0 Filled) in object "bar" barPic False (w/2,30) (0,0) () -moveBarToRight :: PongAction () -moveBarToRight = do +moveBarToRight :: Modifiers -> Position -> IOGame GameAttribute () () () () +moveBarToRight mods pos = do obj <- findObject "bar" "barGroup" (pX,pY) <- getObjectPosition obj (sX,_) <- getObjectSize obj @@ -57,8 +54,8 @@ then (setObjectPosition ((pX + 5),pY) obj) else (setObjectPosition ((w - (sX/2)),pY) obj) -moveBarToLeft :: PongAction () -moveBarToLeft = do +moveBarToLeft :: Modifiers -> Position -> IOGame GameAttribute () () () () +moveBarToLeft mods pos = do obj <- findObject "bar" "barGroup" (pX,pY) <- getObjectPosition obj (sX,_) <- getObjectSize obj @@ -66,7 +63,7 @@ then (setObjectPosition ((pX - 5),pY) obj) else (setObjectPosition (sX/2,pY) obj) -gameCycle :: PongAction () +gameCycle :: IOGame GameAttribute () () () () gameCycle = do (Score n) <- getGameAttribute printOnScreen (show n) TimesRoman24 (0,0) 1.0 1.0 1.0
examples/worms/worms.hs view
@@ -124,26 +124,26 @@ | (tMin > tMax) = [] | otherwise = (object ("tail" ++ (show tMin)) pic True (0,0) (0,0) (Tail 0)):(createAsleepTails (tMin + 1) tMax pic) -turnLeft :: WormsAction () -turnLeft = do +turnLeft :: Modifiers -> Position -> WormsAction () +turnLeft _ _ = do snakeHead <- findObject "head" "head" setObjectCurrentPicture 8 snakeHead setObjectSpeed (-speedMod,0) snakeHead -turnRight :: WormsAction () -turnRight = do +turnRight :: Modifiers -> Position -> WormsAction () +turnRight _ _ = do snakeHead <- findObject "head" "head" setObjectCurrentPicture 7 snakeHead setObjectSpeed (speedMod,0) snakeHead -turnUp :: WormsAction () -turnUp = do +turnUp :: Modifiers -> Position -> WormsAction () +turnUp _ _ = do snakeHead <- findObject "head" "head" setObjectCurrentPicture 5 snakeHead setObjectSpeed (0,speedMod) snakeHead -turnDown :: WormsAction () -turnDown = do +turnDown :: Modifiers -> Position -> WormsAction () +turnDown _ _ = do snakeHead <- findObject "head" "head" setObjectCurrentPicture 6 snakeHead setObjectSpeed (0,-speedMod) snakeHead