construindo um jogo para a web flappybirddocente.ifsc.edu.br/vilson.junior/pi/05_construindo... ·...
TRANSCRIPT
Construindo um Jogo para a Web – Flappy Bird
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• Flappy Bird:
– Lançado em 2013;
– Plataforma: Móvel;
– Desenvolvido por Nguyễn Hà Đông (Vetinamita);
– Publicado pela .GEARS studios;
– Foi programado em 3 dias;
– Chegou a faturar $50.000,00 por dia;
Enredo
• Flappy Bird:– Jogo de rolagem horizontal;
– Pássaro avança ao longo do cenário;
– Desviar canos;
– Sem bater no chão ou teto.
No
sso
Co
nce
ito
LISTA DE RECURSOS INICIAISFlappy Bird
Recursos Iniciais
• Pasta: “FlappyBird”:– 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/ Flappy.js, Jogador.js, Obstaculo.js, TipoObstaculo.js, Geometria.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/Geometria.js
– js/TipoObstaculo.js
– js/Obstaculo.js
– js/Jogador.js
– js/Flappy.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=600 height=400
– <button>Iniciar</button>
• onclick=“Flappy.pausar();” id=“btnIniciar”
– <button>Novo Jogo</button>
• onclick=“Flappy.novoJogo();”
– <p id="tecla"></p>
– <p>A: Bater asas</p>
estilo.css (1/2)
body {
background-color: #111611;
text-align: center;
color: white;
}
#tela {
background: linear-gradient(#A7EEFF, #63a6d0);
border-bottom: 10px solid #526F35;
border-top: 10px solid #B6B6B4;
}
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 CANVASFlappy Bird
<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/Flappy.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
Rotação
• Cada elemento do jogo poderá ser girado. Istoimplica em girar a tela para desenhar eprocessar corretamente as colisões.
Angulo
Dimensões
• Além de tudo, sempre poderemos processar edesenhar somente aquilo que está envolvido com atela.
tela.height
tela.width
O OBJETO FLAPPYFlappy Bird
Objeto Flappy
• Nosso projeto será, em maior parte,Orientado a Objetos;
• O objeto central será chamado de Flappye terá por responsabilidade gerenciartodos os demais objetos;
• O objeto Flappy também seráresponsável por obter as referências dosobjetos DOM, tal como o Canvas.
js/Flappy.js
function Flappy(canvasStr) {
this.canvas = document.getElementById(canvasStr);
this.ctx = this.canvas.getContext("2d");
this.larTela = this.canvas.width;
this.altTela = this.canvas.height;
this.tempo = null;
}
O JOGADORFlappy Bird
Objeto Jogador
• Construiremos um objeto para representarabstratamente o jogador;
• No nosso caso, este objeto será o pássaro do jogoe deverá estar em alguma posição do cenário;
• O jogador é quem recebera os comandosexecutados pelo usuário e processará as ações.
js/Jogador.jsfunction Jogador(flappy) {
this.flappy = flappy;
this.altura = 15; //Raio
this.angulo = 0;
this.x = (flappy.larTela / 8) + this.altura / 2;
this.y = (flappy.altTela / 2) + this.altura / 2;
this.desenhar = function() {
var ctx = this.flappy.ctx;
ctx.save();
ctx.translate(this.x, this.y);
ctx.beginPath();
ctx.arc(0, 0, this.altura, Math.PI * 0.25, Math.PI * 1.75);
ctx.stroke();
ctx.fill();
ctx.restore();
};
}
js/Flappy.jsfunction Flappy(canvasStr) {
this.jogador = new Jogador(this);
this.desenharTudo = function() {
this.ctx.clearRect(0,0,this.larTela, this.altTela);
this.jogador.desenhar();
};
} //FIM FUNCTION FLAPPY
var jogo = null;
Flappy.novoJogo = function () {
Flappy.intervalo = 25;
jogo = new Flappy("tela");
jogo.desenharTudo();
document.getElementById("btnIniciar").innerHTML = "Iniciar";
document.getElementById("btnIniciar").disabled = false;
}
Flappy.novoJogo(); Testar!
O OBSTÁCULOFlappy Bird
Objeto Obstaculo
• Cada obstáculo existente que o jogador devesuperar serão representados por um objetochamado Obstaculo.
• Estes objetos serão responsáveis por identificar otipo de obstáculo, bem como o seuposicionamento.
js/Obstaculo.jsfunction Obstaculo(flappy) {
this.flappy = flappy;
this.tipo = new TipoObstaculo();
if (Obstaculo.todos.length == 0) {
this.x = flappy.larTela * 0.666;
} else {
this.x = flappy.larTela * 1.3;
}
Obstaculo.todos.push(this);
}
Obstaculo.todos = [];
Objeto TipoObstaculo
• Um conjunto diferente de formas, tamanhos etexturas devem definir as possibilidades derepresentação dos objetos Obstaculo.
• Este objeto TipoObstaculo será responsável pordefinir estes modelos possíveis para osObstáculos.
js/TipoObstaculo.jsfunction TipoObstaculo() {
var sorteio = Math.floor(Math.random() * TipoObstaculo.todos.length);
var modelo = TipoObstaculo.todos[sorteio];
this.moveY = modelo.moveY;
this.passagem = modelo.passagem;
this.altura = modelo.altura;
this.largura = modelo.largura;
this.angulo = modelo.angulo;
this.corPreenchimento = modelo.corPreenchimento;
this.corContorno = modelo.corContorno;
this.imagem = modelo.imagem;
}
js/TipoObstaculo.jsTipoObstaculo.todos = [//Inicio do vetor
{
moveY : -0.25,
passagem : 150,
altura : 200,
largura : 100,
angulo : Math.PI / 90,
imagem : new Image()
}, //Fim elemento 0
{
moveY : 0.5,
passagem : 120,
altura : 150,
largura : 60,
angulo : Math.PI / -40,
imagem : new Image()
}, //Fim elemento 1
js/TipoObstaculo.js{
moveY : 0.5,
passagem : 120,
altura : 250,
largura : 60,
angulo : Math.PI / 40,
imagem : new Image()
}, //Fim elemento 2
{
moveY : 0,
passagem : 120,
altura : 100,
largura : 40,
angulo : 0,
imagem : new Image()
} //Fim elemento 3 (último)
]; //Fim do vetor
js/TipoObstaculo.js
TipoObstaculo.todos[0].imagem.src = "img/bricks0.jpg";
TipoObstaculo.todos[1].imagem.src = "img/bricks1.jpg";
TipoObstaculo.todos[2].imagem.src = "img/bricks2.jpg";
TipoObstaculo.todos[3].imagem.src = "img/bricks3.jpg";
Baixar as imagens da pagina da disciplina para a subpasta img
js/Obstaculo.jsthis.desenhar = function () {
flappy.ctx.save();
flappy.ctx.lineWidth = 4;
flappy.ctx.translate(this.x + (this.tipo.largura / 2), flappy.altTela / 2);
flappy.ctx.rotate(this.tipo.angulo);
var p1 = -((flappy.altTela / 2) - this.tipo.altura);
var p2 = p1 + this.tipo.passagem;
flappy.ctx.drawImage(this.tipo.imagem, 0,0,this.tipo.largura, flappy.altTela, this.tipo.largura / -2, p1, this.tipo.largura, -flappy.altTela);
flappy.ctx.drawImage(this.tipo.imagem, 0,0,this.tipo.largura, flappy.altTela, this.tipo.largura / -2, p2, this.tipo.largura, flappy.altTela);
flappy.ctx.restore();
};
js/Obstaculo.js
Obstaculo.desenharTodos = function () {
for(var i = 0; i < Obstaculo.todos.length; i++) {
Obstaculo.todos[i].desenhar();
}
};
js/Flappy.jsfunction Flappy(canvasStr) {
this.jogador = new Jogador(this);
new Obstaculo(this);
this.desenharTudo = function() {
this.ctx.clearRect(0,0,this.larTela, this.altTela);
this.jogador.desenhar();
Obstaculo.desenharTodos();
};
} //FIM FUNCTION FLAPPY
Testar!
js/Flappy.js
Flappy.desenharTudo = function() {
jogo.desenharTudo();
}
for (var ia = 0; ia < TipoObstaculo.todos.length; ia++) {
TipoObstaculo.todos[ia].imagem.onload = Flappy.desenharTudo;
}
Testar novamente!
js/Jogador.jsthis.desenhar = function() {
var ctx = this.flappy.ctx;
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.angulo);
ctx.drawImage(Jogador.imagem, -this.altura, -this.altura, this.altura * 2, this.altura * 2);
ctx.beginPath();
ctx.arc(0, 0, this.altura, Math.PI * 0.25, Math.PI * 1.75);
ctx.stroke();
ctx.fill();
ctx.restore();
};
Jogador.imagem = new Image();
Jogador.imagem.src = "img/bird.png";
Apagar!
Incluir!
Baixar eIncluir!
Testar!
COLOCANDO VIDAFlappy Bird
O que precisamos?
• Fazer o “jogador se movimentar” ao iniciar e pressionar tecla?
• Inserir e fazer os obstáculos se movimentarem:
– Com qual intervalo de tempo?
– Para qual direção?
• O que acontece se o jogador colidir contra um obstáculo?
• O que ocorre quando o jogador “bate as asas”?
• O que acontece se o jogador colidir com o teto ou com o chão?
Movimentação do Jogo
• O Jogador irá se movimentar continuamentepara “frente” e irá responder conforme a teclaque o usuário pressionar:
– A: bater asas.
– Outras teclas podem ser configuradas;
INTERAGINDO COM O USUÁRIOFlappy Bird
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.onkeyup = function (evt) {
document.getElementById("tecla").innerHTML = evt.keyCode;
}
js/Flappy.js
Teste!
js/Flappy.js
Apagar o <p id=“tecla”>
do HTML
document.onkeyup = function (evt) {
jogo.pressionarTecla(evt);
}
js/Flappy.js
this.pressionarTecla = function (evt) {
if (evt.keyCode == 65) {
this.jogador.baterAsas();
//this.desenharTudo();
}
};
js/Jogador.js
this.baterAsas = function (){
this.angulo -= Math.PI / 3;
this.y -= 8;
if (this.angulo < -Math.PI / 4) {
this.angulo = -Math.PI / 4;
}
};
Testar!
CONTROLE GLOBAL DO MOVIMENTO
Flappy Bird
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 do cenário e dos inimigos será por umadistância pré-determinada;
• Agora precisamos determinar o intervalo de tempo quenosso jogo irá usar para fazer cada movimento doselementos;
• Como nosso jogo gira em torno do “avanço” do jogador estetempo será um guia para todo o jogo.
js/Flappy.js
Flappy.novoJogo = function () {
Flappy.intervalo = 25; //Conforme já definido anteriormente
jogo = new Flappy("tela");
jogo.desenharTudo();
document.getElementById("btnIniciar").innerHTML = "Iniciar";
document.getElementById("btnIniciar").disabled = false;
}
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/Flappy.js
function Flappy(canvasStr) {
...
this.tempo = null; //Conforme já definido anteriormente
...
}
js/Flappy.js
this.pausar = function () {
if (this.tempo == null) {
this.tempo = setInterval(Flappy.atualizar, Flappy.intervalo);
document.getElementById("btnIniciar").innerHTML = "Pausar";
} else {
clearInterval(this.tempo);
this.tempo = null;
document.getElementById("btnIniciar").innerHTML = "Continuar";
}
};
js/Flappy.jsFlappy.novoJogo = function () {
if (jogo != null) {
if (jogo.tempo != null) {
jogo.pausar();
}
Obstaculo.todos = [];
}
Flappy.intervalo = 25;
...
}
Flappy.pausar = function() {
jogo.pausar();
}
Flappy.atualizar = function() {
jogo.atualizar();
}
js/Flappy.js
this.atualizar = function () {
//Mover obstáculos
Obstaculo.moverTodos(this.jogador.mover(5));
//Desenhar tudo
this.desenharTudo();
//Verificar colisões com obstáculos
//Verificar colisão com teto e chão
};
js/Obstaculo.js
Obstaculo.moverTodos = function (dist) {
var ultimo = Obstaculo.todos.length - 1;
for(var i = ultimo; i >= 0; i--) {
var obAtual = Obstaculo.todos[i];
obAtual.x -= dist;
}
};
js/Jogador.js
this.mover = function (dist){
var varX = dist * Math.cos(this.angulo);
this.y += dist * Math.sin(this.angulo);
this.angulo += Math.PI / 60;
if (this.angulo > Math.PI / 2.8) {
this.angulo = Math.PI / 2.8;
}
return varX;
};
Testar!
MOVIMENTAÇÃO DOS OBSTÁCULOS
Flappy Bird
Movimentação dos Obstáculos
• Os obstáculos terão sua base de movimento conformeo método iniciado anteriormente;
• Agora, ao movimentar todos os obstáculos, precisamosir criando novos objetos à medida que obstáculosultrapassados sejam descartados:
– Para detectar se um obstáculo foi completamente superado,precisaremos detectar seus principais pontos em relação àtela;
• Para adicionar um maior desafio ao jogador, também éproposta a movimentação vertical dos obstáculos;
Superior
Inferior
Sup[0]
Sup[1] Sup[2]
Sup[3]
Inf[0]
Inf[1] Inf[2]
Inf[3]
Cada ponto tem as coordenadas X e Y.
Exemplo: Inf[1][0] é XInf[1][1] é Y
js/Obstaculo.js (1/3)
this.getPontosSuperior = function () {
var pontos = []; //Vetor de retorno dos pontosvar meioLarg = this.tipo.largura / 2;var meioAlTel = flappy.altTela / 2;var senAng = Math.sin(this.tipo.angulo);var cosAng = Math.cos(this.tipo.angulo);
//X1Y1 - 0px = -meioLarg;py = -(meioAlTel - this.tipo.altura) - flappy.altTela;xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
js/Obstaculo.js (2/3)
//X1Y2 - 1px = -meioLarg;py = -(meioAlTel - this.tipo.altura);xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
//X2Y2 - 2px = meioLarg;py = -(meioAlTel - this.tipo.altura);xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
js/Obstaculo.js (3/3)
//X2Y1 - 3px = meioLarg;py = -(meioAlTel - this.tipo.altura) - flappy.altTela;xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
return pontos;};
js/Obstaculo.js (1/3)
this.getPontosInferior = function () {
var pontos = []; //Vetor de retorno dos pontosvar meioLarg = this.tipo.largura / 2;var meioAlTel = flappy.altTela / 2;var senAng = Math.sin(this.tipo.angulo);var cosAng = Math.cos(this.tipo.angulo);
//X1Y4 - 0px = -meioLarg;py = -(meioAlTel - this.tipo.altura) + this.tipo.passagem +
flappy.altTela;xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
js/Obstaculo.js (2/3)
//X1Y3 - 1px = -meioLarg;py = -(meioAlTel - this.tipo.altura) + this.tipo.passagem;xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
//X2Y3 - 2px = meioLarg;py = -(meioAlTel - this.tipo.altura) + this.tipo.passagem;xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
js/Obstaculo.js (3/3)
//X2Y4 - 3px = meioLarg;py = -(meioAlTel - this.tipo.altura) + this.tipo.passagem +
flappy.altTela;xy = [];xy[0] = this.x + meioLarg + px * cosAng - py * senAng;xy[1] = meioAlTel + px * senAng + py * cosAng;pontos.push(xy);
return pontos;};
js/Obstaculo.jsObstaculo.moverTodos = function (dist) {
var ultimo = Obstaculo.todos.length - 1;for(var i = ultimo; i >= 0; i--) {
var obAtual = Obstaculo.todos[i];obAtual.x -= dist;if (i != ultimo && i != 0) {
continue;}pontosSup = obAtual.getPontosSuperior();pontosInf = obAtual.getPontosInferior();var maiorX = Math.max(pontosSup[2][0], pontosSup[3][0],
pontosInf[2][0], pontosInf[3][0]);if (ultimo == i && maiorX < jogo.larTela) {
new Obstaculo(jogo);}if (maiorX < 0) {
Obstaculo.todos.splice(i,1);}
} //Fim do for}; //Fim método
Testar!
Movimentação dos Obstáculos
• Para implementar a movimentação vertical,precisaremos levar em consideração ainformação armazenada em:
– tipo. moveY e
– tipo.angulo
js/Obstaculo.jsObstaculo.moverTodos = function (dist) {
var ultimo = Obstaculo.todos.length - 1;for(var i = ultimo; i >= 0; i--) {
var obAtual = Obstaculo.todos[i];obAtual.x -= dist;obAtual.tipo.altura += obAtual.tipo.moveY;if (obAtual.tipo.altura < 0) {
obAtual.tipo.altura = 0;obAtual.tipo.moveY *= -1;
}if (obAtual.tipo.altura + obAtual.tipo.passagem >=
jogo.canvas.height) {
obAtual.tipo.altura = (jogo.canvas.height - 1) –obAtual.tipo.passagem;
obAtual.tipo.moveY *= -1;}if (i != ultimo && i != 0) {
continue;... Testar!
Alterações Restantes
• O que falta alterar?
– Quando colide:• Chão?
• Teto?
• Obstáculo?
– Fim de jogo?
– Sons?
js/Flappy.jsthis.verificaColisao = function (px, py, raio, pts) {
if (this.linhaColide(px, py, raio, pts[0], pts[1]) ||
this.linhaColide(px, py, raio, pts[1], pts[2]) ||
this.linhaColide(px, py, raio, pts[2], pts[3])) {
this.ctx.strokeStyle = "#FF0000";
this.ctx.beginPath();
for (var a = 0; a <= 2; a++) {
this.ctx.moveTo(pts[a][0], pts[a][1]);
this.ctx.lineTo(pts[a+1][0], pts[a+1][1]);
}
this.ctx.stroke();
return true;
}
return false;
};
Desenhar borda do retângulo onde ocorreu
colisão
js/Flappy.js
this.linhaColide = function (cx, cy, raio, A, B) {
var dist = distToSegment([cx, cy],A,B);
if (dist <= raio) {
return true;
} else {
return false;
}
};
js/Geometria.jsfunction 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));
}
http://stackoverflow.com/questions/849211/shortest-distance-between-a-point-and-a-line-segment
js/Flappy.js (1/2)this.atualizar = function () {
//Mover obstáculos
Obstaculo.moverTodos(this.jogador.mover(5));
//Desenhar tudo
this.desenharTudo();
//Verificar colisões com obstáculos
var jog = this.jogador;
for (var i = 0; i < Obstaculo.todos.length; i++) {
var ptsInf = Obstaculo.todos[i].getPontosInferior();
var ptsSup = Obstaculo.todos[i].getPontosSuperior();
if (this.verificaColisao(jog.x, jog.y, jog.altura, ptsSup) ||
this.verificaColisao(jog.x, jog.y, jog.altura, ptsInf)) {
this.gameOver();
}
}
//Verificar colisão com teto e chão
}; //Fim do método
js/Flappy.js (2/2)this.atualizar = function () {
//Mover obstáculos
//Desenhar tudo
...
//Verificar colisões com obstáculos
...
//Verificar colisão com teto e chão
if (jog.y - jog.altura <= 0 ||
jog.y + jog.altura >= this.altTela) {
this.gameOver();
}
}; //Fim do método
js/Flappy.jsthis.gameOver = function() {
if (this.tempo != null) {
this.pausar();
console.log("Game Over");
document.getElementById("btnIniciar").disabled = true;
}
};
Testar!
ESTÍMULOS SONOROSFlappy Bird
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:– asa.mp_ e asa.ogg
– batida.mp_ e batida.ogg
– ponto.mp_ e ponto.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="sndAsa">
<source src="snd/asa.mp_" type="audio/mpeg">
<source src="snd/asa.ogg" type="audio/ogg">
</audio>
<audio controls id="sndBatida">
<source src="snd/batida.mp_" type="audio/mpeg">
<source src="snd/batida.ogg" type="audio/ogg">
</audio>
<audio controls id="sndPonto">
<source src="snd/ponto.mp_" type="audio/mpeg">
<source src="snd/ponto.ogg" type="audio/ogg">
</audio>
<script ...></script>
js/Jogador.jsthis.baterAsas = function (){
this.angulo -= Math.PI / 3;
this.y -= 8;
if (this.angulo < -Math.PI / 4) {
this.angulo = -Math.PI / 4;
}
Jogador.somAsa.cloneNode(true).play();
}; //Fim do método
//Incluir no fim do arquivo
Jogador.somAsa = document.getElementById("sndAsa");
Jogador.somPonto = document.getElementById("sndPonto");
Jogador.somBatida = document.getElementById("sndBatida");
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;
5. Crie uma indicação visual dentro do Canvas de fim de jogo;
6. Adicione os novos sons a eventos diferentes no jogo;
7. Adicione teclas de atalho para “Pausa” e para “Novo Jogo”;
8. Corrija o bug: se o jogo não estiver executando e tela a “A” forpressionada o jogador “bate asas”;
9. Ao evoluir no jogo, crie novos desafios para o jogador;
– Adicione outros elementos a seu critério:
– Exemplos: novos tipos de obstáculos; “presentes” aleatórios quejogador deve capturar; tecla com movimento especial (limitadasvezes); outros pássaros inimigos aleatórios; use sua criatividade.
10. Entregue os arquivos por e-mail ao Professor junto com umadescrição/resposta para cada item do trabalho.