6

Gloss ライブラリを使用して Haskell で倉庫番プログラムを作成しています。プレーヤーがレベルを破ったときに、テキスト ファイルから新しいレベルをロードして、プログラムを続行させたいところまで来ています。 .

Gloss の制限により、これに少し苦労していplayます。ゲームをセットアップして継続的に更新する機能は次のようになります。

play    :: forall world
        .  Display                      -- ^ Display mode.
        -> Color                        -- ^ Background color.
        -> Int                          -- ^ Number of simulation steps to take for each second of real time.
        -> world                        -- ^ The initial world.
        -> (world -> Picture)           -- ^ A function to convert the world a picture.
        -> (Event -> world -> world)    -- ^ A function to handle input events.
        -> (Float -> world -> world)    -- ^ A function to step the world one iteration.
                                        --   It is passed the period of time (in seconds) needing to be advanced.
        -> IO ()

( http://hackage.haskell.org/packages/archive/gloss/1.7.4.1/doc/html/Graphics-Gloss-Interface-Pure-Game.htmlから直接コピー)

world私が使用しているタイプは次のとおりです。

data Game = Game
  { levelNumber  :: Int,
    currentLevel :: Level Square,
    won          :: Bool }

ここで、Levels には現在のレベルのブロックが含まれます。私はGame次のようなものを使用して s を読んでいます(実際にはまだ一般化されたものは作成していませんが、ファイル名引数を使用する場合は基本的にこれだけです):

startGame = do
  lvl <- readFile "levels/level001.lvl"
  let lvl' = parseLevel lvl
  return $ Game 1 lvl' False

の更新機能が原因で、私の困難が生じていplayます。単一のレベルで操作している場合は、ファイル システムからデータを読み取る必要なく、簡単に を取得して(およびなど) をGame生成できます。ゲーム、私は自分の sをすべて s にするのを避ける方法がわかりません。おそらく、これはこの状況では不可能であり、それには正当な理由があるのでしょうか? 私常にファイルからプルされたものを操作しますが、それがいつでも回避できるかどうかはわかりません。回避できる場合は、避けたいと思います。PictureGameGameIO GameGame

4

1 に答える 1

3

Graphics.Gloss.Interface.IO.Gameの Gloss を使用することになりましplayIOた。いくつかの関数を変更して、純粋なデータ型を操作し、それらをモナドにラップして出力する必要がありました。変更しなければならなかったタイプは次のとおりです。IO

worldToPicture :: World -> IO Picture
eventHandler   :: Event -> World -> IO Picture
stepWorld      :: Float -> World -> IO World 

ほとんどの場合、これはreturn既存の関数にいくつかの を追加するだけでしたが、多くの機能を追加することになりました (オンザフライでの保存、新しいレベルのロード、グラフィックス用の BMP ファイルの使用など)。IOまた、新しい関数はまだ純粋なデータ型をパラメーターとして使用していたため、現在の既存のコードのほとんどすべてを自由に保つことができました。それは本当に簡単なリファクタリングになり、私の問題を完全に解決しました。

于 2013-04-03T02:47:20.900 に答える