2010-05-31 31 views
6

我正在爲使用Cocoa的Mac編寫遊戲。我目前正在實施命中測試,並發現CALayer提供命中測試,但似乎沒有實現alpha屬性。正如我有時候許多CALayer堆疊在一起,我真的需要找到一種方法來確定用戶實際上想要點擊什麼。使用CALayer內容的alpha屬性命中測試

我在想如果我能以某種方式獲得一個包含指向包含點擊點的所有CALayers的指針的數組,我可以通過它們過濾一些方法。不過,我已經走到這一步,創建磁盤陣列的唯一途徑是:

NSMutableArray* anArrayOfLayers = [NSMutableArray array]; 
    for (CALayer* aLayer in mapLayer.sublayers) 
    { 
     if ([aLayer containsPoint:mouseCoord]) 
      [anArrayOfLayers addObject:aLayer]; 
    } 

然後通過的CALayer的Z值的數組排序,然後經過檢查,如果在位置的像素是阿爾法與否。然而,在排序和阿爾法檢查之間,這似乎是一個令人難以置信的表現豬。 (你會怎麼檢查阿爾法?)

有沒有辦法做到這一點?

回答

10

東西我偶然發現而抓我的頭過類似的問題是CALayer的使用containsPoint:當你把它hitTest:

它的默認行爲是要測試的範圍,但是我們可以覆蓋,並讓它檢查阿爾法通道,只是使用的CALayer內置的命中測試來處理餘下的:

- (BOOL) containsPoint:(CGPoint)p 
{ 
    return CGRectContainsPoint(self.bounds, p) && !ImagePointIsTransparent(self.contents, p)) return YES; 
} 

有在Retrieving a pixel alpha value for a UIImage

T檢驗原理對單個像素的Alpha的討論他對我的工作的目的:

static BOOL ImagePointIsTransparent(CGImageRef image, CGPoint p) 
{ 
    uint8_t alpha; 

    CGContextRef context = CGBitmapContextCreate(&alpha, 1, 1, 8, 1, NULL, kCGImageAlphaOnly); 
    CGContextDrawImage(context, CGRectMake(-p.x, -p.y, CGImageGetWidth(image), CGImageGetHeight(image)), image); 
    CGContextRelease(context); 

    return alpha == 0; 
} 

(如果你使用renderInContext:繪製到CALayer的,而不是設置它的內容屬性,那麼它將會更加複雜。這可能是有用的,在這種情況下:http://www.cimgf.com/2009/02/03/record-your-core-animation-animation/

+0

克里斯,這是了不起!對你的問題:當通過這一點時,它似乎要求它的原點位於左下角和右上角。我懷疑這是在通過此處之前必須發生的事情,對吧? (除了使用圖像高度來翻轉y)。我想我正在試圖確定放置該調整的正確位置 - 在ImagePointIsTransparent中,還是在手勢/觸摸處理函數中。 – 2011-09-19 18:50:15

+0

碰巧,我認爲我鏈接的問題是關於你所問的--Core Graphics和UIKit有不同的Y軸,所以我想你會想在兩者之間的接口進行轉換。還有一個關於渲染圖層的不同方式對性能產生影響的討論(重複渲染所有圖層而不是重複像素),您可能還想查看一下。 – 2011-09-19 21:14:51

+0

克里斯,我剛剛意識到:你正在寫一個Mac應用程序。我在寫一個iOS應用程序。事實證明,使用Retina顯示器時,此測試不起作用(在iPhone 4或Retina模式下的模擬器上)。 「Quartz 2D編程指南」建議我使用UIGraphicsBeginImageContextWithOptions與較低級別的Quartz函數,所以我將不得不看看CTM是否有幫助等等。 (這也可以解釋爲什麼響應似乎「在整個地方」在視網膜上。)http://stackoverflow.com/questions/7506248/alpha-detection-in-layer-ok-on-simulator-not-iphone – 2011-09-22 16:16:48