我使用Objective-C在SpriteKit中创建游戏。我正在尝试为游戏中的屏幕生成块。
我在启动时遇到应用程序崩溃:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Attemped to add a SKNode which already has a parent: <SKSpriteNode> name:'Block-0.000000-440.000000' texture:['nil'] position:{0, 440} size:{64, 64} rotation:0.00'
*** First throw call stack:
(
0 CoreFoundation 0x00891df6 __exceptionPreprocess + 182
1 libobjc.A.dylib 0x0051ba97 objc_exception_throw + 44
2 CoreFoundation 0x00891d1d +[NSException raise:format:] + 141
3 SpriteKit 0x00e8c94c -[SKNode addChild:] + 119
4 Hidden Route 0x0003b3c1 -[GameScene didMoveToView:] + 2417
5 SpriteKit 0x00e6031b -[SKScene _didMoveToView:] + 97
6 SpriteKit 0x00e7b157 -[SKView presentScene:] + 283
7 Hidden Route 0x00039e9e -[GameViewController viewDidLoad] + 526
8 UIKit 0x0115ad54 -[UIViewController loadViewIfRequired] + 771
9 UIKit 0x0115b045 -[UIViewController view] + 35
10 UIKit 0x0105f477 -[UIWindow handleStatusBarChangeFromHeight:toHeight:] + 879
11 UIKit 0x0106252d +[UIWindow _noteStatusBarHeightChanged:oldHeight:forAutolayoutRootViewsOnly:] + 273
12 UIKit 0x01006ad1 __79-[UIApplication _setStatusBarHidden:animationParameters:changeApplicationFlag:]_block_invoke + 163
13 UIKit 0x010862c6 +[UIView(UIViewAnimationWithBlocks) _setupAnimationWithDuration:delay:view:options:factory:animations:start:animationStateGenerator:completion:] + 494
14 UIKit 0x01086701 +[UIView(UIViewAnimationWithBlocks) animateWithDuration:animations:completion:] + 115
15 UIKit 0x0100699e -[UIApplication _setStatusBarHidden:animationParameters:changeApplicationFlag:] + 506
16 UIKit 0x01006128 -[UIApplication _updateCurrentStatusBarViewControllerAppearance] + 286
17 UIKit 0x0105223a -[UIWindow _updateContextOrderingAndSetLayerHidden:] + 548
18 UIKit 0x0105319e -[UIWindow _setHidden:forced:] + 257
19 UIKit 0x01053473 -[UIWindow _orderFrontWithoutMakingKey] + 49
20 UIKit 0x01061615 -[UIWindow makeKeyAndVisible] + 80
21 UIKit 0x00ffecd6 -[UIApplication _callInitializationDelegatesForMainScene:transitionContext:] + 3108
22 UIKit 0x0100216d -[UIApplication _runWithMainScene:transitionContext:completion:] + 1639
23 UIKit 0x0101ad30 __84-[UIApplication _handleApplicationActivationWithScene:transitionContext:completion:]_block_invoke + 59
24 UIKit 0x01000d7f -[UIApplication workspaceDidEndTransaction:] + 155
25 FrontBoardServices 0x06f909de __37-[FBSWorkspace clientEndTransaction:]_block_invoke_2 + 71
26 FrontBoardServices 0x06f9046f __40-[FBSWorkspace _performDelegateCallOut:]_block_invoke + 54
27 FrontBoardServices 0x06fa2425 __31-[FBSSerialQueue performAsync:]_block_invoke + 26
28 CoreFoundation 0x007b57a0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 16
29 CoreFoundation 0x007ab0b3 __CFRunLoopDoBlocks + 195
30 CoreFoundation 0x007aaf0b __CFRunLoopRun + 2715
31 CoreFoundation 0x007aa1ab CFRunLoopRunSpecific + 443
32 CoreFoundation 0x007a9fdb CFRunLoopRunInMode + 123
33 UIKit 0x01000744 -[UIApplication _run] + 571
34 UIKit 0x01003e16 UIApplicationMain + 1526
35 Hidden Route 0x0003c41d main + 141
36 libdyld.dylib 0x02fa0ac9 start + 1
37 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
我查看了堆栈跟踪,发现造成问题的方法是我的didMoveToView:
方法,即:
-(void)didMoveToView:(SKView *)view
{
// ViewDidLoad
[self initialize];
/* Setup your scene here
SKLabelNode *myLabel = [SKLabelNode labelNodeWithFontNamed:@"Arial"];
myLabel.text = @"Hello, World!";
myLabel.fontSize = 65;
myLabel.position = CGPointMake(CGRectGetMidX(self.frame),
CGRectGetMidY(self.frame));
*/
player = [SKSpriteNode spriteNodeWithColor:[AppDelegate getRandomColor] size:CGSizeMake(40, 40)];
player.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame));
[self generateBoard];
[self generateNextAtIndex:kNeed - 3];
int width = (self.frame.size.width) / [AppDelegate numberOfColumns];
int height = (self.frame.size.height) / kNeed;
for (int i = 0; i < boardRows.count; i++)
{
Row *current = [boardRows objectAtIndex:i];
for (int j = 0; j < current.blocks.count; j++)
{
Block *block = [current.blocks objectAtIndex:j];
block.anchorPoint = CGPointMake(0, 1);
block.position = CGPointMake((j * width), self.frame.size.height - (i * width));
[block setName:[NSString stringWithFormat:@"Block-%f-%f", block.position.x, block.position.y]];
NSLog(@"Position for item %i", i);
block.size = CGSizeMake(width, width);
[self addChild:block];
}
}
[self addChild:player];
}
我觉得它与self addChild:block
行有关,但我无法找到解决方案。如果您需要更多信息,我会在此处发布(只是要求它)
感谢您的帮助
编辑1:
generateBoard
方法:
- (void)generateBoard
{
int rnd = 2;
int from = rnd;
int to = 0;
Row *row = [defaultRows objectAtIndex:rnd];
[boardRows replaceObjectAtIndex:0 withObject:row];
for (int i = 2; i < boardRows.count; i++)
{
rnd = arc4random() % [AppDelegate numberOfColumns];
to = rnd;
Row *rowThis = [defaultRows objectAtIndex:rnd];
Row *rowBelow = [[Row alloc] initWithSize:CGSizeMake(self.frame.size.width, self.frame.size.height) need:kNeed];
[rowBelow generateWithPoint:from toPoint:to];
[boardRows replaceObjectAtIndex:i withObject:rowThis];
[boardRows replaceObjectAtIndex:i-1 withObject:rowBelow];
to = from;
from = rnd;
// to make it add 2
i++;
}
}
编辑2:
在异常断点中添加后,它显示导致问题的行是self addChild:block
行
答案 0 :(得分:0)
这个问题的答案非常简单,基本上我有一些预配置的块来简化生成,但是在这样做时,调用self addChild:block
实际上是在尝试添加相同的块(具有相同的内存地址)一次进入2个地方,因此崩溃了应用程序。
我刚刚在Block类中添加了一个重复的函数,并开始实现它而不是直接调用块。