Elimination of communication and global status in the singleton "Game"

I work on the game (by writing my own physics engine) and try to follow a good design when writing. Recently, I came across a lot of hard-to-reach errors, and in order to more easily catch these errors, I tried to write unit tests. This was difficult to do due to the fact that many of my components are closely related, especially to the module game.

In my module, gameI export an instance of the singleton class that contains the current state of the game, time, game events, etc. However, after reading this and exploring how to reduce this connection, I decided to try rewriting the class so that it was no longer a single.

The idea is to use a class GameStateand traverse these objects everywhere so that unit tests can create minimal states for tests. Most of the functions then simply become a function of the state of the game and return the new state of the game. However, I ran into some design issues :

The position and speed of the object of my objects are python properties that are calculated according to the current time. This means that I can’t just pass the object GameStatewithout rewriting it as a function (leading to fuzzy syntax). Code example:

class Entity:
    @property
    def position(self):
        """Interpolate the position from the last known position from that time."""
        # Here, the game class instance is referenced directly, creating coupling.
        dt = game.game_time - self._last_valid_time
        # x_f = x_i + v_i*t + 1/2 at^2
        return self._position + self._velocity * dt + .5 * self._acceleration * dt**2

, , Injection Dependency. , GameState 'getter' . GameState 'getter' . GameStateGetter class:

class GameStateGetter:
    _CurrentState = None

    def update(self, new_state):
        GameStateGetter._CurrentState = new_state

    def __getattr__(self, name):
        # GameState object properties are immutable, so this can't cause issues
        return getattr(GameStateGetter._CurrentState, name)

.

  • GameState 'getter' ?

( update, ). , , , .

  • "" game Entity class position?

, . GameStateGetter ( ). , .

, !

+5
2

GameStateProvider Entity - , -, , .

Entity , . , . ( -, , , ?) current_time , - position .

:

class Entity(object):

   def __init__(self, game_state_provider):
      self.provider = game_state_provider

   @property
   def position(self):
      # lazily evaluate position as a function of the current time
      if self._last_valid_time == self.provider.current_time:
         return self._position
      self._last_valid_time = self.provider.current_time
      self._position = // insert physics here
      return self._position
+1

, .

: , , . / . setUp .

Edit:

"GameState" . . GameState, ( __deepcopy__) .

+1

All Articles