Iphone CCSprite'的数组;s VS CCSpriteBatchNode和NSMutable数组?
我正在开发一个小的弓箭手游戏,在之前的代码中,我将每个箭精灵放入Iphone CCSprite'的数组;s VS CCSpriteBatchNode和NSMutable数组?,iphone,objective-c,xcode,cocos2d-iphone,Iphone,Objective C,Xcode,Cocos2d Iphone,我正在开发一个小的弓箭手游戏,在之前的代码中,我将每个箭精灵放入CCSprite[7]数组,在ccTime内,我会更新x/y坐标,并做一些数学运算,使箭头移动优美平滑。所以所有的数学/角度/运动都是有效的 后来,在尝试实现碰撞检测时,我无法使用一种能让我的生活变得更轻松的数据类型,我认为它是cgrit,它将获取一个精灵的内容并检查它是否与另一个精灵相交。错误是说我必须使用NSMutable数组的成员或类似的东西,这很好,因为这样对内存更有利,可以将我的精灵放在batchNode和NSMutabl
CCSprite[7]代码>数组,在ccTime内,我会更新x/y坐标,并做一些数学运算,使箭头移动优美平滑。所以所有的数学/角度/运动都是有效的
后来,在尝试实现碰撞检测时,我无法使用一种能让我的生活变得更轻松的数据类型,我认为它是cgrit
,它将获取一个精灵的内容并检查它是否与另一个精灵相交。错误是说我必须使用NSMutable数组的成员或类似的东西,这很好,因为这样对内存更有利,可以将我的精灵放在batchNode和NSMutable数组中。但有一个问题
在我看过的每一个教程中,投射物都是根据预定时间的动作序列移动的。只是一个动作序列的示例(不在我的代码中)
在我所见过的任何地方,精灵都是这样移动的,但我不能这样做,因为箭头的速度取决于触摸的时间长短、使箭头看起来逼真的角度等等
因此,在我的Touches代码中开始:
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阵列时完全相同。唯一的问题是,每次我调用cctouchesbreated
时,如果上一个箭头在飞行途中,它将停止所有操作并坐在那里。半空中。所以我的问题是一个逻辑错误,显然我在touchsbegind中做了一些错误的事情,因为它终止了上一个箭头的投影
因此,我的问题是:
我该如何解决这个问题
我应该坚持使用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;
}
-(void)callEveryFrame:(ccTime)dt{
...
...
//移动选定箭头
对于(int-xe=0;xe<7;xe++{
float x=_theArrowArray[xe]。位置.x;
浮动y=_theArrowArray[xe]。位置。y;
vyArray[xe]+=重力;vyArray是y轴阵列上的速度,我只是在添加重力
x+=vxArray[xe]*dt;//dt在方法定义中的(ccTime)之后
y+=vyArray[xe]*dt;
CGPoint newLocation=CGPointMake(x,y);
_箭头数组[xe]。位置=新位置;
//上面的代码移动CCSprite数组中的箭头,而不是批处理/nsmutable数组。
//下面的代码只是对batchnode/nsmutable的一个复制粘贴,稍作修改
float x2=\u nextproject.x;//mextsprojectle是在我的代码前面声明的
float y2=_nextproject.y;
vyArray[xe]+=重力;vyArray是y轴阵列上的速度,我只是在添加重力
x2+=vxArray[xe]*dt*1.2;//这样(dt*1.2),两个箭头都被射出,但这一个有更大的引力,所以你可以分辨哪个箭头是哪个箭头,并看到它们都在工作。
y2+=vyArray[xe]*dt*1.2;
CGPoint newLocation2=CGPointMake(x2,y2);
_nextproject.position=newlocation2;
}
除非NextProject属性保留投射物,否则不要释放投射物。CCSprite spriteWithFile返回一个自动释放的对象,该对象由batchNode和投射物数组保留
奇怪的是,射弹从来没有设置为具有标记==1,因此释放射弹的代码可能会被跳过
我的猜测是关于#1,射弹将被停止,但不会被删除,因为它仍然添加到节点层次结构中。查看实际删除射弹的代码会很有帮助
至于你的第二个问题,我不理解你的担忧。你有7个投射物。它们是使用7字节、700字节还是7千字节根本不重要。与最小的纹理相比,这个内存量仍然可以忽略不计
帮助自己使用NStutabRayLayCurn等常规基础集合来存储你的对象。对于一个,它们将保留被添加的对象并在删除时释放它们。如果代码中有一个导致数组超时的错误,则还会出现错误。C样式数组可能有点快,可能占用更少的内存,但它们也是继承的。y不安全,需要更加小心地处理。
您为“下一个项目精灵”上的标记指定了哪些值?arrowTracker有哪些值?是否可能所有精灵都被指定了相同的标记?每次触摸开始时,arrow tracker都会递增,我在旧数组中使用它来跟踪事物。我想我可以用它来代替标记号吗?你能再帮我吗?好的,如果你的箭头停止,数组中可能有一些混乱。你应该在调试器中单步执行代码。这几乎不可能在so上进行调试,而且太本地化了。有关调试的帮助,请参阅本文:我解决了问题,摆脱了批处理节点做了一些其他的事情。
-(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;
}