[reactive] A pong and integrate
Limestraël
limestrael at gmail.com
Sat May 15 07:19:10 EDT 2010
Hello,
As a newbie with reactive, I'm trying to make a simple example, namely a
pong.
But I'm stuck with the paddle animation. Here is a how I proceed :
A paddle:
data Paddle = Paddle {
paddleCol :: Double,
paddleCenter :: Behavior Double }
The paddle moves along a column, so only it's Y coordinate changes.
paddleCenter is the Y coordinate of its center.
This is how I create a paddle:
data Direction = PaddleUp | PaddleDown | PaddleStill
deriving (Eq, Show)
newPaddle :: Behavior Direction -> Double -> Paddle
newPaddle direction column =
let
position = fmap ((initY ^+^)) $ integral *beat* $
fmap ((speed *) . factor) direction
factor PaddleUp = -1
factor PaddleDown = 1
factor _ = 0
speed = 50 -- pixels per second
initY = 400 -- suppose we have a 800x600 window: paddle is right at
the middle
*beat = atTimes [0, 0.01..]*
in Paddle column position
Basically, a paddle is driven by a behavior which tells him to go up, down
or to stand still.
My problem is with the tuning of the beat, a ticker event which is used for
the integration.
How do I have to think ?
- My speed is in pixels/second, so it has to tick every second? (atTime [0,
1..])
- My app will run at 60fps, so it has to tick 60 times per second? (atTime
[0, 1/60..])
The main program (I'm not using any graphics library, just getting keys ('u'
for up, 'd' for down) and displaying the current paddle pos)
makeKeyboardEvent = do
hSetBuffering stdin NoBuffering
hSetBuffering stdout NoBuffering
(buttonPressedSink, event) <- makeEvent =<< makeClock
forkIO . forever $
getChar >>= buttonPressedSink
return event
main = do
keyEvt <- makeKeyboardEvent
let
dirEvt = fmap key2dir keyEvt
paddle = newPaddle (stepper PaddleStill dirEvt) 50
adaptE $ fmap print $ snapshot_ (paddleCenter paddle) $ atTimes [0,
0.01..]
key2dir k = maybe PaddleStill snd $
find (($ k) . fst) [((== 'u'), PaddleUp),
((== 'd'), PaddleDown)]
When I launch the program, I hit 'u' or 'd' and I see the position
increase/decrease.
If the beat ticks every second, I see the position being increased by 50
every second, which is normal, but it's a too low refresh rate for an app
that is to run at 60fps.
But when I set my beat to tick every 60 times per second, the position is
well updated, but I clearly see that the display dramatically slows down
after a few seconds of execution. Too heavy rate for integrate?
That's why I'm asking: how should I use integrate?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/reactive/attachments/20100515/7f146ae5/attachment.html
More information about the Reactive
mailing list