http://pastebin.com/2CS1k1Zq如何獲得輸入遊戲循環在Haskell
在這場比賽中我需要得到步驟遊戲前進的每半秒左右,而偶爾讓輸入改變方向。這些與Haskell似乎無法做到的事情有沒有辦法做到?目前我有一個mv tread stall異常。
http://pastebin.com/2CS1k1Zq如何獲得輸入遊戲循環在Haskell
在這場比賽中我需要得到步驟遊戲前進的每半秒左右,而偶爾讓輸入改變方向。這些與Haskell似乎無法做到的事情有沒有辦法做到?目前我有一個mv tread stall異常。
更新:在System.IO
中找到hWaitForInput
函數,它與waitFor
基本相同。
以下是一些很大程度上基於this answer的代碼。
我所做的主要區別是等待按鍵的線程不直接執行getChar
。在MVar
中傳達的結果表示超時或按鍵已經發生。實際獲得角色是主線程的責任。這樣可以防止在讀取字符並將其放入MVar
之間而導致char讀取線程中斷的情況下出現可能的競爭情況。
import Control.Concurrent
import Control.Monad
import Data.Maybe
import System.IO
import Control.Exception
data Event = CharReady | TimedOut
withRawStdin :: IO a -> IO a
withRawStdin = bracket uncook restore . const
where
uncook = do
oldBuffering <- hGetBuffering stdin
oldEcho <- hGetEcho stdin
hSetBuffering stdin NoBuffering
hSetEcho stdin False
return (oldBuffering, oldEcho)
restore (oldBuffering, oldEcho) = do
hSetBuffering stdin oldBuffering
hSetEcho stdin oldEcho
waitFor :: Int -> IO Event
waitFor delay = do
done <- newEmptyMVar
withRawStdin . bracket (start done) cleanUp $ \_ -> takeMVar done
where
start done = do
t1 <- forkIO $ hLookAhead stdin >> putMVar done CharReady
t2 <- forkIO $ threadDelay delay >> putMVar done TimedOut
return (t1, t2)
cleanUp (t1, t2) = do
killThread t1
killThread t2
loop state = do
if state <= 0
then putStrLn "Game over."
else do putStrLn $ "Rounds to go: " ++ show state
e <- waitFor 3000000
case e of
TimedOut -> do putStrLn "Too late!"; loop state
CharReady -> do c <- getChar -- should not block
if c == 'x'
then do putStrLn "Good job!"; loop (state-1)
else do putStrLn "Wrong key"; loop state
main = loop 3
的[我怎樣寫在Haskell遊戲循環?(
Haskell新手在這裏,這幫助了我,謝謝。我嘗試使用hWaitForInput,但getChar變成阻塞,然後,不知道爲什麼。 – 2017-01-06 18:27:10
可能重複http://stackoverflow.com/questions/19285691/how-do-i-write-a-game-loop-in- haskell) – 2014-11-21 16:43:06
不,因爲我理解如何製作gameloop的基礎知識,我不明白的是你如何延遲你的遊戲或使其及時步入。還有如何獲得輸入。 – 2014-11-21 16:54:16
你可能需要一個觀察者來檢查關鍵字。如何做到這一點取決於你的平臺,你可能需要做一些「FFI-ing」。一旦被覆蓋了,你的實際遊戲循環看起來就像是一個標準的Haskell遊戲循環。爲了使它可以播放,不要忘記延遲渲染部分(例如,使線程在遊戲步驟之間休眠,但要確保仍然可以輸入!)。如果你可以提到你的平臺,甚至標記它,這將是有益的(特別是因爲這似乎是一個控制檯遊戲)。 – MasterMastic 2014-11-21 17:10:39