什么是Haskell中典型的游戏骨架

时间:2014-09-30 11:47:56

标签: haskell 2d-games

Haskell游戏的典型游戏骨架是什么,让我们说一个简单的射击游戏?   对于不变性问题,我对数据结构以及如何管理世界上所有元素的更新特别感兴趣。   只是说那个

  new_world=update_world(world)

有点过分简单。例如,如何处理世界元素之间可能发生的多种交互(碰撞,对玩家的反应等),尤其是当你有很多“独立”元素受到影响时。

主要关注的是世界的不变性,这使得根据世界的另一个子集更新世界的“小”部分非常困难。

1 个答案:

答案 0 :(得分:4)

我喜欢glossgloss 2D库。它非常接近您的需求(我认为)

一个非常简单的例子

import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game

-- Your app data
data App = App { mouseX :: Float
               , mouseY :: Float
               }

-- Draw world using your app data
      -- Here thing about *draw* your world (e.g. if radius > MAX then red else blue)
drawWorld (App mousex mousey) = color white $ circle mousex

-- Handle input events and update your app data
      -- Here thing about user interaction (e.g. when press button start jump!)
handleEvent
    (EventMotion (x, y)) -- current viewport mouse coordinates
    (App _ _) = App x y
handleEvent e w = w


-- Without input events you can update your world by time
     -- Here thing about time (e.g. if jumping use `t` to compute new position)
handleTime t w = w

runApp =
    play
        ( InWindow "Test" (300, 300) (0, 0) ) -- full screen or in window
        black                                 -- background color
        20                                    -- frames per second
        ( App 0 0 )                           -- your initial world
        drawWorld                             -- how to draw the world?
        handleEvent                           -- how app data is updated when IO events?
        handleTime                            -- how app data is updated along the time?

-- enjoy!
main = runApp

沿着三个事件处理程序(绘图,输入和时间)修改一些数据结构(圆半径列表)的一个简单示例

import Graphics.Gloss
import Graphics.Gloss.Interface.Pure.Game
import System.IO.Unsafe

data App = App { mouseX :: Float
               , mouseY :: Float
               , circleList :: [Float]
               , lastTime :: Float
               , currTime :: Float
               }

drawWorld app =
    color white $ pictures $ map circle $ circleList app

handleEvent
    (EventMotion (x, y)) -- current viewport mouse coordinates
    app = app { mouseX = x, mouseY = y,
                -- drop circles with radius > mouse **MOVED** position
                circleList = filter (<(abs x)) $ circleList app }
handleEvent e app = app

handleTime t app =
    app { currTime = currTime', lastTime = lastTime', circleList = circleList' }
    where currTime' = currTime app + t
          -- create new circle each 1 second
          createNew = currTime' - lastTime app > 1
          lastTime' = if createNew then currTime' else lastTime app
          -- each step, increase all circle radius
          circleList' = (if createNew then [0] else []) ++ map (+0.5) (circleList app)

runApp =
    play
        ( InWindow "Test" (300, 300) (0, 0) )
        black
        20
        ( App 0 0 [] 0 0 )
        drawWorld
        handleEvent
        handleTime

main = runApp

结果

enter image description here