Ecco la logica pertinente che ho usato sul pong sulla mia homepage : (per favore vai a giocarci prima di leggere, in modo che tu sappia l'effetto che sto ottenendo con il seguente codice)
In sostanza, quando la palla si scontra con la paletta, la sua direzione viene completamente ignorata; gli viene data una nuova direzione in base alla distanza dal centro della paletta. Se la palla colpisce la paletta proprio al centro, viene espulsa esattamente in orizzontale; se colpisce proprio sul bordo, vola via con un angolo estremo (75 gradi). E viaggia sempre a velocità costante.
var relativeIntersectY = (paddle1Y+(PADDLEHEIGHT/2)) - intersectY;
Prendi il valore Y centrale della paletta e sottrai l'intersezione Y della palla. Se la paletta è alta 10 pixel, questo numero sarà compreso tra -5 e 5. Lo chiamo "incrocio relativo" perché ora si trova nello "spazio della paletta", l'intersezione della palla rispetto al centro della paletta.
var normalizedRelativeIntersectionY = (relativeIntersectY/(PADDLEHEIGHT/2));
var bounceAngle = normalizedRelativeIntersectionY * MAXBOUNCEANGLE;
Prendi l'intersezione relativa e dividila per metà dell'altezza della paletta. Ora il nostro numero da -5 a 5 è un decimale da -1 a 1; è normalizzato . Quindi moltiplicalo per l'angolo massimo con cui vuoi far rimbalzare la palla. L'ho impostato su 5 * Pi / 12 radianti (75 gradi).
ballVx = BALLSPEED*Math.cos(bounceAngle);
ballVy = BALLSPEED*-Math.sin(bounceAngle);
Infine, calcola le nuove velocità della palla, usando una semplice trigonometria.
Questo potrebbe non essere l'effetto che stai cercando o potresti anche determinare una velocità moltiplicando l'intersezione relativa normalizzata per una velocità massima; questo renderebbe la palla più veloce se colpisce vicino al bordo di una paletta, o più lenta se colpisce vicino al centro.
Vorrei forse un po 'di codice su come sarebbe un vettore o su come potrei salvare la variabile del vettore che hanno le palle (velocità e direzione).
Un vettore contiene sia la velocità che la direzione, implicitamente. Conservo il mio vettore come "vx" e "vy"; cioè, la velocità nella direzione xe la velocità nella direzione y. Se non hai seguito un corso introduttivo di fisica, questo potrebbe sembrare in qualche modo estraneo a te.
Il motivo per cui lo faccio è perché riduce i calcoli per frame necessari; ogni fotogramma, lo fai x += vx * time;
e y += vy * time;
dove il tempo è il tempo dall'ultimo fotogramma, in millisecondi (quindi le velocità sono in pixel per millisecondo).
Per quanto riguarda l'implementazione della capacità di curvare la palla:
Prima di tutto, dovresti conoscere la velocità della paletta nel momento in cui la palla colpisce; ciò significa che dovresti tenere traccia della cronologia della paletta, in modo da poter conoscere una o più delle posizioni passate della paletta in modo da poterle confrontare con la sua posizione attuale per vedere se si è mossa. (cambio di posizione / cambio di tempo = velocità; quindi sono necessarie 2 o più posizioni e i tempi di tali posizioni)
Ora devi anche tenere traccia di una velocità angolare della palla, che rappresenta praticamente la curva lungo la quale sta viaggiando, ma equivale alla rotazione reale della palla. In modo simile all'interpolazione dell'angolo di rimbalzo dalla posizione relativa della sfera in caso di collisione con la paletta, è necessario interpolare questa velocità angolare (o rotazione) dalla velocità della paletta in caso di collisione. Invece di impostare semplicemente la rotazione come fai con l'angolo di rimbalzo, potresti voler aggiungere o sottrarre alla rotazione esistente della palla, perché tende a funzionare bene nei giochi (il giocatore può notare che la palla gira e fa girare la palla) ancora più selvaggiamente, o contrastare la rotazione nel tentativo di farla viaggiare dritta).
Si noti, tuttavia, che mentre questo è il senso più comune e probabilmente il modo più semplice per implementarlo, la fisica effettiva di un rimbalzo non si basa esclusivamente sulla velocità dell'oggetto che colpisce; un oggetto senza velocità angolare (senza rotazione) che colpisce una superficie ad angolo, avrà una rotazione impartita su di essa. Questo potrebbe portare a una migliore meccanica di gioco, quindi potresti voler esaminare questo, ma non sono sicuro della fisica che sta dietro, quindi non proverò a spiegarlo.