Construindo um Jogo para a Web Pinball -...

101
Construindo um Jogo para a Web – Pinball Programação para a Internet Prof. Vilson Heck Junior

Transcript of Construindo um Jogo para a Web Pinball -...

Construindo um Jogo para a Web – Pinball

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• Pinball:

– Originalmente era um jogo eletromecânico - 1869;

– O nome das palhetas “flíper” batizou os fliperamas;

– Tem uma bola de ferro que deve ser rebatida e percorrer obstáculos;

– As primeiras eram apenas mecânicas. Com o tempo, foram ganhando recursos eletrônicos;

– Máquina de 1750:

Enredo

• Pinball:– Com o advento dos videogames surgiram várias versões 100%

eletrônicas de pinballs;

– Objetivo: fazer pontos e não deixar a bolinha cair;

No

sso

Co

nce

ito

LISTA DE RECURSOS INICIAISPinball

Recursos Iniciais

• Pasta: “Pinball”:– 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, funcoes.js, Mapa.js, Palheta.js e Pinball.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/Mapa.js

– js/Ball.js

– js/funcoes.js

– js/Palheta.js

– js/Pinball.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=400 height=500

– <button>Pausar</button>

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

– <button>Novo Jogo</button>

• onclick=“Pinball.novoJogo();”

estilo.css (1/2)

body {

background-color: #2a2a2a;

text-align: center;

color: white;

}

#tela {

background-image: url(../img/cenario1.png);

border-left: 5px solid #000000;

border-right: 5px solid #000000;

}

Baixar da página e salvar no local

correto!

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 CANVASPinball

<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/Pinball.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

Cenário

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 PINBALLPinball

Objeto Pinball

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

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

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

js/Pinball.js//Parte dinâmica

function Pinball() {

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

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

this.tempo = null;

this.iniciado = false;

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

Pinball.jogo = this;

}

//Parte estática

Pinball.jogo = null;

js/Pinball.js//Parte estática

Pinball.novoJogo = function() {

if (Pinball.jogo != null) {

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

Pinball.jogo.pausar();

}

}

new Pinball();

};

Pinball.jogo = null;

Pinball.novoJogo();

A BOLAPinball

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() {

}

//Imagem da bola

Ball.img = new Image();

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

//Posição atual da bola

Ball.x = 0;

Ball.y = 0;

//Posição anterior da bola

Ball.lastX = Ball.x;

Ball.lastY = Ball.y;

//Perímetro e passAng: serão utilizados para detectar batidas da bola

Ball.perimetro = Math.floor(2 * Math.PI * Ball.raio) * 2;

Ball.passoAng = (Math.PI * 2) / (Ball.perimetro / 1);

//Raio da bola

Ball.raio = 7;

Baixar da página e salvar no local

correto!

js/Ball.js//Força do movimento da bola nos eixos x e y

Ball.fx = 0;

Ball.fy = 0;

//Força da gravidade sobre a bola

Ball.grav = 0.05;

//Velocidade máxima da bola

Ball.velMax = Ball.raio;

//Número de sprites diferentes existentes no Mapa

Ball.nSprites = 3;

//Indica se a bola esta liberada ou foi capturada por objetos

// 0: ainda não capturada

// 1: já capturada

// 2: em fase de fuga

Ball.liberada = 0;

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

Ball.x = 388;

Ball.y = 68;

Ball.lastX = Ball.x;

Ball.lastY = Ball.y;

Ball.fx = 0;

Ball.fy = 0;

};

Ball.desenhar = function(ctx) {

ctx.drawImage(Ball.img, Ball.x - Ball.raio, Ball.y - Ball.raio,

Ball.raio * 2, Ball.raio * 2);

};

js/Pinball.js//Parte dinâmica

function Pinball() {

...

Pinball.jogo = this;

Ball.posicaoInicial();

this.desenharTudo();

setTimeout(Pinball.desenharTudo, 1000);

}

//Parte estática

Pinball.desenharTudo = function () {

Pinball.jogo.desenharTudo();

};

