Introdução

O desenvolvimento de jogos é uma área que vem crescendo a cada ano e ganhando cada vez mais destaque. A cada dia surgem novas engines, novos métodos, gráficos e recursos que possibilitam a criação de games que rapidamente ganham o mundo.

Com o avanço da web também veio a tendência do surgimento de jogos de browser, cada vez mais leves e dinâmicos. A chegada da HTML5 e do elemento canvas permitiu ainda o surgimento de jogos feitos inteiramente em JavaScript, o que os torna leves e independentes de plataforma, fator que tem ganhado cada dia mais importância.

O desenvolvimento de um jogo completo requer bastante análise, escrita do roteiro, criação dos gráficos, entre outros procedimentos fundamentais e relativamente complexos. Porém, para demonstrar um pouco do que pode ser feito com JavaScript, manipulando o elemento canvas, este artigo apresentará o código necessário para criar um menu simples, desenhando-o dinamicamente na tela do browser, sem usar divs, listas, ou qualquer outro elemento HTML.

Como este artigo está organizado

O código será apresentado em partes, para facilitar o entendimento de cada funcionalidade utilizada e procedimento realizado. Inicialmente será apresentada a estrutura básica do arquivo HTML. Em seguida, os códigos das listagens subsequentes podem ser copiados, na ordem em que aparecem, para o local indicado na listagem 1. Assim teremos um desenvolvimento incremental, entendendo cada parte individualmente e analisando sua participação no resultado final.

O código HTML

O seguinte código pode ser salvo como um arquivo de extensão HTML, mas inicialmente não será possível observar nenhum resultado gráfico, pois isso será feito posteriormente usando JavaScript.

Listagem 1: Código HTML da página

<!DOCTYPE html>

<html lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head>
    <meta charset="utf-8" />
    <title>Menu com canvas e JS</title>

    <style>
        body
        {
            margin:0;
            overflow:hidden;
        }
    </style>
    <script src="http://code.jquery.com/jquery-1.9.1.min.js"></script>
    <script>
        $(function () {
		//o restante do código ficará aqui
        });
    </script>
</head>
<body>
    <canvas id="canvasMenu"></canvas>
</body>
</html>

A estrutura é bastante simples, composta basicamente pelo elemento canvas no corpo do documento. Inicialmente aplicamos algumas configurações via CSS para remover as margens e as barras de rolagem da página, pois assim poderemos aproveitar uma maior área para desenhar o menu.

Em seguida foi feita referência à biblioteca jQuery, pois ela será usada para controlar o evento ready do documento, dentro do qual escreveremos todo o código para montagem do menu, conforme a indicação da linha 18.

O código JavaScript

Agora começaremos a inserir o código JavaScript. Vale ressaltar que serão apresentadas várias listagens, cujo conteúdo deve ser adicionado ao local indicado na linha 18 da listagem 1, na ordem em que aparecem.

Listagem 2: Definições iniciais

var largura;
var altura;
var larguraMenu = 400;
var alturaMenu = 300;

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

Na listagem 2 declaramos algumas variáveis que serão utilizadas em todo o código e em seguida obtemos uma referência ao elemento canvas, usando o método getElementById(). Esse método poderia ser substituído pelo seletor $ da jQuery, mas aqui buscaremos trabalhar ao máximo com JavaScript “pura”. O objeto ctx armazena a referência ao contexto 2d da canvas, área onde serão feitos os desenhos, mais adiante.

Listagem 3: Função atualizarPlanoDeFundo

function atualizarPlanoDeFundo() {
    largura = window.innerWidth;
    altura = window.innerHeight;
    canvas.setAttribute("width", largura);
    canvas.setAttribute("height", altura);
    var img = new Image();
    img.src = "bg.jpg";
    ctx.drawImage(img, 0, 0);
}

A função atualizarPlanoDeFundo é responsável por atualizar a canvas de forma geral, redesenhando a área sobre a qual será posta o menu. Foi utilizada uma imagem (qualquer, de dimensões bastantes ara ocupar todo o browser). Essa função será chamada com frequência para redesenhar a canvas, por isso é necessário obter sempre as dimensões atuais da janela.

Listagem 4: Função desenharBaseMenu

function desenharBaseMenu() {
    ctx.fillStyle = "rgba(255,255,255,0.7)";
    var x = parseInt((largura / 2) - (larguraMenu / 2));
    var y = parseInt((altura / 2) - (alturaMenu / 2));
    ctx.fillRect(x, y, larguraMenu, alturaMenu);
}

Essa função é responsável por desenhar um retângulo no centro da tela, onde serão inseridos os itens do menu. Os atribuídos às variáveis x e y representam a posição da tela onde o retângulo deve ser desenhado, de forma que ocupe sempre o centro da tela. Para esse retângulo foi definido um plano de fundo branco com 70% de opacidade, para se obter um leve efeito de transparência. Suas dimensões foram previamente definidas no início do código.

Listagem 5: Função desenharItensMenu

