Construindo um Jogo Web de Evitar Blocos

JavaScriptBeginner
Pratique Agora

Introdução

Neste projeto, vamos construir um jogo divertido e simples de evitar blocos usando HTML, CSS e JavaScript. Este jogo envolve mover blocos onde o jogador deve clicar nos blocos pretos para marcar pontos e evitar clicar nos blocos brancos. Vamos começar a construí-lo passo a passo!

👀 Pré-visualização

block avoidance game preview

🎯 Tarefas

Neste projeto, você aprenderá:

  • Como projetar o layout do jogo usando HTML
  • Como adicionar estilo ao jogo usando CSS
  • Como implementar a lógica básica do jogo usando JavaScript
  • Como inicializar o jogo e criar o conjunto inicial de blocos
  • Como implementar a funcionalidade do jogo, incluindo detecção de clique em blocos, cenários de fim de jogo (game-over), criação e movimento de blocos
  • Como finalizar a pontuação e o gerenciamento da velocidade do jogo

🏆 Conquistas

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

  • Projetar layouts web usando HTML
  • Aplicar técnicas de estilo usando CSS
  • Implementar a lógica do jogo usando JavaScript
  • Manipular o Document Object Model (DOM)
  • Lidar com eventos e interações do usuário
  • Criar e gerenciar variáveis de estado do jogo
  • Modificar e atualizar a exibição do jogo dinamicamente
  • Testar e depurar a implementação do jogo

Projetando o Layout do Jogo com HTML

Requisitos:

  • Abra o arquivo index.html.
  • Familiaridade com tags e estrutura HTML.

Funcionalidade:

  • Layout do contêiner principal do jogo.
  • Exibir a pontuação do jogo.
  • Fornecer um botão de início para iniciar o jogo.

Passos:

<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>Avoid the white block</title>
    <link rel="stylesheet" href="styles.css" />
  </head>
  <body>
    <h2>score</h2>
    <h2 id="score">0</h2>
    <div id="main">
      <div id="con"></div>
      <!-- Game container -->
    </div>
    <div class="btn">
      <button class="start" onclick="start()">Start</button>
      <!-- Start button -->
    </div>
  </body>
  <script src="script.js"></script>
</html>

No código acima, criamos uma estrutura HTML básica para o nosso jogo. Temos uma div com id="main" que será o nosso contêiner do jogo. Dentro do contêiner do jogo, temos outra div com id="con" que será o nosso jogador. Também criamos um button com class="start" que será usado para iniciar o jogo.

✨ Verificar Solução e Praticar

Adicionar Estilo ao Jogo

Requisitos:

  • Abra o arquivo styles.css.
  • Conhecimento básico de propriedades e seletores CSS.
  • Compreensão de técnicas de estilo para designs responsivos.

Funcionalidade:

  • Melhorar o apelo visual do jogo.
  • Tornar a interface do jogo responsiva a diferentes tamanhos de tela.

Passos:

body {
  background-color: #f0f0f0;
  font-family: "Arial", sans-serif;
}
h2 {
  text-align: center;
  color: #333;
  margin-bottom: 8px;
}
#main {
  width: 408px;
  height: 408px;
  background: white;
  border: 8px solid #ccc;
  border-radius: 10px;
  /* Added border-radius for a softer look */
  margin: 20px auto;
  overflow: hidden;
  position: relative;
  /* Added relative positioning for child positioning */
}
#con {
  width: 100%;
  height: 400px;
  position: absolute;
  /* Changed to absolute */
  top: -408px;
}
.row {
  height: 100px;
  width: 100%;
}
.cell {
  height: 100px;
  width: 100px;
  float: left;
  border-bottom: rgb(200, 200, 200) 1px solid;
  /* Lighter border color */
}
.black {
  background: #444;
  /* Dark grey instead of black for a softer look */
}
.btn {
  width: 100%;
  text-align: center;
  margin-top: 20px;
}
.start {
  margin: 20px auto;
  width: 150px;
  height: 50px;
  border-radius: 25px;
  /* Increased border-radius for a pill shape */
  background: #4caf50;
  /* Green button */
  color: #fff;
  font-size: 16px;
  /* Increased font size */
  border: none;
  /* Remove default border */
  cursor: pointer;
  /* Cursor effect */
  transition: background 0.3s;
  /* Transition effect */
}
.start:hover {
  background: #45a049;
  /* Darker green on hover */
}

