Массив VS CCSpriteBatchNode и массива NSMutable в CCSprite? - PullRequest
1 голос
/ 02 ноября 2011

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

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

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

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

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

Так что в моем коде в штрихах: Beg:

    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 Ответ

2 голосов
/ 02 ноября 2011

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

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

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

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...