2015-10-14 7 views
7

In iOS 9 Apple ha introdotto collisionBoundsType in UIKit-Dynamics.Impostazione del percorso di limitazione delle collisioni di un UIView in iOS 9

Non ho alcun problema quando si imposta questo UIDynamicItemCollisionBoundsTypeRectangle o quando si imposta su UIDynamicItemCollisionBoundsTypeEllipse.

La figura seguente è da un gioco che sto facendo in cui la collisionBoundsType del lettore è impostato su rettangolo e la palla è impostato ellisse:

enter image description here

Tuttavia, quando ho impostato il collisionBoundsType al giocatore percorso ottengo un comportamento strano come si vede qui:

enter image description here

la vista appare superiore a quello che dovrebbe e il corpo di collisione è a destra di dove dovrebbe essere.

Attualmente ho collisionBoundingPath insieme a questo:

- (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; 
} 

Inoltre, la mia funzione drawRect assomiglia a questo:

- (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]; 
} 

Perché succede questo? Come faccio a impostare il percorso del corpo di collisione per essere uguale al disegno nella vista?

Inoltre, il rosso è solo lo sfondo della vista (ad esempio view.backgroundColor = [UIColor redColor];).

+0

Non un esperto di disegno, ma la documentazione suggerisce che il percorso dovrebbe essere un poligono.Il tuo codice aggiunge un arco ma non chiude il percorso. Forse dovresti chiamare '[maskPath closePath]' per creare un percorso chiuso che potrebbe fare la differenza? –

+0

Si chiude automaticamente – WMios

+0

Per il riempimento in 'drawRect' questo sarà il caso. Sei sicuro per il tuo 'collisionBoundingPath'? Dove dice nei documenti che chiude il percorso? –

risposta

2

Dalla documentazione sulla UIDynamicItem here, la seguente dichiarazione circa il sistema di coordinate per i percorsi sembra rappresentare ciò che è sbagliato:

L'oggetto percorso creato deve rappresentare un poligono convesso con contatore - in senso antiorario o in senso orario, e il percorso non deve essere intersecato da . Il punto (0, 0) del percorso deve trovarsi nel punto centrale dell'elemento dinamico corrispondente. Se il punto centrale non corrisponde all'origine del percorso, i comportamenti di collisione potrebbero non funzionare come previsto .

Qui si afferma che lo (0,0) per il percorso DEVE essere il punto centrale.

Penso che il centro del percorso dell'arco dovrebbe essere (0,0) e non (SLIME_SIZE/2,SLIME_SIZE/2). Hai forse impostato la larghezza e l'altezza del riquadro UIView su SLIME_SIZE anziché su SLIME_SIZE*2?

SLIME_SIZE sembra davvero definire il raggio, quindi la larghezza del frame deve essere SLIME_SIZE*2. Se è impostato come SLIME_SIZE, ciò spiegherebbe perché è necessario tradurre da SLIME_SIZE/2 come correzione.

+0

Ottima risposta, questo spiegava davvero il ragionamento dietro il perché la mia correzione funzionava. – WMios

1

ho potuto rispondere a questo cambiando:

- (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; 
} 

a:

- (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; 
} 

La differenza principale è che ho modificato il centro dell'arco dividendo il valori xey da 2

1

Il debug della fisica è una cosa. Probabilmente non è qualcosa a cui gli utenti iOS tendono a pensare molto, dato che in genere hanno fatto cose molto semplici con UIKit Dynamics. Questo è un peccato, in quanto è uno degli aspetti migliori delle recenti edizioni di iOS e offre un modo davvero divertente per rendere coinvolgenti le esperienze degli utenti.

Quindi ... come eseguire il debugging della fisica?

Un modo è immaginare mentalmente quello che sta succedendo, quindi correlarlo con quello che sta succedendo, e trovare la dissonanza tra l'immaginario e il reale, e quindi risolvere il problema tramite una miscela di processi di eliminazione, processo mentale o reale & errore e detrazione, fino a quando il problema non viene determinato e risolto.

Un altro è avere una rappresentazione visiva di tutto ciò che è stato creato e interagire presentando un feedback sufficiente a determinare più rapidamente la natura e l'estensione degli elementi, le loro relazioni e incidenti/eventi e risolvere i problemi con la vista letterale.

A tal fine, dal momento della loro introduzione sono stati creati vari debugger visivi e costruttori di simulazioni fisiche.

Sfortunatamente iOS non ha un editor basato su schermo o un "editor di scena" per UIKit Dynamics, e ciò che è disponibile per questo tipo di debugging visivo in Sprite Kit e Scene Kit è rudimentale, nel migliore dei casi.

Tuttavia ci sono CALayer, che sono presenti in tutte le Viste UIKit, in cui i CAShapeLayers possono essere creati e disegnati manualmente per rappresentare accuratamente tutti gli elementi fisici, i loro limiti e le loro ancore e relazioni.

CAShapeLayers è un "contenitore" per CGPath e può avere colori diversi per il contorno e il riempimento e più di un elemento CGPath all'interno di un singolo CAShapeLayer.

E, per citare il grande Rob:.

"Se si aggiunge un CAShapeLayer come strato a vista, non c'è bisogno di realizzare qualsiasi codice di disegno te Basta aggiungere il CAShapeLayer e Ad esempio, puoi anche cambiare il percorso, ad esempio, e lo lo ridisegnerà automaticamente per te. CAShapeLayer ti fa uscire dalle erbe infestanti di scrivendo le tue routine drawRect o drawLayer. "

Se si dispone di un enorme numero di elementi che interagiscono e si desidera eseguire il debug di loro, problemi di prestazioni di CAShapeLayer potrebbero entrare in gioco, a questo punto è possibile utilizzare shouldRasterize per convertire ciascuno per una bitmap, e ottenere un significativo miglioramento delle prestazioni quando colpire i limiti creati dalle capacità "dinamiche" di CAShapeLayers.

Inoltre, per rappresentare elementi quali vincoli e giunti, c'è un semplice processo di creazione di linee tratteggiate su CAShapeLayers, semplicemente impostando le proprietà. Ecco le basi della configurazione delle proprietà di un CAShapeLayer e il modo di utilizzare un array per creare un profilo tratteggiato 5-5-5 con un tratto di blocco, larghezza di 3, nessun riempimento.

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]]; 
Problemi correlati