开发者

Design choice with a container class that several classes use

开发者 https://www.devze.com 2022-12-13 19:31 出处:网络
I have a class that wraps around a list called ExplosionGroup (previously called AllExplosions for reasons I\'ll explain) which is a list of \'Explosion\'s (another class).

I have a class that wraps around a list called ExplosionGroup (previously called AllExplosions for reasons I'll explain) which is a list of 'Explosion's (another class).

My original design choice, and what ran for awhile, was to have an ExplosionGroup in the 'Level' class that runs all the levels. Any classes (like ships or bosses) that had functions that would cause them to explode would have this ExplosionGroup passed to those functions. So basically, the Level's ExplosionGroup was sucking in all of the explosions created (hence it was then called AllExplosions).

void Foo::Explode( AllExplosions &explosions ) {
  ...// Create the explosion
  explosions.Add( newExplosions );
}

Recently I ran into a problem where this solution wouldn't work since I needed to create an explosion outside one of these functions, and just putting the code in those functions would a) not make any sense and b) not work correctly.

Thus I came up with the idea to have each of the classes that exploded have their own explosion group. This would allow the classes to deal with explosions however they want, not just in a function where an ExplosionGroup was passed. Then I wrote a TakeExplosions function for ExplosionGroup (which just uses std::list's splice) which took an ExplosionGroup parameter and sucked all of the explosions out of that group. This would be used by Level in unison with an accessor for each classes' ExplosionGroup.

void Foo::TakeExplosions( ExplosionGroup &explosions ) {
  m_Explosions.splice( m_Explosions.end(), explosions );
}

I thought this was great, but I've realized that if I use this technique I'll want to use it for all classes that can explode to be consistent. However, there are a few special cases in which I'll need to do this indirectly in order to get the explosions to the Level's explosions. For example, a Boss class holds a BlockWall (a list of blocks), and blocks explode.

Thus, the block wall would need to extract explosions from its blocks, the boss would need to extract explosions from the block wall, and the level would need to extract explosions from the Boss (unless I provided an accessor for the Boss' wall, which I have no intention of doing).

I really don't want to use a global container for explosions so that all of the classes can just add in explosions as they please and be done with it, so I'm asking for any recommendations or ideas towards this issue. I've also considered ditching handling explosions in the Level class and having each class handling in completely on its own, but that seems like a bad abstraction to me.

someBlockWall.ShowExplosions( p_Buffer );
playerShip.ShowExplosions( p_Buffer );
// etc. Seems ugly?

P.S. I understand that its hard to answer a question like this without knowing how animations in the game work, etc. I'm also being tempted to use a global container bec开发者_运维知识库ause I'm slightly worried that all of this playing with lists could have performance implications. However, I haven't done any profiling so I'm trying not to even consider it.


I have no answers, just some questions that would help others (and maybe also yourself) to find a good answer.

  1. What are the exact steps that have to be performed in order to show an explosion?
  2. What are my invariants here? (e.g. are all explosions the same, are the object-specific, dependant on time or position on the level)
  3. Which objects are involved in showing an explosion (renderer, clock, explodable object, etc.)?

There are many possible solutions, but it is hard to choose without knowing all the forces involved.

0

精彩评论

暂无评论...
验证码 换一张
取 消