2013-10-21 4 views
5

Gibt es eine Möglichkeit, ein Bild über einen Bereich wie einen SKSpriteNode zu wiederholen? SKColor colorWithPatternImage funktioniert leider nicht.Sprite Kit und colorWithPatternBeispiel

Edit:

Ich habe die folgenden Kategorien, so scheint es so weit zu arbeiten. Verwenden von Mac, nicht auf iOS getestet. Benötigt wahrscheinlich ein Update für iOS.

// Add to SKSpriteNode category or something. 
+(SKSpriteNode*)patternWithImage:(NSImage*)image size:(const CGSize)SIZE; 

// Add to SKTexture category or something. 
+(SKTexture*)patternWithSize:(const CGSize)SIZE image:(NSImage*)image; 

Und die Implementierungen. Legen Sie die entsprechenden Dateien ein.

+(SKSpriteNode*)patternWithImage:(NSImage*)imagePattern size:(const CGSize)SIZE { 
    SKTexture* texturePattern = [SKTexture patternWithSize:SIZE image:imagePattern]; 
    SKSpriteNode* sprite = [SKSpriteNode spriteNodeWithTexture:texturePattern]; 
    return sprite; 
} 

+(SKTexture*)patternWithSize:(const CGSize)SIZE image:(NSImage*)image { 
    // Hopefully this function would be platform independent one day. 
    SKColor* colorPattern = [SKColor colorWithPatternImage:image]; 

    // Correct way to find scale? 
    DLog(@"backingScaleFactor: %f", [[NSScreen mainScreen] backingScaleFactor]); 
    const CGFloat SCALE = [[NSScreen mainScreen] backingScaleFactor]; 
    const size_t WIDTH_PIXELS = SIZE.width * SCALE; 
    const size_t HEIGHT_PIXELS = SIZE.height * SCALE; 
    CGContextRef cgcontextref = MyCreateBitmapContext(WIDTH_PIXELS, HEIGHT_PIXELS); 
    NSAssert(cgcontextref != NULL, @"Failed creating context!"); 
    // CGBitmapContextCreate(
    //             NULL, // let the OS handle the memory 
    //             WIDTH_PIXELS, 
    //             HEIGHT_PIXELS, 

    CALayer* layer = CALayer.layer; 
    layer.frame = CGRectMake(0, 0, SIZE.width, SIZE.height); 

    layer.backgroundColor = colorPattern.CGColor; 

    [layer renderInContext:cgcontextref]; 

    CGImageRef imageref = CGBitmapContextCreateImage(cgcontextref); 

    SKTexture* texture1 = [SKTexture textureWithCGImage:imageref]; 
    DLog(@"size of pattern texture: %@", NSStringFromSize(texture1.size)); 

    CGImageRelease(imageref); 

    CGContextRelease(cgcontextref); 

    return texture1; 
} 

Ok das wird auch benötigt. Dies funktioniert wahrscheinlich nur auf Mac.

CGContextRef MyCreateBitmapContext(const size_t pixelsWide, const size_t pixelsHigh) { 
    CGContextRef context = NULL; 
    CGColorSpaceRef colorSpace; 
    void *   bitmapData; 
    //int    bitmapByteCount; 
    size_t    bitmapBytesPerRow; 

    bitmapBytesPerRow = (pixelsWide * 4);// 1 
    //bitmapByteCount  = (bitmapBytesPerRow * pixelsHigh); 

    colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);// 2 
    bitmapData = NULL; 

#define kBitmapInfo  kCGImageAlphaPremultipliedLast 
//#define kBitmapInfo  kCGImageAlphaPremultipliedFirst 
//#define kBitmapInfo  kCGImageAlphaNoneSkipFirst 
    // According to http://stackoverflow.com/a/18921840/129202 it should be safe to just cast 
    CGBitmapInfo bitmapinfo = (CGBitmapInfo)kBitmapInfo; //kCGImageAlphaNoneSkipFirst; //0; //kCGBitmapAlphaInfoMask; //kCGImageAlphaNone; //kCGImageAlphaNoneSkipFirst; 
    context = CGBitmapContextCreate (bitmapData,// 4 
            pixelsWide, 
            pixelsHigh, 
            8,  // bits per component 
            bitmapBytesPerRow, 
            colorSpace, 
            bitmapinfo 
            ); 
    if (context== NULL) 
    { 
     free (bitmapData);// 5 
     fprintf (stderr, "Context not created!"); 
     return NULL; 
    } 
    CGColorSpaceRelease(colorSpace);// 6 

    return context;// 7 
} 
+0

Ich habe versucht, es funktioniert .. muss ein Fehler mit colorWithPatternImage und initWithPatternImage, kein Glück überhaupt. – DogCoffee

+0

Für Mac geschrieben, nicht auf iOS getestet. Ich sage nur – Jonny

+0

Ich habe für iOS getestet und kein Glück, etwas mit diesen Methoden zu arbeiten. – DogCoffee

Antwort

3

iOS Arbeitscode:

CGRect textureSize = CGRectMake(0, 0, 488, 650); 
CGImageRef backgroundCGImage = [UIImage imageNamed:@"background.png"].CGImage; 

UIGraphicsBeginImageContext(self.level.worldSize); // use WithOptions to set scale for retina display 
CGContextRef context = UIGraphicsGetCurrentContext(); 
CGContextDrawTiledImage(context, textureSize, backgroundCGImage); 
UIImage *tiledBackground = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

SKTexture *backgroundTexture = [SKTexture textureWithCGImage:tiledBackground.CGImage]; 
SKSpriteNode *backgroundNode = [SKSpriteNode spriteNodeWithTexture:backgroundTexture]; 
[self addChild:backgroundNode]; 
0

Ja, es ist möglich, dass mit einem Aufruf an CGContextDrawTiledImage() zu implementieren, aber dass vergeudet vielen Speicher für mittlere und großen Knoten. Ein wesentlich verbesserter Ansatz wird bei spritekit_repeat_shader bereitgestellt. Dieser Blogbeitrag enthält Beispiel-GLSL-Code und BSD-lizenzierte Quelle wird bereitgestellt.