
Nathan Hüsken wrote:
Heinrich Apfelmus wrote:
In that light, the separation seems straightforward to me. Given the time-varying values that represent game objects,
bSpaceShipPosition :: Behavior Position bAsteroidPositions :: Behavior [Position] bTime :: Behavior Time
you can transform and combine them into a graphic, for instance like this
bSpaceShipPicture :: Behavior Graphic bSpaceShipPicture = blinkenLights <$> bTime <*> bSpaceShipPosition
bAsteroidPictures = map drawAsteroid <$> bAsteroidPositions
bPicture = overlay <$> ((:) <$> bSpaceShipPicture <*> bAsteroidPictures)
In other words, you just combine old time-varying values into new ones, much like you would combine combine graphical plots. Also note that you can add animation a posteriori; it doesn't have to be part of the values representing a space ship.
Yes, but these examples are extremely simple. The animation has no internal "state". What if every Asteroid also has a animation state (which I would want to add a posteriori) and can be destroyed. Than the connection between the asteroids "game logic" value, and "rendering" value needs some kind of bookkeeping to be maintained.
Fair enough, but I don't see how this can be fitted into a general pattern. If the animation "state" is coupled tightly to the game logic "state", then the question whether the animation is part of the game logic or not does not have a clear answer anymore. Hm. You mentioned that in an imperative setting, you would use something similar to the observer pattern. Judging from the wikipedia page http://en.wikipedia.org/wiki/Observer_pattern, it seems to me that this is just the Event type, though, so I don't understand how this helps with the problem at hand. Maybe discussing a concrete example could be very helpful. Could you give a minimal example that still contains the key difficulties? Maybe a collection of asteroids that float in space, can be added or removed with a button click and who are animated as rotating rocks, all starting in a certain position when they are created? How would you use the observer pattern in this case? Best regards, Heinrich Apfelmus -- http://apfelmus.nfshost.com