js/Pinball.js//Parte dinâmica

this.desenharTudo = function() {

this.ctx.clearRect(0,0, this.canvas.width,

this.canvas.height);

Ball.desenhar(this.ctx);

};

this.desenharTudo();

Este código deve ser inserido depois de:Ball.posicaoInicial();

E antes de:this.desenharTudo();

setTimeout(Pinball.desenharTudo, 1000);

Testar!

CONTROLE GLOBAL DO MOVIMENTO

Pinball

Movendo com Tempo

• Todo tipo de movimento tem uma velocidade;

• Como determinamos a velocidade de algumobjeto?

– Medida Espacial / Tempo!• KM/h

• m/s

• ...

js/Ball.js//Parte estática

Ball.atualizar = function() {

Ball.y += Ball.fy;

Ball.x += Ball.fx;

Ball.lastX = Ball.x;

Ball.lastY = Ball.y;

Ball.fy = Math.max(-Ball.velMax, Ball.fy + Ball.grav);

Ball.fx *= 0.997;

};

Console//Testar no console:

function moveBola() {

Ball.atualizar();

Ball.desenhar(Pinball.jogo.ctx);

};

//Define valores para Ball.fx e Ball.fy

moveBola();

Controlando o Tempo

• Como já definimos, a unidade de espaço de cadamovimento da bola será por uma distância pré-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.

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;

Console//Testar no console:

function moveBola() {

Ball.atualizar();

Ball.desenhar(Pinball.jogo.ctx);

};

//Define valores para Ball.fx e Ball.fy

var tempo = setInterval(moveBola, 100);

clearInterval(tempo);

INTERAGINDO COM O USUÁRIOPinball

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;

js/Pinball.js//Parte estática

Pinball.atualizar = function() {

Pinball.jogo.atualizar();

};

document.onkeydown = function(evt) {

Pinball.jogo.processarTeclas(evt);

};

Pinball.pausar = function() {

Pinball.jogo.pausar();

};

js/Pinball.js//Parte dinâmica

this.atualizar = function() {

Ball.atualizar();

this.desenharTudo();

};

this.processarTeclas = function(evt) {

console.log(evt.keyCode);

};

Testar e descobrir os códigos de teclas para os números de 1 até 9

e as letras Z e X

js/Pinball.js//Parte dinâmica

this.processarTeclas = function(evt) {

if (Ball.x > 370 && evt.keyCode >= 49 && evt.keyCode <= 57) {

var intensidade = evt.keyCode - 48;

Ball.fy = -(Ball.raio * intensidade / 9);

this.iniciado = true;

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

if (this.tempo == null) {

this.pausar();

}

}

};

Reescrever a função

js/Pinball.js//Parte dinâmica

this.pausar = function() {

if (this.tempo == null && this.iniciado) {

this.tempo = setInterval(Pinball.atualizar, 20);

} else if (this.tempo != null) {

clearInterval(this.tempo);

this.tempo = null;

}

};

Testar!

O MAPAPinball

Matriz Mapa

• Na matriz mapa nós representaremos cadacoordenada do cenário, para fins de detectar ondea bola pode passar e onde ela colidirá;

• É importante ressaltar que apesar do Mapa sergerado a partir de uma imagem, outra imagemcompletamente diferente poderá ser utilizada paraexibição em tela;

• Baixem, descompactem e abram no NetBeans oarquivo PinballMapGenerator.zip

Matriz Mapa

• Atenção, sejam cuidadosos com os passos abaixo:

1. Execute o projeto;

2. Abra o arquivo cenario1.png da pasta img;

3. Salve o arquivo resultante sobrescrevendo o arquivoMapa.js;

4. Abra o arquivo Mapa.js no brackets;

js/Mapa.js

