-2
\$\begingroup\$

I had a problem with the build of a TD.

I got a slow - non efficient search for towers find targets to shoot.

PD: enemies[] got all the active & non-active enemies (death and alive) ->Im using COCOS2dX and don't know yet how to remove items while the array is still on use. it is

CCArray enemies[Enemies];

and if anyone know how to remove without crashing in cocos2d-x or leaving the "NULL pointer", please tell me..

void Tower::update()
{  

if (this->pChosenEnemy == NULL)
{
    int i = 0, size = enemies.size();
    for ( ; i < size; i++)
    {
        if (circleCollition(enemies[i]->getPosition(),    enemies[i]->getContentSize().width)  && enemies[i]->notDead())
        {
            //cout << << endl;
            this->chosenEnemyForAttack(enemies[i]);
            break;
        }
    }
}
else if(this->pChosenEnemy != NULL)
{
    if( pChosenEnemy->notDead())
    {
        if (!circleCollition(this->pChosenEnemy->getPosition(), this->pChosenEnemy->getContentSize().width)   )
        {
            this->lostSightOfEnemy();
        }
    }
}
}

I would like to know how you guys solve this unefficient problem. Thanks.

\$\endgroup\$
1
\$\begingroup\$
  1. Keep the array free of dead creatures. Here is the API for manipulating arrays. See removeObjectAtIndex
  2. You can iterate once over all living creatures and check if their distance from each tower is smaller than the range of the tower.
  3. If so decide on the factor you wish to pick the target by. Normally towers pick the target that is closest to the objective. You can remember which one of the creatures you iterated over was picked for each tower.

pseudo code:

array creatures;
array towers;
array tower_targets;
for (i = 0; i < creatures.length; i++){
  for(j = 0; j < towers.length; j++){
    if(distance(creature[i], tower[j] < tower.range){
      if(is_closer_to_objective(creature[i], tower_targets[j]){
        tower_targets[j] = creature[i];
      }
    }
  }
}

This is just pseudo code, convert it to working code.

\$\endgroup\$
  • \$\begingroup\$ Checking about the uniform grid \$\endgroup\$ – OsbSoto Mar 3 '14 at 2:48
  • \$\begingroup\$ I changed the answer and included code \$\endgroup\$ – wolfdawn Mar 3 '14 at 8:05
  • \$\begingroup\$ Hello Artur, usefully the link to manage CCArrays But.. what exactly is "is_closer_to_objective", don't it is the same verification that on the prior code line? \$\endgroup\$ – OsbSoto Mar 3 '14 at 16:00
  • \$\begingroup\$ @OsbSoto No, it means pick the monster closest to the exit or whatever it is the towers are defending (from all monsters in range). \$\endgroup\$ – wolfdawn Mar 3 '14 at 20:41
  • \$\begingroup\$ let me see if I figure out, with the distance I search if that monster is inside the range, but then isclosertoobjetive is some that check if that enemy is closer to the end than the actual tower opponent? example: I got 3 enemies in the range, but compare who is the "first" to attack him. Q) Do you meant some like that? \$\endgroup\$ – OsbSoto Mar 3 '14 at 20:52
0
\$\begingroup\$

and if anyone know how to remove without crashing in cocos2d-x or leaving the "NULL pointer", please tell me.. Understand that:

int i = enemies->count();
for(int j = 0; j < i; j++){
  ...
  myArray->removeObjectAtIndex(j);
  ...
}

In this time myArray will be the count() = i - 1, but i will stay in i. On the last iteration a null pointer will happen. So, use that way to avoid null pointer:

int i = enemies->count();
for(int j = i - 1; j >= 0; j--){
  ...
  myArray->removeObjectAtIndex(j);
  ...
}
\$\endgroup\$
  • \$\begingroup\$ don't use: for(int j = 0; j < enemies->count(); j++){ \$\endgroup\$ – Guilherme Nov 16 '14 at 10:38

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.