Aqui está a lógica relevante que usei no pong na minha página inicial : (por favor, jogue-a antes de ler, para que você saiba o efeito que estou conseguindo com o código a seguir)
Essencialmente, quando a bola colide com a raquete, sua direção é completamente desconsiderada; é dada uma nova direção de acordo com a distância do centro da raquete que colidiu. Se a bola acertar a raquete bem no centro, ela será enviada exatamente na horizontal; se atingir a borda, voa em um ângulo extremo (75 graus). E viaja sempre a uma velocidade constante.
var relativeIntersectY = (paddle1Y+(PADDLEHEIGHT/2)) - intersectY;
Pegue o valor Y médio da raquete e subtraia a interseção Y da bola. Se a raquete tiver 10 pixels de altura, esse número estará entre -5 e 5. Eu chamo isso de "interseção relativa" porque agora está no "espaço da raquete", a interseção da bola em relação ao meio da raquete.
var normalizedRelativeIntersectionY = (relativeIntersectY/(PADDLEHEIGHT/2));
var bounceAngle = normalizedRelativeIntersectionY * MAXBOUNCEANGLE;
Pegue a interseção relativa e divida-a pela metade da altura da raquete. Agora nosso número de -5 a 5 é um decimal de -1 a 1; está normalizado . Em seguida, multiplique pelo ângulo máximo pelo qual você deseja que a bola salte. Defino-o como 5 * Pi / 12 radianos (75 graus).
ballVx = BALLSPEED*Math.cos(bounceAngle);
ballVy = BALLSPEED*-Math.sin(bounceAngle);
Finalmente, calcule novas velocidades da bola, usando trigonometria simples.
Esse pode não ser o efeito que você está buscando ou também pode determinar uma velocidade multiplicando a interseção relativa normalizada por uma velocidade máxima; isso tornaria a bola mais rápida se acertar perto da borda de uma raquete ou mais lenta se acertar perto do centro.
Eu gostaria de algum código sobre como seria um vetor ou como eu poderia salvar a variável do vetor que as bolas têm (velocidade e direção).
Um vetor contém velocidade e direção, implicitamente. Eu armazeno meu vetor como "vx" e "vy"; isto é, a velocidade na direção x e a velocidade na direção y. Se você não fez um curso introdutório de física, isso pode parecer um pouco estranho para você.
A razão pela qual faço isso é porque reduz os cálculos por quadro necessários; cada quadro, você faz x += vx * time;
e y += vy * time;
onde o tempo é o tempo desde o último quadro, em milissegundos (portanto, as velocidades são em pixels por milissegundo).
Em relação à implementação da capacidade de curvar a bola:
Primeiro de tudo, você precisa saber a velocidade da raquete no momento em que a bola bate; o que significa que você precisa acompanhar o histórico da raquete, para poder conhecer uma ou mais posições anteriores da raquete, para poder compará-las à sua posição atual para ver se ela se moveu. (mudança de posição / mudança de tempo = velocidade; você precisa de 2 ou mais posições e os horários dessas posições)
Agora você também precisa rastrear uma velocidade angular da bola, que praticamente representa a curva ao longo da qual está viajando, mas é equivalente ao giro da bola no mundo real. Semelhante à maneira como você interpolava o ângulo de ressalto da posição relativa da bola em colisão com a raquete, também seria necessário interpolar essa velocidade angular (ou rotação) da velocidade da raquete em colisão. Em vez de simplesmente definir o giro como você faz com o ângulo de pulo, você pode adicionar ou subtrair o giro existente da bola, porque isso tende a funcionar bem nos jogos (o jogador pode perceber que a bola está girando e fazer com que ela gire ainda mais descontroladamente, ou contrarie o giro na tentativa de fazê-lo viajar reto).
Note, however, that while this is the most common sense and probably easiest way to implement it, the actual physics of a bounce doesn't rely solely on the velocity of the object it hits; an object with no angular velocity (no spin) which hits a surface at an angle, will have a spin imparted upon it. This might lead to a better game mechanic, so you may want to look into this, but I'm not certain of the physics behind it so I'm not going to try to explain it.