2009-03-12 8 views
11

Je développe un jeu 2d pour iPhone en utilisant cocos2d. J'utilise beaucoup de petits sprites (image) dans mon jeu. Je veux toucher deux types similaires de sprite (image), puis les deux sprite (image) seront cachés.Comment puis-je détecter le toucher dans cocos2d?

Comment puis-je détecter un contact dans une image-objet spécifique?

Répondre

16

Dans votre calque contenant l'image-objet, vous devez dire:

self.isTouchEnabled = YES; 

alors vous pouvez utiliser les mêmes événements que vous utiliseriez dans un UIView, mais ils sont nommés un peu différemment:

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

ce n'est pas ma réponse. Je veux détecter un contact particulier. – Nasir

+5

Je ne suis pas sûr de savoir ce que vous voulez dire ... quelle touche particulière? – Jonas

23

en suivant les instructions de Jonas, et en ajoutant sur un peu plus ...

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

Vous suis un y ont besoin d'ajuster le x/ya peu pour tenir compte du « positionnement centré » dans Cocos

+2

+1 pour m'avoir appris que CGRectContainsPoint fonctionne dans CocosLand. – Genericrich

+0

Cocos2D, depuis 0.7.1 (ou 0.7.2?) Utilise maintenant CCP (CGPoint) au lieu du CPV (Chipmunk Vector) pour ses coordonnées. Ils sont interchangeables, cependant - afaik, ils ont toujours été car ils sont définis de la même manière. La plupart des méthodes CG * devraient fonctionner. –

+0

Il ne semble pas que cela gérera les sprites qui ont été mis à l'échelle depuis que Sprite.contentSize est le contenu entier non mis à l'échelle ... Bien que je ne l'ai pas encore essayé. – Dad

0

@Genericrich: CGRectContainsPoint travaille à CocosLand en raison de l'appel 2 lignes ci-dessus:

[[Director sharedDirector] convertCoordinate:] 

Les objets seront Cocos2d en utilisant le système de coordonnées OpenGL, où 0,0 est la partie inférieure gauche, et les coordonnées UIKit (comme où le contact est arrivé) ont 0,0 est en haut à gauche. convertCoordinate: fait le passage d'UIKit à OpenGL pour vous.

+1

c'est une instruction inexacte - il ne convertit pas d'OpenGL en UIKit ... mais plutôt d'OpenGL View Space en Screen Space car les coordonnées non converties ont des valeurs plutôt ridicules. De plus, les objets CocosNode sont ancrés au centre par défaut (0,0 == centre de l'objet) La valeur renvoyée est simplement un point sur l'écran, par rapport à Cocos2D Space. convertCoordinate est écrit comme: int newY = openGLView_.frame.size.height - p.y; int newX = openGLView_.frame.size.width - p.x; CGPoint ret; switch (deviceOrientation_) {// cas variés à échanger pour des raisons d'orientation} return ret; –

7

@david, votre code contient quelques fautes de frappe pour les cocos 0.7.3 et 2.2.1, en particulier CGRectMake au lieu de CGMakeRect et [touch location] est maintenant [touch locationInview: touch.view].

voici ce que je faisais:

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

Le directeur n'existe pas. Devrait être CCDirector, mais ce code ne fonctionne pas de toute façon. Trop vieux? (en utilisant cocos2d 2.x) – Jonny

+0

Oui, cela a fonctionné en 2009 mais je pense que beaucoup a changé. La chose dont vous avez besoin dans la ligne d'emplacement est de convertir la coordonnée en un CGPoint, pas sûr de ce que cela fait maintenant. Cela ressemble à la référence mise à jour: http://www.cocos2d-x.org/projects/cocos2d-x/wiki/Coordinate_System – John

0

Voilà comment cela a fonctionné pour moi ... Où spriteSize est évidemment la taille de l'image-objet ...: 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

Pourquoi nous édité après 1 an – Srinivas

0

Je suis en train de comprendre comment se procurer des touches d'un sprite donné et trouvé ce fil.

Est-ce la façon correcte de détecter quel sprite a été touché? Cela semble une manière plutôt étrange de le faire par rapport à la manière habituelle de sous-classe dans obj-c?

Donc, tout le code de détection tactile est dans la classe de calque?

Merci pour les pointeurs

27

Une meilleure façon de le faire est d'utiliser effectivement la zone de délimitation sur l'image-objet lui-même (qui est un CGRect). Dans cet exemple de code, je mets tous mes sprites dans un NSMutableArray et je vérifie simplement si le sprite est dans la zone de délimitation. Assurez-vous d'activer la détection tactile dans init.Si vous remarquez que je l'accepte aussi/rejeter des touches sur la couche en retournant OUI (si j'utilise le toucher) ou NON (si je ne le fais pas)

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

Souciez-vous expliquer pourquoi c'est un "meilleur moyen" "? – kizzx2

+2

Je suis d'accord c'est mieux parce que c'est très propre –

+0

Celui-ci est le seul sur cette page qui semble uptodate avec cocos2d récente. (2.x) – Jonny

0

c'est un bon tutoriel expliquant le système tactile de base http://ganbarugames.com/2010/12/detecting-touch-events-in-cocos2d-iphone/

premier, écrire

self.isTouchEnabled = YES; 

alors, vous devez implémenter les fonctions ccTouchesEnded, ccTouchesBegan, etc

de w J'ai compris que vous voulez être en mesure de faire correspondre deux sprites qui peuvent être sur des coordonnées différentes sur l'écran.

une méthode pour le faire ..: (je suis sûr que beaucoup d'autres méthodes Theres)

considèrent avoir 2 variables globales. Ainsi, chaque fois qu'une touche touche une image-objet, vous utilisez la fonction CGRectContainsPoint mentionnée à plusieurs reprises pour trouver l'image-objet qui a été touchée. Vous pouvez ensuite enregistrer la "balise" de cette image-objet dans l'une des variables globales.

Vous faites la même chose pour la deuxième touche, puis vous comparez les 2 variables globales.

vous devriez être en mesure de comprendre le reste, mais commentez si vous avez des problèmes.