Haskell中典型的游戏框架是什么? [英] What would be a typical game skeleton in Haskell

查看:177
本文介绍了Haskell中典型的游戏框架是什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Haskell游戏的典型游戏骨架是什么?比如说简单的射击游戏?
我对数据结构特别感兴趣,并且关于 immutability 问题如何管理全球所有元素的更新。
只是说

  new_world = update_world(全球)

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

主要关心的是世界的不可变性,这使得基于世界的另一个子集很难更新世界的小部分。

解决方案

我爱 gloss

p>一个非常简单的例子

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

- 您的应用数据
data App = App {mouseX :: Float
,mouseY :: Float
}

- 绘制世界使用你的应用数据
- 这里关于*绘制*你的世界的事情(例如,如果radiu s> MAX then red else blue)
drawWorld(App mousex mousey)= color white $ circle mousex

- 处理输入事件并更新您的应用程序数据
- 此处关于用户交互的东西(例如)当前的视口鼠标坐标
(App _ _)= App xy
handleEvent ew = w


- 如果没有输入事件,您可以按时间更新您的世界
- 这里是关于时间的事情(例如,如果跳跃使用`t`来计算新位置)
句柄tw = w

runApp =
播放
(InWindowTest(300,300)(0,0)) - 全屏或窗口
黑色 - 背景颜色
每秒20帧 -
(应用程序0 0) - 您的初始世界
drawWorld - 如何绘制世界?
handleEvent - IO事件时如何更新应用程序数据?
handleTime - 应用程序数据如何随时间更新?

- 享受!
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)) - 当前视口鼠标坐标
app = app {mouseX = x,mouseY = y,
- 半径> mouse ** MOVED ** position
circleList = filter(<(abs x))$ circleList app}
handleEvent e app = app

handleTime t app =
app {currTime = currTime',lastTime = lastTime',circleList = circleList'}
其中currTime'= currTime app + t
- 每1秒创建一个新的循环
createNew = currTime' - lastTime应用程序> 1
lastTime'= if createNew then currTime'else lastTime app
- 每一步,增加所有圆半径
circleList'=(如果createNew then [0] else [])++ map (+0.5)(circleList app)

runApp =
play
(InWindowTest(300,300)(0,0))
black
20
(App 0 0 [] 0 0)
drawWorld
handleEvent
handleTime
$ b $ main = runApp

结果


What would be the typical game skeleton for a Haskell game, let's say a simple shoot them up for instance? I am particularly interested on the data structure, and how to manage the update of all the elements in the world, in regards of immutability issue. Just saying that

  new_world=update_world(world)

is a little bit simplistic. For instance, how to deal with multiple interaction that can occurs between element of the world (collisions, reaction to player, etc....) especially when you have a lot of 'independent' elements impacted.

The main concern is about immutability of the world, which makes very difficult to update a "small" part of the world based on another subset of the world.

解决方案

I love gloss (gloss 2D library. it's very closed to your needs (I think)

A very simple example

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

One simple example modifying some data structure (a list of circle radius) along the three event handlers (draw, input and time)

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

with result

这篇关于Haskell中典型的游戏框架是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