Preview only show first 10 pages with watermark. For full document please download

Rpg Em Javascript

Criando um jogo simples atravéz do Canvas do HTML 5 e JavaScript

   EMBED


Share

Transcript

Seu Primeiro jogo com JavaScript GUIA PASSO A PASSO Diego Oliveira www.number.890m.com INTRODUÇÃO Se você deseja entrar no mundo da programação de jogos 2D para web e não tem qualquer experiência então esse ebook foi escrito para você. Ao longo deste pdf veremos como programar um jogo bastante simples, baseado no exemplo apresentado por Matt Hackett em sua página pessoal (http://www.lostdecadegames.com/how-to-make-a-simple-html5-canvas-game/) usando o Canvas do html5, onde basicamente temos um personagem que se move capturando monstros pelo campo. Vamos refazer o mesmo exemplo, mas ao invés de capturas monstros coletaremos baús em quanto somos perseguidos pelo monstro. Evidentemente é necessário que se tenha pelo menos o básico em javascript para continuar Diego Oliveira | www.number.890m.com | [email protected] 1 COMEÇANDO Como o jogo se executa através do Canvas que é uma tecnologia do HTML5 então, obviamente, temos de escrever os nossos códigos dentro de um arquivo html. 1 2 3 4 5 6 7 8 9 10 11 Game Phaser Usaremos quatro figuras para o jogo. Uma para compor o cenário, outra para o monstro, outra para o nosso herói e por fim uma para o bau. . Figura 1: Cena do Jogo O link para baixar as imagens é o seguinte: https://drive.google.com/folderview?id=0BzHHa0H6iGgRaU92dXZ1UUpmVDg&usp=sharing É importante lembrar de que as imagens devem estar no mesmo diretório que o arquivo html ou pelo menos lincadas corretamente ao arquivo. 2 Criando a Tela A primeira coisa que precisamos fazer é criar o elemento Canvas. O elemento pode ser criado usando tanto JavaScript como HTML. Neste caso vamos usar o mínimo de html. O que é uma abordagem mais vantajosa. 9 10 11 12 13 14 // Criando o Canvas var canvas = document.createElement("canvas"); var ctx = canvas.getContext("2d"); canvas.width = 512; canvas.height = 480; document.body.appendChild(canvas); A primeira linha (após o comentário), captura o elemento Canvas. A segunda captura seu contexto gráfico. Usaremos esse contexto para emitir comandos de desenho. O width (largura) e height (altura), definem as dimensões do Canvas, sem eles o elemento não irá aparecer na página. 3 Incluindo Imagens Um jogo precisa de gráficos, então vamos carrega-las. Como mencionado anteriormente vamos utilizar quatro imagens caixa.png sprite.png background.png monster.png Que neste exemplo estão situadas no mesmo diretório que o arquivo html. 10 /* Imagem de fundo */ var fundo = new Image(); fundo.src = "background.png"; /* Bau */ var bau = new Image(); bau.src = "caixa.png"; /* Monstro */ var monstro = new Image(); monstro.src = "monster.png"; /* continua na próxima página... */ /* ...continuação da página anterior */ /* Heroi */ var heroi = new Image(); heroi.src = "sprite.png"; var carregadas = 0; var total = 4; // total de imagens do jogo var carregadas = 0; var total = 4; // total de imagens do jogo fundo.onload = carregando; caixa.onload = carregando; monstro.onload = carregando; heroi.onload = carregando; function carregando(){ carregadas++; if(carregadas == total){ reset(); main(); }; }; Antes que um jogo comece é necessário que todas as imagens sejam carregadas, por isso muitos jogos possuem tela de load. O script acima não só carrega as imagens do jogo no browser como ao final do carregamento chama a função reset() e main(). Que serão escritas mais adiante. 4 Objetos do Jogo Existe mais de uma forma de se declarar um objeto em JavaScript aqui está sendo usada a forma mais simples, conhecida como literal. // Objetos do jogo var hero = { speed: 256, // movimento em pixels por segundo x: 0, y: 0 }; var monster = { speed: 100, x: 0, y: 0 }; var trunk = { x: 0, y: 0 }; /* contador de baús coletados */ var caught = 0; Agora vamos definir algumas variáveis que necessitaremos para mais tarde. O nosso herói (objeto hero) possuirá os atributos "x" e "y", que serão as coordenadas de sua posição inicial na tela e "speed", que é a velocidade em pixels por segundo que o nosso herói irá se mover. O objeto monster segue a mesma lógica. O baú do jogo (objeto trunk) vai ficar sempre parado, assim só tem como atributos as coordenadas "x" e "y". Por último, criamos a variável caught. Ela irá armazenar o número de baús coletados pelo jogador. 5 Controle de Teclado A interação entre o Canvas e o teclado do seu PC é possível através dos chamados Listener (ouvintes) do JavaScript. /* Controle do teclado */ var keysDown = {}; document.addEventListener('keydown', keydownHandle, false); function keydownHandle(evt){ keysDown[evt.keyCode] = true; }; document.addEventListener('keyup', keyupHandler, false); function keyupHandler(evt){ delete keysDown[evt.keyCode]; }; O script acima é bem simples. Quando uma tecla do teclado é pressionada ele armazenada o código da tecla no array keysDown. Se um código de tecla está no array, o usuário está pressionando essa tecla. Simples assim! Quando a tecla é liberada então seu código é retirado do array. 6 Novo Jogo function reset(){ /* Posiciona o jogador no centro da tela */ hero.x = canvas.width/2; hero.y = canvas.height/2; /* Coloca o baú em posição aleatória */ trunk.x = 32 + (Math.random()*(canvas.width - 100)); trunk.y = 32 + (Math.random()*(canvas.height - 100)); /* Coloca o monstro em posição aleatória */ monster.x = 32 + (Math.random()*(canvas.width - 64)); monster.y = 32 + (Math.random()*(canvas.height - 64)); }; A função reset é chamada para começar um novo jogo, ou nível. Ele coloca o herói (jogador) no centro da tela e o baú em algum lugar aleatório no campo. 7 Atualização Criamos dois objetos, o objeto hero e trunk. A posição de cada um desses objetos precisa ser constantemente atualizada na tela. Em outras palavras precisamos realizar um update dos objetos. // Atualizações dos objetos function update(mod){ if(38 in keysDown){ // Jogador vai para cima hero.y -= hero.speed * mod; } if(40 in keysDown){ // Jogador vai para baixo hero.y += hero.speed * mod; } if(37 in keysDown){ // Jogador vai para esquerda hero.x -= hero.speed * mod; } if(39 in keysDown){ // Jogador vai para direita hero.x += hero.speed * mod; } }; A função update será chamada diversas vezes no jogo. A primeira coisa que ela faz é verificar se alguma das teclas UP, DOWN, LEFT ou RIGHT do seu teclado está sendo pressionada. E se assim for, o herói é movido na direção correspondente. O que pode parecer estranho é o argumento mod passado para função update. O mod (modificador) é um número baseado no tempo. Se exatamente um segundo se passou desde a última chamada da função update, então o valor que será passado a ela é igual a 1 e a velocidade do herói será multiplicado por 1. O que fará com que o jogador se mova 256 pixels. Assim, se se passou a metade de um segundo, o valor será de 0.5 e o herói vai se mover apenas a metade de sua velocidade e assim por diante. Esse controle é necessário pois a função update será chamada rapidamente em intervalos de tempos pouco precisos. O que faria o nosso herói andar ora muito rapidamente ora muito devagar. Usando esse padrão garantiremos que o herói se mova sempre na mesma velocidade, não importa o quão rápido (ou lentamente) o script está sendo executado. Mais tarde voltaremos a mexer na função update para implementar o movimento do monstro. 8 Desenhando Objetos function render(){ // Desenha o fundo ctx.drawImage(fundo, 0, 0); //Desenha o herói ctx.drawImage(heroi, hero.x, hero.y); // Desenha o baú ctx.drawImage(bau, trunk.x, trunk.y); // Desenha o monstro ctx.drawImage(monstro, monster.x, monster.y); // Desenha o placar ctx.fillStyle = "rgb(250, 250, 250)"; ctx.font = "24px Helvetica"; ctx.textAlign = "left"; ctx.textBaseline = "top"; ctx.fillText("Baus coletados: " + caught, 32, 32); }; A função render terá a finalidade de desenhar nosso herói, baú, monstro e imagem de fundo na tela. Essa função também escreve na tela o número de baús já coletados através da variável caught e do método fillText. 9 O Loop de Animação Todo jogo é um loop infinito. O que na prática significa que existe em todo caso uma função sendo chamada em loop infinito. var then = Date.now(); // A função Game loop function main(){ var now = Date.now(); var delta = now - then; // Limpa o canvas ctx.clearRect(0, 0, canvas.width, canvas.height); update(delta/1000); render(); colisao(); then = now; requestAnimationFrame(main); }; O loop principal do jogo é o que controla o fluxo do jogo. Primeiro queremos checar a hora atual para que possamos calcular o delta (quantos milissegundos se passaram desde o último intervalo). O valor de delta divido por 1000 (quantidade de milissegundos num segundo) será o valor passado para a função update. Em seguida capturamos novamente a data atual. A função requestAnimationFrame é uma função específica para animação. Ela é quem coloca a função game em loop. 11 Colisões function colisao(){ if( hero.x <= (trunk.x + 32) && trunk.x <= (hero.x + 32) && hero.y <= (trunk.y + 32) && trunk.y <= (hero.y + 32) ){ ++caught; reset(); } }; Quando o herói colide com o baú então o contador caught sofre um incremento em uma unidade, indicando que o baú foi coletado. 12 Experimentando! Já temos a maior parte do jogo finalizada. E já podemos testar o resultado. Então abra seu trabalho em algum navegador e verifique se está tudo ok. Imagem do jogo atualmente. 13 Movendo o Monstro Vamos dar alguma ação ao monstro. A partir de agora ele vai perseguir o player. if(monster.y < hero.y -2){ monster.y += monster.speed * mod; }else if(monster.y > hero.y+2){ monster.y -= monster.speed * mod; }else{ if(monster.x < hero.x) monster.x += monster.speed * mod; if(monster.x > hero.x) monster.x -= monster.speed * mod; } O código acima deve ser colocado dentro da função update. Abrindo o jogo no navegador já podemos ver o monstro correndo atrás do player. 14 Matando o Player Quando o monstro tocar o personagem exibiremos uma mensagem escrito "perdeu"!. function coliderMonstro(){ if( hero.x <= (monster.x + 32) && monster.x <= (hero.x + 32) && hero.y <= (monster.y + 32) && monster.y <= (hero.y + 32) ){ ctx.fillStyle = "rgba(0, 0, 0, 0.7)"; ctx.fillRect(75, 105, 362, 245); ctx.fillStyle = "white"; ctx.font = "24px Helvetica"; ctx.fillText("Perdeu!", 210, 220); } }; A chamada da função coliderMonstro() é feita dentro da função main(). Agora quando o player colidir com o monstro a seguinte tela irá aparecer. Você perdeu! Se você não conseguiu chegar ao resultado desejado pode solicitar o código por e-mail escrevendo para: [email protected] TNT www.number.890m.com