当前位置: 首页 > 知识库问答 >
问题:

如何在纯Haskell中编写一个简单的实时游戏循环?

巴洲
2023-03-14

我刚开始使用Haskell,希望在不安装额外库的情况下制作一个简单的实时游戏。我需要写一个循环,扫描键盘输入,但如果没有输入,游戏也必须运行。我该怎么做?

共有1个答案

贡威
2023-03-14

随着我找到新的解决方案,这个答案正在更新

经过几个小时的学习,我想出了以下代码:

    {- Simple game loop example. -}

import System.IO
import System.Timeout

inputTimeout = 50000           -- in microseconds
initialGameState = 100    
type GameState = Int           -- change to your own gamestate type here

nextGameState :: GameState -> Char -> GameState
nextGameState previousGameState inputChar =

  -- REPLACE THIS FUNCTION WITH YOUR GAME

  case inputChar of
    's' -> previousGameState + 1
    'a' -> previousGameState - 1
    _   -> previousGameState

loop :: GameState -> IO ()            -- game loop
loop gameState =
  do
    putStrLn (show gameState)
    hFlush stdout

    c <- timeout inputTimeout getChar -- wait for input, with timeout

    case c of
      -- no input given
      Nothing -> do loop gameState

      -- quit on 'q'
      Just 'q' -> do putStrLn "quitting"                     

      -- input was given
      Just input -> do loop (nextGameState gameState input)

main = 
  do
    hSetBuffering stdin NoBuffering   -- to read char without [enter]
    hSetBuffering stdout (BlockBuffering (Just 80000))  -- to reduce flickering, you can change the constant
    hSetEcho stdout False             -- turn off writing to console with keyboard
    loop initialGameState

几点注意事项

  • 这(不是真的)一个游戏只是写出世界状态,这只是一个数字,然后用“s”或“a”递增/递减q’退出该计划

在以前的代码中,如果游戏nextGameState函数花费了大量时间来计算,输入字符将堆积在stdin中,程序的反应将被延迟。下面的代码通过始终读取输入的所有字符并只取最后一个来解决这个问题。

    {- Simple game loop example, v 2.0. -}

import System.IO
import Control.Concurrent

frameDelay = 10000             -- in microseconds
initialGameState = 100    
type GameState = Int           -- change to your own gamestate type here

nextGameState :: GameState -> Char -> GameState
nextGameState previousGameState inputChar =

  -- REPLACE THIS FUNCTION WITH YOUR GAME

  case inputChar of
    's' -> previousGameState + 1
    'a' -> previousGameState - 1
    _   -> previousGameState

getLastChar :: IO Char
getLastChar =
  do  
    isInput <- hWaitForInput stdin 1      -- wait for char for 1 ms

    if isInput
      then
        do
          c1 <- getChar
          c2 <- getLastChar

          if c2 == ' '
            then return c1
            else return c2

      else
        do
          return ' '

gameLoop :: GameState -> IO ()            -- game loop
gameLoop gameState =
  do
    threadDelay frameDelay
    putStrLn (show gameState)
    hFlush stdout

    c <- getLastChar

    case c of
      'x' -> do putStrLn "quitting"
      _   -> do gameLoop (nextGameState gameState c)

main = 
  do
    hSetBuffering stdin NoBuffering   -- to read char without [enter]
    hSetBuffering stdout (BlockBuffering (Just 80000))  -- to reduce flickering, you can change the constant
    hSetEcho stdout False             -- turn off writing to console with keyboard
    gameLoop initialGameState
 类似资料:
  • 我刚开始学习Haskell,但是现在没有循环是非常令人沮丧的。我想出了如何为函数编写循环。然而,我的问题是,我想在迭代循环时输出一些结果。似乎我必须使用debug来执行这个简单的任务。 所以现在我只想举一个例子,说明如何在主结构中打印字符串10次。 换句话说,我想这样做10次: 谢谢。我觉得这对我的任务很有启发。

  • 本文向大家介绍使用C++ MFC编写一个简单的五子棋游戏程序,包括了使用C++ MFC编写一个简单的五子棋游戏程序的使用技巧和注意事项,需要的朋友参考一下 MFC简介:   MFC(MicrosoftFoundationClasses)是微软基础类库的简称,是微软公司实现的一个c++类库,主要封装了大部分的windows API函数。 MFC除了是一个类库以外,还是一个框架,在vc++里新建一个M

  • 我正在创建一个骰子游戏,其中2个玩家有他们自己的骰子,每个人都有自己的轮到扔他的骰子,玩家可以完全失去分数或获得分数取决于他们站在窗口的位置,游戏结束时,任何一个玩家首先站在终点车道上,获胜者是得分最高的玩家,我已经在游戏的设计到目前为止,但还没有在逻辑上工作。 这个链接是游戏应该是什么样子的图片: 我想知道我如何才能添加球员1和球员2在每个瓷砖上面的照片,所以基本上每次当一个球员玩他的回合,我希

  • 本文向大家介绍用Python编写一个简单的俄罗斯方块游戏的教程,包括了用Python编写一个简单的俄罗斯方块游戏的教程的使用技巧和注意事项,需要的朋友参考一下 俄罗斯方块游戏,使用Python实现,总共有350+行代码,实现了俄罗斯方块游戏的基本功能,同时会记录所花费时间,消去的总行数,所得的总分,还包括一个排行榜,可以查看最高记录。 排行榜中包含一系列的统计功能,如单位时间消去的行数,单位时间得

  • 这是我为一个班级做的一个项目。我还是一个初学者,所以这个主题只应该涵盖到字符串、循环和数组。如果你对游戏不熟悉的话,进阶版就是这个。然而,我的任务是一个更简单的版本。以下是这个版本的规则。 程序开始时要求第一个玩家,即代码制造者,输入一个用于游戏的模式。图案长4个字母,每个字母代表一种颜色(R为红色,G为绿色)。 为了简化游戏,只有两种颜色可以使用,红色和绿色。因此,例如,用户可以输入RRGR来表

  • 问题内容: 我正在做一个简单的游戏,例如马里奥游戏,角色固定在一个位置,地面向左移动,给人一种角色移动的幻觉。地面由由左上角和右下角坐标定义的矩形块组成: 跳跃只是在向左移动表面的同时更改角色的y坐标,因此跳跃看起来像倒转的字母。 其余代码- 动画,移动精灵-与http://zetcode.com/tutorials/javagamestutorial/movingsprites/非常相似 我希望