CCSprite VS CC SpriteBatch节点和NSMutablearray的数组?

时间:2011-11-02 14:11:45

标签: iphone objective-c xcode cocos2d-iphone

我正在制作一个小弓箭手游戏,之前在我的代码中我将每个箭头精灵放入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];

我见过的每个地方,这就是精灵的移动方式,但我不能这样做,因为箭头的速度会根据触摸的持续时间而变化,角度会使箭头看起来很逼真,就像那样。

所以在我的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](sprite的数组)?我没有找到图像的内容,而是找到箭头的端点,只检查是否与另一个图像相交,但这需要更多的工作/数学/记忆(我不太确定内存的工作原理如何编程...但我很确定CCSprite数组会占用更多内存。
  3. EDIT ---------------------------------------------- -----------------------------------------

    这是箭头位置的更新位置。

    -(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 个答案:

答案 0 :(得分:2)

除非下一个弹丸属性保留弹丸,否则不要释放弹丸。 CCSprite spriteWithFile返回一个自动释放的对象,该对象由batchNode和projectiles数组保留。

奇怪的是,射弹永远不会被设置为标签== 1所以释放射弹的代码可能会被跳过。

我的猜测是关于#1射弹将被停止但是它没有被移除,因为它仍然被添加到节点层次结构中。看到实际移除射弹的代码会很有帮助。

关于你的第二个问题,我不理解你的担忧。你有7个射弹。他们使用7字节,700字节还是7千字节无关紧要。与即使是最小的纹理相比,这种内存量仍然可以忽略不计。

帮自己一个忙,并使用像NSMutableArray这样的常规Foundation集合来存储你的对象。例如,他们将保留添加的对象并在删除时释放它们。如果您的代码有一个导致数组溢出的错误,您也会收到错误。 C风格的数组可能会更快一些,并且可能占用更少的内存,但它们本质上也是不安全的,需要更加谨慎地处理。