【问题标题】:My spritekit game crashes when I am reloading the game?当我重新加载游戏时,我的 spritekit 游戏崩溃了?
【发布时间】:2013-12-24 09:39:04
【问题描述】:

在我的 spritekit 游戏中,我通过更新方法随机创建石头。这是我随机创建石头的代码

//Create random island
-(void)createRandomStone:(NSMutableArray *)imageArray
{

    int getRandomNumberCoordinate = [self getRandomNumberBetween:(int)0 to:(int)768];
    int getRandomStoneImage = [self getRandomNumberBetween:0 to:(int)([imageArray count] - 1)];

    NSLog(@"Stone Image name = %d", getRandomStoneImage);

    SKSpriteNode *createStone = [SKSpriteNode spriteNodeWithTexture:[imageArray objectAtIndex:getRandomStoneImage]];

    if((getRandomNumberCoordinate + createStone.size.height / 2) > 768 )
        createIsland.position = CGPointMake(_myScreenSize.width + createStone.size.width, 768 - createStone.size.height / 2);
    else if((getRandomNumberCoordinate - createStone.size.height / 2) < 0 )
        createStone.position = CGPointMake(_myScreenSize.width + createStone.size.width, 0 + createIsland.size.height / 2);
    else
        createStone.position = CGPointMake(_myScreenSize.width + createStone.size.width, getRandomNumberCoordinate);
    createStone.name = @"Stone";
    createStone.zPosition = 3;
    [self addChild:createStone];

    //Apply physics on the Stone

    createStone.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize: CGSizeMake(createStone.size.width - createStone.size.width / 4, createStone.size.height - createStone.size.height / 6)];
    createStone.physicsBody.categoryBitMask = CollisionTypeStone;
    createStone.physicsBody.contactTestBitMask = CollisionTypeMan;
    createStone.physicsBody.usesPreciseCollisionDetection = YES;
    createStone.physicsBody.collisionBitMask = 0;
}

石头从坐标 1024 移动到 0,如果任何石头越过 0 坐标,石头将使用代码移除

-(void)updateStonePosition:(NSString *)whichDirection andMoveAmount:(float)speed
{
    for (SKNode* node in self.children)
    {
    if([node.name isEqualToString:@"Stone"])
    {
        node.position = CGPointMake(node.position.x - speed, node.position.y);
        if(node.position.x < -node.frame.size.width / 2)
            [node removeFromParent];

    }  
   }
  }

以上两个方法都是从update方法调用的。如果该人被任何 5 块石头击中,那么游戏将再次重新加载。重载代码为:

[self.view presentScene:[[MyScene alloc] initWithSize:self.size] transition:[SKTransition doorsCloseHorizontalWithDuration:0.5f]];

游戏已重新加载,但几秒钟后,一条错误消息显示 EXC_BAD_ACCESS(code=2, address = 0x0) 在线

SKSpriteNode *createStone = [SKSpriteNode spriteNodeWithTexture:[imageArray objectAtIndex:getRandomStoneImage]];

请帮忙。提前致谢。

【问题讨论】:

    标签: ios objective-c ios7 sprite-kit


    【解决方案1】:

    对我来说,根据您提供的代码/信息,当您的场景重新加载时,您传递给“createRandomStone:”的数组似乎为零。

    在调用方法之前尝试检查 nil:

    if (imageArray != nil) {
        // call createRandomStone
    } else {
        NSLog(@"imageArray is nil")
    }
    

    看看这是否有助于确定错误的根本原因。

    【讨论】:

    • 并在函数内部,进一步检查 [imageArray count]>0
    【解决方案2】:

    我还试图找出一些有关如何重置/重新启动 SpriteKit 游戏的信息,但没有成功。我没有花足够的时间来找出为什么会在我的情况下发生这种情况,可能应该尝试在转换发生之前进行一些清理,例如删除所有操作,也许是所有节点......但我为自己找到了一个解决方法......

    因此,当您调用/执行转换到您当前所在的同一场景时,似乎正在发生崩溃,所以我所做的是:

    1) 我过渡到我的 ResetScene,这只是一个空场景 - 有一些参数,所以我可以识别以前的场景

    2) 在 DidMoveToView 的 ResetScene 中,我会转换回之前的场景

    这就是我解决此问题的方法,但我认为这不是一个理想的解决方案。请注意,您无法真正发现有 2 个转换而不是 1 个转换的区别。

    让我们看看是否有人会更聪明地加入这个线程:)

    【讨论】:

    • 感谢您的回复。我正在尝试删除所有动作和节点并重新加载场景,但它再次崩溃。
    【解决方案3】:

    如果您的 imageArray 不是 nil,并且您有多个项目,并且它仍然崩溃,那么您可能遇到了 SpriteKit 的物理体(或其他地方的 skshapenodes)错误之一。 看到这个线程..:https://stackoverflow.com/a/25007468/557362

    我自己也遇到过这种问题,我的通用场景基类中有代码来清理场景,但我不使用物理体 - 这可能是你的问题(见链接)。

    -(void)cleanUp
    {
        [self cleanUpChildrenAndRemove:self];
    }
    
    
    - (void)cleanUpChildrenAndRemove:(SKNode*)node {
        for (SKNode *child in node.children) {
            [self cleanUpChildrenAndRemove:child];
        }
        [node removeFromParent];
    }
    

    我还发现转换时会发生崩溃 - 如果我在转换后延迟清理一秒钟(并让场景保持足够长的时间),我不会发生崩溃。 例如

    SKTransition* doors = [SKTransition fadeWithDuration:0.75]; 
    [[self view] presentScene:newscene transition:doors];
    
    SKNode* dummynode = [SKNode node];
    
    // wait for the transition to complete before we give up the reference to oldscene
    [dummynode runAction:[SKAction waitForDuration:2.0] completion:^{
        // failing to clean up nodes can result in crashes... nice.
        [((MySceneBaseClass*)oldscene) cleanUp];
    }];
    [newscene addChild:dummynode];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-06-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多