1

I got a problem that is beyond my knowledge. I'm working on a HGE project, but this is a c++ issue, not the HGE engine itself.

The question: I want to create a 2D array with 3 different animations on 5 different turtles. However, I need to use a constructor in HGE something like this; turtleAnim[i] = new hgeAnimation( turtleTexture, 6, 6, 0, 0, 110, 78 )

But I don't know how to do it! All examples on the interwebz handle the problem as if it got a default constructor. Something like this:

in class:

#define     TURTLECOUNT     5
#define     TURTLEANIMATIONS    3

private:
hgeAnimation** turtleAnim;

in the.cpp

turtleAnim= new hgeAnimation*[TURTLECOUNT];

for(int i=0; i<TURTLECOUNT; i++)
{
    turtleAnim[i]= new hgeAnimation[TURTLEANIMATIONS]; // Uses default constructor. I don't want that cuz it doesn't exists.
    turtleAnim[i]->Play();
}
Jesus Ramos
  • 22,940
  • 10
  • 58
  • 88
Alex
  • 365
  • 4
  • 17
  • 1
    What about a `std::vector`? It let's you specify with what the elements should be initialized. And it's more "modern" and object oriented than raw arrays. – leemes May 07 '13 at 20:38
  • possible duplicate of [c++ Object array initialization without default constructor](http://stackoverflow.com/questions/4754763/c-object-array-initialization-without-default-constructor) – David Brown May 07 '13 at 20:39
  • You could try a messier "hgeAnimation*** turtleAnim;" and make corresponding changes to the body, but eventually you'll have to supply the ctor arguments. – dan May 07 '13 at 21:08
  • As @DavidBrown suggested, look at the discussion of “placement new” here: http://stackoverflow.com/a/4756306/2332553 – microtherion May 07 '13 at 21:20

1 Answers1

1

First, you have to decide whether you want your objects on the stack or the heap. Since they're objects, you probably want them on the heap, which means your 2D array will have 3 stars, and you will access the animations like this:

hgAnimation* theSecondAnimOnTheFourthTurtle = turtleAnim[4][2];
theSecondAnimOnTheFourthTurtle->DoSomething();

If that's what you want, then first you make the matrix of pointers.

hgeAnimation*** turtleAnim = new hgeAnimation**[TURTLECOUNT];

Then you can loop through the turtles. For each turtle, you make an array of pointers to the animations. For each element of that array, you make the animation itself.

for (int turt=0; turt<TURTLECOUNT; ++turt) {
   turtleAnim[turt] = new hgeAnimation*[TURTLEANIMATIONS];
   for (int ani=0; ani<TURTLEANIMATIONS; ++ani) {
      turtleAnim[turt][ani] = new hgeAnimation(parameter1, par2, par3);
   }
}

If that looks tricky, deleting all the arrays will be a pain too:

for (int turt=0; turt<TURTLECOUNT; ++turt) {
   for (int ani=0; ani<TURTLEANIMATIONS; ++ani) {
      delete turtleAnim[turt][ani];
   }
   delete[] turtleAnim[turt];
}
delete[] turtleAnim;

The fact that this is tricky is a good sign that there's probably a more simple way to design it.

How about a turtle class that has a member like:

class ATurtle {
  private:
    std::vector<hgeAnimation*>   myAnimations;

Then in your class's constructor, you can do whatever you want in order to make the animations.

ATurtle::ATurtle(par1, par2, par3) {
    myAnimations.push_back( new hgeAnimation(par1, x, y) );
    myAnimations.push_back( new hgeAnimation(par2, z, a) );
    myAnimations.push_back( new hgeAnimation(par3, b, c) );
}

That way, you can make your turtles in a single array:

ATurtle* turtles[TURTLECOUNT];
for (int t=0; t<TURTLECOUNT; ++t) {
    turtles[t] = new ATurtle(par1, par2);
}

And in your turtle class, you would access the animations like so:

(*(myAnimations.at(1)))->DoSomething();

or

std::vector<hgAnimation*>::iterator i, end=myAnimations.end();
for (i=myAnimations.begin(); i!=end; ++i) {
    (*i)->DoSomething();
}

You will still have to call delete on each element of your vector in this case, though, since you called new for every element.

ATurtle::~ATurtle() {
   std::vector<hgAnimation*>::iterator i, end=myAnimations.end();
   for (i=myAnimations.begin(); i!=end; ++i) {
       delete (*i);
   }       
}
Corey
  • 1,845
  • 1
  • 12
  • 23