image

Acesse bootcamps ilimitados e +650 cursos pra sempre

60
%OFF
Article image
Fernando Araujo
Fernando Araujo22/08/2025 13:55
Compartir

Os Sistemas Web e os Jogos Digitais

  • #JavaScript

Sumário

 1. Introdução

2. O que é um sistema web?

3. Criando um sistema web básico

4. Sistema web para um jogo multiplayer

5. Considerações finais

6. Referências

 

1 – Introdução

 No início da programação, os sistemas eram baseados em mainframes, rodavam localmente e os programadores não tinham acesso direto ao hardware. Depois vieram os PCs e as coisas ficaram mais coloridas e divertidas, mas ainda rodavam localmente. Depois vieram as redes e a arquitetura cliente-servidor.

 Com a chegada da Internet, vieram os sistemas web, com websites coloridos, dinâmicos e a interação real começou a acontecer blogs etc.

 Atualmente, é muito comum ver sistemas simples ou complexos, como os financeiros rodando como sistemas web. E os jogos, divertidos, emocionantes e viciantes!

 Este artigo apresenta o histórico dos sistemas de computador, até os sistemas web, e mostra exemplos de códigos de sistemas web simples.


 2 – O que é um sistema web?

image

 Um sistema web é um software projetado para rodar em servidores web, sendo acessado pelos usuários através de navegadores (browsers), usando a Internet.

 Suas características principais são:

  • Acesso via navegador - não exige instalação no computador do usuário;
  • Multiplataforma - funciona em diferentes sistemas operacionais (Windows, Linux, Android etc);
  • Atualização centralizada - basta atualizar o servidor, sem necessidade de atualizar manualmente cada dispositivo;
  • Arquitetura cliente-servidor: o navegador (cliente) solicita informações, e o servidor processa e responde;
  • Escalabilidade - atende qualquer quantidade de usuários, de 1 até milhões;
  • Integração - com bancos de dados, APIs, serviços externos e outros sistemas corporativos.

  

Histórico

 Eu aprendi a programar em 1980 e acompanhei a evolução dos sistemas de computação até hoje. Acreditem, nem sempre foi assim. 😊

 No início dos anos 80, na universidade, a gente programava perfurando cartões, para mainframes, recebendo o resultado em listagens impressas, sem nenhum contato com os equipamentos. Depois, vieram os terminais burros, onde a gente digitava o programa e ele era executado no mainframe, com o resultado da execução chegando na tela textual monocromática. O processamento era centralizado, com poucos usuários simultâneos e o processamento era, principalmente, em lote (batch).

 No início dos anos 90, com a chegada no Brasil dos primeiros PCs, os sistemas passaram a rodar localmente, instalados no computador. Isso trouxe mais facilidade de uso, mas resultou na dificuldade de manutenção, pois cada máquina precisava de atualização manual e local.

 Logo depois vieram as redes locais e os programas passaram, a ser instalados em um computador separado e dedicado, o servidor, e os usuários podiam executá-los nos seus computadores clientes. Era a arquitetura cliente-servidor, que permitiu sistemas corporativos maiores e mais complexos. Além disso, a atualização do software só precisava ser feita no servidor, não em cada máquina cliente. No cliente ficava a interface com o usuário e no servidor o processamento dos dados e o acesso ao banco de dados.

 O próximo passo, a partir de 1995, foi o surgimento da Internet, especialmente do serviço www (ou a web). As aplicações passaram a rodar em navegadores (browsers), com o acesso passando a ser global. Os programas não precisavam ser instalados em nenhuma máquina do cliente, criando o modelo de 3 camadas (navegador, servidor e bando de dados). Inicialmente, os sistemas eram escritos em HTML, CSS e Javascript. Depois vieram as linguagens de backend.

 Os passos seguintes foram o lançamento e popularização dos smartphones e seus aplicativos mobile (apps), armazenamento em nuvem, ferramentas de IA, e contando...

  

3 – Criando um sistema web básico

 Como foi dito, um sistema web é construído sobre a arquitetura cliente-servidor e é composta do frontend e do backend:

