Массив CCSprite ПРОТИВ CCSpriteBatchNode и NSMutable массива?

#iphone #objective-c #xcode #cocos2d-iphone

#iPhone #objective-c #xcode #cocos2d-iphone

Вопрос:

У меня есть небольшая игра в лучника, над которой я работаю, и ранее в моем коде я помещал каждый спрайт со стрелками в CCSprite[7]; массив, а внутри ccTime я обновлял координаты x / y и выполнял некоторые вычисления, чтобы стрелки двигались красиво и плавно. Итак, вся математика / углы / движение работают.

Позже, пытаясь реализовать обнаружение столкновений, я не смог использовать тип данных, который бы намного упростил мою жизнь, я думаю, что это было CGRect , и он получил бы содержимое спрайта и проверил, пересекается ли он с другим спрайтом. В ошибке говорилось, что мне пришлось использовать элементы NSMutable array или что-то в этом роде, что здорово, потому что в любом случае это лучше для памяти, чтобы поместить мои спрайты в batchNode и NSMutable array. Но есть проблема.

В каждом уроке, который я видел, снаряды перемещаются на основе последовательности действий с заранее определенным временем. Просто пример последовательности действий (не в моем коде)

 id action = [Sequence actions:
             [ScaleTo actionWithDuration:.3 scale:0.7f],
             [ScaleTo actionWithDuration:.3 scale:1.0f],
             nil];
  

Везде, где я видел, так перемещаются спрайты, но я не могу этого сделать, потому что скорости стрелок меняются в зависимости от того, как долго удерживаются касания, углы, которые делают стрелку реалистичной, и тому подобное.

Итак, в моем коде в touchesBegan:

     ccTouchesBegan:(NSSet *) blah blah {
    ...
    ...
    self.nextProjectile = [[CCSprite spriteWithFile:@"arrow.png"];
    _nextProjectile.rotation = vector2 - 90; //this is angle of where the user touched screen

    //add projectiles to array
    _nextProjectile.tag = arrowTracker;

    [_batchNode addChild:_nextProjectile z:1];
    [_projectiles addObject:_nextProjectile];

    //Release? If I don't have this the arrow fails to move at all... and it was in the tutorial
    if(_nextProjectile.tag == 1){
          [_nextProjectile release];
          _nextProjectile = nil;
       }
    }
  

Каждый раз, когда я касаюсь, первая стрелка не вылетает (это НЕ проблема, я могу это легко исправить), и стрелки вылетают идеально, движение точно такое же, как при использовании массива CCSprite. Единственная проблема в том, что каждый раз, когда я вызываю ccTouchesBegan , если предыдущая стрелка была в середине полета, она останавливает все действия и просто сидит там. В воздухе. Итак, моя проблема — логическая ошибка, очевидно, я делаю что-то не так в touchesBegan, потому что это завершает проекцию предыдущей стрелки!

Итак, мои вопросы:

  1. Как мне это исправить.
  2. Должен ли я просто придерживаться CCSprite [7] (массив спрайтов)? Вместо того, чтобы находить содержимое изображения, я мог бы найти конечную точку стрелки и просто проверить, пересекается ли она с другим изображением, но это потребовало бы гораздо больше работы / математики / памяти (я не совсем уверен, как память вообще работает в программировании… но я почти уверен, что массив CCSprite занимает больше памяти.

Редактировать—————————————————————————————

Здесь обновляется положение стрелки.

 -(void)callEveryFrame:(ccTime)dt{
...
...

//move selected arrows
for(int xe = 0; xe < 7; xe  {
float x = _theArrowArray[xe].position.x;
float y = _theArrowArray[xe].position.y;
vyArray[xe]  = gravity; vyArray is the velocity on the y axis array, I'm just adding gravity
x  = vxArray[xe] *dt; // dt is after (ccTime) in the method definition
y  = vyArray[xe] *dt;
CGPoint newLocation = CGPointMake(x,y);
_theArrowArray[xe].position = newlocation;
//The Code above this moves the arrows inside the CCSprite array, not the batch/nsmutable array.

//The code below is just a copy and paste with a little change to it, for the batchnode/nsmutable
float x2 = _nextProjectile.x; // mextProjectile was declared earlier in my code
float y2 = _nextProjectile.y;
vyArray[xe]  = gravity; vyArray is the velocity on the y axis array, I'm just adding gravity
x2  = vxArray[xe] *dt*1.2; // This way(dt*1.2), both arrows are being shot out but this one has more gravity to it, so you can tell which arrow is which and see that both are working.
y2  = vyArray[xe] *dt*1.2;
CGPoint newLocation2 = CGPointMake(x2,y2);
_nextProjectile.position = newlocation2;

}
  

Комментарии:

1. Какие значения вы присваиваете тегу на вашем _nextProjectile sprite? Какие значения имеет arrowTracker? Возможно ли, что всем спрайтам присваивается один и тот же тег?

2. отслеживание стрелок увеличивается каждый раз, когда начинается касание, я использовал это в своем старом массиве, чтобы отслеживать вещи. Я подумал, что могу использовать его вместо номера тега

Ответ №1:

Не выпускайте снаряд, если свойство nextProjectile не сохранит его. CCSprite spriteWithFile возвращает автоматически выпущенный объект, который сохраняется пакетным узлом и массивом снарядов.

Странно то, что для снаряда никогда не устанавливается тег == 1, поэтому код, который выпускает снаряды, вероятно, будет пропущен.

Я предполагаю, что # 1 снаряд будет остановлен, но он не будет удален, потому что он все еще добавлен в иерархию узлов. Было бы полезно посмотреть код, который фактически удаляет снаряды.

Что касается вашего второго вопроса, я не понимаю вашего беспокойства. У вас есть 7 снарядов. Используют ли они 7 байт, 700 байт или 7 килобайт, просто не имеет значения. Этот объем памяти все еще незначителен по сравнению даже с самыми маленькими текстурами.

Сделайте себе одолжение и используйте обычные базовые коллекции, такие как NSMutableArray, для хранения ваших объектов. Во-первых, они сохранят добавленные объекты и освободят их при удалении. Вы также получаете ошибки, если в вашем коде есть ошибка, которая приводит к переполнению массива. Массивы в стиле C могут быть немного быстрее и могут занимать меньше памяти, но они также по своей сути небезопасны и требуют гораздо большей осторожности.

Комментарии:

1. Можете ли вы мне еще чем-нибудь помочь?

2. Итак, если ваша стрелка останавливается, вероятно, в массиве какая-то путаница. Вы должны пошагово выполнить код в отладчике. Это будет практически невозможно отладить на SO и слишком локализовано. Смотрите Этот пост для получения справки по отладке: learn-cocos2d.com/2011/10/xcode-4-debugging-crashcourse

3. Я исправил проблему, избавился от пакетного узла и сделал кое-что еще.