2015-10-14 118 views
7

包圍一個UIView的路徑在iOS系統9蘋果公司推出了collisionBoundsTypeUIKit-Dynamics設置碰撞的iOS 9

我沒有問題,設置這個UIDynamicItemCollisionBoundsTypeRectangle或當我設置爲UIDynamicItemCollisionBoundsTypeEllipse時。

下面的屏幕截圖是從遊戲我提出讓玩家的collisionBoundsType設置爲矩形,球被設置爲橢圓:

enter image description here

但是,當我設置玩家的collisionBoundsType到路上,我得到奇怪的行爲,在這裏看到:

enter image description here

的看法比它應該出現更高的碰撞身體向右它應該在哪裏。

目前我有collisionBoundingPath一套這樣的:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

此外,我的drawRect函數如下所示:

- (void) drawRect:(CGRect)rect 
{ 
    if (!_color){ 
    [self returnDefualtColor]; 
    } 
    if (!maskPath) maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    [_color setFill]; 
    [maskPath fill]; 
} 

這究竟是爲什麼?如何將碰撞體的路徑設置爲與視圖中的圖形相同?

另外,紅色是視圖(即view.backgroundColor = [UIColor redColor];)的只是背景。

+0

不是繪圖專家,但文檔建議路徑應該是多邊形。您的代碼添加了一個弧,但沒有關閉路徑。也許你應該調用'[maskPath closePath]'來創建一個封閉的路徑,這可能會有所不同? –

+0

它會自動關閉 – WMios

+0

對於填寫'drawRect',情況就是這樣。你確定你的'collisionBoundingPath'嗎?它在文檔中說它關閉路徑的地方在哪裏? –

回答

2

從上UIDynamicItem here的文檔,關於路徑的座標系下面的語句似乎代表了什麼是錯的:

創建必須代表與 反凸多邊形的路徑對象順時針或順時針纏繞,並且路徑不能相交於其自身。路徑的(0,0)點必須位於相應動態項目的中心點 處。如果中心點 與路徑的原點不匹配,則碰撞行爲可能不起作用 預期。

這裏指出路徑的(0,0)必須是中心點。

我會認爲你的弧形路徑的中心應該是(0,0)而不是(SLIME_SIZE/2,SLIME_SIZE/2)。你有沒有設置UIView幀的寬度和高度爲SLIME_SIZE而不是SLIME_SIZE*2

SLIME_SIZE確實似乎定義了半徑,所以框架寬度應該是SLIME_SIZE*2。如果它被設置爲SLIME_SIZE,那麼這將解釋爲什麼您需要將SLIME_SIZE/2作爲更正來翻譯。

+0

很好的答案,這真的解釋了爲什麼我的修復工作的原因。 – WMios

1

我能夠通過改變來回答這樣的:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE, SLIME_SIZE) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

到:

- (UIBezierPath *)collisionBoundingPath 
{ 
    maskPath = [[UIBezierPath alloc] init]; 
    [maskPath addArcWithCenter:CGPointMake(SLIME_SIZE/2, SLIME_SIZE/2) radius:SLIME_SIZE startAngle:0*M_PI endAngle:M_PI clockwise:NO]; 
    return maskPath; 
} 

關鍵的區別是,我修改的圓弧的中心通過將x和y值由2

1

調試物理是一件事情。這可能不是iOS用戶傾向於考慮的東西,因爲他們通常使用UIKit Dynamics完成非常簡單的事情。這有點令人遺憾,因爲它是iOS最新版本的最佳方面之一,並提供了一種真正有趣的方式來提供令人信服的用戶體驗。

那麼...如何調試物理?

一種方法是從心理上想象發生了什麼,然後將其與發生的事情聯繫起來,並找出想象與真實之間的不和諧,然後通過消除,精神或實際試驗的混合過程來解決問題&錯誤和扣除,直到問題確定並解決。

另一種方式是對所有創建和交互的視覺描繪呈現足夠的反饋,以更快地確定元素的性質和範圍,它們之間的關係和事件/事件,並通過文字視線來解決問題。

爲此,自推出以來,已經創建了各種可視化調試器和物理仿真的構建器。

不幸的是,iOS沒有UIKit Dynamics的這種基於屏幕的編輯器或「場景編輯器」,在Sprite套件和場景套件中可用於這種可視化調試的功能是最基本的。

但是,在所有UIKit視圖中都有CALayers,可以手動創建和繪製CAShapeLayers以精確地表示任何和所有物理元素,它們的邊界以及它們的錨點和關係。

CAShapeLayers是CGPaths的「容器」,對於輪廓和填充以及一個CAShapeLayer中的多個CGPath元素可以有不同的顏色。

,借用偉大羅布:

「如果添加了CAShapeLayer作爲一個層到一個視圖,你不必 自己實現任何繪圖代碼只需添加CAShapeLayer和 例如,你甚至可以稍後改變路徑,並且它會自動爲你重新繪製,CAShapeLayer可以讓你擺脫編寫你自己的drawRect或drawLayer例程的 雜草。

如果你有互動元素的數量巨大,並希望對其進行調試,CAShapeLayer的性能問題可能會發揮作用,此時你可以用shouldRasterize每個轉換爲位圖,並獲得顯著改善時的性能達到由CAShapeLayers的「動態」功能創造的極限。此外,爲了表示諸如約束和關節之類的東西,只需簡單設置屬性即可在CAShapeLayers上創建虛線。以下是設置CAShapeLayer屬性的基礎知識,以及使用數組創建塊筆畫,寬度爲3,無填充的5-5-5虛線輪廓的基礎知識。

CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
[shapeLayer setBounds:self.bounds]; 
[shapeLayer setPosition:self.center]; 
[shapeLayer setFillColor:[[UIColor clearColor] CGColor]]; 
[shapeLayer setStrokeColor:[[UIColor blackColor] CGColor]]; 
[shapeLayer setLineWidth:3.0f]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setLineDashPattern: 
[NSArray arrayWithObjects:[NSNumber numberWithInt:10], 
    [NSNumber numberWithInt:5],nil]];