什么更能代表一个角色,SKNode还是SKSpriteNode?

6

enter image description here目前,我的类看起来像这样

@interface Character : SKNode

@property (nonatomic, assign) CGFloat walkingSpeed;

@implementation Character

+(Character*)characterWithLevel:(BaseLevel *)level {
  return [[self alloc] initWithLevel:level];
}

-(id)initWithLevel:(BaseLevel*)level {

    if (self = [super init]) {
        _sprite = [SKSpriteNode spriteNodeWithImageNamed:level.heroTexture];
        _sprite.position = level.heroStartingPosition;

        [self addChild:_sprite];
        [level addChild:self];
    }

    return self;
}

问题在于,当对关卡中的角色节点运行操作时,由于正在动画的是SpriteNode,因此它根本不会执行任何操作。我想知道你们如何解决这种问题?
操作示例:
触摸事件:
CGPoint location = [[touches anyObject] locationInNode:self];
[character moveToPosition:location];

字符类内部

-(void)move {
    [self runAction:[SKAction repeatActionForever:[SKAction animateWithTextures:[self walkFrames]
                                                                   timePerFrame:0.1f
                                                                         resize:NO
                                                                        restore:YES]] withKey:@"moving"];
    return;
}

这段代码并没有实现任何功能。唯一能让它工作的方法是将Character作为SKSpriteNode的子类。对self.sprite运行动作似乎有点不规范,而且节点本身也不会移动。

有什么建议吗?

1个回答

8
为什么使用self.sprite看起来很奇怪?这是完全有效的。实际上,从面向对象编程的角度来看,SKNode聚合其他可见节点是更具通用性的方法。例如,如果玩家获得了使他隐形(或非常透明)并围绕着他有一些闪亮的东西的能力提升,那么它将允许您隐藏精灵并使粒子发射器可见。为了实现这个效果,你需要将一个发射器作为角色节点的子节点。如果角色节点是玩家精灵,你无法只将精灵变为不可见状态,因为这也会影响子级发射器。因此,从长远来看,更好的方法是聚合视图(可见节点),而不是对它们进行子类化。把Character SKNode想象成一个或多个视图(比如它的子精灵、发射器和标签等)的视图控制器。

1
优秀的解释...不过,当执行移动操作时,我需要在Sprite还是节点上执行呢?移动精灵不会导致它在节点内消失吗? - MrShoot
我按照你建议的方式做了,它执行了我想要的 :) 谢谢。然而,当调用多个触摸事件(取消/移除节点中的所有操作)时,我遇到了崩溃。崩溃似乎没有任何意义,我已经在原始帖子中附上了屏幕截图。 - MrShoot
最好为此开一个新问题。 - CodeSmile

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