·       Cliente (Front-end): navegador (ou app) do usuário, responsável pela apresentação na interface do usuário;

·       Servidor (Back-end): responsável pelo processamento de dados, fluxos e regras de negócio, ou seja, a lógica do negócio.

·        Banco de Dados: armazena as informações de forma persistente, permitindo consultas em SQL;

 

No frontend, temos as linguagens:

·        HTML – responsável pelo layout dos elementos da página;

·        CSS – cuida da formatação dos elementos do jogo, configurando cores, alinhamento, fontes etc.;

·        Javascript – é quem dá a dinâmica da página, inserindo ações para eventos da interface com o usuário, definindo temporizações, e mensagens para o usuário;

·        Também são usados frameworks como React, Angular ou Vue.js.

  

Já o Backend é composto de:

·        Linguagens como Python (Django/Flask), Java (Spring), PHP (Laravel), JavaScript (Node.js), .NET, Go etc.

·        Banco de dados – Pode ser um banco de dados relacional (como MySQL, PostgreSQL, SQL Server) ou não-relacional (MongoDB, Redis, Cassandra). No caso de elementos geográficos, para georreferenciamento, é preciso usar um banco que ofereça esta característica, como o PostgreSQL;

  • Servidor Web: cuida da comunicação dos dados entre o backend e o frontend dos usuários. Exemplos são Apache, Nginx ou serviços em nuvem;

  

Um típico exemplo de fluxo de um sistema web é:

Usuário → navegador envia requisição HTTP → servidor processa → consulta banco de dados → retorna resposta → servidor web envia resposta HTTP → navegador exibe.

  image


Exemplo de sistema web bem simples

 A seguir, segue a codificação para um sistema web de cadastro de usuários, usando frontend com HTML e backend com Python e Flask), com integração a um banco SQLite.

  

O seu funcionamento é o seguinte:

  1. O usuário acessa http://localhost:5000.
  2. O navegador exibe o formulário HTML.
  3. Quando ele envia os dados, o Flask recebe pela rota /cadastro.
  4. Os dados são salvos no banco usuarios.db.
  5. O servidor responde com uma mensagem de sucesso ou erro.

 

Front-end (formulário HTML)

 

<!DOCTYPE html>
<html lang="pt-br">
<head>
 <meta charset="UTF-8">
 <title>Cadastro de Usuário</title>
</head>
<body>
 <h2>Cadastro de Usuário</h2>
 <form action="/cadastro" method="post">
     Nome: <input type="text" name="nome" required><br><br>
     Email: <input type="email" name="email" required><br><br>
     Senha: <input type="password" name="senha" required><br><br>
     <button type="submit">Cadastrar</button>
 </form>
</body>
</html>

 

 A seguinte tela será gerada

 

image


 Back-end (Python + Flask)

 

from flask import Flask, request, render_template_string
import sqlite3
 
app = Flask(__name__)
 
# Cria o banco de dados (se não existir)
def init_db():
 conn = sqlite3.connect("usuarios.db")
 cursor = conn.cursor()
 cursor.execute("""
 CREATE TABLE IF NOT EXISTS usuarios (
     id INTEGER PRIMARY KEY AUTOINCREMENT,
     nome TEXT NOT NULL,
     email TEXT UNIQUE NOT NULL,
     senha TEXT NOT NULL
 )
 """)
 conn.commit()
 conn.close()
 
init_db()
 
# Página inicial (formulário HTML)
@app.route("/")
def index():
 html = open("index.html", "r", encoding="utf-8").read()
 return render_template_string(html)
 
# Rota de cadastro
@app.route("/cadastro", methods=["POST"])
def cadastro():
 nome = request.form["nome"]
 email = request.form["email"]
 senha = request.form["senha"]
 
 try:
     conn = sqlite3.connect("usuarios.db")
     cursor = conn.cursor()
     cursor.execute("INSERT INTO usuarios (nome, email, senha) VALUES (?, ?, ?)", 
                    (nome, email, senha))
     conn.commit()
     conn.close()
     return f"Usuário {nome} cadastrado com sucesso!"
 except sqlite3.IntegrityError:
     return "Erro: este email já está cadastrado!"
 
