I am sort of a noob in C++ and I am trying to make a simplegame. This is my problem:
I created class called sprite:
class Sprite
{
private:
Point2D sp_pos;
Point2D sp_vel;
SDL_Surface* sp_img;
Point2D sp_center;
Point2D sp_size;
double sp_radius;
bool sp_animated;
int sp_frames;
int sp_cur_frame;
public:
Sprite() {}
Sprite(Point2D pos, Point2D vel, SDL_Surface *img, ImageInfo info, bool animated = false, int frames = 0);
virtual void draw(SDL_Surface* screen);
virtual void update();
void setInfo (ImageInfo info);
void setPos( Point2D pos ) { sp_pos = pos; }
void setVel( Point2D vel ) { sp_vel = vel; }
void setImg (SDL_Surface* img) { sp_img = img; }
void setNextFrame() { sp_cur_frame++; }
void setFrame( int frame ) { sp_cur_frame = frame; }
void setAnimated(bool animated) { sp_animated = animated; }
void changeVelX (int c) { sp_vel.setX(c);}
void changeVelY (int c) { sp_vel.setY(c);}
void changePosX (int c) { sp_pos.setX(c);}
void changePosY (int c) { sp_pos.setY(c);}
SDL_Surface* getImg() { return sp_img; }
Point2D getPos() { return sp_pos; }
Point2D getVel() { return sp_vel; }
Point2D getCenter() { return sp_center; }
Point2D getSize() { return sp_size; }
double getRadius() { return sp_radius; }
int getCurFrame() { return sp_cur_frame; }
int getFrames() { return sp_frames; }
bool collide(Sprite &another_sprite);
};
Which has a method called "collide", this method detects a collision between two sprites, and works as follows:
bool Sprite::collide(Sprite &another_sprite)
{
double d = getPos().dist(another_sprite.getPos());
if ( d < ( getRadius() + another_sprite.getRadius() ) )
return true;
else
return false;
}
The method works fine. My problem arises with the following, I have implemented different classes that are subclasses of "Sprite" and will represent enemies in my game, so, for instance I would have objects: Class enemy1 : public Sprite, Class enemy2 : public Sprite, etc. They are different because they have different behaviors. I implemented other two helper functions called group_collide and group_group_collide, that work as follows:
bool group_collide(std::list<Sprite> &group, Sprite other_object)
{
bool collision = false;
for (std::list<Sprite>::iterator sprite = group.begin(), end = group.end(); sprite != end; ++sprite)
{
if (sprite->collide(other_object))
{
Sprite exp = Sprite(sprite->getPos(), Point2D(0, 0), exp_image, exp_info, true, 7);
exp_group.push_back(exp);
if( Mix_PlayChannel( -1, explosion, 0 ) == -1 )
{
//abort();
}
sprite = group.erase(sprite);
collision = true;
}
}
return collision;
}
int group_group_collide(std::list<Sprite> &group, std::list<Sprite> &other_group)
{
int scored = 0;
for (std::list<Sprite>::iterator it1 = group.begin(), end1 = group.end(); it1 != end1; ++it1)
{
if (group_collide(other_group, *it1))
{
it1 = group.erase(it1);
scored += 10;
}
}
return scored;
}
So, in fact, group collide will detect collisons between a sprite and a list of sprites, and group_group_collide will detect collisions between group of sprites (two different lists). The problem that arises is: There will be at least 4 types of enemies, and all of them are subclasses of my Sprite class, but I get compilation errors when I create a list of sprites and add elements that are subclasses of sprites. My solution was writing a method group_collide and group_group collide for all types of enemies, but this is quite inelegant. Is there a better way to approach this problem?
EDIT:
Thanks for your suggestions. I defined the list as a pointers list as you have suggested:
std::list<Sprite*> enemy_group;
And for instance, I am adding elements of class "Kamikaze" which is a subclass of sprite, in this way (the method update is different in this class):
enemy_group.push_back(new Kamikaze(enemy_pos, enemy_vel, 0, enemy_image, enemy_info));
However, when iterating over the list:
for (list<Sprite*>::iterator it = enemy_group.begin(), end = enemy_group.end(); it != end; ++it) {
(*it)->draw(screen);
(*it)->update();
if ((*it)->getPos().getY() > SCREEN_HEIGHT + 30)
{
delete *it;
it = enemy_group.erase(it);
}
}
The method update is called from the Sprite class, not Kamikaze class, therefore I also have object slicing problem with this approach, perhaps there is something wrong with what I have done?