sinon je viens de piger pourquoi c'est plus dur, ta balle est mouvement. Au pire ralenti de vitesse ce sera plus simple.
edit: tes commentaires de code sont en anglais. Essai de faire par toi même pour bien comprendre commen ca marche. Copier/coller n'est pas la bonne solution. Meme si tu n'arrives pas tout de suite à ce que tu veux tu auras les bases pour aller plus loin.
Je parierai pour un oubli de travailler dans le même repère donc un oubli de demander par exemple "locationInView:" sur le touch (ou de passer la mauvaise view en paramètre) ?
sinon je viens de piger pourquoi c'est plus dur, ta balle est mouvement. Au pire ralenti de vitesse ce sera plus simple.
edit: tes commentaires de code sont en anglais. Essai de faire par toi même pour bien comprendre commen ca marche. Copier/coller n'est pas la bonne solution. Meme si tu n'arrives pas tout de suite à ce que tu veux tu auras les bases pour aller plus loin.
Je mets moi-même mes commentaires en anglais, pour que ce soit lu par tout le monde sur les forums. C'est moi qui ai fait mon code de a à z.
Sinon je pense maintenant que le problème se situe là :
Mais je viens de m'apercevoir de quelque chose, dans ma console, à chaque clique j'ai : X =-10.000000 | Y =-22.000000 || DoigtX =166.000000 | DoigtY =84.953613
mais pour chaque clic le X et le Y restent pareils et ne changent pas. L'erreur doit venir d'ici, les coordonnées ne sont pas mises à jour non ?
C'est pas touch.view qu'il faut utiliser, mais la vue qui te sert de "plateau de jeu", la vue dans laquelle sont placées tes balles. Il faut que tu utilises le même système de coordonnées dans les 2 cas, quand tu places tes balles dans ta vue principale (à priori la view gérée par ton viewController j'imagine, en tout cas la superview de tes balles donc) et celui où dans lequel tu récupères les coordonnées du Touch.
Là tu as les coordonnées de tes balles dans leur superview (donc dans la vue qui te sert de "plateau de jeu" je dirais) mais tu demandes les coordonnées de ta vue dans touch.view qui est la vue qui se trouve sous ton toucher... qui est donc à priori ta balle... Donc tu obtiendras à priori par [locationInView:touch.view] toujours des coordonnées de ton "touch" dans... la vue de ta balle (donc les coordonnées seront toujours très petites et leur valeur max sera le rayon de ta balle...)
Il suffit de remplacer par [locationInView:self] ou [locationInView:self.view], (selon si tu mets ce code dans la vue ou le viewController). Ceci dit puisque tu sembles avoir choisi comme solution de représenter chacune de tes balles par une UIView que tu mets en tant que subView dans ta UIView "plateau de jeu", tu devrais pouvoir directement récupérer la UIView et donc la balle qui était sous ton doigt via touch.view justement !! Bon après c'est pas très MVC et ça a les inconvénients qu'on évoquait dans les autres threads récents sur la gestion de vues pour les jeux du genre...
Ca marche, il y a juste une petit partie de l'écran quand la balle est dans une position particulière que l'écran est actif comme la balle, je pense pouvoir régler ça tout seul.
Par contre j'ai quelques petites questions. La première est que je voudrais savoir comment je peux charger un .png dans une UIImageView en gérant sa transparence de celui-ci. Comme dans cet exemple où je souhaite enlever le fond noir :
La deuxième est que dans le code de la page que je vous ai donné, je charge le début de l'action de la balle avec awakeFromNib, donc, quand je charge mon jeu, même dans mon écran d'accueil le jeu est lancé en arrière tache (même sans le voir). J'ai donc essayer de le remplacer par loadView mais le fond d'écran que je charge à l'aide de
Oulà je crois qu'il y a certaines bases à reprendre...
Il faut que tu fasses une vue dédiée pour chaque partie de ton jeu (menu d'accueil, plateau de jeu avec les balles, tableau de high scores, etc etc), avec un ViewController dédié pour chacune, le mieux étant de les mettre dans un XIB séparé chacune, et demander par code au ViewController adéquat de se "pusher" quand tu souhaites afficher la vue. Ca c'est un grand classique dont tu trouveras pas mal d'exemples dans les templates Xcode. Lis la doc sur les ViewControllers & co dans la doc Apple aussi, c'est assez bien foutu ça devrait t'expliquer comment tout ça fonctionne.
Une fois les NIB séparés faits, déjà tu n'auras plus ce problème.
Ensuite pour ton PNG, bah il suffit d'avoir un PNG avec un canal alpha (canal de transparence) qui fait que seule la balle est opaque et le reste est transparent (avec un dégradé de transparence sur les bords de la balle pourquoi pas pour faire une transition de opaque à transparent entre la balle et son fond). A partir du moment où l'image PNG est bien faite avec son canal alpha, t'as rien à faire en Cocoa pour gérer le reste, Cocoa sait prendre en compte la transparence du PNG et t'affichera la balle comme il faut sans le fond si ce dernier est bien transparent dans le PNG.
Enfin pour tes calculs de clics, je ne vois pas en quoi il y aurait des cas particuliers, sauf si tu as utilisé touch.view pour savoir quelle vue était sous ton doigt et que tu n'as pas pris en compte le cas où la vue sous ton doigt était le plateau car aucune balle n'était par dessus à cet endroit.
Et enfin pour des questions d'optimisation déjà discutées dans d'autres threads, utiliser une UIView pour chaque balle n'est pas la meilleure façon de procéder, une solution alternative aurait été de dessiner tes images (ou tes CGPath) toi-même dans la vue de plateau plutôt que d'utiliser des subViews... mais bon tu vas p'tet pas tout refaire now, ça dépend jusqu'où tu veux aller, ça t'obligerait à refaire ton algo de détection de clic (que j'ai donné dans l'autre thread à GreenSource pour la solution que j'évoque) donc à toi de voir. Une autre solution vu que tu as bcp de rendu et de mouvement à gérer serait de passer par OpenGL ES, mais je crois que c'est encore un peu tôt pour partir là -dessus et peut-être un peu machine à gaz pour un premier projet... d'autant que même si tu y gagnerais en performances et donc en nombre de frames/seconde, c'est quand même un peu plus dur encore à se plonger dedans (moi-même j'ai parfois du mal avec, c'est pas trivial)...
Le mieux est peut-être de commencer par quelques tutos de montrant comment manipuler des ViewControllers différents, et comment personnaliser une UIView aussi, avec un exemple type comme il en existe dans la doc ou sur le net, pour revenir à ton jeu ensuite avec une vision plus claire de tout ça. Rien ne sert de vouloir aller trop vite en besogne.
Merci beaucoup pour ta réponse détaillé Ali ! Oui, je suis encore débutant. Et c'est pour ça que je vais plutôt utiliser Quartz 2D pour créer mes cercles. Je pense que ça sera plus facile de les gérer.
J'utilise ceci pour bouger mon cercle mais ça ne marche pas :
Il faut que tu refraichisses ta méthode drawRect. Tu vas donc faire un [self setNeedsDisplay] qui va rappelé ton drawRect et tout bien redessiner avec les nouvelles coordonnées.
et j'insère le [self setNeedsDisplay]; dans la fonction qui appelle mon drawRect: mais mon cercle ne bouge pas, il n'y a pas grand chose sur internet la dessus.
Non, c'est plus simple de faire bouger un dessin qu'une vue.
Sauf que là je vois pas ce que t'essaies de changer avec ton "blushBall.origin = ..." ??? Tous tes paramètres de dessin sont définies dans le "drawRect", donc je vois pas trop ce qui risque de bouger.
1) Tu modifies "blushBall.origin" dans ton randomMove, mais qu'est-ce que blushBall ? Une variable d'instance de ta classe apparemment ? puisque tu ne la déclares pas dans ta fonction randomMove c'est qu'elle est déclarée en variable d'instance dans ton .h, non ? (et quel type au fait ?) Mais dans drawRect, tu déclares un CGRect du nom de blushBall... donc une variable de même nom, qui va venir masquer la déclaration de ta variable d'instance (si c'en est bien une) que tu utilises dans randomMove ! D'ailleurs tu as dû avoir un warning à ce propos genre "declaration of blushBall shadows instance variable" ou un truc du genre qui te prévient du problème quand tu compiles...
2) Tu modifies blushBall.origin dans randomMove... mais tu ne t'en sers jamais, puisque dans drawRect tu redéfinis blushBall, mais en plus sans te servir de ce blushBall.origin précédemment modifié ! Au lieu de ça tu redéfinis un CGRect toujours positionné au centre de ta vue (center.x & center.y c'est le center de l'objet dans lequel tu as mis ton code drawRect, j'imagine ta vue qui te sert de "plateau de jeu")... donc forcément il ne va pas bouger bien loin !
J'ai réussi a faire bouger mon cercle. Maintenant je veux lui associer une action lorsque l'utilisateur tappe dessus.
J'ai repris l'idée de Ali mais le problème c'est que la zone active du cercle est seulement le quart en haut à gauche, ce qui est logique d'après mon code :
Mais je n'arrive pas à créer le rectangle pour contenir la totalité de mon cercle, et pourtant j'ai fait des tonnes de dessins sur papier pour m'aider mais à chaque fois une seule zone est couverte.
Heu c'est pas parce que droite et haut ne sont pas bons ? Déjà tu appelles ta variable "droite" alors qu'en fait j'imagine que c'est plutôt le bord gauche de ta balle que tu voulais désigner... Ensuite du prends l'origine et tu enlèves le rayon... Mais l'origine de ta blushBall, ne serait-ce pas l'origine du CGRect qui encapsule ta balle ? Et donc déjà son coin haut/gauche ! Tu dois confondre avec blushBall.center qui lui est le centre de ta balle !
D'ailleurs je me demande si blushBall, si c'est un CGRect... n'est pas déjà le rectangle qu'il te faut pour tester CGRectContainsPoint ! Si c'est pas déjà le rectangle englobant de ta balle... du coup bas besoin de faire CGRectMake pour recréer un rectangle si tu as déjà le bon...
Oui j'avoue que c'est un peu désordonné... Désolé ::)
En remplaçant par blushBall ça marche, ça valait pas le coup que je me torture le cerveau... Effectivement blushBall est bien de type CGRect. Mais dans la fonction - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event, une fois que j'ai vérifier que le tap de l'utilisateur est bien sur la balle, il n'y a aucun moyen de modifier le l'apparence du cercle établit dans drawRect: ? Par exemple changer sa couleur et le faire disparaà®tre.
Réponses
sinon je viens de piger pourquoi c'est plus dur, ta balle est mouvement.
Au pire ralenti de vitesse ce sera plus simple.
edit: tes commentaires de code sont en anglais. Essai de faire par toi même pour bien comprendre commen ca marche. Copier/coller n'est pas la bonne solution. Meme si tu n'arrives pas tout de suite à ce que tu veux tu auras les bases pour aller plus loin.
Je mets moi-même mes commentaires en anglais, pour que ce soit lu par tout le monde sur les forums. C'est moi qui ai fait mon code de a à z.
Sinon je pense maintenant que le problème se situe là :
Si tu mets :
ca donne quoi?
Mais je viens de m'apercevoir de quelque chose, dans ma console, à chaque clique j'ai :
X =-10.000000 | Y =-22.000000 || DoigtX =166.000000 | DoigtY =84.953613
mais pour chaque clic le X et le Y restent pareils et ne changent pas. L'erreur doit venir d'ici, les coordonnées ne sont pas mises à jour non ?
Je regarde ton code, pourquoi tu n'utilises pas cercle.center.x etc ... ? C'est bien les coordonnées de ton cercle que tu veux. non?
Par contre ma balle ne sort pas de l'écran, elle rebondit bien contre les bords.
Voici mon if :
Lorsque mon if est vérifié, j'exécute la fonction suivante qui me permet de changer la trajectoire de la nouvelle boule :
Sauf que l'on peut quand même cliquer dans des parties de l'écran comme si l'on le faisait sur la boule.
Bonne nuit
Il faut que tu utilises le même système de coordonnées dans les 2 cas, quand tu places tes balles dans ta vue principale (à priori la view gérée par ton viewController j'imagine, en tout cas la superview de tes balles donc) et celui où dans lequel tu récupères les coordonnées du Touch.
Là tu as les coordonnées de tes balles dans leur superview (donc dans la vue qui te sert de "plateau de jeu" je dirais) mais tu demandes les coordonnées de ta vue dans touch.view qui est la vue qui se trouve sous ton toucher... qui est donc à priori ta balle... Donc tu obtiendras à priori par [locationInView:touch.view] toujours des coordonnées de ton "touch" dans... la vue de ta balle (donc les coordonnées seront toujours très petites et leur valeur max sera le rayon de ta balle...)
Il suffit de remplacer par [locationInView:self] ou [locationInView:self.view], (selon si tu mets ce code dans la vue ou le viewController). Ceci dit puisque tu sembles avoir choisi comme solution de représenter chacune de tes balles par une UIView que tu mets en tant que subView dans ta UIView "plateau de jeu", tu devrais pouvoir directement récupérer la UIView et donc la balle qui était sous ton doigt via touch.view justement !! Bon après c'est pas très MVC et ça a les inconvénients qu'on évoquait dans les autres threads récents sur la gestion de vues pour les jeux du genre...
Par contre j'ai quelques petites questions.
La première est que je voudrais savoir comment je peux charger un .png dans une UIImageView en gérant sa transparence de celui-ci. Comme dans cet exemple où je souhaite enlever le fond noir :
La deuxième est que dans le code de la page que je vous ai donné, je charge le début de l'action de la balle avec awakeFromNib, donc, quand je charge mon jeu, même dans mon écran d'accueil le jeu est lancé en arrière tache (même sans le voir). J'ai donc essayer de le remplacer par loadView mais le fond d'écran que je charge à l'aide de ne se met pas alors que dans awakeFromNib il s'affiche.
Merci d'avance pour votre aide !
Il faut que tu fasses une vue dédiée pour chaque partie de ton jeu (menu d'accueil, plateau de jeu avec les balles, tableau de high scores, etc etc), avec un ViewController dédié pour chacune, le mieux étant de les mettre dans un XIB séparé chacune, et demander par code au ViewController adéquat de se "pusher" quand tu souhaites afficher la vue.
Ca c'est un grand classique dont tu trouveras pas mal d'exemples dans les templates Xcode. Lis la doc sur les ViewControllers & co dans la doc Apple aussi, c'est assez bien foutu ça devrait t'expliquer comment tout ça fonctionne.
Une fois les NIB séparés faits, déjà tu n'auras plus ce problème.
Ensuite pour ton PNG, bah il suffit d'avoir un PNG avec un canal alpha (canal de transparence) qui fait que seule la balle est opaque et le reste est transparent (avec un dégradé de transparence sur les bords de la balle pourquoi pas pour faire une transition de opaque à transparent entre la balle et son fond). A partir du moment où l'image PNG est bien faite avec son canal alpha, t'as rien à faire en Cocoa pour gérer le reste, Cocoa sait prendre en compte la transparence du PNG et t'affichera la balle comme il faut sans le fond si ce dernier est bien transparent dans le PNG.
Enfin pour tes calculs de clics, je ne vois pas en quoi il y aurait des cas particuliers, sauf si tu as utilisé touch.view pour savoir quelle vue était sous ton doigt et que tu n'as pas pris en compte le cas où la vue sous ton doigt était le plateau car aucune balle n'était par dessus à cet endroit.
Et enfin pour des questions d'optimisation déjà discutées dans d'autres threads, utiliser une UIView pour chaque balle n'est pas la meilleure façon de procéder, une solution alternative aurait été de dessiner tes images (ou tes CGPath) toi-même dans la vue de plateau plutôt que d'utiliser des subViews... mais bon tu vas p'tet pas tout refaire now, ça dépend jusqu'où tu veux aller, ça t'obligerait à refaire ton algo de détection de clic (que j'ai donné dans l'autre thread à GreenSource pour la solution que j'évoque) donc à toi de voir.
Une autre solution vu que tu as bcp de rendu et de mouvement à gérer serait de passer par OpenGL ES, mais je crois que c'est encore un peu tôt pour partir là -dessus et peut-être un peu machine à gaz pour un premier projet... d'autant que même si tu y gagnerais en performances et donc en nombre de frames/seconde, c'est quand même un peu plus dur encore à se plonger dedans (moi-même j'ai parfois du mal avec, c'est pas trivial)...
Le mieux est peut-être de commencer par quelques tutos de montrant comment manipuler des ViewControllers différents, et comment personnaliser une UIView aussi, avec un exemple type comme il en existe dans la doc ou sur le net, pour revenir à ton jeu ensuite avec une vision plus claire de tout ça. Rien ne sert de vouloir aller trop vite en besogne.
Oui, je suis encore débutant. Et c'est pour ça que je vais plutôt utiliser Quartz 2D pour créer mes cercles. Je pense que ça sera plus facile de les gérer.
J'utilise ceci pour bouger mon cercle mais ça ne marche pas :
où myOval est de type CGRect.
et j'insère le [self setNeedsDisplay]; dans la fonction qui appelle mon drawRect: mais mon cercle ne bouge pas, il n'y a pas grand chose sur internet la dessus.
Je comprends pas trop ta phrase.
En gros :
drawRect() {
tu dessinnes ton cercle
}
uneFonction(){
blushBall.origin = CGPointMake(blushBall.origin.x+coordonnees.x, blushBall.origin.y+coordonnees.y);
et a la fin de cette fonction,
[self setNeedsDisplay];
}
blushBall est initialisé CGRect blushBall;
Fonction qui fait bouger le cercle
et voici comment je met à jour dans le awakeFromNib :
Autant il est simple de faire rebondir une UIImageView, autant il est compliqué de le faire avec un CGRect !
Sauf que là je vois pas ce que t'essaies de changer avec ton "blushBall.origin = ..." ???
Tous tes paramètres de dessin sont définies dans le "drawRect", donc je vois pas trop ce qui risque de bouger.
1) Tu modifies "blushBall.origin" dans ton randomMove, mais qu'est-ce que blushBall ? Une variable d'instance de ta classe apparemment ? puisque tu ne la déclares pas dans ta fonction randomMove c'est qu'elle est déclarée en variable d'instance dans ton .h, non ? (et quel type au fait ?)
Mais dans drawRect, tu déclares un CGRect du nom de blushBall... donc une variable de même nom, qui va venir masquer la déclaration de ta variable d'instance (si c'en est bien une) que tu utilises dans randomMove ! D'ailleurs tu as dû avoir un warning à ce propos genre "declaration of blushBall shadows instance variable" ou un truc du genre qui te prévient du problème quand tu compiles...
2) Tu modifies blushBall.origin dans randomMove... mais tu ne t'en sers jamais, puisque dans drawRect tu redéfinis blushBall, mais en plus sans te servir de ce blushBall.origin précédemment modifié ! Au lieu de ça tu redéfinis un CGRect toujours positionné au centre de ta vue (center.x & center.y c'est le center de l'objet dans lequel tu as mis ton code drawRect, j'imagine ta vue qui te sert de "plateau de jeu")... donc forcément il ne va pas bouger bien loin !
Et oui, en fait tu fait bien bouger ta balle mais tu l'écrases dans drawRect().
Maintenant je veux lui associer une action lorsque l'utilisateur tappe dessus.
J'ai repris l'idée de Ali mais le problème c'est que la zone active du cercle est seulement le quart en haut à gauche, ce qui est logique d'après mon code :
Mais je n'arrive pas à créer le rectangle pour contenir la totalité de mon cercle, et pourtant j'ai fait des tonnes de dessins sur papier pour m'aider mais à chaque fois une seule zone est couverte.
Quelqu'un pourrait-il m'aider ?
Merci d'avance !
Déjà tu appelles ta variable "droite" alors qu'en fait j'imagine que c'est plutôt le bord gauche de ta balle que tu voulais désigner...
Ensuite du prends l'origine et tu enlèves le rayon... Mais l'origine de ta blushBall, ne serait-ce pas l'origine du CGRect qui encapsule ta balle ? Et donc déjà son coin haut/gauche ! Tu dois confondre avec blushBall.center qui lui est le centre de ta balle !
D'ailleurs je me demande si blushBall, si c'est un CGRect... n'est pas déjà le rectangle qu'il te faut pour tester CGRectContainsPoint ! Si c'est pas déjà le rectangle englobant de ta balle... du coup bas besoin de faire CGRectMake pour recréer un rectangle si tu as déjà le bon...
Vous pourriez vous organiser dans un seul sujet, ça serait plus pratique !
En remplaçant par blushBall ça marche, ça valait pas le coup que je me torture le cerveau... Effectivement blushBall est bien de type CGRect.
Mais dans la fonction - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event, une fois que j'ai vérifier que le tap de l'utilisateur est bien sur la balle, il n'y a aucun moyen de modifier le l'apparence du cercle établit dans drawRect: ? Par exemple changer sa couleur et le faire disparaà®tre.
Merci !
Dans ce cas là , il faudrait que je fasse apparaà®tre un nouveau cercle aux même coordonnées que celui de départ.