Olá! Segue agora uma postagem sobre um tema interessante: CANVAS. Mas, o que é isso? Como se sabe, a versão do HTML reinante nos dias de hoje é a versão 4. Porém, muitas grandes desenvolvedoras, no intuito de melhorar funcionalidades existentes e incluir novas, estavam elaborando uma nova versão pro HTML, o HTML5.
Entre as novas possibilidades, destaca-se:
1) Conformidade com as especificações do CSS32) Reprodução de determinados conteúdos multimídia (Vídeo, audio) sem necessidade de plugins.3) Possibilidade de armazenamento de cache4) Tags novas (Canvas, video, audio, nav, sidebar, etc)Pois bem! Dentre estas tags novas, falaremos agora do canvas. Mas, o que é isto? Em poucas palavras, ela permite que, sejam criadas animações wm 2D apenas com uso de javascript. É como se voçê criasse animações FLASH diretamente em javascript. Enfim, nota-se que esta tecnologia abre um grande leque de possibilidades para designers e programadores de jogos.Apenas como aprendizado, sugiro que leia o seguinte tutorial, que me serviu de portas para esta novidade, que agora compartilho:Tutorial básico de CANVASAgora, segue abaixo algumas coisas (Bem toscas!), sobre o que consegui fazer esta tecnologia:Jogo de duas bolasPonteiro de relógio
Caso queira o link para ambos os testes, baixe-os, clicando no link abaixo:Segue abaixo o código do primeiro exemplo, no qual, como voçê pode ver, é criado, pixel á pixel, todo o cenário e os personagens.<!DOCTYPE html> <html> <head>Testes com CANVAS Controlando um boneco com CANVAS
</body> </html>No arquivo draw.js, estão todas as funções e módulos para controle da animação./*Toda vez que é executado algo na tag CANVAS, deve-se instanciar o objeto especificado na variável context abaixo * pertencente á própria tag CANVAS. * */ function carregaContexto(id){ var elemento = document.getElementById(id); var context = elemento.getContext("2d"); if(context){ return context; }else{ return false; } } /* Função abaixo para desenhar um triângulo simples */ function drawTriangulo(x,y,tamX,tamY){ var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); x = parseInt(x); y = parseInt(y); tamX = parseInt(tamX); tamY = parseInt(tamY); if(contexto){ contexto.fillStyle = "#00FF00"; contexto.moveTo(x-tamX,tamY); contexto.lineTo(tamX+x,tamY); contexto.lineTo(x,y); contexto.fill(); } } /* Função abaixo necessário para desenhar rostos */ function drawRosto(x,y,r){ x = parseInt(x); y = parseInt(y); r = parseInt(r); var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.fillStyle = "#FFE4B5"; contexto.moveTo(x,y); contexto.arc(x,y,r,0,Math.PI*2,false); contexto.fill(); //Desenhando os olhos contexto.fillStyle = "#000000"; contexto.moveTo(x-7,y-4); contexto.fillRect(x-7,y-4,4,4); contexto.moveTo(x+7,y-4); contexto.fillRect(x+7,y-4,4,4); //Desenhando a boca contexto.beginPath(); contexto.strokeStyle = "#FF0000"; contexto.moveTo(x-4,y+10); contexto.lineTo(x+5,y+10); contexto.stroke(); } } /* Função para se desenhar qualquer forma quadrada */ function drawQuadrada(x,y,tamX,tamY,cor){ x = parseInt(x); y = parseInt(y); tamX = parseInt(tamX); tamY = parseInt(tamY); var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.fillStyle = cor; contexto.beginPath(); contexto.moveTo(x,y); contexto.fillRect(x,y,tamX,tamY); contexto.fill(); } } /* Função abaixo desenha um sapato */ function drawSapato(x,y,tamX,tamY,cor){ x = parseInt(x); y = parseInt(y); tamX = parseInt(tamX); tamY = parseInt(tamY); var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.fillStyle = cor; contexto.beginPath(); contexto.moveTo(x,y); contexto.fillRect(x,y,tamX/2,tamY/2); contexto.fill(); contexto.beginPath(); contexto.moveTo(x+tamX/2,y-tamY/2); contexto.arc(x+tamX/2,y+7,9,Math.PI*1.5,Math.PI*0.5,false); contexto.fill(); } } /* Função para desenhar mãos */ function drawMao(x,y,r,cor){ var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.fillStyle = cor; contexto.beginPath(); contexto.moveTo(x,y); contexto.arc(x,y,r,0,Math.PI*2,false); contexto.fill(); contexto.beginPath(); contexto.moveTo(x,y-r); contexto.quadraticCurveTo(x+50,y-50,x+2,y+5); contexto.moveTo(x,y-r); contexto.quadraticCurveTo(x+5,y-100,x-20,y+5); contexto.fill(); } } /* Função para desenhar relógio*/ function drawRelogio(x,y,r,cor){ x = parseInt(x); y = parseInt(y); r = parseInt(r); var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.fillStyle = cor; contexto.beginPath(); contexto.moveTo(x,y); contexto.arc(x,y,r,0,Math.PI*2,false); contexto.fill(); //Marcando os números do relógio contexto.fillStyle = "#FFFF00"; contexto.fillText("12",x,y-(r-10)); contexto.fillText("3",x+(r-10),y); contexto.fillText("6",x,y+(r-10)); contexto.fillText("9",x-(r-10),y); //Desenhando o ponteiro } } /*Função abaixo move o braço do boneco com base no clique na mão do mesmo */ function moveBraco(x,y,tamB,bX,bY){ var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ x = parseInt(x); y = parseInt(y); tamB = parseInt(tamB); if(y >= bY){ if(x >= bX){ c = 2; }else{ c = 4; } }else{ if(x >= bX){ c = 8; }else{ c = 6; } } var minX = bX - tamB-15; var minY = bY-tamB; var maxX = bX + tamB-15; var maxY = bY+tamB; cX = (xmaxX?maxX:x)); cY = (y maxY?maxY:y)); //Rotação do braço com base nas coordenadas drawQuadradaComRotacao(bX,bY,cX,cY,tamB,"#2F4F4F"); //alert(cX + "-" + minX); drawMao(cX,cY,20,"#F0E68C"); } } /*Desenhando o braço, para que sei posicionamento esteja relativo ao posicionamento da mão*/ function drawQuadradaComRotacao(x,y,cX,cY,tamB,cor){ x = parseInt(x); //Coordenadas do braço y = parseInt(y); cX = parseInt(cX); // Coordenadas c são coordenadas da mão. São passadas como parâmetro para que o braço possa acompanhar a mão cY = parseInt(cY); tamB = parseInt(tamB); // Tamanho do braço var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.fillStyle = cor; contexto.beginPath(); contexto.moveTo(x,y); //Setar a coordenada do braço para que acompanhe a mão contexto.lineTo(cX,(cY-2)); contexto.lineTo(cX,(cY-2) + tamB); contexto.lineTo(x,y + tamB); contexto.fill(); } } /*Desenhando um corpo inteiro*/ function desenhoCorpo(){ var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ //Desenho de um corpo humano drawRosto(165,50,25); //Pesco词 drawQuadrada(150,70,30,20,"#FFE4B5"); //Barriga drawQuadrada(80,100,45,30,"#2F4F4F"); //Perna direita drawQuadrada(130,210,30,100,"#000000"); //P顥squerdo drawSapato(130,310,60,30,"#A52A2A"); //M䯠direita drawMao(75,115,20,"#F0E68C"); //Barriga drawQuadrada(125,90,80,120,"#2F4F4F"); //Perna esquerda /*drawQuadrada(170,210,30,100,"#000000"); //Pé ireito drawSapato(170,310,60,30,"#A52A2A");*/ //Ch䯍 drawQuadrada(0,325,document.getElementsByTagName('canvas')[0].width,document.getElementsByTagName('canvas')[0].height-310,'#8B4513'); } } /* Função para mover o pé */ function movePe(x,y,tamX,tamY,cX,cY){ var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ //Desenhando a perna com base nas coordenadas c contexto.fillStyle = "#000000"; contexto.moveTo(x,y); contexto.lineTo(cX,cY); contexto.lineTo(cX+tamX,cY); contexto.lineTo(x+tamX,y); contexto.fill(); drawSapato(cX,cY,60,30,"#A52A2A"); } } /*Limpar a tela inteira. Executada quando se encerra o jogo, ou para que tudo se inicie do zero*/ function limpaTela(){ drawQuadrada(0,0,document.getElementsByTagName('canvas')[0].width,document.getElementsByTagName('canvas')[0].height,'#FFFFFF'); } No arquivo boneco.js, tem os atributos e métodos próprios dos personagens./* Criando o objeto Boneco, que será o responsável pelas movimentações no cenário(boneco.html) */ function Boneco(cor){ this.cor = cor; this.dX = 0; //Coordenada X atual do objeto this.dY = 0; // Coordenada Y atual do objeto this.s = "d"; //Sentido do objeto: Pode ser d(Direito) ou e(Esquerdo) this.minY = 240; // Coordenada Y m[inima(Ponto Y do chão) this.sY = "C"; //Sentido horizontal do objeto this.maxY = 0; } /*Gambiarra abaixo para associar o método constroe á classe Boneco * Forma alternativa de definir métodos á uma classe * */ Boneco.prototype.constroe = function(x,y){ this.dX = x; this.dY = y; this.maxY = 320; var contexto = carregaContexto(document.getElementsByTagName('canvas')[0].id); if(contexto){ contexto.beginPath(); contexto.fillStyle = this.cor; contexto.arc(x,y,20,0,2*Math.PI,false); contexto.fill(); //Desenhando os olhos contexto.beginPath(); contexto.fillStyle = "#FFFFFF"; contexto.moveTo(x+2,y-2); contexto.arc(x+2,y-2,3,0,2*Math.PI,false); contexto.fill(); contexto.beginPath(); contexto.fillStyle = "#FFFFFF"; contexto.moveTo(x+8,y-4); contexto.arc(x+8,y-4,3,0,2*Math.PI,false); contexto.fill(); } } /* Método abaixo executa move o objeto Boneco para os lados. Quando o objeto está no limite(Final do caminho), seu sentido é alterado(Esquerdo ou Direito). Como terceiro parâmetro, recebe o array de obstáculos a serem ultrapassados. Se x estiver entre propriedades minX e maxX Se for menor ou igual á minY do obstáculo Seta atributo dY como sendo equivalente á minY. Senão Se sentido é igual á direito Seta dx como equivalente á minX Senão Seta dx como equivalente á maxX Senão Se dx for maior do que maxX e sentido for D OR se dx for menor do que minX e sentido for E Seta dY como maxY(Toca o solo) */ Boneco.prototype.andar = function(dx,s,obstaculos){ var maxX = document.getElementsByTagName('canvas')[0].width; this.s = s; if(this.dX >= maxX){ this.s = "e"; }else if(this.dX <= 10){ this.s = "d"; } for(obs in obstaculos){ if( (obstaculos[obs].minX <= this.dX) && ( this.dX <= obstaculos[obs].maxX)){ if(this.dY <= obstaculos[obs].minY){ this.dY = obstaculos[obs].minY; }else{ if(this.s == "d" && (this.dX <= obstaculos[obs].minX + obstaculos[obs].width/2)){ this.dX -= 2*dx; return; }else if(this.s == "e" && (this.dX >= obstaculos[obs].maxX - obstaculos[obs].width/2)){ this.dX += 2*dx; return; } } }else if((this.dX > obstaculos[obs].maxX && this.s == "d") || (this.dX < obstaculos[obs].minX && this.s == "e")){ this.dY = this.maxY; } } if(this.s == "d"){ this.dX += dx; }else{ this.dX -= dx; } } /* Método abaixo faz o objeto pular. Quando o usuário clica na barra de espaço, o usuário pula á uma altura maior do que a caixa */ Boneco.prototype.pular = function(){ var maxY = this.maxY; if(this.dY >= maxY){ this.sY = "C"; }else if(this.dY <= this.minY){ //this.dY = this.minY; this.sY = "B"; } if(this.sY == "C"){ this.dY -= 20; }else if(this.sY == "B"){ this.dY += 20; } } /* Método abaixo serve para criar obstáculos na tela. */ function Obstaculo(x,y,lar,tam,cor){ lar = parseInt(lar); x = parseInt(x); y = parseInt(y); //Desenhando o objeto drawQuadrada(x,y,lar,tam,cor); this.minY = y; this.minX = x; this.maxX = x+lar; this.width = lar; this.altura = tam; }Quando se usa CANVAS, pode-se notar que os desenhos são feitos pixel-á-pixel. Ou seja, são feitos especificando as coordenadas de cada fígura. Por isso, apesar de o carregamento ser bem mais rápido, se comparado com o SVG (Mesmo propósito que o CANVAS, porém, mais fácil e menos flexível), demanda muito esforço de desenvolvimento. Além disso, é necessário que se tenha a disposição, um conjunto de funções básicas como: Andar, pular, tratamento de colisões; caso desenvolva animações mais complexas. Do contrário, estará perdendo tempo com detalhes que podem muito bem ser encapsulados.
Espero que tenham gostado, e, se gostou, poste seu comentário. Se não, manda sua crítica, para que possamos sempre melhorar.Abraços
Nenhum comentário:
Postar um comentário