2009-03-12 9 views
11

Sto sviluppando un gioco 2D per iPhone usando cocos2d.Come posso rilevare il tocco in cocos2d?

Io uso molti piccoli sprite (immagine) nel mio gioco. Voglio toccare due tipi simili di sprite (immagine) e quindi entrambi gli sprite (immagine) saranno nascosti.

Come posso rilevare il tocco in uno sprite specifico (immagine)?

risposta

16

Nel vostro livello che contiene il vostro sprite, è necessario dire:

self.isTouchEnabled = YES; 

quindi è possibile utilizzare gli stessi eventi che si usa in un UIView, ma sono chiamati un po 'diverso:

- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    UITouch* touch = [touches anyObject]; 
    //in your touchesEnded event, you would want to see if you touched 
    //down and then up inside the same place, and do your logic there. 
} 
+0

questa non è la mia risposta. Voglio rilevare un tocco particolare. – Nasir

+5

Non sono sicuro di cosa intendi ... quale particolare tocco? – Jonas

23

Seguendo le istruzioni di Jonas, e l'aggiunta su di esso un po 'più ...

- (void)ccTouchesBegan:(NSSet*)touches withEvent:(UIEvent*)event 
{ 
    UITouch* touch = [touches anyObject]; 
    CGPoint location = [[[Director sharedDirector] convertCoordinate: touch.location]; 
    CGRect particularSpriteRect = CGMakeRect(particularSprite.position.x, particularSprite.position.y, particularSprite.contentSize.width, particularSprite.contentSize.height); 
    if(CGRectContainsPoint(particularSpriteRect, location)) { 
    // particularSprite touched 
    return kEventHandled; 
    } 
} 

è mA y necessità di regolare il x/ya poco per spiegare il 'posizionamento centrato' in Cocos

+2

+1 per avermi insegnato che CGRectContainsPoint funziona in CocosLand. – Genericrich

+0

Cocos2D, dal momento che 0.7.1 (o 0.7.2?) Ora utilizza CCP (CGPoint) anziché il CPV (Chipmunk Vector) per le sue coordinate. Sono intercambiabili, tuttavia - afaik, sono sempre stati da quando sono definiti allo stesso modo. La maggior parte dei metodi CG * dovrebbe funzionare. –

+0

Non sembra che questo gestirà gli sprite che sono stati ridimensionati poiché Sprite.contentSize è l'intero contenuto non in scala ... Anche se non l'ho ancora provato. – Dad

0

@Genericrich: CGRectContainsPoint funziona in CocosLand causa della chiamata 2 linee sopra:

[[Director sharedDirector] convertCoordinate:] 

Gli oggetti Cocos2d saranno usando il sistema di coordinate OpenGL, dove 0,0 è in basso a sinistra e le coordinate UIKit (come dove è avvenuto il tocco) hanno 0,0 in alto a sinistra. convertCoordinate: sta facendo il flip da UIKit a OpenGL per te.

+1

è un'affermazione imprecisa - non converte da OpenGL a UIKit ... ma piuttosto da OpenGL Visualizza lo spazio nello spazio di schermo poiché le coordinate non convertite hanno valori piuttosto ridicoli. Inoltre, gli oggetti CocosNode sono ancorati al centro per impostazione predefinita (0,0 == centro dell'oggetto) Il valore restituito è semplicemente un punto sullo schermo, relativo a Cocos2D Space. convertCoordinate è scritto come: int newY = openGLView_.frame.size.height - p.y; int newX = openGLView_.frame.size.width - p.x; CGPoint ret; switch (deviceOrientation_) {// vari casi da scambiare per motivi di orientamento} return ret; –

7

@david, il tuo codice ha alcuni errori di battitura per cocos 0.7.3 e 2.2.1, in particolare CGRectMake invece di CGMakeRect e [touch location] è ora [touch locationInView: touch.view].

ecco quello che ho fatto:

- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch * touch = [touches anyObject]; 

    CGPoint location = [[Director sharedDirector] convertCoordinate: [touch locationInView:touch.view]]; 
    CGRect myRect = CGRectMake(sprite.position.x, sprite.position.y, sprite.contentSize.width, sprite.contentSize.height); 


    if(CGRectContainsPoint(myRect, location)) { 
     // particularSprite touched 
     return kEventHandled; 
    } 
} 
+0