No código acima, adicionamos algum estilo básico ao nosso jogo. Adicionamos uma cor de fundo ao body e uma família de fontes ao texto. Também adicionamos um border radius ao contêiner do jogo para deixá-lo com uma aparência mais suave. Adicionamos também position: relative ao contêiner do jogo e position: absolute ao jogador. Isso nos permitirá posicionar o jogador dentro do contêiner do jogo. Também adicionamos um efeito de transição ao botão de início.

✨ Verificar Solução e Praticar

Implementar a Lógica Básica do Jogo

Requisitos:

  • Abra o arquivo script.js.
  • Conhecimento preliminar dos fundamentos de JavaScript.
  • Compreensão do conceito de Document Object Model (DOM).

Funcionalidade:

  • Configurar funções utilitárias essenciais.
  • Inicializar variáveis cruciais do estado do jogo.

Passos:

// Utility functions and initial variable setup
// Get an element by its id
function $(id) {
  return document.getElementById(id);
}

// Create a div element with a given class name
function creatediv(className) {
  var div = document.createElement("div");
  div.className = className;
  return div;
}
// Set an interval id as null initially
var clock = null;
// State of the game (0 means stopped and 1 means started)
var state = 0;
// Speed of the game blocks movement
var speed = 6;
// Flag to check if the game has started or not
var flag = false;

No código acima, criamos duas funções utilitárias. A primeira função $(id) é usada para obter um elemento pelo seu id. A segunda função creatediv(className) é usada para criar um elemento div com um determinado nome de classe. Também inicializamos algumas variáveis que serão usadas posteriormente no jogo.

✨ Verificar Solução e Praticar

Inicializar o Jogo

Requisitos:

  • Habilidade para criar funções JavaScript.
  • Familiaridade com ouvintes de eventos (event listeners) JavaScript.

Funcionalidade:

  • Preparar o jogo para ser lançado.
  • Criar o conjunto inicial de blocos do jogo.

Passos:

// Clicking the start game button to start the game
function start() {
  if (!flag) {
    init();
  } else {
    alert("The game has already started! No need to click again!");
  }
}

// Initialization (init) function
function init() {
  flag = true;
  for (var i = 0; i < 4; i++) {
    createrow();
  }

  // Adding event listeners with addEventListener
  $("main").addEventListener("click", function (ev) {
    judge(ev);
  });

  // Timer call move() every 30 milliseconds
  clock = setInterval(move, 30);
}

No código acima, criamos uma função start() que será chamada quando o botão de início for clicado. Dentro da função start(), chamamos a função init() que inicializará o jogo. Dentro da função init(), definimos a variável flag como true, que será usada para verificar se o jogo foi iniciado ou não. Também criamos quatro linhas de blocos usando a função createrow(). Também adicionamos um ouvinte de evento (event listener) ao contêiner do jogo, que será usado para detectar o evento de clique no contêiner do jogo. Também definimos um temporizador que chamará a função move() a cada 30 milissegundos.

✨ Verificar Solução e Praticar

Implementar a Funcionalidade do Jogo

Requisitos:

  • Proficiência com laços e condições JavaScript.
  • Conhecimento de como manipular o DOM usando JavaScript.

Funcionalidade:

  • Criar a dinâmica central do jogo.
  • Projetar cenários de fim de jogo.
  • Implementar mecânicas para criação e movimento de blocos.

Passos:

  1. Verifique se o jogador clicou em um bloco preto ou branco. Atualize o status do jogo com base no clique do jogador.
// Determine whether to click on a black or white block
function judge(ev) {
  if (
    ev.target.className.indexOf("black") == -1 &&
    ev.target.className.indexOf("cell") !== -1
  ) {
    ev.target.parentNode.pass1 = 1; // Defines the pass attribute, which indicates that the white block of this row has been clicked
  }

  if (ev.target.className.indexOf("black") !== -1) {
    // Clicking a target with black in the class name is a black block
    ev.target.className = "cell";
    ev.target.parentNode.pass = 1; // Defines the pass attribute, indicating the black block in this row was clicked
    score();
  }
}
  1. Determine quando o jogo termina com base nas interações do jogador. Acione ações de término do jogo quando o jogo terminar.
