2010-08-10 12 views
1

J'essaie de créer un swingomètre, un peu comme ceux utilisés dans les jeux de golf, où l'utilisateur tient un bouton pour démarrer une balançoire, libère à l'apex pour déterminer la puissance , à quel point le «swing» inverse la direction, et l'utilisateur tape à nouveau sur la descente pour régler la précision.Création d'un Swingometer sur l'iPhone en utilisant Core-Animation

Plutôt que d'avoir une barre qui se remplit, j'aimerais utiliser un pendule qui oscille de gauche à droite. Le pendule laisse une marque où il est d'abord tapé (puissance) et une autre marque où il est tapé pour la deuxième fois (précision).

Mon premier problème est la rotation du pendule. J'ai lu ces messages au sujet de la rotation d'un UIImageView - here, here et here mais j'espérais que je pourrais être en mesure d'obtenir un peu de conseils supplémentaires :)

Tout d'abord, est la rotation d'un UIImageView la meilleure façon d'aborder ce? Je pensais déterminer à quel point le pendule est proche du bon endroit en comparant ses coordonnées aux coordonnées du point correct. Mais pour que cela fonctionne, UIImageView devrait bouger physiquement, ce dont je ne suis pas sûr? De même, comment faire en sorte que UIImageView tourne autour d'un point spécifique, plutôt que du point central. Ou devrais-je simplement agrandir la boîte englobante du pendule afin que le point central soit dans la bonne position. Et comment puis-je laisser un «tampon» où l'utilisateur frappe (ou libère) le bouton?

Toute aide générale au sujet de la meilleure façon d'aborder ce serait très apprécié :) Peut-être que ma question est un peu vague et généralisée, mais je suis en espérant que quelqu'un pourrait aimer le défi :)

Merci !!

Michael

MISE À JOUR:

Ok j'ai essayé les deux approches suivantes, les deux qui travaillent maintenant.

- (void)viewDidLoad { 
     pendulum.image = [UIImage imageNamed:@"winkOpen.png"]; 
     [self swingPendulum]; 
    } 

    - (void)swingPendulum { 
    CABasicAnimation *rotationAnimation; 
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"]; 
    rotationAnimation.toValue = [NSNumber numberWithFloat:degreesToRadian(180)]; 
    rotationAnimation.duration = 0.75; 
    rotationAnimation.repeatCount = 1.0; 
    rotationAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseIn]; 

    [pendulum.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"]; 
} 


    /* 
    - (void)swingPendulum { 
     [UIView setAnimationBeginsFromCurrentState:YES]; 
     [UIView beginAnimations:nil context:nil]; 
     [UIView setAnimationDuration:1]; 
     pendulum.transform = CGAffineTransformMakeRotation(degreesToRadian(180)); 
     [UIView setAnimationDelegate:self]; 
     [UIView commitAnimations]; 
    } 
    */ 

Maintenant, je ne suis pas sûr quelle approche est la meilleure, mais avec la première, les oscillations d'un pendule au-dessus de 0 degrés plutôt que ci-dessous, donc je vais avec ça.

Maintenant, j'ai besoin de déterminer où le pendule s'arrête et inverser le swing ... Mais peut-être que je vais les poster comme des questions distinctes, car cela devient un peu encombré! Je ferai en sorte que mes questions soient plus précises à l'avenir :)

+0

J'ai pensé "Swingometer", ça sonne intéressant! Puis j'ai lu la question et j'ai découvert qu'il s'agissait de golf. Soupir. Parlez d'une déception. – TechZen

+0

Eh bien, en fait, je ne l'utilise pas pour un jeu de golf, je pensais juste que c'était un exemple qui décrirait le plus précisément le problème.C'est intéressant, je le promets :) – Smikey

+1

Ces erreurs de "symboles non définis" que vous voyez sont dues au fait que vous ne liez pas le framework QuartzCore (qui contient les classes Core Animation et les types de données). En outre, en pratique, comment l'utilisateur verra-t-il réellement l'écran pendant qu'il se balance? –

Répondre

1

Pour l'animation, vous voudrez regarder les transformations. Voir le Quartz 2D programming guide:Transforms.

Vous ne devez pas utiliser l'emplacement réel des pixels de la vue pour vos calculs. Si vous le faites, les modifications des dimensions de l'écran et/ou de la résolution nécessiteront une réécriture complète. Au lieu de créer un modèle de données abstrait du mouvement et de l'emplacement, effectuez vos calculs dans le modèle abstrait. Traduisez ensuite les coordonnées abstraites aux coordonnées de l'affichage en cours.

Obtenir l'imageView à apparaître où vous le souhaitez est relativement trivial par rapport au calcul où il devrait être en premier lieu. Vous devez obtenir la motion correctement. Rappelez-vous, "ça ne veut pas dire que vous n'avez pas ce swing!"

+0

Merci pour la réponse! J'ai depuis décidé que je n'ai pas besoin de calculer avec précision à quelle distance du point correct le pendule est arrêté, simplement si c'est trop fort, trop faible ou juste. Je peux probablement le faire en prenant simplement l'angle où il se trouve lorsque l'utilisateur appuie sur le bouton. C'est à dire. <170 degrés = trop faible,> 170 et <190 = juste et> 190 = trop fort. Mais alors j'ai besoin d'extraire l'angle de transformation de l'image actuelle de quelque part ... Aussi, j'ai du mal à faire simplement balancer le pendule - affichera le code que j'utilise maintenant et mettre à jour la question, donc toute aide très appréciée – Smikey

+1

Les transformations sont un grand sujet. Le vrai truc pour les apprendre est qu'ils ne s'accumulent pas comme vous les attendez par exemple. vous avez une rotation de 45 degrés et vous l'appelez deux fois. Vous vous attendriez à ce que l'objet transformé pivote de 90 degrés. Ce n'est pas le cas. Il pivote de 45 degrés, peu importe le nombre de fois que vous l'appelez, car la transformation commence toujours par la position de l'objet d'origine. Pour que les transformations s'accumulent, vous devez transformer la transformation existante. Ainsi, vous définissez une transformation à 45 degrés puis appelez une autre transformation à 45 degrés sur la première transformation. – TechZen

+0

Je vois - eh bien j'ai réussi à faire balancer le pendule d'une certaine manière maintenant, mais comme vous dites, quand j'applique une transformation secondaire pour le faire reculer, il applique la transformation à la position d'origine, pas à la position actuelle. le pendule oscille juste à l'envers par rapport à sa position d'origine. Donc, d'après ce que vous dites, j'ai besoin d'appliquer la transformation de courant au pendule lui-même, avant d'appliquer la transformation inverse. Savez-vous comment je pourrais extraire l'angle de transformation actuel de l'animation en cours? J'espère que cela a du sens ...: s Et merci pour l'aide! – Smikey