官术网_书友最值得收藏!

A typical use case

Now we have seen what kinds of different resources there are, but we do not know yet how to apply this knowledge to our game. While the approach you have seen in Chapter 1, Making a Game Tick, may work for simple examples, it does not scale well to a bigger project. As our game grows, we have to reflect about how the resources are going to be used. This is explained in the next sections.

Graphics

In our game, a crucial part will be the visual representation of the world and different objects in it. We need to think about how we get from an image on the hard disk to its visualization on the screen.

  • Game entities such as the player's airplane, enemies, or the landscape are represented with sprites and possibly texts. They do not own the heavy textures and fonts; instead they use the front-end classes to refer to them.
  • As a consequence, the resources (textures and fonts) need to be accessible by the entities. We must make sure that the resource objects stay alive as long as any front-end object refers to them, so we have to find an appropriate scope to declare the resources.
  • A sprite in the airplane must somehow get a reference to the texture stored outside. Therefore, we have to transport this information via constructor parameter to the airplane class.

Audio

Another important resource is audio, which can be divided into sound effects and background music. We have to consider how to make both of them audible in the final application, when all we start with is a bunch of audio files in a directory:

  • Sound effects are not tied to a specific game entity such as an airplane; they persist independently of the object that causes them. Imagine an airplane that explodes and creates an explosion sound. When we destroy the plane object, we still want the explosion to be audible for some time. As a result, we do not store sf::Sound instances in the game entities, but in an object which remains alive throughout a mission. The same applies to the underlying sf::SoundBuffer objects which are used by sf::Sound.
  • For music themes, the semantics are similar. It may even occur that the same theme is played across multiple missions. Ideally, the sf::Music objects exist in a scope that outlives a single mission.
  • Although the game entities do not own sound effects, they are supposed to play them. As a consequence, we shall provide an interface that allows playing new sound effects.

Acquiring, releasing, and accessing resources

Once we have decided which resources are required by the application, the next step is to investigate how long and by whom they are used. This allows us to decide how the resources are stored in the application, as well as who is responsible of loading and releasing them.

  • We want to load the resource in advance, for example, at the time the game starts or the player begins a new mission. In contrast to loading on demand (as soon as a resource is needed), this approach has the advantage that possible loading times occur in the beginning and not during a game. Therefore, the game itself remains fluent and is not interrupted because of resources.
  • When resources are likely to not be needed anymore, we can release them and free the memory. This is usually the case at the end of a mission or when the application is quit. We do not want to release resources too early if we risk reloading them shortly after. For example, we do not release the explosion sound buffer as soon as the sound effect is over, because the next explosion may follow a few seconds later.
  • There must be a possibility to get a reference to a certain resource after it has been loaded—using a resource identifier. This identifier (ID) could be the file path as a std::string. This has some disadvantages: all classes that use a resource must hardcode the path, so if it changes, a lot of code needs to be refactored. Strings are also quite error-prone regarding typographic or case errors. An alternative to strings are enums, where each enumerator denotes an ID. Since an enum has a predefined set of possible states, we get some compile-time safety, and we can handle the paths in a central place.

In conclusion, we have the heavy resource classes which shall be loaded when appropriate, but before the game. Throughout their lifetime, front-end classes such as sprites or sounds may reference them, so we must keep the resources alive. When they are not needed anymore, we can release them.

主站蜘蛛池模板: 凌云县| 科技| 铜梁县| 福安市| 连平县| 内黄县| 界首市| 石台县| 林甸县| 西吉县| 钦州市| 婺源县| 龙井市| 乐都县| 阿坝县| 秭归县| 蓬莱市| 安阳市| 略阳县| 富裕县| 大悟县| 景宁| 德格县| 文化| 曲阜市| 博客| 临海市| 墨脱县| 乐东| 汝州市| 聂荣县| 乌兰察布市| 夹江县| 两当县| 呼图壁县| 施甸县| 大宁县| 齐齐哈尔市| 银川市| 镇原县| 龙井市|