xxxxxxxxxx
304
/*
Artur dos Santos Shon(SkyArtur)
Estudante Alura - abril - 2022
Estudando, testando, arriscando...
===============VARIÁVEIS DE ELEMENTOS DO JOGO===================
Começo o meu arquivo declarando as minhas variáveis globais. Às organizei de modo a facilitar a visualização.
BOLINHA*/
let xBall = 300;
let yBall = 200;
let dBall = 30;
let radBall = dBall / 2;
let speedBall = 5;
let speedX = speedBall;
let speedY = speedBall;
// PLAYERS
let xPlayer1 = 5;
let xPlayer2 = 585;
let yPlayer1 = 150;
let yPlayer2 = 150;
let wPlayers = 10;
let hPlayers = 90;
let speedYPlayer2;
// COLISÃO E ERRO DO JOGADOR 2
let collision = false;
let player2Err = 0;
// PONTOS
let pntsPlayer1 = 0;
let pntsPlayer2 = 0;
// SONS
let points;
let touch;
let soundtrack;
/*
Função para précarregar os sons.
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
function preload(){
points = loadSound("ponto.mp3");
touch = loadSound("raquetada.mp3");
soundtrack = loadSound("trilha.mp3");
}
/*============== CRIAÇÃO DE ELEMENTOS DO JOGO ====================
Optei por encapsular minhas funções todas dentro de uma classe, apenas para manter uma organização melhor do meu código.
*/
class CreateElements{
/*
O construtor da classe coloca todos os elementos do jogo
quando a classe é chamada dentro de "draw()".
*/
constructor(){
fill(color("#FFF8DC"));/*<<==== Adicionando cor aos elementos*/
this.ball = circle(xBall, yBall, dBall);
fill(color("#4169E1"))
this.player_01 = rect(xPlayer1, yPlayer1, wPlayers, hPlayers);
fill(color("#DC143C"))
this.player_02 = rect(xPlayer2, yPlayer2, wPlayers, hPlayers);
}
/*
Função para possibilitar o erro do oponente
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong - 5. Editando placar
e adicionando sons - 7. Para saber mais:
erro do oponete;
*/
chanceToMiss(){
if(pntsPlayer2 > pntsPlayer1){
player2Err++;
if(player2Err >= hPlayers){
player2Err = hPlayers + 10;
}
}else{
player2Err--;
if(player2Err <= 35){
player2Err = 35
}
}
}
/*
Função para movimentar a bolinha.
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
moveBall(){
xBall += speedX;
yBall += speedY;
}
/*
Função para movimentar a raquete1 (Esquerda).
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
movePlayer1(){
if(keyIsDown(87)){/*<<==== Teclas W e S para o vovimento da raquete1*/
yPlayer1 -= 10;
}
if(keyIsDown(83)){
yPlayer1 += 10;
}
}
/*
Função para movimentar a raquete2 (Direita).
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
movePlayer2(){
if(keyIsDown(UP_ARROW)){
yPlayer2 -= 10;
}
if(keyIsDown(DOWN_ARROW)){
yPlayer2 += 10;
}
}
/*
Função para movimentar a raquete2 (Direita) automaticamente.
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
movePlayer2Auto(){
speedYPlayer2 = (yBall - yPlayer2 - hPlayers / 2) - 30;
yPlayer2 += speedYPlayer2 + player2Err;
this.chanceToMiss();
}
/*
Função para verificar a colisão da bolinha
com a borda do canvas. Apenas defini que,
quando a extremidade da bolinha(centro + raio),
for igual a qualquer um dos limites do canvas,
a bolinha deve voltar. Isso porque, quando usamos
maior(>) ou menor(<) ele vai computar mais um, ou
mais dois a depender da velocidade da bolinha, isso
faz o centro da bolinha ficar preso atrás do limite
do canvas e gera um bug que faz a bolinha correr a
borda quicando.
Saber exatamente onde está o centro da bolinha
dentro do plano cartesiano, é que vai ajudar a
solucionar o problema da bolinha presa atrás da
raquete. Em partes...
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
ballCollisionEdge(){
if(xBall + radBall == width || xBall - radBall == 0){
speedX *= -1;
}
if(yBall + radBall == height || yBall - radBall == 0){
speedY *= -1;
}
}
/*
Função para verificar a colisão com a raquete
Utilizei a biblioteca sugerida pelo professor
em aula. Com a função "collideRectCircle" da
biblioteca "p5.collide2d.js". Apenas somei ao
raio da bolinha à largura da raquete quando
passei o parametro "raio" da função
"collideRectCircle", porque observei que a
extremidade da bolinha colidia com a face
oposta(fundo) da raquete.
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
playersCollision(x, y){
collision = collideRectCircle(x, y, wPlayers, hPlayers, xBall, yBall, (radBall + wPlayers));/* <<==== Para corrigir o toque da bolinha*/
if(collision){
/*
-------------------------------------------------
Minha solução para o problema da bolinha presa atrás
da raquete foi construir uma condicional que verifica
a posição do centro da bolinha em relação ao plano
cartesiano do canvas. Como quando a bolinha
toca a face da raquete, seu centro deve estar
a pelo menos 30 (unidades) de distâcia da borda;
[5(unidades) da borda ao fundo da raquete,
10(unidades) da largura da raquete,
15(unidades) de raio da bola.]
- Se a posição do centro da bolinha for maior(direita)
ou menor (esquerda) que estas 30(unidades),
o centro da bolinha esta atrás de uma das raquetes e deve ser
reposicionado à 5(unidades) em relação a raquete.
*/
if(xBall >= 570){/*<<==== bolinha à Direita*/
xBall = 565;
}
if(xBall <= 30){/*<<==== bolinha à Esquerda*/
xBall = 35;
}
/*
É muito simples mas funcionou, pelo menos para mim.
O bug ocorre porque o código está funcionando e
fazendo a programação, quando o centro da bolinha
esta atrás da raquete e retorna, bate contra o ponto
que esta definida a colisão com a raquete, então ele volta e
bate contra o seu limite em relação a borda, o código
faz o que tem que fazer e manda de volta,
repetidamente, até bugar. Assim eu faço com que a
bolinha retorne 5(unidades) sempre que houver toque
com a raquete, para isso eu coloco a condicional
dentro da condicional que verificará a variável
"collision", se ela retornar verdadeira, executamos
o reposicionamento da bolinha.
Ps.:EU ACHO!!!
---------------------------------------------------
*/
speedX *= -1;
touch.play();
}
}
/*
Função para colocar o placar
A única diferença é que eu adiciono 5% de
arrendondamento nas bordas dos placares.
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
putScoreboard(){
textAlign(CENTER)
stroke(255)
//Caixas do Placar
fill(color('#FF8C00'));
rect(130, 10, 40, 20, 5);/* <<==== Arrendondamento de borda*/
rect(430, 10, 40, 20, 5);/* <<==== Arrendondamento de borda*/
//Meus Pontos
fill(255);
textSize(16);
text(pntsPlayer1, 150, 26);
//Pontos do Oponente
fill(255);
textSize(16);
text(pntsPlayer2, 450, 26);
}
/*
Função para manipular o placar
-Jogos clássicos parte 1: Iniciando no
JavaScript com Pong.
*/
scorePoints(){
if(xBall >= 585){
pntsPlayer1 += 1;
points.play();
}
if(xBall <= 15){
pntsPlayer2 += 1;
points.play();
}
}
/*
Função para iniciar os elementos do jogo
Ela será chamada dentro da função "draw()"
*/
launcherElements(){
this.moveBall();
this.movePlayer1();
//this.movePlayer2(); /*<<==== Modo MultiPlayer*/
this.movePlayer2Auto()
this.ballCollisionEdge();
this.playersCollision(xPlayer1, yPlayer1);
this.playersCollision(xPlayer2, yPlayer2);
this.putScoreboard();
this.scorePoints();
}
}
//===========================EXECUÇÃO=============================
function setup() {
createCanvas(600, 400);
soundtrack.loop();
}
/*
Na função "draw()" eu crio uma variável elements que
irá receber como atribuição a classe que criei, sendo
assim, uma nova classe, é dela que chamarei a função
para iniciar os elementos do jogo, a partir de elements.
Nota: Eu notei que quando eu declaro a variável como a
classe, os objetos do "constructor", são posicionados.
*/
function draw() {
background("#2E8B57");
const elements = new CreateElements();
elements.launcherElements();
}
/*
Bora para o próximo...
Bibliografia adicional que fez parte do que apliquei aqui
ref: GRONER, Loiane - Estrutura de dados e algoritmos
com javascript - 2ª ed. - São Paulo: Novatec,2018;
*/