Sprite Kit 修改子 SKShapeNode 的属性无效

3

我有一个名为Node的类,

NodeSKNode的子类,

我在Node对象的init方法中创建并添加了一个SKShapeNode对象作为其子节点,

但是当我尝试在将其添加为子节点后修改此子对象时,什么也没有发生。

@interface Node ()
@property (nonatomic, strong) SKShapeNode *circle;
@end

@implementation Node

- (id)initWithRadius:(float)radius{

    if (self = [super init]) {
        _circle = [SKShapeNode shapeNodeWithCircleOfRadius:radius];
        _circle.fillColor = [UIColor whiteColor];
        _circle.name = @"c";
        [self addChild:_circle];
    }
    return self;
}

//1st type of handling child object
- (void)setHighlighted{

    NSLog(@"Called");
    SKShapeNode *circ = (SKShapeNode *)[self childNodeWithName:@"/c"];
    circ.fillColor = [SKColor redColor];
}

我也尝试直接更改属性的属性。
- (void)setHighlighted{

   _circle.fillColor = [SKColor redColor];
}

肯定调用了setHighlighted方法。

我甚至尝试过[_circle removeFromParent],然后设置位置、透明度、isHidden属性,但仍然没有任何反应!

问题出在哪里呢?

谢谢。

编辑:

上面的代码没有问题!

很抱歉,问题是这样的: 我有一个NSArray *nodes, 我正在填充nodes,并且在创建它们的同时将它们存储在一个虚拟NSMutableArray *mutableNodesArray中,同时将它们添加为场景的子对象; 在循环结束后,我从mutableNodesArray“复制”对象到nodesArray中,

所以当我试图对存储在nodesArray中的Node对象进行操作时,方法被调用了,但这些方法并不属于作为子对象添加的Node对象......

这是我的错误......


1
你应该使用第二种方法,因为circle是全局的,比第一种方法更高效。 - Knight0fDragon
2个回答

3
我想你的问题在这一行:


SKShapeNode *circ = (SKShapeNode *)[self childNodeWithName:@"/c"];

那可能是:

SKShapeNode *circ = (SKShapeNode *)[self childNodeWithName:@"//c"];

API参考文档中的差异:

/ :

当放置在搜索字符串的开头时,表示应在树的根节点上执行搜索。当放置在搜索字符串的任何位置时,表示应移动到节点的子级进行搜索。

// :

当放置在搜索字符串的开头时,指定应从根节点开始递归地执行整个节点树上的搜索。否则,它将从其当前位置执行递归搜索。

您可以尝试在以下行中设置断点,并使用po circ.debugDescription检查调试控制台中的circ属性:

(断点设置在此行:) -> circ.fillColor = [SKColor redColor];

您也可以尝试使用customActionWithDuration

SKAction* circleColor = [SKAction customActionWithDuration:0.5f actionBlock:^(SKNode *node, CGFloat elapsedTime)
{
    circ.fillColor = [UIColor colorWithRed:1.0f green:0.0f blue:0.0f alpha:1.0f];
    NSLog(@"changed to red");
}];
[circ runAction:circleColor];

不幸的是,@"//c"并没有解决问题。我已经使用/c和//c查看了调试描述,对象是有效的。奇怪的是,当我使用SKSpriteNode子对象执行原始问题中的操作时,没有问题(唯一的区别是:我从场景对象发送精灵节点对象,而不是在Node类的init方法中构造)。但是SKShapeNode子对象似乎是静态的(就像我需要调用setNeedsDisplay之类的消息 :) 甚至无法从父级中删除它。 - user3390500
谢谢,我明天才能尝试您的建议,但我认为SKAction方法会直观地解决问题,所以我将其标记为正确答案。我可以理解为什么更改与核心图形相关的属性不起作用,但真的很想知道为什么我无法更改位置等(矩阵/变换相关属性),甚至不能直接从父级中删除而不使用SKAction,有什么想法吗? - user3390500
这项工作很大程度上取决于您调用这些更改的确切时刻,didMoveToView 应该是正确的方法。此外,与 SKSpriteNode 不同,SKShapeNode 没有直接的颜色属性。因此,在 SKShapeNode 中不存在由其他操作调用的“color” getter/setter 方法。在 didFinishUpdate() 中进行调试以查看 fillColor 是否更改其值值得一试...这只是一个想法... - Alessandro Ornano
不幸的是,SKAction方法没有解决问题。非常奇怪的是,在将SKShapeNode作为SKNode的子节点添加后,之后我无法对其进行任何操作... - user3390500
请检查我编辑过的问题。这是我在 Stack Overflow 上的第一个问题,我应该删除它吗? - user3390500
1
@user3390500。不,这是一个好问题,请务必回答。未来的人们会看到它,并获得那个“啊哈!”或者“我真傻”的时刻,你将帮助他们。 - Knight0fDragon

0

这是问题:

- (void)setupNodes{

    NSMutableArray *mutableNodesArray = [[NSMutableArray alloc] init];
    for (int i=0; i<6; i++) {
        Node *node = [[Node alloc] initWithRadius:nodeRadius];
        [self addChild:node];
        [mutableNodesArray addObject:node];
    }

    //Problematic Statement!
    _nodes = [[NSArray alloc] initWithArray:mutableNodesArray copyItems:YES];
}

- (void)operation{
    //This is not the node that is visible on the scene!
    [(Node*)[_nodes objectAtIndex:0] setHighlighted:YES];
}

解决方案是:

_nodes = [[NSArray alloc] initWithArray:mutableNodesArray];

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接