Question

Je voudrais faire dévier une balle selon l’angle où elle frappe une pagaie. Pour le moment, je ne change que la coordonnée y, ce qui entraîne une déviation sans intérêt. Il inclinera mais sera indépendant de l’impact sur la pagaie. Je voudrais quelque chose de plus amusant. La vitesse, l'élan, la masse et d'autres facteurs ne doivent pas être pris en compte. Il suffit d’incliner en fonction de l’impact de la pagaie. J'ai lu cette pas un numéro erreur (NAN) lors de la détection de collision dans une application iPhone , mais cela semble trop compliqué pour ce que je recherche. Existe-t-il un moyen plus simple de calculer la flèche?

Les objets sont deux UIImageViews.

Était-ce utile?

La solution

Eh bien, rien de réaliste, mais vous pouvez faire quelque chose pour que l'angle sortant ne dépende que de l'endroit où il frappe.

Comme je n'ai jamais codé pour l'iPhone ou l'objectif C, je vais simplement écrire quelque chose en pseudo-code C.

Je commencerais par calculer la vitesse, qui est la longueur du vecteur vitesse, ou:

double speed = sqrt(velX * velX + velY * velY); // trigonometry, a^2 + o^2 = h^2

Ensuite, nous voulons calculer le nouvel angle en fonction de l'endroit où nous avons frappé la palette. Je suppose que vous stockez la collision X dans impactX et la longueur de la palette dans paddleLength. De cette façon, nous pouvons calculer un angle sortant. Voyons d’abord comment calculer la plage pour obtenir une valeur comprise entre -1 et 1.

double proportionOfPaddle = impactX / (double) paddleLength; // between 0 and 1
double impactRange = proportionOfPaddle * 2 - 1; // adjust to -1 and 1

Supposons que nous ne voulions pas dévier complètement le ballon, ni à 90 degrés, car il serait difficile de récupérer. Comme je vais utiliser impactRange comme nouvelle vitesse, je vais le réduire pour dire -0,9 à 0,9.

impactRange = impactRange * 0.9;

Nous devons maintenant calculer le VelX pour que la vitesse soit constante.

double newVelX = impactRange;
double newVelY = sqrt(speed * speed - newVelX * newVelX); // trigonometry again

Maintenant, vous retournez newVelX et newVelY et vous obtenez un rebond dépendant de l'impact et de la vitesse.

Bonne chance!

(Peut-être que ce sont des bugs ici, et j'aurais peut-être inversé le X ou le Y, mais j'espère que vous avez compris l'idée générale).

EDIT : ajout de réflexions sur l'obtention de l'impactX.

Supposons que vous avez ball.center.x et paddle.center.x (je ne sais pas comment vous l'appelez, mais supposons que paddle.center.x nous donne le centre de la palette), nous devrions être capable de calculer l'impactRange à partir de cela.

Nous avons également besoin du rayon de la balle (je suppose que ball.width est le diamètre) et de la taille de la palette (paddle.width?).

int ballPaddleDiff = paddle.center.x - ball.center.x;
int totalRange = paddle.width + ball.width;

La plus petite valeur de ballPaddleDiff serait lorsque la balle vient juste de toucher le côté de la raquette. BallPaddleDiff serait alors paddle.width / 2 + ball.width / 2. Ainsi, le nouvel impactRange serait donc

double impactRange = ballPaddleDiff / (double) totalRange / 2;

Vous devriez probablement vérifier l'impactRange de manière à ce qu'il soit compris entre -1 et 1 afin que la balle ne se propage pas dans les étoiles ou quelque chose du genre.

Autres conseils

Vous ne voulez pas nécessairement réaliste, vous voulez vous amuser. Ce ne sont pas toujours les mêmes. Si vous voulez du réalisme, vous ne pouvez pas perdre de vitesse, d’élan, de masse, etc. Dans une partie normale de ping-pong, le point où il frappe la pagaie importe peu, il n’ya pas de place idéale comme sur une raquette de tennis. .

Développe une fonction mathématique qui renvoie un vecteur de sortie, ou une vitesse et un vecteur unitaire, représentant l’angle de sortie et la vitesse de la balle, en donnant un angle d’entrée, une vitesse, un point d’impact sur la palette et la vitesse de la palette .

Nous attendons déjà que l'angle de sortie = -1 * angle d'entrée. La vitesse de sortie devrait également être égale à -1 * la vitesse d'entrée. Donc, si vous voulez mélanger, ajustez-les. Vous pouvez augmenter l'angle de sortie proportionnellement à la distance depuis le centre de la palette. Vous pouvez également augmenter l'angle ou la vitesse proportionnellement à la vitesse de la raquette lorsque vous la touchez.

Il y a beaucoup de façons de le faire, donc je ne peux pas vous dire exactement quelle fonction vous utiliseriez, vous allez devoir comprendre cela en testant et en jouant. Si vous avez encore besoin de plus d’informations, ajoutez plus de détails à votre question.

Le code suivant (C ++ mais assez facile à convertir en ObjC) prend un vecteur 2D entrant et le reflète en fonction d'une surface normale (la face de votre batte pong).

Vous pouvez ajouter un "facteur amusant" aléatoire en randomisant un décalage que vous souhaitez appliquer à "scalaire" - pour modifier la vitesse, ou à la normale à la surface, pour modifier l'angle de réflexion.

J'utilise ceci dans mon projet iPhone, et ça fonctionne très bien:)

void vec2ReflectScalar(vec2& vResult, const vec2& v1, const vec2& normal, float scalar)
{
    vec2  _2ndotvn;
    float dotVal = vec2DotProduct(v1, normal); 

    vec2Scale(_2ndotvn, normal, scalar * 2.f * dotVal);
    vec2Subtract(vResult, v1, _2ndotvn); 
}

void vec2Reflect(vec2& vResult, const vec2& v1, const vec2& normal)
{
    vec2ReflectScalar(vResult, v1, normal, 1.f);
}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top