function desenharItensMenu() {
    var x = parseInt((largura / 2) - (larguraMenu / 2));
    var y = parseInt((altura / 2) - (alturaMenu / 2));
    var img;

    img = new Image();
    img.src = "iniciar_1.png";
    ctx.drawImage(img, x, y);

    img = new Image();
    img.src = "opcoes_1.png";
    ctx.drawImage(img, x, y + 100);

    img = new Image();
    img.src = "sair_1.png";
    ctx.drawImage(img, x, y + 200);
}

Foram criadas três imagens de dimensões 400x100, contendo alguns textos referentes aos itens do menu. Então, na função desenharItensMenu obtemos novamente a posição central da tela e desenhamos as imagens, uma abaixo da outra (aumentando o parâmetro y de 100px para cada imagem, com relação à anterior). Essas imagens estarão disponíveis no código fonte do artigo.

Listagem 6: Função desenharMenu

Na função acima agrupamos as chamadas às três funções anteriores, pois elas, em conjunto, serão responsáveis pela montagem do menu. Assim, a função desenharMenu facilita a chamada às demais funções (apenas a nível de curiosidade, isso é semelhante ao que se faz no padrão de projeto Façade).

Listagem 7: Função selecionarItem

function desenharMenu() {
    atualizarPlanoDeFundo();
    desenharBaseMenu();
    desenharItensMenu();
}

Essa função será utilizada para destacar os itens do menu quando o usuário passar o cursor do mouse por sobre eles. Ela recebe um índice referente a qual item foi selecionado e, de acordo com esse valor, desenha uma nova imagem por cima da original. No início dessa função é chamada a função desenharMenu, para atualizar toda a tela para que em seguida o item seja destacado.

Listagem 8: Evento onresize da janela

function selecionarItem(indice) {
    desenharMenu();
    var x = parseInt((largura / 2) - (larguraMenu / 2));
    var y = parseInt((altura / 2) - (alturaMenu / 2));
    var img;
    img = new Image();
    switch (indice) {
        case 0:                        
            img.src = "iniciar_2.png";
            ctx.drawImage(img, x, y);
            break;
        case 1:
            img.src = "opcoes_2.png";
            ctx.drawImage(img, x, y+ 100);
            break;
        case 2:
            img.src = "sair_2.png";
            ctx.drawImage(img, x, y + 200);
            break;
    }
}

No evento onresize da janela, ou seja, quando esta for redimensionada, invocamos a função desenharMenu para atualizar a tela, pois o menu será reposicionado (redesenhado em uma nova posição, com base nas novas dimensões da janela).

Listagem 9: Evento onmousemove da janela

window.onresize = function () {
    desenharMenu();
}

No evento onmousemove da janela verificamos a posição do cursor, caso este esteja sobre o menu, calculamos o índice do item que está sendo selecionado com base na posição vertical do cursor e da altura dos itens. No caso desse menu, o índice deve variar de 0 a 2.

Em seguida invocamos a função selecionarItem, passando como parâmetro o índice selecionado. Caso o cursor não esteja sobre o meu, é informado o valor -1, fazendo com que nenhum item seja destacado.

Por fim, basta fazer uma chamada à função desenharMenu, para montar a tela inicialmente, ao carregar o documento. Para isso basta inserir a seguinte linha após todo o código já desenvolvido até aqui, antes do fechamento da função principal da jQuery.

Listagem 10: Chamando a função desenharMenu inicialmente

window.onmousemove = function () {
    var posX = event.clientX;
    var posY = event.clientY;
    var x = parseInt((largura / 2) - (larguraMenu / 2));
    var y = parseInt((altura / 2) - (alturaMenu / 2));
    var indice = -1;

    if (posX > x && posX < x + larguraMenu) {
        if (posY > y && posY < y + alturaMenu) {
            indice = parseInt((posY - y) / 100);                        
        }
    }

    selecionarItem(indice);
}

Testando

Agora já é possível testar o código desenvolvido, bastando salvar novamente o arquivo com extensão HTML e abri-lo no browser. O resultado deve ser semelhante ao que ilustra a figura 1.

Menu em funcionamento

Figura 1: Menu em funcionamento

Passando o cursor do mouse sobre os itens, podemos ver a função selecionarItem em funcionamento, destacando uma das opções do menu, como pode ser visto na figura 2.

Menu com opção em destaque

Figura 2: Menu com opção em destaque

Conclusão

Aqui não foi tratado o clique dos itens do menu para executar alguma ação, mas isso pode ser feito seguindo a mesma lógica do evento onmousemove e da função selecionarItem.

Fica como sugestão rever o código, refatorar, alterar as imagens e dimensões utilizadas e testar novas possibilidades de utilização desse menu, pois aqui o código e gráficos foram desenvolvidos da forma mais simples possível, buscando facilitar a compreensão de cada passo.

O código fonte deste artigo pode ser obtido no topo desta página.

Até a próxima publicação.