Crie um Jogo Web de Raspadinha

JavaScriptBeginner
Pratique Agora

Introdução

Neste projeto, vamos guiá-lo através do processo de criação de um simples jogo de Raspadinha (Scratch Card) baseado na web. Este jogo permite que os usuários raspar uma sobreposição cinza para revelar uma imagem subjacente, que será uma mensagem de "vencedor" ou "tente novamente". Usaremos HTML para a estrutura, CSS para estilização e JavaScript para interatividade.

👀 Pré-visualização

🎯 Tarefas

Neste projeto, você aprenderá:

  • Como configurar um projeto web básico com HTML, CSS e JavaScript
  • Como manipular o canvas HTML5 para criar efeitos interativos
  • Como usar JavaScript para lidar com interações do usuário, como cliques e movimentos do mouse
  • Como trabalhar com imagens em desenvolvimento web, incluindo carregamento e exibição dinâmica
  • Como implementar uma lógica de jogo simples que decide aleatoriamente o resultado para o usuário

🏆 Conquistas

Após concluir este projeto, você será capaz de:

  • Demonstrar uma sólida compreensão do canvas HTML5 e suas capacidades para jogos baseados na web e aplicações interativas
  • Apresentar proficiência no uso de JavaScript para criar conteúdo dinâmico e responder às entradas do usuário
  • Integrar várias tecnologias web para criar uma aplicação web completa e funcional
  • Projetar uma interface de usuário simples, mas envolvente, para um jogo baseado na web
  • Aplicar conceitos básicos de desenvolvimento de jogos, como resultados aleatórios e interação do usuário

Criar a Estrutura HTML

Nesta etapa, configuramos a estrutura básica da página web em index.html, incluindo a declaração DOCTYPE, o elemento html e as seções head e body. Definimos o conjunto de caracteres como UTF-8 para reconhecimento universal de caracteres e definimos a viewport para design responsivo, garantindo que nossa aplicação de raspadinha tenha uma boa aparência em dispositivos de vários tamanhos.

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Scratch Card</title>
  </head>
  <body>
    <div id="main">
      <div class="msg">
        Feeling Lucky? Try!
        <a href="#" onclick="window.location.reload()">Try Again</a>
      </div>
      <div>
        <canvas></canvas>
      </div>
    </div>
    <script src="main.js"></script>
  </body>
</html>

Dentro do body, criamos um elemento div com um id de "main" que serve como o contêiner para nossa aplicação. Dentro deste contêiner, incluímos um div com a classe "msg" para exibir uma mensagem divertida convidando o usuário a tentar a sorte. Esta mensagem também inclui um link que, quando clicado, recarrega a página, permitindo que os usuários tentem a raspadinha novamente sem ter que atualizar manualmente o navegador.

Finalmente, incluímos um elemento canvas onde o efeito de raspadinha será implementado e vinculamos um arquivo JavaScript externo chamado "main.js" onde a lógica da nossa aplicação residirá.

Esta estrutura HTML fornece a base necessária para nossa aplicação de raspadinha, definindo as áreas onde o texto e a superfície raspável serão exibidos.

✨ Verificar Solução e Praticar

Estilizar o Canvas

No arquivo JavaScript main.js, começamos selecionando o elemento canvas e aplicando alguns estilos iniciais.

const canvas = document.querySelector("canvas");
canvas.style.backgroundColor = "transparent";
canvas.style.position = "absolute";

Definimos o backgroundColor como "transparent" para garantir que o fundo do canvas não obscureça nenhuma parte da página web em que está colocado. Ao definir a position como "absolute", permitimos mais flexibilidade no posicionamento do canvas sobre outros elementos, se necessário.

Esta etapa é crucial para preparar o elemento canvas, garantindo que ele se integre perfeitamente com o restante do design da página web e esteja pronto para os elementos dinâmicos que adicionaremos a ele nas etapas subsequentes.

✨ Verificar Solução e Praticar

Carregar a Imagem de Rascunho

Aqui, carregamos uma imagem aleatória para ser usada como fundo da raspadinha.

// Continue in main.js

// Array of possible images to reveal
const images = ["winner.png", "try_again.png"];
const selectedImage = images[Math.floor(Math.random() * images.length)];

// Create a new Image object and set the source
const img = new Image();
img.src = selectedImage;

