我在Purescript中使用purescript-signal构建游戏,其中包括移动。用户按左/右键向左/向右移动。最小代码如下。
看起来purescript正在评估从时间开始的信号""每走一步,都令我感到困惑。例如,如果我一直按下右键,则输出为
m: 0
m: 0
m: 1
m: 0
m: 1
m: 2
m: 0
m: 1
m: 2
m: 3
而不是
m: 0
m: 1
m: 2
m: 3
正如我所料,我该如何解决这个问题?
module SimpleMove where
import Prelude
import Control.Monad.Eff (Eff)
import Control.Monad.Eff.Console (CONSOLE, log)
import Data.Functor
import Data.Int
import Signal (Signal, runSignal, foldp, sampleOn, map2)
import Signal.DOM (keyPressed)
import Signal.Time (Time, second, every)
import Partial.Unsafe (unsafePartial)
--MODEL
type Model = Int
step :: forall e. Partial => Int -> Eff (console :: CONSOLE | e) Model -> Eff (console :: CONSOLE| e) Model
step dir m' =
do
m <- m'
log ("m: " <> (show m))
pure (m + dir)
--SIGNALS
inputDir :: Eff _ (Signal Int)
inputDir =
let
f = \l r -> if l
then -1
else if r
then 1
else 0
in
map2 f <$> (keyPressed 37) <*> (keyPressed 39)
input :: Eff _ (Signal Int)
input = sampleOn (every second) <$> inputDir
--MAIN
main :: Eff _ Unit
main =
unsafePartial do
dirSignal <- input
let game = foldp step (pure 0) dirSignal
runSignal (map void game)
答案 0 :(得分:3)
如果您更改main
和step
,我们会得到预期的结果:
main :: Eff _ Unit
main = do
dirSignal <- input
let game = foldp step 0 dirSignal
runSignal (map render game)
step :: forall e. Int -> Model -> Model
step dir m = m + dir
render :: forall e. Model -> Eff (console :: CONSOLE| e) Unit
render m = logShow m