// Check if the game is over
function over() {
  var rows = con.childNodes;
  if (rows.length == 5 && rows[rows.length - 1].pass !== 1) {
    fail();
  }
  for (let i = 0; i < rows.length; i++) {
    if (rows[i].pass1 == 1) {
      fail();
    }
  }
}

// Game Over
function fail() {
  clearInterval(clock);
  flag = false;
  confirm("The final score is " + parseInt($("score").innerHTML));
  var con = $("con");
  con.innerHTML = "";
  $("score").innerHTML = 0;
  con.style.top = "-408px";
}
  1. Gere linhas de blocos para a jogabilidade. Posicione aleatoriamente o bloco "preto" entre os outros.
// Create a <div class="row"> with four children <div class="cell">
function createrow() {
  var con = $("con");
  var row = creatediv("row"); // Create div: className=row
  var arr = createcell(); // Define the class name of the div cell, one of which is cell black

  con.appendChild(row); // Add child node with row as con

  for (var i = 0; i < 4; i++) {
    row.appendChild(creatediv(arr[i])); // Add child nodes of row cell
  }

  if (con.firstChild == null) {
    con.appendChild(row);
  } else {
    con.insertBefore(row, con.firstChild);
  }
}

// Create an array of class names; one of them is "cell black", others are "cell"
function createcell() {
  var temp = ["cell", "cell", "cell", "cell"];
  var i = Math.floor(Math.random() * 4); // Randomly generate the position of the black block Math.random() function parameters 0~1 random number
  temp[i] = "cell black";
  return temp;
}
  1. Faça os blocos se moverem para baixo continuamente. Exclua as linhas antigas à medida que saem da tela.
// Move the black blocks down
function move() {
  var con = $("con");
  var top = parseInt(window.getComputedStyle(con, null)["top"]);

  if (speed + top > 0) {
    top = 0;
  } else {
    top += speed;
  }
  con.style.top = top + "px"; // Keep moving the top value so it moves
  over();
  if (top == 0) {
    createrow();
    con.style.top = "-102px";
    delrow();
  }
}

// Delete a row
function delrow() {
  var con = $("con");
  if (con.childNodes.length == 6) {
    con.removeChild(con.lastChild);
  }
}
✨ Verificar Solução e Praticar

Finalizar a Pontuação e o Gerenciamento da Velocidade do Jogo

Requisitos:

  • Compreensão de variáveis JavaScript e operações aritméticas.
  • Habilidade para escrever lógica de jogo complexa em JavaScript.

Funcionalidade:

  • Estabelecer um sistema de recompensa.
  • Criar um sistema para aumentar progressivamente a dificuldade do jogo.

Passos:

// Acceleration function, increases the speed
function speedup() {
  speed += 2;
  if (speed == 20) {
    alert("That's awesome!");
  }
}
// Scoring
function score() {
  var newscore = parseInt($("score").innerHTML) + 1; // point plus one
  $("score").innerHTML = newscore; // Modify Score
  if (newscore % 10 == 0) {
    // Use the acceleration function when the fraction is a multiple of 10, it gets faster and faster
    speedup();
  }
}

No código acima, criamos uma função speedup() que será usada para aumentar a velocidade do jogo. Também criamos uma função score() que será usada para aumentar a pontuação do jogo. Também adicionamos uma condição na função score() que chamará a função speedup() quando a pontuação for um múltiplo de 10.

✨ Verificar Solução e Praticar

Teste o Seu Jogo

  • Abra index.html em um navegador web.

    open web
  • Jogue o jogo, garantindo que todas as funcionalidades funcionem como esperado.

  • O efeito da página é o seguinte:

    gameplay demonstration animation
✨ Verificar Solução e Praticar

Resumo

Ótimo trabalho! Você acabou de construir um jogo simples, mas divertido, de evitar blocos do zero usando HTML, CSS e JavaScript. Este projeto apresentou a você o tratamento da interação do usuário, a lógica do jogo e a estilização CSS dinâmica com base nas mudanças de estado do jogo. Você pode estender este jogo base com mais recursos, como níveis, limites de tempo ou vários modos de dificuldade. Divirta-se experimentando com seu novo jogo!