// Once the image is loaded, adjust canvas size and background
img.onload = () => {
  const ctx = canvas.getContext("2d");
  const w = img.width;
  const h = img.height;
  canvas.width = w;
  canvas.height = h;
  canvas.style.backgroundImage = `url(${img.src})`;

Criamos um array chamado images contendo os nomes de arquivos de imagens possíveis. Em seguida, selecionamos aleatoriamente uma imagem deste array usando Math.floor(Math.random() * images.length).

Criamos um novo objeto Image e definimos sua fonte (src) para a imagem escolhida. O ouvinte de evento onload garante que prosseguimos com o restante do script somente após a imagem ser totalmente carregada, evitando quaisquer problemas que possam surgir ao tentar manipular uma imagem que não foi completamente baixada.

Esta etapa é crucial para a natureza dinâmica da raspadinha, pois introduz variabilidade e surpresa cada vez que a aplicação é carregada ou atualizada. Ao carregar uma imagem aleatória, simulamos o resultado incerto de uma raspadinha real, aprimorando a experiência do usuário.

✨ Verificar Solução e Praticar

Preparar a Camada de Rascunho

Após carregar a imagem selecionada no canvas, precisamos preparar a camada de raspadinha. Isso é feito cobrindo todo o canvas com um retângulo cinza. Esta camada cinza serve como a superfície raspável com a qual o usuário irá interagir para revelar a imagem por baixo.

// Continue in main.js

// Cover the canvas with a gray rectangle to act as the scratch layer
ctx.fillStyle = "gray";
ctx.fillRect(0, 0, w, h);

// Prepare the canvas for the scratching effect
ctx.globalCompositeOperation = "destination-out";

Nesta etapa, definimos o estilo de preenchimento para cinza e desenhamos um retângulo cobrindo todo o canvas, criando uma camada de raspadinha sobre a imagem selecionada. O globalCompositeOperation definido como "destination-out" garante que qualquer novo desenho no canvas tornará as camadas subjacentes transparentes, permitindo que a imagem por baixo seja revelada onde quer que o usuário raspe.

✨ Verificar Solução e Praticar

Criar a Função de Rascunho

Para implementar o efeito de raspagem, definimos uma função draw que será chamada sempre que o usuário interagir com o canvas. Esta função verifica se o usuário está atualmente desenhando (flag isDrawing) e, em seguida, calcula a posição do cursor ou toque em relação ao canvas. Em seguida, desenha um círculo nessa posição com uma operação de composição que torna a camada cinza transparente, revelando a imagem abaixo.

// Continue in main.js

let isDrawing = false;

// Define the function to simulate scratching
const draw = (e) => {
  if (!isDrawing) return;
  e.preventDefault();
  const clientX = e.clientX || e.touches[0].clientX;
  const clientY = e.clientY || e.touches[0].clientY;
  const rect = canvas.getBoundingClientRect();
  const x = clientX - rect.left;
  const y = clientY - rect.top;

  // Draw a circle at the cursor or touch position
  ctx.beginPath();
  ctx.arc(x, y, 10, 0, Math.PI * 2);
  ctx.fill();
};

Esta função primeiro garante que a flag isDrawing seja verdadeira, indicando que o usuário iniciou uma ação de raspagem. Em seguida, calcula a posição precisa onde a raspagem está ocorrendo e desenha um círculo nessa posição, efetivamente raspando a camada cinza para revelar partes da imagem subjacente.

✨ Verificar Solução e Praticar

Adicionar Listeners de Eventos para Ações de Rascunho

Finalmente, precisamos detectar quando o usuário realiza ações no canvas para acionar o efeito de raspagem.

// Continue in main.js

  // Event listeners to handle mouse and touch interactions
  canvas.addEventListener("mousedown", (e) => {
    isDrawing = true;
    draw(e);
  });
  canvas.addEventListener("touchstart", (e) => {
    isDrawing = true;
    draw(e);
  });
  canvas.addEventListener("mousemove", draw);
  canvas.addEventListener("touchmove", draw);
  canvas.addEventListener("mouseup", () => {
    isDrawing = false;
  });
  canvas.addEventListener("touchend", () => {
    isDrawing = false;
  });
}

Adicionamos listeners de eventos para mousedown, mousemove, mouseup, touchstart, touchmove e touchend. Esses listeners definem a flag isDrawing e chamam a função draw de acordo para criar um efeito de raspagem interativo.

Quando o usuário pressiona o botão do mouse ou toca na tela (mousedown ou touchstart), definimos isDrawing como true e começamos a rastrear seus movimentos para criar o efeito de raspagem. Quando eles soltam o botão ou param de tocar na tela (mouseup ou touchend), definimos isDrawing como false, interrompendo a ação de raspagem. Os eventos mousemove e touchmove continuam a chamar a função draw enquanto isDrawing for true, permitindo que o usuário raspe a camada cinza e revele a imagem por baixo enquanto move o mouse ou o dedo sobre o canvas.

Para ver os seguintes efeitos, clique no botão Go Live no canto inferior direito do WebIDE e mude para a aba "Web 8080".

✨ Verificar Solução e Praticar

Resumo

Neste projeto, criamos um simples jogo de Raspadinha (Scratch Card) onde os usuários podem raspar uma camada para revelar uma mensagem oculta. Configuramos a estrutura HTML, inicializamos o canvas em JavaScript, carregamos e exibimos imagens e implementamos o efeito de raspagem usando a API do canvas. Este projeto pode ser uma adição divertida às páginas web e pode ser estendido de várias maneiras, como adicionar mais imagens, melhorar o design ou integrá-lo a um jogo maior.