2013-10-21 11 views
5

Abbiamo un modo di ripetere un'immagine su un'area, come un SKSpriteNode? SKColor colorWithPatternImage purtroppo non funziona.Kit sprite e colorWithPatternImage

Edit:

ho fatto le seguenti categorie, sembra funzionare finora. Utilizzo di Mac, non testato su iOS. Probabilmente ha bisogno di qualche correzione per 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; 

E le implementazioni. Inserisci i rispettivi file.

+(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 anche questo è necessario. Questo probabilmente funziona solo su 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

ho provato a farlo funzionare .. deve essere un bug con colorWithPatternImage e initWithPatternImage, senza fortuna. – DogCoffee

+0

Scritto per Mac, non testato su iOS. Ho appena detto – Jonny

+0

che ho provato per iOS e non ho avuto fortuna a trovare qualcosa su cui lavorare con questi metodi. – DogCoffee

risposta

3

iOS codice di lavoro:

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

Sì, è possibile implementare che con una chiamata a CGContextDrawTiledImage(), ma che spreca un sacco di memoria per medie e grandi dimensioni nodi. Un approccio significativamente migliorato è fornito a spritekit_repeat_shader. Questo post sul blog fornisce codice GLSL di esempio e viene fornita una fonte con licenza BSD.

Problemi correlati