if __name__ == "__main__":
 app.run(debug=True)

 

   3 – Um sistema web para jogos multiplayer

  image

 

Uma das principais (e mais divertidas e empolgantes!) aplicações para um servidor web são os jogos digitais (os famosos games).

 Seguindo a arquitetura cliente servidor vista na seção anterior, um jogo digital pode ser estruturado da seguinte forma:

 

Front-end (lado do cliente) - É a parte do jogo que o jogador vê e interage. É responsável pela renderização dos gráficos, captura de entradas do jogador (teclado, mouse, toque) e comunicação em tempo real com o servidor.

 As linguagens usadas comumente são HTML5, para a estrutura do jogo, CSS3, para os estilos e o design e JavaScript, para a lógica e interatividade.

 Também costumam ser usados frameworks e bibliotecas como Phaser.js e PixiJS (para jogos 2D), Three.js e Babylon.js (para gráficos 3D no navegador) e WebGL, para renderização gráfica acelerada pela GPU);

 

Back-end (lado do servidor) - Responsável por processar regras que precisam ser centralizadas. As responsabilidades do backend são autenticação de jogadores (login, sessão), armazenamento de dados (pontuações, inventário, progresso), gerenciamento de partidas multiplayer e comunicação para sincronizar estados do jogo (via WebSocket).

 As linguagens e frameworks mais usados são Node.js (com Socket.IO para tempo real), Python (Flask/Django + websockets), Java (Spring), mas também são usadas Go e .NET Core.

 Banco de dados – Os principais bancos de dados utilizados são os relacionais MySQL e PostgreSQL (para as contas de usuários e rankings de pontuação) ou os não-relacionais MongoDB e Redis (para armazenar os estados de jogo e cache de sessão).

 

O fluxo de comunicação durante o jogo é:

  1. O jogador acessa o navegador, que carrega os arquivos HTML/CSS/JS do jogo;
  2. O frontend processa a lógica gráfica e envia eventos (movimento, ações) ao backend;
  3. O backend valida as regras globais (pontos, colisões em multiplayer, ranking etc.);
  4. O banco de dados guarda informações persistentes;
  5. A comunicação entre o frontend e o backend pode ser feita por HTTP/REST, para requisições ocasionais (como salvar a pontuação) ou por meio de WebSockets, para comunicação contínua e em tempo real (ex.: jogos multiplayer).

 

 Como exemplo de implementação de um sistema web para um jogo, vamos criar o código básico para um jogo 2D multiplayer simples.

 O jogo escolhido é bem simples: cada jogador controla um quadradinho colorido em um mapa; o servidor sincroniza posições e salva contas e pontuações.

 Foram escolhidas as stacks HTML5 Canvas + JS, no frontend, e Flask + Flask-SocketIO + SQLite no back-end.

  

Estrutura de pastas:

webgame/

├─ app.py

├─ requirements.txt

├─ templates/

│ └─ index.html

└─ static/

  └─ game.js

 

Arquivo requirements.txt é:

flask==3.0.3

flask-socketio==5.3.6

eventlet==0.36.1

SQLAlchemy==2.0.31

Werkzeug==3.0.3

flask-cors==4.0.1

 

