Domanda

Vorrei deviare una palla inclinata a seconda di dove colpisce una paletta. In questo momento, sto solo cambiando la coordinata y, il che si traduce in una deformazione poco interessante. Sarà inclinato ma indipendente dalla posizione dell'impatto contro la paletta. Vorrei qualcosa di più divertente. Velocità, momento, massa e altri fattori non devono essere presi in considerazione. Basta inclinare in base alla posizione dell'impatto della paletta. Ho letto questo Non un numero errore (NAN) durante il rilevamento delle collisioni in un'app per iPhone ma sembra eccessivamente complicato per quello che sto cercando. Esiste un modo più semplice per calcolare la deflessione?

Gli oggetti sono due UIImageViews.

È stato utile?

Soluzione

Beh, niente di realistico ma potresti fare qualcosa in modo che l'angolo in uscita dipenda solo da dove colpisce la paletta.

Non ho mai fatto nessun codice iPhone o C obiettivo quindi scriverò qualcosa in codice pseudo / C.

Per prima cosa calcolerei la velocità, che è la lunghezza del vettore di velocità, oppure:

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

Quindi vogliamo calcolare il nuovo angolo in base a dove colpiamo la paletta. Presumo che tu memorizzi la collisione X in impactX e la lunghezza della paletta in paddleLength. In questo modo possiamo calcolare un angolo in uscita. Innanzitutto scopriamo come calcolare l'intervallo in modo da ottenere un valore compreso tra -1 e 1.

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

Supponiamo che non vogliamo deviare completamente la palla di lato, o 90 gradi, dal momento che sarebbe piuttosto difficile riprenderci. Dal momento che userò il range di impatto come il nuovo vely, lo ridimensionerò per dire da -0,9 a 0,9.

impactRange = impactRange * 0.9;

Ora dobbiamo calcolare velX in modo che la velocità sia costante.

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

Ora restituisci newVelX e newVelY e hai un impatto che dipende dalla velocità di rimbalzo.

Buona fortuna!

(Potrebbe benissimo essere bug qui, e potrei aver invertito la X o Y, ma spero che tu abbia l'idea generale).

EDIT : aggiungendo alcune idee su come ottenere l'impattoX.

Supponiamo che tu abbia il ball.center.x e il paddle.center.x (non so come lo chiami, ma supponiamo che paddle.center.x ci dia il centro del paddle) dovremmo essere in grado di calcolare la portata dell'impatto da quella.

Abbiamo anche bisogno del raggio della palla (assumerò ball.width come diametro) e delle dimensioni della paletta (paddle.width?).

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

Il valore più piccolo per ballPaddleDiff sarebbe quando la palla tocca appena il lato della paletta. Quel ballPaddleDiff sarebbe quindi paddle.width / 2 + ball.width / 2. Pertanto, la nuova gamma di impatto sarebbe quindi

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

Probabilmente dovresti controllare la gamma di impatto in modo che sia effettivamente compresa tra -1 e 1 in modo che la palla non si spari contro le stelle o qualcosa del genere.

Altri suggerimenti

Non necessariamente realistico, vuoi divertimento. Quelli non sono sempre la stessa cosa. Se volevi realistico, non puoi lanciare velocità, quantità di moto, massa, ecc. In un normale gioco di ping pong, il punto in cui colpisce la pagaia non ha importanza, non c'è un punto debole come su una racchetta da tennis .

Sviluppa una funzione matematica che restituirà un vettore di output, o una velocità e un vettore di unità, che rappresentano l'angolo di output e la velocità della palla, fornendo un angolo di input, velocità, punto di impatto sulla paletta e velocità della paletta .

Prevediamo già che l'angolo di uscita = -1 * angolo di ingresso. Anche la velocità di uscita dovrebbe essere -1 * la velocità di ingresso. Quindi, se vuoi mescolarlo, aggiusta quelli. È possibile aumentare l'angolo di uscita proporzionale alla distanza dal centro della paletta. È inoltre possibile aumentare l'angolo o la velocità proporzionale alla velocità della paletta quando viene colpito.

Ci sono molti modi in cui potresti farlo, quindi non posso dirti esattamente quale funzione utilizzeresti, dovrai scoprirlo con i test e il gioco. Se hai ancora bisogno di maggiori informazioni aggiungi ulteriori dettagli alla tua domanda.

Il seguente codice (C ++ ma abbastanza facile da convertire in ObjC), prende un vettore 2D in arrivo e lo riflette sulla base di una normale superficie (la faccia della tua mazza da pong).

Potresti aggiungere qualche "fattore divertente" casuale randomizzando un offset che applicheresti a "scalare" - per cambiare la velocità, o alla normale della superficie, per alterare l'angolo di riflessione.

Lo sto usando nel mio progetto iPhone e funziona benissimo :)

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);
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top