NSMutableArray表现得很奇怪

时间:2014-11-10 04:17:18

标签: ios objective-c arrays xcode nsmutablearray

我的游戏中有一个NSMutableArray,其中数组存储“云”对象。当产生云时,我遍历数组并检查附近是否有云,如果有,那么我不会产生云。这是代码:

BOOL isCloudInRange = NO;
float distance;
do {
    //Horizontal Position
    isCloudInRange = NO;

    if (self.sprite.physicsBody.velocity.dx > 0) {
        cloud.position = CGPointMake(self.sprite.position.x + HW*16/5, 0);
    }
    else if (self.sprite.physicsBody.velocity.dx <0) {
        cloud.position = CGPointMake(self.sprite.position.x-HW*16/5, 0);
    }
    else {
        cloud.position = CGPointMake(self.sprite.position.x, 0);
    }

    //Vertical Position

    int offset = arc4random() % (int) 2*self.frame.size.height;
    offset -= (int) (self.frame.size.height);

    if (self.sprite.physicsBody.velocity.dy > 0) {
        cloud.position = CGPointMake(cloud.position.x, self.sprite.position.y + offset + self.sprite.physicsBody.velocity.dy);
    }
    else if (self.sprite.physicsBody.velocity.dy <0) {
        cloud.position = CGPointMake(cloud.position.x, self.sprite.position.y - offset - self.sprite.physicsBody.velocity.dy);
    }
    else {
        cloud.position = CGPointMake(cloud.position.x, self.sprite.position.y + 16*HW/5);
    }
    if (cloud.position.y <= 300) {
        cloud.position = CGPointMake(cloud.position.x, 100 + arc4random() %200);
    }

    // THIS IS WHERE THE ERROR HAPPENS

    for (SKNode *myNode in arrayOfClouds) {
        float xPos = myNode.position.x;
        float yPos = myNode.position.y;
        distance = sqrt((cloud.position.x - xPos) * (cloud.position.x - xPos) + (cloud.position.y - yPos) * (cloud.position.y - yPos));
        if (distance < 300.0f) {
            NSLog(@"%f",distance);
            isCloudInRange = YES;
        }
    }

} while (isCloudInRange);

如果底部的代码更改为if (distance < 150.0f),一切正常。但是,如果距离保持在300.0f,则在几秒钟或运行时间内,游戏将开始永久迭代。以下是使用此代码的典型日志文件示例:

![hola][1]

如果上面的图片没有显示(我不知道为什么不是),请点击此链接:http://i.stack.imgur.com/qX8h7.png

记录的浮动是云与附近的云之间的距离。这些距离似乎都没有匹配(我没有每秒产生一百万个云,它们被设置为每秒产生一次),并且因为它一旦游戏开始它就会冻结这些日志,我知道不可能是那么多云。怎么了?请帮忙..谢谢!

2 个答案:

答案 0 :(得分:1)

你说&#34;当产生云时,我遍历数组并检查附近是否有云,如果有,那么我不会产生云&#34;但对我来说,看起来你正好相反。如果云在范围内(<300),则将isCloudInRange设置为yes并重复。一旦有足够的云,它总会在范围内找到一个云,它应该无限循环。你产生的云越多越难,每次离开循环(注意你在顶部设置为no)

如果您正在移动云并检查是否在同一个线程上创建它们(同步的代码或函数调用的同一运行循环),您可以尝试使用dispatch_asynch(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)将此代码移动到后台线程。 ),你的代码块在这里);看看是否有帮助。

有关如何使用dispatch_asynch设置并发的信息,请访问:

https://developer.apple.com/library/mac/documentation/General/Conceptual/ConcurrencyProgrammingGuide/ConcurrencyProgrammingGuide.pdf

解释

和块:

https://developer.apple.com/library/mac/documentation/cocoa/conceptual/ProgrammingWithObjectiveC/WorkingwithBlocks/WorkingwithBlocks.html#//apple_ref/doc/uid/TP40011210-CH8-SW1

答案 1 :(得分:1)

我在这里可以看到的主要问题如下:

你有一个do..while循环运行检查你的云距离。一旦云在范围内,您将其标记为YES并重新运行循环。云的X位置在循环中永远不会改变,这意味着它永远不会再次超出范围(无限循环)。

理想情况下,这是一个应该在每个游戏循环中执行一次的检查(删除do while)。

如果你休息一下,它会更有效率;在你的for循环中。一旦在范围内找到了云,就不需要检查其他云,这样你就可以在这里循环。

for (SKNode *myNode in arrayOfClouds) {
    float xPos = myNode.position.x;
    float yPos = myNode.position.y;
    distance = sqrt((cloud.position.x - xPos) * (cloud.position.x - xPos) + (cloud.position.y - yPos) * (cloud.position.y - yPos));
    if (distance < 300.0f) {
        NSLog(@"%f",distance);
        isCloudInRange = YES;
        break; // <--drop out of the for each loop now
    }
}