Director non esiste. Dovrebbe essere CCDirector, ma questo codice non funziona comunque. Troppo vecchio? (usando cocos2d 2.x) – Jonny

+0

Sì, questo ha funzionato nel 2009 ma penso che sia cambiato molto. La cosa di cui hai bisogno nella linea di posizione è convertire le coordinate in un CGPoint, non è sicuro di cosa lo faccia ora. Questo sembra il riferimento aggiornato: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Coordinate_System – John

0

Ecco come ha funzionato per me ... Dove spriteSize è ovviamente la dimensione dello sprite ...: P

- (BOOL)ccTouchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    UITouch * touch = [touches anyObject]; 

    CGPoint location = [[Director sharedDirector] convertCoordinate: [touch locationInView:touch.view]]; 
    CGRect myRect = CGRectMake(sprite.position.x-spriteSize/2, sprite.position.y-spriteSize/2, spriteSize, spriteSize); 


    if(CGRectContainsPoint(myRect, location)) { 
     // particularSprite touched 
     return kEventHandled; 
    } 
} 
+0

perché modificato dopo 1 anno – Srinivas

0

ho cercato di capire come ottenere i tocchi di un dato sprite e trovato questo thread.

È questo il modo corretto per rilevare quale sprite è stato toccato? Questo sembra un modo piuttosto strano di farlo rispetto al solito modo di sottoclasse in obj-c?

Quindi tutto il codice di rilevamento tocco si trova nella classe layer?

Grazie per puntatori

27

Un modo migliore per farlo è quello di utilizzare effettivamente il rettangolo di selezione sulla sprite in sé (che è un CGRect). In questo codice di esempio, inserisco tutti i miei sprite in un NSMutableArray e controllo semplicemente se il tocco dello sprite è nella casella di delimitazione. Assicurati di attivare il rilevamento del tocco in init.Se si nota anche io accetto/rifiuto tocchi sullo strato restituendo SI (se uso il tatto) o NO (se non lo faccio)

- (BOOL)ccTouchBegan:(UITouch *)touch withEvent:(UIEvent *)event 
{ 
    CGPoint location = [self convertTouchToNodeSpace: touch]; 

    for (CCSprite *station in _objectList) 
    { 
    if (CGRectContainsPoint(station.boundingBox, location)) 
    { 
     DLog(@"Found sprite"); 
     return YES; 
    } 
    } 

    return NO; 
} 
+0

Attenzione a spiegare perché questo è un "modo migliore" "? – kizzx2

+2

Concordo che è meglio perché è molto pulito –

+0

Questo è l'unico su questa pagina che sembra aggiornato con il recente cocos2d. (2.x) – Jonny

0

questo è un buon tutorial che spiega il sistema touch base http://ganbarugames.com/2010/12/detecting-touch-events-in-cocos2d-iphone/

primo luogo, scrivere

self.isTouchEnabled = YES; 

allora, è necessario implementare le funzioni ccTouchesEnded, ccTouchesBegan, ecc

da w ho capito, vuoi essere in grado di "abbinare" due sprite che possono essere su diverse coordinate sullo schermo.

un metodo per fare questo ..: (Im sicuro theres molti altri metodi)

considerare avere 2 variabili globali.

così ogni volta che un tocco tocca uno sprite, si utilizza la funzione CGRectContainsPoint menzionata più volte per trovare quale sprite è stato toccato. quindi, puoi salvare il 'tag' di quello sprite in una delle variabili globali.

Si fa lo stesso per il secondo tocco e quindi si confrontano le 2 variabili globali.

si dovrebbe essere in grado di capire il resto, ma commentare se avete problemi.