2015-06-25 78 views
3

SpriteKit纹理图集我开发一个OS X/iOS的填字游戏中使用的SKLabelNode作为一个SKNode子子显示字谜字母。我可以创建在运行时

所以对于每个字母有SKNode.SKLabelNode。不使用SKLabelNode绘制计数在6-8范围内。使用SKLabelNode他们去了场景中的孩子的数量可以是几乎100

现在我正在寻找一种方法来避免和想出了主意,在SKLabelNode光栅化到纹理,但这并不会降低绘制计数,因为仍然有很多不同的纹理。

我现在的想法就是这些光栅SKNode -Subclasses并把纹理到纹理图集。

所以问题是,是否有可能创造在运行时纹理图集?如果单个纹理改变怎么办?是否有可能在地图集中交换单个纹理,因此我必须重建它?

也许有处理不同SKLabelNodes的大量的“最佳途径”!?

+0

由于FPS较低,您的应用程序是否会遇到性能问题? – sangony

+0

不,绝对不是。但是,对于** SKLabelNode **,我有一个节点数约为** 300节点**和一个**绘制数为100 **。我现在已经为每个可能的情况和字母创建了纹理,并创建了一个纹理地图集,这导致了** 80个节点**和少于** 7个绘制** ...我认为哪个更好,对吗? –

+0

@SimonKemper你不必在运行时创建图集,只需像平常一样创建它。我刚刚搜索,这里是可以用来在运行时创建纹理图集的方法(如果你确实需要的话):https://developer.apple.com/library/ios/documentation/SpriteKit/Reference/SKTextureAtlas/#//apple_ref/occ/clm/SKTextureAtlas/atlasWithDictionary:我同意Sangony认为过早优化是你应该避免的,但是像这样使用SKLabelNodes并不是高性能的解决方案,而且真的不需要IMO。 – Whirlwind

回答

0

我会去信类,这是SKSpriteNode的子类,称为信地图集。这样,您将在单次抽签中抽取所有字母(在这种情况下不需要抽签100次)。或者,你甚至不用做SKSpriteNode的子类...你可以只是这样做:

SKSpriteNode *letterSprite = [SKSpriteNode spriteNodeWithTexture:[atlas textureNamed:[NSString stringWithFormat:@"%@",character]]]; 

这种方法的局限是,信必须预先确定的尺寸。我怀疑你的填字游戏需要不同大小的字母。如果您需要更改字母大小,您仍然可以对其进行缩放,但是由于缩放位图,我认为理论上会出现一些质量损失。我在理论上说,因为在大多数情况下,质量损失并不明显。

这是我的TextNode,它解析给定字符串(数字在我的情况),并创建其在单次通过绘制子画面(而不是使用SKLabelNode为每一个号)的一个实例。在地图册图片应命名为像[email protected][email protected],或者如果使用数字[email protected][email protected]

static const float kCharacterDistance = 6.0f; 

#import "TextNode.h" 

@interface TextNode() 


@property (nonatomic,strong) NSMutableArray* characters; 

@end 

@implementation TextNode 

-(instancetype)initWithPosition:(CGPoint)position andText:(NSString*)text{ 

    if(self =[super init]){ 

     self.characters = [[NSMutableArray alloc] initWithCapacity:[text length]]; 

     SKTextureAtlas *atlas = [SKTextureAtlas atlasNamed:@"numbers"]; 



     for(NSUInteger i =0; i < [text length];i++){ 

      NSString *character = [text substringWithRange:NSMakeRange(i, 1)]; 

      SKSpriteNode *characterSprite = [SKSpriteNode spriteNodeWithTexture:[atlas textureNamed:[NSString stringWithFormat:@"%@",character]]]; 
      characterSprite.color = [SKColor yellowColor]; 
      characterSprite.colorBlendFactor = 1.0f; 
      characterSprite.position = CGPointMake(i*kCharacterDistance,0); 

      [self.characters addObject:characterSprite]; 

      [self addChild:characterSprite]; 
     } 
    self.position = position; 
    } 

    return self; 
} 

@end 

希望这有助于会给你如何在单次抽签中抽取所有字母的基本思路。并注意我如何着色字母。在纹理地图集图像是白色的,但我很容易颜色化为所需的颜色。

+0

这是我已经使用** SSBitmapLabelNode ** - 第三方** SKNode ** - 子类。但是,这会将我的抽签数减少到20-25之间。问题是我的节点树。我有一个子类 - ** SKNode **,它有一个孩子的标签。我正在执行Drag'N'Drop,** SKNode的合并和分组操作** - 子类 - 它比填字游戏更难。问题是这个子类中断了批处理绘制过程,所以我总是以高绘制计数结束,所以我决定将每个字母+背景合并为单个纹理,这给我一个绘制计数<7 –

+0

回到我的问题。我使用'+(void)load'方法尝试了这种方法,并将所有内容合并到**纹理图集**中。问题是,没有办法将** SKTexture **栅格化为UI或NSImage,这对于在运行时创建地图集是必需的... –

+0

@SimonKemper我刚刚更新了我对您关于“创建纹理atlas在运行时“,也许这个链接会有所帮助,但我仍然不确定是否真的需要。我明白你对中断批量过程所说的话,但对于这种情况,20-25次抽签仍然合理。特别是如果你没有遇到性能问题。 – Whirlwind

0

只要你的FPS好,别担心别的。另外,请记住,Xcode auto在运行时创建纹理地图集,所以它不是你必须自己做的。

您可以设置skView.ignoresSiblingOrder = YES;来提高你的表现了一下。

+0

能否请您提供指向Xcode在运行时创建纹理地图集的文档链接? –

相关问题