There is a 2D game with a top view in the real-time RPG genre. The game is written in Java using the Swing library. It is planned to rewrite the part responsible for drawing using JOGL, as well as further transfer the game to Android.

Therefore, I tried to separate the logic from the presentation in such a way that in one place there was pure logic that knows nothing about that someone is going to draw it and in another place there was a display code that received the state of the model through getters and model data is drawn and how to do it. I managed to comply with this principle until it became necessary to animate images.

What was required of the animation: during the gameplay, I should have had the opportunity to pause the animation, resume it, change the playback speed, select an animation for an object depending on the state of its model, play not all the animation but only a part.

Where the problem occurred:

1.) It turned out that each object should store the current frame number, the number of frames for a given state, and the speed of animation playback for a given state. The frame number and playback speed are individual for each object. Therefore, the model began to store data related to the display.

2.) In some moments, the logic became dependent on animation, since Some actions can be performed only after the corresponding animation is played.

3.) Animation for each type of object is stored as a single image, which when you start the game is read and programmatically sliced. To perform the cutting, you need to know the size of the frame, which states of the object are animated, the number of frames for each such state, in what sequence in the image these states are depicted. Mapping is involved in this task, but some of the data it needs has become to store the model, while the model object storing this information may not yet be created.

Question: where is it better to store the data necessary for playing the animation and preparing the images? How to preserve the independence of the model from the display, taking into account the above mentioned difficulties?

Please tell me which architectural solution is best suited in this case.

    1 answer 1

    1. This is not entirely true. The model did not store the "data related to the display." On the contrary, the model includes new state data. Now the object knows not only about its position, but also about what phase its action is now in. And the animation only shows it.

    2. Separate animation into animation, and into keys / triggers. Keys and triggers are properties of model logic. Animation is part of the display.

    3. The order of creation seems to be quite a simple thing. Problems with cross-dependencies, once again, an indicator of the problems of mutual penetration of parts of systems into each other.

    Where to store data? - all that relates to the display - in the display. All that is needed for the operation of the model's logic (that is, for operation without display, in the so-called headless mode) is in the model data.


    In general, a good test for the separation of logic and display - can you replace graphics output from OpenGL to D3D without changing the model? And on the console and ASCII art? And run the game in headless mode? And nothing breaks and does not change with tz. models? If you answered yes to each question, the separation is there and it is good.


    In general, do not get carried away with the early abstract optimizations of the architecture. The best option is to make a port to another paltform. The process itself will tell you what to bring to the general, what to the model, what to the map, etc.

    • Regarding the first item - the number of animation frames for a certain state (or as you called them - the phase of the action) will be determined by how many the artist decided to draw them. Those. determined by the display. Although maybe I'm wrong. Just in my view, the display is absolutely everything related to what is drawn on the screen. Do I understand correctly what you need to understand under the display? - Bakuard
    • The number of animation frames is a display property. The model should know only its length (in ticks, for example) and action keys (also in ticks then). - Kromster
    • If you make the length of an animation a property of a model and measure it in ticks, then in my opinion this data will not always be needed by the model. Example1: there is a magician casting an attacking spell. The spell "shoots" only after the animation of its preparation is completed. This data can be moved to the model by creating a state for the mage - it attacks and prepares_ the attack. For the second, set the maximum time and track the execution time. It is logical to place this data in the model, since duration information is used by her. Also, for example - if the magician is preparing a spell and received damage - interrupt the training spell. - Bakuard
    • Example 2: Take the animation of the burning of the fire. Suppose there are 5 frames for it and the total animation time is 250 milliseconds. In the campfire model, you can create a single_phase_burning condition, a flash_start phase and also track time for them. But this data is not used by the model itself and they are not really needed. This data is only needed for the display and it would be more logical to place it there. But for each fire, these data are unique and it is necessary at the same time to make it clear to which fire this data belongs. And again it turns out that the data are used. Only the display is stored in the model. - Bakuard
    • one
      But in fact, a little bit the other way around - this is the model that has to set the length of the action, and the animation is adjusted to fit it. If the models need the archer to fire for 1.7 seconds and the arrow to fly at the beginning of the action, then the animation for this is done, and not vice versa (imagine, if the animator did a 7-sec shooting and the arrow is released only at the end .. now the archers our game is not good for anything because of the slowness and ease of interrupting the action ...) - Kromster