Limestraël
unread,May 15, 2010, 7:19:10 AM5/15/10Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to reac...@haskell.org
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?