var mapa = [

[1,1,1,1,1,1,1,1, ......

[1,1,1,1,1,1,1,1, ......

......

......

O mapa é representado por linhas e colunas no estilo matriz:

0 = Passagem livre1 = Parede sólida2 = Objeto de repulsão3 = Buraco negro

COLOCANDO VIDAPinball

O que precisamos?

• O que acontece se a bola colidir com a parede?

• O que acontece se a bola colidir com um objeto repulsor?

• O que acontece se a bola cair pra “fora do canvas”?

• Onde estão os atuadores?– E se a bola bater neles? Parados? Se movendo?

– Teclas de atalhos para eles?

js/Ball.js (1/4)Ball.colide = function() {

if (Ball.y + Ball.raio < Pinball.jogo.canvas.height) {

var colidiu = 0;

var menorX = Infinity, maiorX = -Infinity;

var menorY = Infinity, maiorY = -Infinity;

var sprites = new Array(Ball.nSprites);

for (var sa = 0; sa < Ball.nSprites; sa++){

sprites[sa] = 0;

}

for (var r = 1; r <= Ball.raio + 1; r += 2) {

for (var ang = 0; ang < Math.PI * 2; ang += Ball.passoAng) {

var x = Math.round(Ball.x + (r * Math.cos(ang)));

var y = Math.round(Ball.y + (r * Math.sin(ang)));

patual = mapa[y][x];

js/Ball.js (2/4)if (patual != 0) {

sprites[patual-1]++;

if (x < menorX) {

menorX = x;

}

if (x > maiorX) {

maiorX = x;

}

if (y < menorY) {

menorY = y;

}

if (y > maiorY) {

maiorY = y;

}

colidiu++;

} //if (patual != 0)

} //for ang

} //for raio

js/Ball.js (3/4)if (colidiu > 0) {

//Descobre o tipo de colisão predominante

var mQtd = 0, mSpr = 1;

for (var sa = 0; sa < Ball.nSprites; sa++){

if (sprites[sa] >= mQtd) {

mQtd = sprites[sa];

mSpr = sa + 1;

}

}

//Velocidade atual da bola

var velAtual = Math.hypot(Ball.fx, Ball.fy);

//Perde velocidade ao bater

velAtual *= 0.9;

//Direção pra onde a parede vai refletir a bola

var difX = Ball.x - (maiorX + menorX) / 2;

var difY = Ball.y - (maiorY + menorY) / 2;

js/Ball.js (4/4)//Angulo pra onde a parede vai refletir a bola

angPonto = Math.atan2(difY, difX);

//Qual será o angulo que a bola irá refletir?

var angNovo = Math.atan2(Ball.fy, Ball.fx);//Angulo atual.

if (mSpr == 1) {

//O Angulo, de fato, será um meio termo entre a direção

//atual da bola e o sentido de que a parede reflete

var nFx = (velAtual * Math.cos(angPonto) + Ball.fx) / 2;

var nFy = (velAtual * Math.sin(angPonto) + Ball.fy) / 2;

//Angulo do sentido intermediário

angNovo = Math.atan2(nFy, nFx);

}

//Novas forças para a bola

Ball.fx = velAtual * Math.cos(angNovo);

Ball.fy = velAtual * Math.sin(angNovo);

} //Fim do if (colidiu > 0)

} //Fim do if (Ball.y + Ball.raio …

}; //Fim do método

js/Ball.js//Atualizar e testar!!!

Ball.atualizar = function() {

Ball.y += Ball.fy;

Ball.x += Ball.fx;

Ball.lastX = Ball.x;

Ball.lastY = Ball.y;

Ball.fy = Math.max(-Ball.velMax, Ball.fy + Ball.grav);

Ball.fx *= 0.997;

Ball.colide();

};

DETECTANDO GAME OVERPinball

js/Ball.js//Adicionar no final do método colide()!!!

Ball.colide = function() {

...

...

if (Ball.y >= Pinball.jogo.canvas.height + Ball.raio) {

Pinball.jogo.gameOver();

}

};

js/Pinball.js//Parte dinâmica

this.gameOver = function() {

this.pausar();

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

console.log("Game Over!");

};

Testar!

OUTROS SPRITESPinball

Outros Sprites

• Anteriormente, implementamos a colisão da bolacontra as paredes brancas. Agoraimplementaremos a colisão da bola contra:

1. Objetos repulsores;

2. Buracos negros.

js/Ball.js//Atualizar o método colide()

Ball.colide = function() {

...

if (mSpr == 1) {

...

} else if (mSpr == 2) {

//Usar apenas o angulo de reflexo

angNovo = angPonto;

//Velocidade máxima

velAtual = Ball.raio;

}

...

};

Testar!

js/Ball.js//Atualizar o método colide()

Ball.colide = function() {

...

} else if (mSpr == 2) {

...

} else if (mSpr == 3 && Ball.liberada < 2) {

angNovo = angPonto + Math.PI;

velAtual = 0.1;

if (angNovo > 2 * Math.PI) {

angNovo -= Math.PI * 2;

}

if (Ball.liberada == 0) {

Ball.liberada = 1;

setTimeout(Ball.disparaAleatorio, 500);

}

}

...

js/Ball.js//Parte estática

Ball.disparaAleatorio = function() {

var ang = Math.random() * 2 * Math.PI;

var vel = Math.random() * Ball.raio;

Ball.fx = vel * Math.cos(ang);

Ball.fy = vel * Math.sin(ang);

Ball.liberada = 2;

setTimeout(Ball.ativaCaptura, 500);

};

Ball.ativaCaptura = function () {

Ball.liberada = 0;

};

Testar!

OS FLIPPERS (ATUADOR/PALHETA)

Pinball

As Palhetas

• Nosso jogo terá objetos Palheta que serão os“batedores” que o jogador poderá controlar.

• Tudo será implementado dentro do arquivo Palheta.js,exceto a instanciação dos objetos e chamadas paraque elas sejam utilizadas.

• Nós iremos inserir inicialmente apenas 2 palhetas emnosso jogo, mas os alunos poderão adicionar outrasem suas customizações:– As palhetas terão as teclas de atalho: Z e X.

js/Palheta.js//Palhetas tem posição X, Y, largura, altura e tecla de acionamento

function Palheta(x, y, largura, altura, tecla) {

this.x = x;

this.y = y;

//movAtual = 0: Parado. -1: Pra baixo. +1: Pra cima.

this.movAtual = 0;

this.tecla = tecla;

this.largura = largura;

this.altura = altura;

this.maxAng = Math.PI / 5; //36 graus

if (this.largura < 0) {

this.ang = -this.maxAng;

} else {

this.ang = this.maxAng;

}

this.lastAng = this.ang;

Palheta.todas.push(this);

}

js/Palheta.js (1/2)//Parte dinâmica

this.desenhar = function(ctx) {

var meio = this.altura / 2;

ctx.fillStyle = "#0000FF";

ctx.strokeStyle = "#00BB00";

ctx.lineWidth = 1;

ctx.beginPath();

var senAng = Math.sin(this.ang);

var cosAng = Math.cos(this.ang);

var x = meio * senAng;

var y = (-meio) * cosAng;

ctx.moveTo(this.x + x, this.y + y);

x = -(meio * senAng);

y = meio * cosAng;

ctx.lineTo(this.x + x, this.y + y);

js/Palheta.js (2/2)...

x = this.largura * cosAng;

y = this.largura * senAng;

ctx.lineTo(this.x + x, this.y + y);

ctx.fill();

ctx.stroke();

};

js/Palheta.js//Parte estática

Palheta.todas = [];

Palheta.desenharTodas = function (ctx) {

for(var i = 0; i < Palheta.todas.length; i++) {

Palheta.todas[i].desenhar(ctx);

}

};

js/Pinball.js//Alterar o método this.desenharTudo

this.desenharTudo = function() {

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

Ball.desenhar(this.ctx);

Palheta.desenharTodas(this.ctx);

};

//Adicionar ao inicio no construtor do Pinball

new Palheta(250, 410, -36, 10, 88);//Direita

new Palheta(165, 410, 36, 10, 90);//Esquerda

Testar!

MOVIMENTAÇÃO DA PALHETA

Pinball

Movimentação da Palheta

• Como dito antes, a palheta deverá se mover apenas sea tecla respectiva estiver pressionada:– Enquanto a tecla estiver pressionada, a palheta deve estar

fazendo força para cima, até um limite;

– Quando a tecla for liberada, a palheta deve movimentar parabaixo, até outro limite.

– Os movimentos da palheta só devem acontecer conforme atemporização do jogo, ou seja, não pode ocorrer em pausa.

js/Palheta.js//Parte dinâmica

this.atuar = function() {

this.movAtual = -1;

};

this.liberar = function() {

this.movAtual = 1;

};

js/Palheta.js//Parte estática

Palheta.processarTeclas = function(keyCode) {

for(var i = 0; i < Palheta.todas.length; i++) {

if (Palheta.todas[i].tecla == keyCode) {

Palheta.todas[i].atuar();

}

}

};

Palheta.liberarTecla = function(keyCode) {

for(var i = 0; i < Palheta.todas.length; i++) {

if (Palheta.todas[i].tecla == keyCode) {

Palheta.todas[i].liberar();

}

}

};

js/Palheta.js (1/2)//Parte dinâmica

this.atualizar = function() {

var passo = this.maxAng / 5;

this.lastAng = this.ang;

//Subindo

if (this.movAtual == -1) {

//ponta para a esquerda

if (this.largura < 0) {

this.ang += passo;

if (this.ang >= this.maxAng) {

this.ang = this.maxAng;

this.movAtual = 0;

}

} else {//ponta para a direita

this.ang -= passo;

if (this.ang <= -this.maxAng) {

this.ang = -this.maxAng;

this.movAtual = 0;

}

js/Palheta.js (2/2)//continuação...

} //fim do else

} else if (this.movAtual == 1) {

//ponta para a esquerda

if (this.largura < 0) {

this.ang -= passo;

if (this.ang <= -this.maxAng) {

this.ang = -this.maxAng;

this.movAtual = 0;

}

} else {//ponta para a direita

this.ang += passo;

if (this.ang >= this.maxAng) {

this.ang = this.maxAng;

this.movAtual = 0;

}

}

}

};

js/Pinball.js//Parte estática

this.atualizar = function() {

Ball.atualizar();

Palheta.atualizarTodas();

this.desenharTudo();

};

//Parte estática

document.onkeydown = function(evt) {

Pinball.jogo.processarTeclas(evt);

};

document.onkeyup = function(evt) {

Pinball.jogo.liberarTecla(evt);

};

js/Palheta.js//Parte estática

Palheta.atualizarTodas = function() {

for (var i = 0; i < Palheta.todas.length; i++) {

Palheta.todas[i].atualizar();

}

};

js/Pinball.js//Parte dinâmica

this.liberarTecla = function(evt) {

Palheta.liberarTecla(evt.keyCode);

};

js/Pinball.js//Parte dinâmica - atualizar

this.processarTeclas = function(evt) {

if (Ball.x > 370 && evt.keyCode >= 49 && evt.keyCode <= 57) {

var intensidade = evt.keyCode - 48;

Ball.fy = -(Ball.raio * intensidade / 9);

this.iniciado = true;

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

if (this.tempo == null) {

this.pausar();

}

} else if (this.tempo != null) {

Palheta.processarTeclas(evt.keyCode);

}

};

Testar!

Alterações Restantes

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

• Palhetas

– Sons?

js/Palheta.js (1/4)//Parte dinâmica

this.colideBola = function() {

var meio = this.altura / 2;

var Npassos = 10;

for (var passo = 1; passo <= Npassos; passo++){

var angAtual = (this.lastAng * (Npassos - passo) + this.ang* passo) / Npassos;

var bxAtual = Ball.lastX + Ball.fx * (passo / Npassos);

var byAtual = Ball.lastY + Ball.fy * (passo / Npassos);

var senAng = Math.sin(angAtual);

var cosAng = Math.cos(angAtual);

var x = meio * senAng;

var y = (-meio) * cosAng;

var A = [this.x + x, this.y + y];

js/Palheta.js (2/4)//continuação...

x = this.largura * cosAng;

y = this.largura * senAng;

var B = [this.x + x, this.y + y];

var dist = distToSegment([bxAtual, byAtual], A, B);

if (dist <= Ball.raio) {

var angBola = Math.atan2(Ball.fy, Ball.fx);

var vel = Math.sqrt(dist2([Ball.fx, Ball.fy], [0,0]));

var distPonta = Math.sqrt(dist2([bxAtual, byAtual], B));

var fator = (Math.abs(this.largura) - distPonta) /

Math.abs(this.largura);

js/Palheta.js (3/4)//continuação...

var angMeio;

if (angAtual < 0) {

angMeio = angAtual - (Math.PI / 2) - fator *

(Math.PI / 4);

} else {

angMeio = angAtual + (Math.PI / 2) + fator *

(Math.PI / 4);

}

angBola = angMeio;

Ball.x = bxAtual + dist * Math.sin(angBola);

Ball.y = byAtual + dist * Math.cos(angBola);

js/Palheta.js (4/4)//continuação...

if (this.movAtual < 0 && this.ang != this.lastAng) {

var sobra = Ball.velMax - vel;

vel = Ball.velMax;

} else if (this.movAtual > 0) {

vel *= 0.6;

} else {

vel *= 0.6;

}

Ball.fx = vel * Math.sin(angBola);

Ball.fy = vel * Math.cos(angBola);

} //fim if (dist <= Ball.raio)

} //fim for

};

js/funcoes.js//http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment

function sqr(x) { return x * x; }

function dist2(v, w) { return sqr(v[0] - w[0]) + sqr(v[1] - w[1]); }

function distToSegmentSquared(p, v, w) {

var l2 = dist2(v, w);

if (l2 == 0) return dist2(p, v);

var t = ((p[0] - v[0]) * (w[0] - v[0]) + (p[1] - v[1]) * (w[1] –

v[1])) / l2;

t = Math.max(0, Math.min(1, t));

return dist2(p, [ v[0] + t * (w[0] - v[0]), v[1] + t * (w[1] –

v[1]) ] );

}

function distToSegment(p, v, w) {

return Math.sqrt(distToSegmentSquared(p, v, w));

}

js/Palheta.js//Atualizar função já existente!

Palheta.atualizarTodas = function() {

for (var i = 0; i < Palheta.todas.length; i++) {

Palheta.todas[i].colideBola();

Palheta.todas[i].atualizar();

Palheta.todas[i].colideBola();

}

};

Testar!

ESTÍMULOS SONOROSPinball

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="musica">

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

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

</audio>

<audio controls id="bateParede">

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

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

</audio>

<script ...></script>

js/Pinball.jsfunction Pinball() {

this.tempo = null;

this.musica = document.getElementById('musica');

this.sndBateParede = document.getElementById('bateParede');

if (!this.musica.paused) {

this.musica.pause();

}

this.musica.position = 0;

js/Pinball.js//atualizar...

this.pausar = function() {

if (this.tempo == null && this.iniciado) {

this.tempo = setInterval(Pinball.atualizar, 20);

this.musica.play();

this.musica.volume = 1;

} else if (this.tempo != null) {

clearInterval(this.tempo);

this.tempo = null;

this.musica.volume = 0.2;

}

};

Testar!

js/Ball.js//atualizar...

if (mSpr == 1) {

//O Angulo, de fato, será um meio termo entre a direção

//atual da bola e o sentido de que a parede reflete

var nFx = (velAtual * Math.cos(angPonto) + Ball.fx) / 2;

var nFy = (velAtual * Math.sin(angPonto) + Ball.fy) / 2;

//Angulo do sentido intermediário

angNovo = Math.atan2(nFy, nFx);

Pinball.jogo.sndBateParede.cloneNode(true).play();

} else if (mSpr == 2) {

Testar!

1

1

1

1

1

2

1

2

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 cenário para o seu jogo;

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

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

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

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

9. Identifique e corrija os bugs que você encontrar.

10. 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,relevos, em certos momentos a bola ter comportamento diferente,etc.

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