Archived

This topic is now archived and is closed to further replies.

graveyard filla

simple inheritense question

Recommended Posts

high, i have a class caled Entity. Entity contains xPosition, yPosition, xVelocity, yVelocity, width, height. i have 3 other classes, Player, Enemy, and Bullets. these 3 classes inherit from Entity. of course they each have their own properties like Update(), or image, ETC. now, i want to start doing collision detection for the bulltes against the players. could i write:

bool BulletCollision(Entity &target1, Entity &bullet); // or even could have done Bullet &bullet for the second parameter

 
would this work? OR, would i have to do:
bool PlyrBulletCollision(Player &player, Bullets &bullet);

bool EnmyBulletCollision(Enemy &enemy, Bullets &bullet);
 
do you see what im doing here? i guess what im asking is, what kind of tricks can i pull if i inherit from a class? im really new to this inheritense stuff, but i can swear i remember there being "tricks" where you could call a Player Entity instead, or call a Enemy Entity. i KNOW there are tricks like this available, could anyone inform me of any of them? what about doing this:
Entity myentities[2];
Player player;
Enemy enemy;

myentities[0] = player;
myentities[1] = enemy;

for(int i = 0; i < 2; i++)
{ 
   if(entities.xPos == entities[i + 1].xPos)
     the enemy and player have the same xPosition!!

}
 
do you see what im getting at? i think some things like this are possible, i just dont know what. thanks for any help!!

Share this post


Link to post
Share on other sites
The idea behind inheritence is that you can write basic code in the base class (Entity in your case), and add more exact code in the derived classes.

So, to answer your question. You could create a Collision(Entity &e1) function in your base class, and Player/Bullet/other derived classes could use it as it. Good use of C++ is a huge subject, if you plan to use it extensivly, you sould read up on it. On more thing, if your Collison function is in a class, then you only need to send 1 parameter.

[edited by - Onemind on April 21, 2004 1:44:52 PM]

Share this post


Link to post
Share on other sites
cool... so i CAN use the Entity class as a "generic" variable when i send it to functions... this rocks! i thought i would have to get into templates to do this, but im glad i can do it with inheritense... im starting to see the power of c++

also, what about the array thing? will that work? what else can you do with inheritense?

also, is polymorphism just making it so you inherit from a class, but certain functions you inherit will be "custom" to that specific class? i think you do something like a virtual function, then in the child class, you can customize this function to be spcific to that child? is this what polymorphism is? at that point, i could send Entity &whatever and still use the player/enemy specific functions ?

Share this post


Link to post
Share on other sites
Yes, polymorphism is when you allow functions in derived classes to take control of base class functions. Generally, you have to use the virtual keyword to do this.

By declaring a function virtual, you are telling the compiler to always call the most derived version of it.


Entiy *entPtr, *playerPtr;

entPtr = new Entity();
playerPtr = new Player(); // NOTE: I can use a base class pointer to instantiate a derived calss


entPtr->AVirtualFunction(); // this still calls the "AVirtualFunction" in class Entity

playerPtr->AVirtualFunction(); // this calls the "AVirtualFunction" in the Player class



Notice that even though entPtr and playerPtr were both Entity pointers, they called different functions. That is the most common example of polymorphism.

[edited by - Onemind on April 21, 2004 1:54:26 PM]

Share this post


Link to post
Share on other sites
Your first post would not work because you did not use pointers. It would be fairly easy to rewrite your code to use pointers tho.


// somewhere in a header
typedef (Entity*) EntityPtr;


// a global variable
EntityPtr entities[2];

void CreateStuff()
{

entities[0] = new Bullet();
entities[1] = new Player();
}

void DeleteStuff()
{
// NOTE: You must delete each array element seperately
delete entities[0];
delete entities[1];
}





[edited by - Onemind on April 21, 2004 5:06:31 PM]

Share this post


Link to post
Share on other sites
Yeah. Basically, "new Derived" returns a Derived *, which can be assigned to a Base *.

Caveats:

- Derived** is *not* assignable to Base** (IIRC anyway.) If it were possible, it could be exploited to seriously mess things up.
This is covered in that parashift.com C++ faq I think, but I''m too lazy to look it up right now

- Information about the Derived-ness of a function parameter gets lost:

Player * myPlayer;
Bullet * myBullet;
myPlayer->collide(myBullet);

void Player::collide(Entity * e) {
// Oops, I don''t know that "myBullet" is a Bullet* anymore, I just see an Entity*.
}


You can fix this by casting, but you should be careful about what kind of casting you do, and how you handle things if you don''t have the type that you think you do. It''s best to try to design things so that you don''t need to know the subtypes of your arguments; if that''s not possible, google "double dispatch" (or look it up on wiki) for a possible solution.

- IIRC, if you pass a value or reference to your function rather than a pointer, you lose even more information:

void Player::collideValue(Entity e) {
BoundingBox bb = e->getBoundingBox(); // Entity::getBoundingBox() gets called even if it''s overridden in the subclass of Entity that you''re passing in
}


This is C++ specific stuff (not a problem in Java, which basically dispensed with all the *''s and &''s), so I probably don''t remember it correctly. But I can tell you what to google for (and/or look for on Wiki): "object slicing".

Share this post


Link to post
Share on other sites