2015-09-12 53 views
1

我有一個NSView的子類,我需要繪製雙色跳棋(交替顏色的正方形)。以下是我的。NSView - 繪製2色跳棋

- (void)drawRect:(NSRect)rect {  
    NSInteger k = 1; 
    for (int j = 0; j < self.frame.size.width; j += 20) { 
     for (int i = 0; i < self.frame.size.height; i +=20) { 
      if (k%2 == 0) { 
       [[NSColor whiteColor] set]; 
      } 
      else { 
       [[NSColor lightGrayColor] set]; 
      } 
      [NSBezierPath fillRect:NSMakeRect(j,i,20,20)]; 
      k++; 
     } 
    } 
} 

如果我運行它,我會得到交替顏色的正方形。如果我改變框架高度,我有時會得到交替顏色的條紋。我如何改進上面的代碼?

謝謝。

回答

0

你確定平方顏色交替向下的顏色的方法一列,然後繼續下一列。如果你有一個偶數行,每一行將以相同的顏色開始,給你條紋。

認爲簡單,你只需要兩個狀態 - 黑色或白色 - 所以不是整數,加法和奇數/偶數測試將整數減少到兩個值之一,只是以只有兩個值的類型開始,即布爾。

要處理奇數行或偶數行的問題,請使用兩個變量,一個用於跟蹤列中第一個方塊的顏色 - 這將翻轉外部循環的每次迭代,一個用於跟蹤顏色的當前平方 - 對於每列,它以第一個變量的值開始,並翻轉內循環的每次迭代。

在代碼大綱,外循環之前:

BOOL colStartsWhite = YES; // or NO, you decide - this is the corner color 

裏面的外環:

BOOL squareIsWhite = colStartsWhite; // inner tracker 
colStartsWhite = !colStartsWhite; // flip ready for next column 

內環內:

if (squareIsWhite) ... else ... // fill the square 
squareIsWhite = !squareIsWhite; // flip for next square 

HTH

0

請記住,您的視圖不會因爲它被調整大小而重繪!所以你的棋盤被擠壓或拉伸與視圖。您可以致電setNeedsDisplay

+0

請原諒我,但不能保證框架itsel f是正方形。所以我不能用不同的數字來分隔寬度和高度。 –

1

繪製棋盤圖案的另一種方法是在繪圖程序中製作2x2棋盤,將其作爲資源添加到項目中,將該圖像傳遞到+[NSColor colorWithPatternImage:],然後您可以用該顏色填充區域。

1

好的,所以問題是一行可能有奇數個方格,在這種情況下,下一行再次顯示相同的模式。以下是我如何解決這個問題。我也改變了NSBezierPath到NSRectFill()的使用,因爲後者在概念上更簡單並且可能更快。

- (void)drawRect:(NSRect)rect {  
    for (int j = 0; j * 20 < self.frame.size.width; j++) { 
     for (int i = 0; i * 20 < self.frame.size.height; i++) { 
      if (((i^j) & 1) == 0) 
       [[NSColor whiteColor] set]; 
      else 
       [[NSColor lightGrayColor] set]; 
      NSRectFill(NSMakeRect(j*20,i*20,20,20)); 
     } 
    } 
} 

的​​使用按位異或(^運算符),然後按位與(所述&操作者)的奇偶狀態結合行和列索引兩者。會有多種方法來優化乘法,但是這些代碼似乎是最明智的方式。 ,將運行速度更快,或許會避免一些繪圖僞像將涉及首先清除到一種顏色,然後繪製僅相反顏色的正方形一個有些清潔器版本:

- (void)drawRect:(NSRect)rect { 
    [[NSColor whiteColor] set]; 
    NSRectFill(rect); 
    [[NSColor lightGrayColor] set]; 
    for (int j = 0; j * 20 < self.frame.size.width; j++) 
     for (int i = 0; i * 20 < self.frame.size.height; i++) 
      if ((i^j) & 1) 
       NSRectFill(NSMakeRect(j*20,i*20,20,20)); 
} 
+0

感謝您的嘗試。如果我運行第一組代碼,我會得到完全灰色的背景。如果我運行第二組代碼,我會得到一個完全灰色的背景,對角線爲白色方塊。如果((i^j)&1)我想你有一個錯字。 –

+0

第一個代碼塊中有一個我剛剛修復的拼寫錯誤。 (由於運算符優先級問題,缺少(i^j)&1的括號)。第二個代碼塊完美地工作;我只是測試它。我不確定它爲什麼不適合你,但如果你認爲它((i^j)&1)的使用是一個錯字,並且試圖糾正這個錯字,那麼你可能引入了一個錯誤。無論如何,這兩個代碼塊現在都可以正常工作。 – bhaller

+0

是的。第一組代碼現在可用。謝謝。 –