Construindo um Jogo para a Web Futebol de...

108
Construindo um Jogo para a Web – Futebol de Cabeça Programação para a Internet Prof. Vilson Heck Junior

Transcript of Construindo um Jogo para a Web Futebol de...

Construindo um Jogo para a Web – Futebol de Cabeça

Programação para a InternetProf. Vilson Heck Junior

Tecnologias Necessárias

• Tecnologias já Estudadas:– HTML;

– CSS;

– JavaScript;

• Tecnologias Novas:– Computação Gráfica Básica;

– Noções de Geometria;

– Noções de Física;

– Reprodução de Sons;

– Enredo;

Computação Gráfica

• É um campo da Ciência da Computação que estuda métodos para sintetizar e manipular digitalmente conteúdo visual:– Geração de imagens 2D;

– Geração de imagens 3D (renderização);

– Com ou sem animação;

Noções de Geometria

• Gráficos 2D ou 3D são na verdade acomposição de pequenas peças geométricas:

• A relação espacial dada entre diferentesobjetos existentes em uma cena deve serrespeitada:

– Dois corpos não podem ocupar um mesmo lugar noespaço!

Noções de Física

• Objetos podem possuir algum tipo demovimento ou interação com outros objetos;

• Para isto, geralmente respeitam alguma(s)regras físicas:

– Próximas a real: Simulação;

– Diferenciadas: Arcade;

Reprodução de Sons

• O som é o elemento responsável porestimular o sentido da audição;

• Não tanto quanto os gráficos, mas os sonssão responsáveis por completar uma boasensação de imersão em jogos eentretenimento;

• Geralmente os sons (músicas ou barulhos)serão escolhidos conforme umdeterminado contexto ou acontecimento.

Enredo

• O enredo irá explicar ao usuário o quedeverá ser feito e deve ser o principalresponsável por atrair a atenção dojogador:

– História;

– Diversão;

– Desafios;

– Passatempo;

– ...

Enredo• Futebol de Cabeça:

– Lançado nos anos 201X;

– Plataforma: Web;

– Desenvolvido por várias empresas;

– Tem várias versões com muita variedade de opções e modos;

Enredo

• Futebol de Cabeça:– Jogo de bola;

– Objetivo: fazer gols;

– Na proposta original é possível segurar a bola e chutar, mas a movimentação principal se baseia em cabecear a bola.

No

sso

Co

nce

ito

LISTA DE RECURSOS INICIAISFutebol de Cabeça

Recursos Iniciais

• Pasta: “Futebol”:– index.html

• Construiremos de um documento web, inserindo todos os demais elementos necessários;

– css/estilo.css

• Definiremos algumas configurações de cores, bordas e outros para nossa interface;

– js/ Ball.js, Load.js, Net.js, Player.js e Soccer.js

• Faremos todo o processamento e configurações do jogo, dando ações aos acontecimentos e eventos do jogo.

– subpastas: img e snd

• Armazenaremos os arquivos responsáveis pelas imagens e sons do jogo.

index.html

• Crie o arquivo como doctype para html 5;

• Crie as tags para:

– <html>, <head>, <body>, <title> e <meta>;

• Estipule um <link> com arquivo de estilo (css/estilo.css);

• Adicione os arquivos de <script> ao fim do <body>:

– js/Load.js

– js/Ball.js

– js/Player.js

– js/Net.js

– js/Soccer.js

– Importante: adicionar os outros arquivos js na ordem informada, pois os últimos podem precisar dos primeiros já executados.

index.html

• Adicione as seguintes Tags com seus atributos dentro do <body>:

– <canvas>Navegador não suportado!</canvas>

• id = “tela” width=650 height=500

– <button>Iniciar</button>

• onclick=“Soccer.jogo.pausar();”id=“btnPausar”

– <button>Novo Jogo</button>

• onclick=“novoJogo();”

estilo.css (1/2)

body {

background-color: #2a2a2a;

text-align: center;

color: white;

}

