   Trouble Generalising methods to handle all weapon types in my scrolling shooter
  Hello Everyone. I'm currently making a vertical scrolling shooter in C++ using allegro. It's going well, although I've hit a bit of a brick wall. lol. I'm using linked lists to keep track of things like laser and missile fire on the screen, although I want to generalise my methods so that the same methods can be used for many different types of weapons. When my game is done, I'm going to have 6/7 different weapon types (although I may want to add new weapons in later, so I want to adopt a general technique for handling weapons in the game). At the moment, I have only lasers, and already have 8 methods in a class for that, although 6 of those 8 could be used for other weapon types aswell. So rather than having 6/7 versions of same 6 methods, to handle all the weapons, the plan was to write the code so that 6-10 methods could handle all different weapon types.Anyway, at present, I use linked lists for the weapons, with different linked lists for the weapon type. That way, every time a laser etc goes off the screen, its just a case of getting rid of that link in the list. But I'm having some problems generalising the code.These are some of the weapon types:/* Laser Structure */struct LaserStruct{  unsigned int weapon_position[2];  unsigned int weapon_speed;  LaserStruct *next_weapon;};/* Missile Structure */struct MissileStruct{  unsigned int weapon_position[2];  MissileStruct *next_weapon;};And this is some of the code:unsigned int CGameWeapons::GetWeaponPosition(unsigned int array_idx1, void *current_node){    if( (array_idx1 &lt; 2)&&(current_node != NULL) )    {   return (current_node-&gt;weapon_position[array_idx1]);    }    else    {   return (RETURN_ERROR);    }}void CGameWeapons::SetWeaponPosition(unsigned int array_idx1, unsigned int position, void struct *current_node){if( (current_node != NULL)&&(array_idx1 &lt; 2) ){ current_node-&gt;weapon_position[array_idx1] = position;}return;}Although in order to generalise it, I had to declare the argument to the methods as void (rather than type LaserStruct or MissileStruct - which depends on the type of weapon), and because of that, when I try and compile, it says " `void*' is not a pointer-to-object type ". I understand the problem, but I'm not sure how to solve it.In the method declaration etc, I did try changing the pointer from type void to type void struct, although that didn't work, lol. Any ideas?[Edited by - Swarvy on May 21, 2009 6:01:41 PM]
  you need to use inheritance, http://www.csharp-station.com/Tutorials/Lesson08.aspx.http://www.cs.bu.edu/teaching/cpp/inheritance/intro/Basically, what inheritance means is you make one class (Structs can't use this) and then the Laser and Missle classes are extensions of that class. I'll give you an examplethis is your base class, where you put the methods and such you want to generalize between the weapons, you would place your GetWeaponPosition and SetWeaponPosition methods in this class.public class Weaponry{}These two classes inherit the Weaponry class.public class Laser : Weaponry{}public class Missle : Weaponry{}Then you could declare a missleMissle magic_missle_of_light = new Missle();and call the methods in weaponry as if Missle was the Weaponry classmagic_missle_of_light.GetWeaponsPosition();In the Missle and Laser classes, you would place the non generalized functions and variables and such. The magic of this is, say you have a method that deletes a weapon, with inheritance its easypublic void DeleteWeapon(Weaponry w){}any class that inherits from the Weaponry class will be a valid object to pass to that method. However it wouldn't work the other way around, if you had this methodpublic void DeleteLaser(Laser l){}You could not pass a Weaponry object and have it work because Laser inherits from Weaponry.Hopefully I covered all the bases, if not the webpages I posted are my go to resources regarding this.   ;Quote:http://www.csharp-station.com/Tutorials/Lesson08.aspx.Quote:Basically, what inheritance means is you make one class (Structs can't use this) and then the Laser and Missle classes are extensions of that class.The OP is using C++.@The OP: Using inheritance would work, but I'd at least consider using a data-driven approach instead. That is, create a single weapon class/struct, and allow the parameters for each weapon (e.g. speed, range, guided or not guided) to dictate the weapon's behavior.   ;  I'm reading about inheritance atm, although I'm still a little confused. If I have a base class and then from that, I have derived laser and missile classes, where exactly would the details e.g. laser/missile position etc be held? Would they be held as private members of the laser and missile classes? If that was the case, wouldn't that declare a new class object for every new laser/missile created?I did consider just putting everything into one massive list for all the different weapon types, but I thought that that would make it too hard for further development if I decided to add new weapons or take some away.   ;  Anything the weapons have in common could be stored in the base class (position, speed, etc). On another note, are these the weapons themselves? Rifle, handgun etc, or are these projectiles fired from the weapon - bullet, missile...?  From your OP i'm guessing these are the projectiles. Anyway...A base class projectile:Class Projectile{  private:    Vector3 position;    Vector3 velocity;    float maxSpeed; public:   virtual ~Projectile()    virtual void Update();    Vector3 GetPosition();    Vector3 GetVelocity();    Vector3 SetPosition(Vector3 pos){position = pos;}    Vector3 SetVelocity(Vector3 vel){velocity = vel;}};void Projectile::Update(){   position += velocity;}A guided missile class which inherits from projectile:class GuidedMissile : public Projectile{   private: Entity* target;    public:  GuidedMissile(Vector3 position, Vector3 velocity, Entity* target);   void Update();  Vector3 SetTarget(Entity* targ){target = targ;}};void GuidedMissile::Update(){   velocity = target->GetPosition() - position;   velocity.normalise();   velocity *= maxSpeed;   Projectile::Update();}A laser or whatever else....class Laser : public Projectile{   // whatever makes your laser different than any other projectile can go in here.};Now due to polymorphism we can treat all the projectiles the same once created, regardless of which derived type they are.std::vector<Projectile*> ourProjectiles;ourProjectiles.push_back(new GuidedMissile(position, velocity, target));ourProjectiles.push_back(new Laser(position, velocity));for(int i = 0; i < ourProjectile.size(); i++){// update our projectiles.ourProjectiles->Update();// check for collisions, check if they projectile left the screen etc.// and whatever else you want to do with them.if( isOutOfScreenBounds( ourProjectiles->GetPosition() ) ){    delete ourProjectiles;    ourProjectiles.erase( ourProjectiles.begin() + i );    i--;}}