标签: netwire

与 Netwire 一起使用时对 ArrowLoop 的误解

在这篇文章中出色的答案的引导下,我试图获得一个ArrowLoop不使用箭头表示法的工作示例。在我完全理解箭头在幕后的工作原理之前,我对使用箭头表示法感到不舒服。话虽这么说,我已经构建了一个小程序,基于我对 Arrows 的(有限)理解应该可以工作。然而,它最终以可怕的异常终止<<loop>>

module Main where

import Control.Wire
import FRP.Netwire

farr :: SimpleWire (Int, Float) (String, Float)
farr = let
  fn :: Int -> Float -> ((String, Float), SimpleWire (Int, Float) (String, Float))
  fn i f = (("f+i: " ++ (show (fromIntegral i + f)), f + 0.1), loopFn)

  loopFn :: SimpleWire (Int, Float) (String, Float)
  loopFn = mkSFN $ \(i, f) -> fn i f
  in
   mkSFN $ \(i, _) -> fn i 0.0 …
Run Code Online (Sandbox Code Playgroud)

haskell arrows frp netwire

5
推荐指数
1
解决办法
311
查看次数

正确使用Netwire(5)

我一直想给FRP一点时间,昨天我终于咬了一口,然后开始使用Netwire 5开始(这本身就是一个相当随意的选择,但我必须从某个地方开始!).我已经设法达到了"有效的代码"这一点,但我注意到了一些模式,我不确定它们是如何使用库的一部分,或者它们是否是我的症状.在某处做错了什么.

我从这个教程开始,这足以让我很容易地启动和运行 - 我现在有一个由简单的"递增数字"线控制的旋转立方体:

spin :: (HasTime t s, Monad m) => Wire s e m a GL.GLfloat
spin = integral 0 . 5
Run Code Online (Sandbox Code Playgroud)

当按下"Esc"时,应用程序将退出,使用netwire-input-glfw中提供的电线:

shouldQuit :: (Monoid e, Functor m, Monad m) => Wire s e (GLFWInputT m) a a
shouldQuit = keyPressed GLFW.Key'Escape
Run Code Online (Sandbox Code Playgroud)

这些之间的一个重要区别是spin永远不会抑制 - 它应该总是返回一些价值 - 同时一直shouldQuit抑制; 直到按键实际被按下,在这种情况下我退出了应用程序.

让我感到不安的是我最终不得不使用这些电线的方式.现在,它看起来像这样:

(wt', spinWire') <- stepWire spinWire st $ Right undefined
((qt', quitWire'), inp'') <- runStateT (stepWire quitWire st $ Right …
Run Code Online (Sandbox Code Playgroud)

haskell frp netwire

5
推荐指数
1
解决办法
234
查看次数

什么可以是用Haskell编写的游戏的最小例子?

三个月后更新

我在下面的回答中使用netwire-5.0.1+ sdl,在使用Arrows和Kleisli Arrows进行I/O的功能反应编程结构中.虽然太简单,不能被称为"游戏",但它应该是非常可组合的并且非常可扩展.

原版的

我正在学习Haskell,并尝试用它制作一个小游戏.但是,我想看看小型(规范)文本游戏的结构.我也尽量保持代码尽可能纯净.我现在正在努力了解如何实施:

  1. 主循环.这里有一个例子如何在Haskell中编写游戏循环?但似乎接受的答案不是尾递归.我不确定这是否重要.据我了解,内存使用量会增长,对吧?
  2. 国家转型.不过,我认为这与第一个问题非常相关.我试了一下State,在http://www.gamedev.net/page/resources/_/technical/game-programming/haskell-game-object-design-or-how-functions-can-get-you中试了一下-apples-r3204,但是虽然单个组件可以在有限的步骤中工作和更新,但我看不出如何在无限循环中使用它.

如果可能的话,我想看一个基本上最小的例子:

  1. 要求玩家反复输入内容
  2. 满足某些条件时,请更改状态
  3. 当满足其他一些意愿时,退出
  4. 理论上可以无限时间运行而不会破坏内存

我没有任何可用的代码,因为我无法获得最基本的东西.我在网上找到的任何其他材料/示例都使用其他一些库,比如SDLGTK驱动事件.我发现在Haskell中完全写的唯一一个是http://jpmoresmau.blogspot.com/2006/11/my-first-haskell-adventure-game.html,但是那个在主循环中看起来不像是一个尾递归(同样,我不知道这是否重要).

或者,可能Haskell不打算做这样的事情?或者我可能应该放入mainC?

编辑1

所以我在https://wiki.haskell.org/Simple_StateT_use中修改了一个小例子,使它更简单(并且它不符合我的标准):

module Main where
import Control.Monad.State

main = do 
  putStrLn "I'm thinking of a number between 1 and 100, can you guess it?"
  guesses <- execStateT (guessSession answer) 0
  putStrLn $ "Success in " ++ (show guesses) ++ " tries."
  where
    answer = …
Run Code Online (Sandbox Code Playgroud)

haskell arrows game-engine frp netwire

5
推荐指数
1
解决办法
1448
查看次数

Netwire - 如何构建能够产生位置,弹跳墙壁的电线?

使用netwire-4.0.7

正如问题标题所说,我正在尝试创建一条产生位置的导线(在每一步中以一定的速度移动位置),"弹跳"掉其他物体.我能想到的最简单的例子就是在一个盒子里移动,就像在一些屏幕保护程序中一样.

我写这个函数是为了做到这一点(仅针对一个轴):

import Control.Wire
bouncyWire :: Double -> Double -> Double -> Double -> Wire () IO a Double
bouncyWire startPosition startVelocity lowerBound upperBound = proc _ -> do
  rec
     v <- delay startVelocity -< if p < lowerBound || p > upperBound
                                    then -v else v
     p <- integral_ startPosition -< v
  returnA -< p
Run Code Online (Sandbox Code Playgroud)

(我实际上使用它与不同的monad,但这段代码实际上并没有使用它,这会使问题过于复杂).

counterSession $ 1/60然而,踩着它,我遇到了一个问题 - 而不是从墙上"弹跳",它会卡在那里.我认为发生的事情是它一直在翻转速度v,但我不知道为什么.我想我可能会使用延迟错误或其他东西.

haskell netwire

3
推荐指数
1
解决办法
241
查看次数

标签 统计

haskell ×4

netwire ×4

frp ×3

arrows ×2

game-engine ×1