2009-07-10 8 views
2

Je voudrais utiliser Cocos2d sur l'iPhone pour dessiner une voiture 2D et le faire tourner de gauche à droite d'une manière naturelle.Car tourner cercle et déplacer le sprite

Voici ce que j'ai essayé:

  1. Calculer l'angle des roues et déplacer juste au point de destination où les roues pointent. Mais cela crée une sensation très artificielle. Après cela, j'ai commencé à faire des recherches sur la façon d'obtenir un cercle de braquage d'une voiture, ce qui signifiait que j'avais besoin de quelques constantes comme l'empattement et la largeur de la voiture.

Après beaucoup de recherches, j'ai créé le code suivant:

float steerAngle = 30; // in degrees 
float speed = 20; 
float carWidth = 1.8f; // as in 1.8 meters 
float wheelBase = 3.5f; // as in 3.5 meters 

float x = (wheelBase/abs(tan(steerAngle)) + carWidth/ 2); 
float wheelBaseHalf = wheelBase/2; 
float r = (float) sqrt(x * x + wheelBaseHalf * wheelBaseHalf); 

float theta = speed * 1/r; 
if (steerAngle < 0.0f) 
    theta = theta * -1; 

drawCircle(CGPointMake(carPosition.x - r, carPosition.y), 
      r, CC_DEGREES_TO_RADIANS(180), 50, NO); 

Les deux premières lignes sont mes constantes. carPosition est du type CGPoint. Après cela, j'essaie de dessiner un cercle qui montre le cercle de braquage de ma voiture, mais le cercle qu'elle dessine est beaucoup trop petit. Je peux simplement agrandir mes constantes, agrandir le cercle, mais je devrais quand même savoir comment déplacer mon sprite sur ce cercle.

J'ai essayé de suivre un .NET tutorial que j'ai trouvé sur le sujet, mais je ne peux pas vraiment le convertir complètement car il utilise des matrices, qui ne sont pas supportées par Cocoa. Est-ce que quelqu'un peut me donner quelques conseils sur la façon de commencer cela? J'ai cherché un exemple de code, mais je n'en trouve pas.

EDIT Après les commentaires ci-dessous je corrigeais mes constantes, mon Empattement est maintenant 50 (le sprite est 50px élevé), mon carWidth est 30 (le sprite est 30px en largeur).

Mais maintenant j'ai le problème, que lorsque ma voiture fait d'abord «coche», la rotation est correcte (et aussi le placement), mais après que les calculs semblent faux.

Le centre du cercle de rotation est déplacé au lieu d'être maintenu à sa position d'origine. Ce dont j'ai besoin (je pense) c'est qu'à chaque angle de la voiture j'ai besoin de recalculer le centre d'origine du cercle de braquage. Je pense que c'est facile, parce que j'ai le rayon et l'angle de virage, mais je n'arrive pas à comprendre comment garder la voiture dans un joli cercle.

Plus de pointeurs?

+0

Les matrices ne sont que des tableaux multidimensionnels. Vous devriez être capable d'adapter/travailler le code de référence. – EightyEight

Répondre

1

Vous avez la bonne idée. Les constantes sont le problème dans ce cas. Vous devez spécifier wheelBase et carWidth dans les unités correspondant à la taille de votre vue. Par exemple, si l'image de votre voiture sur l'écran a une base de 30 pixels, vous utiliserez 30 pour la variable WheelBase. Cela explique pourquoi vos cercles à l'écran sont trop petits. Cocoa essaie de dessiner des cercles pour une minuscule petite voiture de seulement 1,8 pixels de large!

Maintenant, pour la question de déplacer votre voiture le long du cercle:

La variable theta vous calculez dans le code ci-dessus est une vitesse de rotation, qui est ce que vous utilisez pour déplacer la voiture autour du point central de ce cercle:

Supposons que votre variable speed est en pixels par seconde, pour faciliter les calculs. Avec cette hypothèse en place, vous simplement exécuter le code suivant une fois par seconde:

// calculate the new position of the car 
newCarPosition.x = (carPosition.x - r) + r*cos(theta); 
newCarPosition.y = carPosition.y + r*sin(theta); 

// rotate the car appropriately (pseudo-code) 
[car rotateByAngle:theta]; 

Note: Je ne suis pas sûr de ce que la bonne méthode consiste à faire pivoter l'image de votre voiture, alors je viens d'utiliser rotateByAngle: pour obtenir le point à travers. J'espère que ça aide!

mise à jour (après les commentaires):

Je n'avais pas pensé au centre du cercle tournant en mouvement avec la voiture. Le code d'origine ne prend pas en compte l'angle de rotation de la voiture. Je changerais comme suit:

... 
if (steerAngle < 0.0f) 
    theta = theta * -1; 

// calculate the center of the turning circle, 
// taking int account the rotation of the car 
circleCenter.x = carPosition.x - r*cos(carAngle); 
circleCenter.y = carPosition.y + r*sin(carAngle); 

// draw the turning circle 
drawCircle(circleCenter, r, CC_DEGREES_TO_RADIANS(180), 50, NO); 

// calculate the new position of the car 
newCarPosition.x = circleCenter.x + r*cos(theta); 
newCarPosition.y = circleCenter.y + r*sin(theta); 

// rotate the car appropriately (pseudo-code) 
[car rotateByAngle:theta]; 
carAngle = carAngle + theta; 

Cela devrait garder le centre du cercle tournant au moment approprié, même si la voiture a été tourné.

+0

J'ai essayé d'intégrer vos commentaires, mais cela ne fonctionne toujours pas. J'ai essayé d'expliquer cela dans mon post original. J'espère que vous pouvez me donner d'autres conseils? –

+0

J'ai ajouté du code pour résoudre le problème en déplaçant le centre du cercle. Donner un coup de feu! –

+0

Merci, il faut encore peaufiner, mais cela semble être un très bon début .. Je mettrai à jour mon départ après la minute où je l'ai complètement travaillé! –