The data model in my program has a number of discrete states, but I want to animate the transition between these states. While the animation is going on, what the user sees on the screen is disconnected from what the underlying data is like. Once the animation is complete, they match up again.
For example, let's say we have a simple game where Snuffles the bunny hops around on a 2D grid. The model of Snuffles contains integer x/y coordinates. When the player tells Snuffles to hop north, his y-coordinate is decremented by one immediately. However, on the screen, Snuffles should at that point still be in his old location. Then, frame by frame, Snuffles proceeds to hop over to his new location, until he is shown in the location his model states.
So usually, when we draw Snuffles, we can just look up his coordinates in his model. But when he's hopping, that coordinate is wrong.
If there is only ever one thing moving on the screen, I can just about get away with freezing the entire game state and not allowing the user to do anything until Snuffles has finished hopping. But what if there is more than one bunny on the screen?
It gets worse if elements interact, merge or split. If Snuffles magically merges with a hat to become a potato, at which point does the data model delete the bunny and the hat, and add the potato? If it does so immediately, the view instantly loses access to information about Snuffles and the potato which it still needs to draw the animation of the magical merger.
I have come across this problem multiple times while implementing animated GUIs, especially games, and have found no satisfactory solution.
Unsatisfactory ones include:
Do the changes immediately, but then suspend any further changes in the model until the animation has resolved. Makes things unresponsive and doesn't work if more than one thing can move or things interact in complex ways.
Merge the model and the view - Snuffles gains floating-point coordinates, and probably a z-coordinate to indicate how far up he is. The model's rules become massively more complex as a result, as the model can no longer make concise statements like "you cannot hop north if there is a wall at (x, y - 1)". Any change to the rules takes much longer, and development slows to a crawl.
Keep what amounts to a duplicate of the data in the view. SnufflesModel has integer coordinates, but SnufflesSprite has floating-point ones. End up duplicating some of the model rules in the view and having to keep them in sync. Spend lots of time debugging to make sure that SnufflesModel and SnufflesSprite don't de-sync under some rare circumstance.
My best bet at the moment is option 3, but it hardly strikes me as elegant. Thoughts?