O código para o frontend ficaria assim (templates/index.html (HTML + Canvas + UI simples):

 

<!doctype html>
<html lang="pt-br">
<head>
 <meta charset="utf-8" />
 <meta name="viewport" content="width=device-width,initial-scale=1" />
 <title>Web Arena</title>
 <style>
 body{font-family:system-ui,Segoe UI,Arial,sans-serif;margin:0;background:#0b1020;color:#e9f0ff}
 header{padding:10px 16px;background:#0f1630;display:flex;gap:12px;align-items:center}
 #status{margin-left:auto;font-size:.9rem;opacity:.8}
 main{display:grid;grid-template-columns:1fr 320px;gap:0}
 #gameWrap{display:flex;justify-content:center;align-items:center;padding:8px;background:#0b1020}
 canvas{background:#0d1328;border:1px solid #1f2b54;border-radius:12px;box-shadow:0 8px 24px rgba(0,0,0,.35)}
 aside{background:#0f1630;border-left:1px solid #22305f;padding:12px 12px 80px}
 h3{margin:.2rem 0 .6rem}
 .card{background:#0d1533;border:1px solid #213269;border-radius:12px;padding:12px;margin:8px 0}
 input,button{padding:10px 12px;border-radius:10px;border:1px solid #2b3f7c;background:#0b1330;color:#e9f0ff}
 button{cursor:pointer}
 table{width:100%;border-collapse:collapse}
 th,td{padding:6px 8px;border-bottom:1px solid #24346b;font-size:.95rem}
 #auth{display:flex;gap:6px;flex-wrap:wrap}
 small{opacity:.75}
 </style>
</head>
<body>
<header>
 <strong>🕹️ Web Arena</strong>
 <div id="auth">
 <input id="user" placeholder="usuário">
 <input id="pass" placeholder="senha" type="password">
 <button id="btnReg">Registrar</button>
 <button id="btnLogin">Login</button>
 </div>
 <div id="status">Desconectado</div>
</header>
 
<main>
 <div id="gameWrap">
 <canvas id="game" width="900" height="600"></canvas>
 </div>
 <aside>
 <div class="card">
   <h3>Perfil</h3>
   <div id="profile"><small>faça login para jogar</small></div>
 </div>
 <div class="card">
   <h3>Ranking (Top 10)</h3>
   <table id="rank"><thead><tr><th>Jogador</th><th>Pontos</th></tr></thead><tbody></tbody></table>
   <button id="refreshRank">Atualizar ranking</button>
 </div>
 <div class="card">
   <h3>Ajuda</h3>
   <small>Use WASD ou setas para mover. A cada segundo em movimento: +1 ponto. Clique “Salvar Pontos”.</small><br><br>
   <button id="saveScore" disabled>Salvar Pontos</button>
 </div>
 </aside>
</main>
 
<script src="https://cdn.socket.io/4.7.5/socket.io.min.js" integrity="sha384-FtM6k4r5J6c0vUo5CwH5pVxQx+0d9y8v8s9n7N9rXQz0mN0l5tF9Ew7zQ3A0y7yQ" crossorigin="anonymous"></script>
<script src="/static/game.js"></script>
</body>
</html>

 

O código para a lógica do cliente (static/game.js), com WebSocket:

 

// --------------------------- Config & State ---------------------------
const API = "";
let AUTH = { token: null, username: null };
let socket = null;
 
const cv = document.getElementById("game");
const ctx = cv.getContext("2d");
let world = { w: cv.width, h: cv.height, players: {} };
let my = { x: 100, y: 100, vx: 0, vy: 0, points: 0, alive: false, t0: null };
 
// --------------------------- UI Helpers ---------------------------
const $ = (sel) => document.querySelector(sel);
const statusEl = $("#status");
const profileEl = $("#profile");
const rankBody = $("#rank tbody");
 
function setStatus(s){ statusEl.textContent = s; }
function setProfile(){
 if (!AUTH.token) { profileEl.innerHTML = "<small>faça login para jogar</small>"; return; }
 profileEl.innerHTML =<b>${AUTH.username}</b><br><small>token: ${AUTH.token.slice(0,12)}…</small>`;
}
 
// --------------------------- Auth (HTTP) ---------------------------
async function json(url, method, body, auth=false){
 const r = await fetch(url, {
 method,
 headers: {
   "Content-Type": "application/json",
   ...(auth && AUTH.token ? { "Authorization": `Bearer ${AUTH.token}` } : {})
 },
 body: body ? JSON.stringify(body) : undefined
 });
 const data = await r.json().catch(()=>({}));
 if (!r.ok) throw new Error(data.error || r.statusText);
 return data;
}
 
async function registerUser(u,p){
 const res = await json("/api/register", "POST", {username:u, password:p});
 AUTH = { token: res.token, username: res.username };
 localStorage.setItem("auth", JSON.stringify(AUTH));
 setProfile();
}
 
async function loginUser(u,p){
 const res = await json("/api/login", "POST", {username:u, password:p});
 AUTH = { token: res.token, username: res.username };
 localStorage.setItem("auth", JSON.stringify(AUTH));
 setProfile();
}
 
async function loadRank(){
 const rows = await json("/api/highscores", "GET");
 rankBody.innerHTML = rows.map(r => `<tr><td>${r.username}</td><td>${r.points}</td></tr>`).join("");
}
 
// --------------------------- Game / Socket ---------------------------
function connectSocket(){
 if (!AUTH.token) return;
 socket = io("/game", { transports: ["websocket"] });
 
 socket.on("connect", () => {
 setStatus("Conectado");
 socket.emit("join", { token: AUTH.token });
 $("#saveScore").disabled = false;
 my.alive = true; my.points = 0; my.t0 = performance.now();
 });
 
 socket.on("disconnect", () => setStatus("Desconectado"));
 
 socket.on("world", (data) => { world = data; draw(); });
 socket.on("state", (data) => { world.players = data.players; draw(); });
 socket.on("player_joined", () => {/* opcional: mostrar mensagem */});
 socket.on("player_left", () => {/* opcional */});
 socket.on("score_saved", () => { loadRank(); });
 socket.on("error", (e) => alert(e.message || "Erro"));
}
 
// input
const keys = {};
window.addEventListener("keydown", e => { keys[e.key.toLowerCase()] = true; });
window.addEventListener("keyup", e => { keys[e.key.toLowerCase()] = false; });
 
function step(){
 if (!my.alive || !socket) return;
 const up = keys["w"] || keys["arrowup"];
 const down = keys["s"] || keys["arrowdown"];
 const left = keys["a"] || keys["arrowleft"];
 const right = keys["d"] || keys["arrowright"];
 let dx = 0, dy = 0;
 if (up) dy -= 1; if (down) dy += 1; if (left) dx -= 1; if (right) dx += 1;
 
 if (dx || dy) {
 socket.emit("move", { token: AUTH.token, dx, dy });
 // pontuação simples: +1 por segundo em movimento
 const dt = (performance.now() - my.t0)/1000;
 if (dt >= 1){ my.points += Math.floor(dt); my.t0 = performance.now(); }
 }
 
 requestAnimationFrame(step);
}
 
function draw(){
 ctx.clearRect(0,0,cv.width,cv.height);
 // grade leve
 ctx.globalAlpha = 0.15;
 for(let x=0; x<cv.width; x+=50){ ctx.fillRect(x,0,1,cv.height); }
 for(let y=0; y<cv.height; y+=50){ ctx.fillRect(0,y,cv.width,1); }
 ctx.globalAlpha = 1;
 
 // desenha jogadores
 for (const [token, p] of Object.entries(world.players)){
 const me = (AUTH.token && token === AUTH.token);
 ctx.beginPath();
 ctx.fillStyle = me ? "#5cf27b" : "#7aa8ff";
 ctx.strokeStyle = "#0b0";
 ctx.rect(p.x-8, p.y-8, 16, 16);
 ctx.fill();
 // nome
 ctx.font = "12px system-ui";
 ctx.fillStyle = "#e9f0ff";
 ctx.fillText(p.username, p.x - ctx.measureText(p.username).width/2, p.y - 12);
 }
 
 // HUD com pontos
 ctx.font = "14px system-ui";
 ctx.fillStyle = "#e9f0ff";
 ctx.fillText(`Pontos: ${my.points}`, 10, 20);
}
 
// --------------------------- UI wiring ---------------------------
$("#btnReg").onclick = async () => {
 const u = $("#user").value.trim(); const p = $("#pass").value;
 if (!u || !p) return alert("Informe usuário e senha");
 try { await registerUser(u,p); connectSocket(); await loadRank(); requestAnimationFrame(step); }
 catch(e){ alert(e.message); }
};
 
$("#btnLogin").onclick = async () => {
 const u = $("#user").value.trim(); const p = $("#pass").value;
 if (!u || !p) return alert("Informe usuário e senha");
 try { await loginUser(u,p); connectSocket(); await loadRank(); requestAnimationFrame(step); }
 catch(e){ alert(e.message); }
};
 
$("#refreshRank").onclick = loadRank;
 
$("#saveScore").onclick = async () => {
 if (!socket || !AUTH.token) return;
 socket.emit("submit_score", { token: AUTH.token, points: my.points, duration_sec: 0 });
};
 
// restaura sessão
const saved = localStorage.getItem("auth");
if (saved){
 try { AUTH = JSON.parse(saved); setProfile(); connectSocket(); loadRank(); requestAnimationFrame(step); }
 catch{}
}
setProfile();

 

O código do backend é muito longo e, como aqui eu quero focar no frontend, não será mostrado.

 O backend (servidor) gerencia a posição de todos e garante que os movimentos sejam sincronizados. O banco de dados guarda a conta do jogador (usuário, senha, ranking), a pontuação total acumulada e o histórico de partidas.

 A tela do jogo é mostrada abaixo:

 image


O tabuleiro é uma arena em grade (grid). O jogador controla um quadrado colorido (verde ou azul na figura) no tabuleiro.

O jogo funciona da seguinte maneira:

 image


 É um jogo multiplayer, em que os jogadores competem para coletar itens e pontuar. O objetivo é coletar pontos e evitar ser atingido por outros jogadores ou obstáculos. Ganha quem acumular mais pontos antes do fim do tempo ou quem atingir primeiro uma pontuação máxima.


 O jogador pode ganhar pontos - Cada vez que o jogador se move até uma célula especial (um item ou power-up que aparece aleatoriamente), ele ganha pontos. O Power-up dá pontos e uma vantagem temporária, como mais velocidade.

 

Ele também pode perder pontos - Se colidir com outro jogador, perde pontos ou fica temporariamente congelado. Se ficar muito tempo sem coletar nada, pode perder pontos por inatividade. Se houver armadilhas na arena, o jogador perde pontos ao cair nelas.

 image


Os quadrados com números são as pontuações de 4 jogadores, os quadradinhos coloridos são os jogadores, as outras figuras são os itens de pontuação.

  

5 – Considerações finais

 Uma das formas modernas de criação de sistemas e aplicativos segue a arquitetura cliente-servidor.

 Ela é baseada no uso de navegadores web para renderizar a tela do usuário (frontend), bancos de dados remotos para armazenar os dados persistentes do programa, controlados por regras de negócio armazenadas em servidores (backend), e servidores web, para comunicação com o frontend;

 A base para o frontend é composta das linguagens HTML, CSS e Javascript, enquanto no backend são usados Python, Node.js, Java e outras.

 Os sistemas web são usados para aplicações simples, sistemas robustos de comércio eletrônico, além de sistemas financeiros, e sistemas divertidos como os jogos digitais.

 Este artigo apresentou as características de sistemas web comuns e os conceitos técnicos por trás deles.

 Além disso, foram mostrados códigos de exemplo para sistemas web básicos e para o frontend de um jogo digital simples.

 Eu gosto de jogar jogos digitais simples. Atualmente, jogo Sudoku, Xadrez, gamão e Rummikub – este último eu jogo todo dia! Inclusive comprei o jogo de tabuleiro dele. Recomendo!!!

  

6    – Referências

 [1] DevMedia. Como funcionam as aplicações web. Disponível em: <https://www.devmedia.com.br/como-funcionam-as-aplicacoes-web/25888>. Acesso em: 21/08/2025.

 [2] Kelvin SUNG et all. Build Your Own 2D Game Engine and Create Great Web Games : Using HTML5, JavaScript, and WebGL2. Apress, 2021.

 [3] ChatGPT - Jogo criado pelo ChatGPT, Disponível em: <chatgpt.com>. Acesso em: 22/08/2025.

Compartir
Recomendado para ti
Ri Happy - Front-end do Zero #2
Avanade - Back-end com .NET e IA
Akad - Fullstack Developer
Comentarios (0)