#tela {

background: linear-gradient(#A7EEFF, #63a6d0);

border-left: 10px solid #BBBBBB;

border-right: 10px solid #BBBBBB;

}

estilo.css (2/2)button { background-color: #eb6262;

color: white;

border: 2px solid #af0303;

width: 100px;

height: 30px;

font-weight: bold;

cursor: pointer;

margin: 2px; }

button:hover { background-color: #f57b7b; }

button:disabled { background-color: #b49191;

border-color: #332f2f;

color: gray;

cursor: not-allowed; }

DESENHANDO NO CANVASFutebol de Cabeça

<canvas>

• Canvas é um termo inglês dado a alguns tipos de telapara pintura;

• No nosso caso, será uma área dentro do documentoHTML onde poderemos pintar o que precisarmos;

• Nosso pincel e paleta de cores estão disponíveisatravés de código JavaScript.

<canvas>

• O Canvas é feito para oferecer suporte arápido desenho de cenas bidimensionaisou tridimensionais:

– Geralmente acelerado por Hardware;

0 X width

0 y h

eigh

t

js/Soccer.js

//Um pequeno teste (remover depois de testar)

//Recuperando referência dos objetos no documento

var canvas = document.getElementById("tela");

var ctx = canvas.getContext("2d");

ctx.fillStyle = "#FF0000"; //Usar cor vermelha

ctx.fillRect(20, 30, 50, 100); //x=20, y=30, w=50 e h=100

Desenhando

• Temos uma tela para desenho;

• Conhecemos uma primeira ferramenta parapintar algo;

• Temos que utilizar esta ferramenta de forma aconstruir o cenário inicial do nosso jogo;

Relembrando

Dimensões

• Cada elemento do jogo terá uma dimensão.Círculos serão determinados por um raio eretângulos por uma largura e altura.

Largura

Dimensões

• Além de tudo, sempre poderemos processar edesenhar somente aquilo que está envolvido com atela.

tela.height

tela.width

O OBJETO SOCCERFutebol de Cabeça

Objeto Soccer

• Nosso projeto será, em maior parte,Orientado a Objetos;

• O objeto central será chamado de Soccere terá por responsabilidade gerenciartodos os demais objetos;

• O objeto Soccer também seráresponsável por obter as referências dosobjetos DOM, tal como o Canvas.

js/Soccer.js//Parte dinâmica

function Soccer() {

Soccer.jogo = this;

this.canvas = document.getElementById("tela");

this.ctx = this.canvas.getContext("2d");

this.intervalo = 34;

this.tempo = null;

document.getElementById("btnPausar").disabled = false;

}

//Parte estática

Soccer.jogo = null;

A REDEFutebol de Cabeça

Objeto Net

• A Rede será representada e gerenciada por umobjeto Net;

• Este será o objeto mais simples do jogo, sendo quetodos os atributos e métodos são estáticos (existesempre uma única rede no jogo);

• A Rede deverá ser posicionada no centro da tela,entre os jogadores.

js/Net.js (1/2)function Net() {

}

Net.x = 0;

Net.y = 0;

Net.altura = 220;

Net.cor = "#EEEEEE";

Net.largura = 10;

Net.ajusta = function(xi, yi) {

Net.x = xi;

Net.y = yi;

};

js/Net.js (2/2)

Net.desenhar = function(ctx) {

var metade = Net.largura / 2;

ctx.save();

ctx.translate(Net.x - metade, Net.y);

ctx.fillStyle = Net.cor;

ctx.fillRect(0, 0, Net.largura, Net.altura * 0.9);

ctx.restore();

};

js/Soccer.js//Parte dinâmica

function Soccer() {

Soccer.jogo = this;

this.canvas = document.getElementById("tela");

this.ctx = this.canvas.getContext("2d");

Net.ajusta(this.canvas.width / 2, this.canvas.height - Net.altura);

this.intervalo = 34;

this.tempo = null;

document.getElementById("btnPausar").disabled = false;

}

js/Soccer.js//Parte dinâmica

function Soccer() {

...

document.getElementById("btnPausar").disabled = false;

this.desenharTudo = function() {

this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

Net.desenhar(this.ctx);

};

this.desenharTudo(); //Dentro do construtor, fora de métodos

}

js/Soccer.js//Parte estática

Soccer.jogo = null;

function novoJogo() {

if (Soccer.jogo != null) {

if (Soccer.jogo.tempo != null) {

Soccer.jogo.pausar();

}

}

Soccer.jogo = new Soccer();

}

novoJogo(); //Última linha, sempre

Testar!

O JOGADORFutebol de Cabeça

Objeto Player

• Construiremos um objeto para representarabstratamente os jogadores;

• No nosso caso, este objeto será cada um dospersonagens do jogo, deverá estar em algumaposição do cenário e terá uma imagem derepresentação;

• Os jogadores é que receberão os comandosexecutados pelo usuário e processarão as ações.

js/Player.jsfunction Player(imagem, xi, yi, context) {

Player.todos.push(this);

this.largura = 75;

this.altura = 150;

this.cabecaR = 38;

this.cabecaX = 37;

this.cabecaY = 37;

this.x = xi;

this.maxX = 0;

this.minX = 0;

if (Player.todos[0] == this) {

this.minX = 0;

this.maxX = Net.x - this.cabecaR;

} else {

this.minX = Net.x + this.cabecaR;

this.maxX = Soccer.jogo.canvas.width - 1;

}

//continua no próximo slide

js/Player.jsfunction Player(imagem, xi, yi, context) {

...

this.y = yi;

this.chao = yi;

this.imgs = [];

this.imgs.push(new Image());

this.imgs[0].src = imagem + "-1.png";

this.imgs.push(new Image());

this.imgs[1].src = imagem + "-2.png";

this.imgPulo = new Image();

this.imgPulo.src = imagem + "-p.png";

this.imgAtual = 0;

this.ctx = context;

//continua no próximo slide

js/Player.jsfunction Player(imagem, xi, yi, context) {

...

this.desenhar = function() {

this.ctx.save();

this.ctx.translate(this.x, this.y);

this.ctx.drawImage(this.imgs[this.imgAtual], this.largura /

-2, this.altura / -2, this.largura, this.altura);

this.ctx.restore();

};

} //Fecha a função construtora Player

js/Player.js//Parte estática (fora da função construtora)

Player.todos = [];

Player.desenharTodos = function() {

for(var i = 0; i < Player.todos.length; i++) {

Player.todos[i].desenhar();

}

}

js/Soccer.js//Parte dinâmica, após Net.ajusta

Player.todos = [];

new Player("img/jog1", this.canvas.width / 4, (this.canvas.height /

4) * 3, this.ctx);

new Player("img/jog2", (this.canvas.width / 4) * 3,

(this.canvas.height / 4) * 3, this.ctx);

Baixar imagens de jogadores!

js/Soccer.js//Parte dinâmica, método de desenho

this.desenharTudo = function() {

this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

Net.desenhar(this.ctx);

Player.desenharTodos();

};

Testar!

No console, utilize o seguinte comando:Soccer.jogo.desenharTudo();

A BOLAFutebol de Cabeça

Objeto Bola

• A bola terá uma imagem de representação, umraio e métodos para representar o seumovimento.

• Neste objeto, implementaremos todas asfuncionalidades ligadas a bola.

js/Ball.jsfunction Ball() {

}

Ball.x = 0;

Ball.y = 0;

Ball.raio = 30;

Ball.img = new Image();

Ball.img.src = "img/ball.png";

Ball.velY = 0;

Ball.velX = 0;

js/Ball.jsBall.ajusta = function(xi, yi) {

Ball.x = xi;

Ball.y = yi;

Ball.velY = 0;

Ball.velX = (Math.random() - 0.5) * 20;

};

Ball.desenhar = function(ctx) {

ctx.save();

ctx.translate(Ball.x, Ball.y);

ctx.drawImage(Ball.img, -Ball.raio, -Ball.raio, Ball.raio * 2,

Ball.raio * 2);

ctx.restore();

};

js/Soccer.js//Parte dinâmica, método de desenho

this.desenharTudo = function() {

this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

Net.desenhar(this.ctx);

Player.desenharTodos();

Ball.desenhar(this.ctx);

};

Testar!

No console, utilize o seguinte comando:Soccer.jogo.desenharTudo();

js/Soccer.js//Parte dinâmica

function Soccer() {

Soccer.jogo = this;

this.canvas = document.getElementById("tela");

this.ctx = this.canvas.getContext("2d");

Net.ajusta(this.canvas.width / 2, ...

Ball.ajusta(this.canvas.width / 2, this.canvas.height / 5);

Testar!

No console, utilize o seguinte comando:Soccer.jogo.desenharTudo();

Chão!

• O chão em nosso jogo será um retângulo simples,em um tom de verde.

• Iremos adicionar o desenho do chão no métodode desenhar tudo, haja visto que não há umaclasse específica para o cenário, ou para o chão.

• Para desenhar o chão, tomaremos com base aposição inicial dos pés dos jogadores.

js/Soccer.js//Parte dinâmica, método de desenho

this.desenhoChaoY = Player.todos[0].y + Player.todos[0].altura / 3;

this.chaoY = Player.todos[0].y + Player.todos[0].altura / 2;

this.desenharTudo = function() {

this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

this.ctx.fillStyle = "#069106";

this.ctx.fillRect(0, this.desenhoChaoY, this.canvas.width,

this.canvas.height - this.desenhoChaoY);

Net.desenhar(this.ctx);

Player.desenharTodos();

Ball.desenhar(this.ctx);

}; Testar!

No console, utilize o seguinte comando:Soccer.jogo.desenharTudo();

GERENCIAMENTO DE CARGAFutebol de cabeça

Gerenciamento de Carga

• Ao abrir a página do jogo, nem sempre os elementosdesenhados a partir de imagens serão desenhados.

• Isto devido ao fato do código não esperar que asimagens sejam carregadas. O código continuaexecutando enquanto o navegador faz “download” dasimagens.

• Eventualmente a imagem pode ter sido carregada aoser desenhada, mas não há garantidas.

• Implementaremos um objeto de gerenciamento dacarga das imagens utilizadas no jogo.

js/Load.jsfunction Load() {

}

Load.pronto = false; //Terminou a carga?

Load.totalImagens = 7; //Número de imagens que serão carregas

Load.imagensCarregadas = 0; //Número que já foi carregado

Load.jogoCarregado = false; //O jogo está esperando as imagens?

Load.imagemCarregada = function() {

Load.imagensCarregadas++;

};

js/Load.jsLoad.verificaPronto = function () {

if (Load.totalImagens > Load.imagensCarregadas &&

!Load.jogoCarregado) {

setTimeout(Load.verificaPronto, 100);

} else {

Load.pronto = true;

Soccer.jogo.desenharTudo();

}

}

Load.verificaPronto();

/*A função verificaPronto irá verificar a cada 100ms se tudo terminou de ser carregado.*/

js/Soccer.js//Parte dinâmica, método de desenho

this.desenharTudo = function() {

this.ctx.clearRect(0, 0, this.canvas.width, this.canvas.height);

if (Load.pronto) {

... //desenha elementos (já implementado).

} else {

this.ctx.fillStyle = "#FFFFFF";

this.ctx.font = "30px Arial";

this.ctx.fillText("Carregando...", 10, this.canvas.height / 2,500);

}

};

Testar!

js/Ball.jsfunction Ball() {

}

Ball.x = 0;

Ball.y = 0;

Ball.raio = 30;

Ball.img = new Image();

Ball.img.src = "img/ball.png";

Ball.img.onload = Load.imagemCarregada;

Ball.velY = 0;

Ball.velX = 0;

js/Player.jsfunction Player(imagem, xi, yi, context) {

...

this.imgs.push(new Image());

this.imgs[0].src = imagem + "-1.png";

this.imgs[0].onload = Load.imagemCarregada;

this.imgs.push(new Image());

this.imgs[1].src = imagem + "-2.png";

this.imgs[1].onload = Load.imagemCarregada;

this.imgPulo = new Image();

this.imgPulo.src = imagem + "-p.png";

this.imgPulo.onload = Load.imagemCarregada;

Testar!

COLOCANDO VIDAFutebol de cabeça

O que precisamos?

• Fazer os “jogadores se movimentarem” ao pressionar tecla?

• Fazer a bola se movimentar:

– Com qual intervalo de tempo?

– Para qual direção?

• O que acontece se o jogador colidir com a parede?

• O que acontece se o jogador colidir com a rede?

• O que acontece se o jogador colidir com a bola?

• O que acontece se a bola colidir com o chão? E com a parede?

Movimentação do Jogo

• A Bola irá se movimentar continuamente para“o sentido” em que ela foi direcionada:

– A gravidade deverá sempre atuar na bola.

• Os jogadores irão se movimentarconforme as teclas pressionadas:– Jogador 1: A, D e W

– Jogador 2: Setas

INTERAGINDO COM O USUÁRIOFutebol de cabeça

Eventos!

• A interação é dada por uma troca entre amáquina e o usuário;

• A máquina fornece principalmente imagensque descrevem uma situação, onde pode sernecessária a intervenção do usuário;

• O usuário irá intervir basicamente através decomandos!

– Comandos são captados através de eventos.

Eventos!

• Nosso document possui propriedades deeventos que podem ser associadas àfunções quaisquer;

• Estas funções determinam algo a serfeito quando aquele evento ocorrer:

– document.onkeydown

• Ao descer uma tecla qualquer;

– document.onkeyup

• Ao soltar uma tecla qualquer;

document.onkeydown = Player.pressionaTecla;

document.onkeyup = Player.liberaTecla;

js/Soccer.js

js/Player.js

Testar

//Parte estática

Player.pressionaTecla = function(evt) {

console.log(evt.keyCode);

};

js/Player.js//Parte estática

Player.UP1 = 87; //W

Player.RI1 = 68; //D

Player.LE1 = 65; //A

Player.UP2 = 38; //Seta acima

Player.RI2 = 39; //Seta direita

Player.LE2 = 37; //Seta esquerda

js/Player.js (1/2)//Sobreescrever

Player.pressionaTecla = function(evt) {

switch (evt.keyCode) {

case Player.UP1:

Player.todos[0].pular();

break;

case Player.RI1:

Player.todos[0].moveDir = true;

break;

case Player.LE1:

Player.todos[0].moveEsq = true;

break;

js/Player.js (2/2)

case Player.UP2:

Player.todos[1].pular();

break;

case Player.RI2:

Player.todos[1].moveDir = true;

break;

case Player.LE2:

Player.todos[1].moveEsq = true;

break;

}

};

js/Player.jsPlayer.liberaTecla = function(evt) {

switch (evt.keyCode) {

case Player.RI1:

Player.todos[0].moveDir = false;

break;

case Player.LE1:

Player.todos[0].moveEsq = false;

break;

case Player.RI2:

Player.todos[1].moveDir = false;

break;

case Player.LE2:

Player.todos[1].moveEsq = false;

break;

}

};

CONTROLE GLOBAL DO MOVIMENTO

Futebol de Cabeça

Movendo com Tempo

• Todo tipo de movimento tem uma velocidade;

• Como determinamos a velocidade de algumobjeto?

– Medida Espacial / Tempo!• KM/h

• m/s

• ...

Controlando o Tempo

• Como já definimos, a unidade de espaço de cadamovimento dos jogadores e da bola será por uma distânciapré-determinada;

• Agora precisamos determinar o intervalo de tempo quenosso jogo irá usar para fazer cada movimento doselementos;

• Este tempo será um guia para todo o jogo.

js/Soccer.js

function Soccer() {

...

this.intervalo = 34; //Conforme já definido anteriormente

...

}

Controlando o Tempo

• Exemplo de função JavaScript:

– relogio = setInterval(“NomeFuncao()”, intervalo);• relogio é uma referência ao timer/clock que foi criado;

• NomeFuncao() é a função que será executada a cadaintervalo;

• intervalo é um número inteiro representando aquantidade em milissegundos de intervalo entre umaexecução e outra da função NomeFuncao().

– clearInterval(relogio);• Para o relógio de repetição;

js/Soccer.js

function Soccer() {

...

this.tempo = null; //Conforme já definido anteriormente

...

}

js/Soccer.js

this.pausar = function () {

if (this.tempo == null) {

this.tempo = setInterval(atualizar, this.intervalo);

document.getElementById("btnPausar").innerHTML = "Pausar";

} else {

clearInterval(this.tempo);

this.tempo = null;

document.getElementById("btnPausar").innerHTML = "Continuar";

}

};

js/Soccer.jsfunction atualizar() {

Soccer.jogo.atualizar();

}

js/Soccer.jsthis.atualizar = function () {

//Player.todos[0].mover();

//Player.todos[1].mover();

Ball.mover();

this.desenharTudo();

};

MOVIMENTAÇÃO DA BOLA

Futebol de Cabeça

Movimentação da Bola

• A bola sempre terá uma velocidade associada aomovimento.

• A velocidade dela pode mudar conforme ocorraalguma ação (uma cabeçada, por exemplo).

• A velocidade da bola também pode mudar de sentidoconforme a bola bata em algum objeto.

• Por fim, devemos considerar uma gravidade para abola, ou seja, uma aceleração crescente sentido aochão.

js/Ball.jsBall.mover = function() {

//Ball.colide();Ball.velX *= 0.99; //Diminui velocidade da bola

if (Ball.velY > 0) {//Gravidade – aumenta velocidade pra baixoBall.velY += 0.5;

} else {Ball.velY += 0.66;

}var vel = Math.sqrt(Ball.velX*Ball.velX+Ball.velY*Ball.velY);var velMax = 20; //Limita a velocidade da bolaif (vel > velMax) {

var prop = velMax / vel;Ball.velX *= prop;Ball.velY *= prop;

}Ball.x += Ball.velX;Ball.y += Ball.velY;

};Testar!

MOVIMENTAÇÃO DO JOGADOR

Futebol de Cabeça

Movimentação do Jogador

• O jogador possui variáveis que indicam se ele deve semover para um lado, para outro, ou estar pulando.

• Precisamos implementar os métodos queefetivamente geram estas mudanças de estado.

• Isto será feito pelo método mover() de cada jogador.

js/Player.js//Dinâmicathis.moveEsq = false;this.moveDir = false;this.forcaPulo = Player.alturaPulo;

//EstáticaPlayer.alturaPulo = 10;

js/Player.jsthis.mover = function() {

if (this.moveEsq) {this.x -= 5;this.x = Math.max(this.x, this.minX);this.imgAtual++;

}if (this.moveDir) {

this.x += 5;this.x = Math.min(this.x, this.maxX);this.imgAtual++

}if (this.imgAtual >= this.imgs.length) {

this.imgAtual = 0;}if (this.forcaPulo != Player.alturaPulo) {

this.forcaPulo++;this.y += this.forcaPulo;if (this.y > this.chao) {

this.y = this.chao;}

}};

js/Soccer.jsthis.atualizar = function () {

Player.todos[0].mover(); //Remover os comentários que haviam

Player.todos[1].mover(); //Remover os comentários que haviam

Ball.mover();

this.desenharTudo();

};

Testar!

js/Player.jsthis.pular = function(){

if (this.forcaPulo == Player.alturaPulo) {this.forcaPulo = -Player.alturaPulo;

}};

Testar!

js/Player.jsfunction Player(imagem, xi, yi, context) {

...

this.desenhar = function() {

this.ctx.save();

this.ctx.translate(this.x, this.y);

if (this.forcaPulo == Player.alturaPulo) {

this.ctx.drawImage(this.imgs[this.imgAtual], this.largura /

-2, this.altura / -2, this.largura, this.altura);

} else {

this.ctx.drawImage(this.imgPulo, this.largura / -2,

this.altura / -2, this.largura, this.altura);

}

this.ctx.restore();

};

Testar!

Alterações Restantes

• O que falta alterar?– Quando colide a bola:

• Chão?

• Teto?

• Cabeça dos jogadores?

• Rede?

– Fim de jogo?

– Sons?

js/Ball.jsBall.colide = function() {

//Colide com o chão

if (Ball.y + Ball.raio > Soccer.jogo.chaoY) {

Ball.y = Soccer.jogo.chaoY - Ball.raio;

Ball.velY *= -1;

}

};

js/Ball.jsBall.mover = function() {

Ball.colide(); //Remover comentário que havia

Ball.velX *= 0.99; //Diminui velocidade da bola

...};

Testar!

js/Ball.jsBall.colide = function() {

//Colide com o chão

...

//Colide com a parede direita

if (Ball.x + Ball.raio >= Soccer.jogo.canvas.width) {

Ball.x = Soccer.jogo.canvas.width - Ball.raio;

Ball.velX *= -1;

}

//Colide com a parede esquerda

if (Ball.x - Ball.raio < 0) {

Ball.x = Ball.raio;

Ball.velX *= -1;

}

};

Testar!

js/Ball.js//Colide com a rede (dentro do Ball.colide() )var dx = Ball.x - Net.x;var dy = Ball.y - Net.y;if (Math.abs(dx) <= Ball.raio && Ball.y + Ball.raio >= Net.y) {var dc = Math.sqrt(dx*dx+dy*dy);if (Ball.y < Net.y && dc <= Ball.raio) {//Mais da metade da bola está pra cima da rede e//a bola está em contato com a ponta da rede.var ang = Math.atan2(dy, dx);var passou = Ball.raio - dc;Ball.x += Math.cos(ang) * passou;Ball.y += Math.sin(ang) * passou;

var c = -2 * (Ball.velX * dx + Ball.velY * dy) / (dx * dx + dy * dy);Ball.velX = Ball.velX + c * dx;Ball.velY = Ball.velY + c * dy;

} else {//Mais da metade da bola está pra baixo da rede.Ball.inverteRedeX();

}}

js/Ball.js

Ball.inverteRedeX = function() {Ball.velX *= -1;if (Ball.x < Net.x) {

Ball.x = Net.x - Ball.raio;} else {

Ball.x = Net.x + Ball.raio;}

};

Testar!

js/Ball.jsBall.colide = function() {

...

//Colide com jogador

for (var i = 0; i < Player.todos.length; i++) {

Player.todos[i].colideBola();

}

js/Player.js (1/2)

this.colideBola = function() {

var cx = this.x;

var cy = this.y - (this.altura / 2) + this.cabecaY;

var dx = Ball.x - cx;

var dy = Ball.y - cy;

var dc = Math.sqrt(dx * dx + dy * dy);

if (dc <= this.cabecaR + Ball.raio){

//CÓDIGO NO PRÓXIMO SLIDE

}

};

js/Player.js (2/2)//DENTRO DO IF DO SLIDE ANTERIOR

var ang = Math.atan2(dy, dx);

var passou = ((Ball.raio + this.cabecaR) - dc)+1;

Ball.x += Math.cos(ang) * passou;

Ball.y += Math.sin(ang) * passou;

var c = -2 * (Ball.velX * dx + Ball.velY * dy) / (dx * dx + dy * dy);

Ball.velX = Ball.velX + c * dx;

Ball.velY = Ball.velY + c * dy;

if (Ball.y <= cy && this.forcaPulo < 0) {

Ball.velY *= 1.5;

Ball.velY = -Math.abs(Ball.velY);

Ball.velY = Math.min(Ball.velY, this.forcaPulo);

}

Testar!

js/Ball.jsBall.colide = function() {

//Colide com o chão

if (Ball.y + Ball.raio > Soccer.jogo.chaoY) {

/*Ball.y = Soccer.jogo.chaoY - Ball.raio;

Ball.velY *= -1;*/

Soccer.jogo.gameOver();

}

js/Soccer.js

this.gameOver = function() {

this.pausar();

document.getElementById("btnPausar").disabled = true;

console.log("Game Over!");

};

Testar!

ESTÍMULOS SONOROSFutebol de Cabeça

Estímulos Sonoros

• Conforme comentado anteriormente, quanto maisestimularmos, de forma positiva, os sentidos dosjogadores, maior a probabilidade dele se sentircomo parte do jogo;

• Para isto, iremos adicionar alguns pequenos sonsassociados a eventos como colisões;

• Baixe os arquivos e salve na subpasta snd:– .mp_ e .ogg

<audio> e <source>

• HTML 5!

• MIME Types:– MP3 – audio/mpeg

– Ogg – audio/ogg

– Wav – audio/wav

• Suporte:– Ps.: Múltiplos <source> fornecem redundância!

• Suporte dos diferentes navegadores

index.html

...

<audio controls id="sndWall">

<source src="snd/wall.mp_" type="audio/mpeg">

<source src="snd/wall.ogg" type="audio/ogg">

</audio>

<audio controls id="sndHead">

<source src="snd/head.mp_" type="audio/mpeg">

<source src="snd/head.ogg" type="audio/ogg">

</audio>

<audio controls id="sndWhistle">

<source src="snd/whistle.mp_" type="audio/mpeg">

<source src="snd/whistle.ogg" type="audio/ogg">

</audio>

<script ...></script>

js/Ball.js

//Incluir no fim do arquivo (estático)

Ball.sndWall = document.getElementById("sndWall");

js/Ball.jsBall.colide = function() {

...

//Colide com a parede direita

if (Ball.x + Ball.raio >= Soccer.jogo.canvas.width) {

Ball.x = Soccer.jogo.canvas.width - Ball.raio;

Ball.velX *= -1;

Ball.sndWall.cloneNode(true).play();

}

//Colide com a parede esquerda

if (Ball.x - Ball.raio < 0) {

Ball.x = Ball.raio;

Ball.velX *= -1;

Ball.sndWall.cloneNode(true).play();

}

...

}; //Fim do método

Testar!

1

1

1

1

1

1

4

Trabalho1. Customize cores e outras configurações do arquivo de estilo;

2. Customize cores, tamanhos e disposição dos objetos do jogo (dentro doJavascript). Utilize gradientes e/ou imagens;

3. Complete o HTML informando o nome da disciplina, o nome doinstituto e o seu nome, dispondo os elementos com layouts CSS;

4. Crie um placar com pontuação e opções de continuar e fim de jogo;

5. Crie uma indicações visuais dentro do Canvas do placar e fim de jogo;

6. Adicione e customize os sons de eventos diferentes no jogo;

7. Adicione teclas de atalho para “Pausa” e para “Novo Jogo”;

8. Corrija o bug: ao utilizar as setas para movimentar o segundo jogar,quando há barra de rolagem na janela, a barra se movimenta;

9. Ao evoluir no jogo, crie novos desafios para o jogador;

– Adicione outros elementos a seu critério:

– Exemplos: objetos que aparecem repentinamente, tempo de jogo,chutar a bola, em certos momentos a bola ter comportamentodiferente, etc.

10. Entregue os arquivos por e-mail ao Professor junto com umadescrição/resposta para cada item do trabalho.