Elaborei uma forma mais "natural" de movimentação e chance de erro do oponente.
Eu fiz com que a raquete do oponente busque uma posicaoYAlvo
que é obtida através da posição Y da bolinha e um desvio gerado aleatoriamente. Abaixo está a função de movimento:
function movimentaRaqueteAdversaria() {
var posicaoYAlvo = posicaoYBolinha - desvioYRaqueteAdversaria;
if(adversarioComputador) { //opção para jogar com o computador controlando a raquete da direita.
if(direcaoXBolinha == 1) { //faz com que a raquete do computador se movimente apenas quando a bolinha vai em sua direção.
if(posicaoYRaqueteAdversaria > posicaoYAlvo && posicaoYRaqueteAdversaria > 0) {
posicaoYRaqueteAdversaria -= velocidadeYRaquete; //a velocidade da raquete é constante e igual para as duas raquetes.
}
if(posicaoYRaqueteAdversaria < posicaoYAlvo && posicaoYRaqueteAdversaria < (height - alturaRaquete)) {
posicaoYRaqueteAdversaria += velocidadeYRaquete; //a velocidade da raquete é constante e igual para as duas raquetes.
}
}
}
if(!adversarioComputador) { //opção para jogar com uma pessoa controlando a raquete da direita.
if(keyIsDown(UP_ARROW) && posicaoYRaqueteAdversaria > (0)) {
posicaoYRaqueteAdversaria -= velocidadeYRaquete;
}
if(keyIsDown(DOWN_ARROW) && posicaoYRaqueteAdversaria < (height - alturaRaquete)) {
posicaoYRaqueteAdversaria += velocidadeYRaquete;
}
}
}
Achei interessante a ideia do Raphael Aracelli, em que a raquete do oponente não está o tempo todo em movimento. No entanto decidi implementar apenas a restrição de direção.
O desvio utilizado para o cálculo da posicaoYAlvo
é gerado pela função:
function calculaDesvioYRaqueteAdversaria() {
var margemDeErro = 20;
//o desvio é calculado com base na altura da raquete com a adição de uma margem de erro em cada ponta.
desvioYRaqueteAdversaria = random(margemDeErro * -1, alturaRaquete + margemDeErro);
}
O calculo do desvio é feito em dois momentos. Um deles é na colisão da bolinha com a raquete do jogador e o outro é no saque da bolinha após o ponto.
//função que reposiciona a bolinha após um ponto marcado.
function realizaSaque(direcaoXSaque) {
var distanciaSaque = 20;
posicaoYBolinha = random((0 + 2 * raioBolinha), (height - 2 * raioBolinha)); //a posição Y é redefinida aleatóriamente com um offset para que a bolinha não fique presa nas bordas.
if(direcaoXSaque === 'direita') {
calculaDesvioYRaqueteAdversaria(); //é necessário calcular o desvio, caso contrario o computador iria continuar errando a bolinha.
direcaoXBolinha = 1;
posicaoXBolinha = posicaoXRaqueteJogador + distanciaSaque;
}
if(direcaoXSaque === 'esquerda') {
direcaoXBolinha = -1;
posicaoXBolinha = posicaoXRaqueteAdversaria - distanciaSaque;
}
}
Achei interessante essa implementação da movimentação e erro, pois ela possibilita que ocorra o impacto da bolinha em qualquer ponto da raquete assim como que o erro ocorra tanto a cima quanto abaixo da raquete.
Segue os links do projeto:
jogo: https://editor.p5js.org/gustavowill/full/vFKRNiinM
código: https://editor.p5js.org/gustavowill/sketches/vFKRNiinM
PS: Eu adicionei algumas funcionalidades enquanto estava brincando com o código. Uma delas é a opção de jogar com as duas raquetes sendo controladas pelo teclado.