Monday 11 November 2013

Spawning in Games My Game Implementation

I was recently looking at and implementing spawning in my GDW game and though that I would write a blog on my thoughts and implementation. Spawning is when a something in the game is created. It refers to the live creation of something in the game world. This entity can be a live creature or an object it does not matter. When I first started to work with implementing my spawning system I looked to factories to do this for me. But what is a factory?

Factory
The Factory design pattern is one solution for creating objects.  The factory design pattern works well to return one of several classes that share one base class. For example you want to spawn a random enemy at a random point in time. Each enemy has it's own class structure, but they all inherit from the base class GameObject. You have a random number generator and a number that corresponds to each type of enemy. You can send the information to the factory and it will return a newly created enemy of that type specified. This will work as long as each class has the same base class. This brings us to one of the limitations of factories. Each object that a factory can make must have the same base class. Another limitation come when refactoring is attempted. When refactoring an existing class to use factories it will break all other existing clients. A client is the user or anything that can use the class. If you want more information about the factory design pattern I would suggest watching this video.

Once I started to implement a factory I relised that what I was doing was redundant. I am using Ogre and Havok to make my game and they have a list of everything in the scene. Before to make entities I was using that list to make an instance of an object and then add it to the scene. I relised that Ogre and Havok were already factories in a sense. I can use Ogre and Havok to make instances of models and then add these instances to the scene. There I had my makeshift factory.

Now once I had creating models done I started work on where to place them and came up with this solution. In Maya you can create locators that when you export to an fbx file can be called in code to get positions. This way I can set the bounds of my level with these locators. I can read in the bounds of the level and then divide it into chunks. Our game is a wave based game so enemies cant spawn in chunks that are to close to the player.  Within these chunks I can generate a random location and then spawn an entity there. I took this idea and made spawn chunks with this functionality. This is what the class looked like.


 class SpawnChunk{  
 public:  
      SpawnChunk(Ogre::Vector3 min, Ogre::Vector3 max);  
      // pick a random point in the chunk to spawn an entiry  
      Ogre::Vector3 generateRandomPosition(Real yVal);  
      void renderChunk(Ogre::SceneManager *sceneManager);  
 private:  
      // these are the bounds of the spawnchunk with the min point and  
      // the max point  
      /*        --------* max  
                -       -  
                -       -  
           min  *-------- */  
      Ogre::Vector3 m_min;  
      Ogre::Vector3 m_max;  
      Real generateNumberRange(Real one, Real two);  
 };  

Once I had that I took the bounds of the level and divided it up into a number that was passed in. To divide the level up I took the min and max bounds of the level and created a box. From there I took the length of the side of the box and divieded it by the number of sections. Then creating a list of spawn chunks from there. The code looked like this.

 Real l_divLengthX = (m_bmax.x - m_bmin.x) / (float)p_times;  
      Real l_divLengthZ = (m_bmax.z - m_bmin.z) / (float)p_times;  
      Ogre::Vector3 l_tempMin(0,0,0);  
      Ogre::Vector3 l_tempMax(0,0,0);  
      for(int i = 0; i < p_times; ++i){ // looping through in the x dir       
           for(int j = 0; j < p_times; ++j){ // looping through in the z dir            
                l_tempMin.x = m_bmin.x + (l_divLengthX * (float)i) ;  
                l_tempMin.z = m_bmin.z + (l_divLengthZ * (float)j) ;  
                l_tempMax.x = m_bmin.x + (l_divLengthX * ((float)i + 1.0));  
                l_tempMax.z = m_bmin.z + (l_divLengthZ * ((float)j + 1.0));  
                m_spawnChunkList.push_back(SpawnChunk( l_tempMin, l_tempMax ));  
           }  
      }  

Once I had a list of spawn chunks I was finished. Now I just have to add wave based spawning and our game will start to have some gameplay, wOOt!






No comments:

Post a Comment