- Ender Efrain R. Carrasco
- Kaio Nicolas F. Rodrigues
- Thiago C. Magalhães
- Yohan B. Cys
Projeto final desenvolvido para a disciplina de Desenvolvimento Web I (DS122), UFPR.
O objetivo foi criar uma aplicação Full Stack de teste de digitação inspirada no Monkeytype, com foco técnico na otimização de renderização do front-end e na integridade relacional do back-end.
A aplicação vai além de testar a velocidade de digitação, gerenciando um ecossistema completo com:
- Autenticação Segura (Login/Cadastro).
- Histórico de Partidas persistente.
- Sistema de Ligas Privadas para competição entre amigos.
gameplay.mp4
cadastro_login.mp4
ligas.mp4
A stack foi escolhida para consolidar os conceitos fundamentais de Desenvolvimento Web, utilizando o ambiente XAMPP (PHP/MySQL) com Bootstrap v5.3 no front-end, sem o uso de frameworks no back-end.
- Front-end:
- JavaScript (Vanilla ES6+): Lógica do jogo, manipulação do DOM em tempo real, validação de formulários e comunicação assíncrona via
Fetch API. - CSS3: Framework Bootstrap v5.3 (Grid system e componentes responsivos), com estilização personalizada (Theming) para Dark Mode no arquivo
estilo.css. - HTML5: Estrutura semântica e acessível.
- JavaScript (Vanilla ES6+): Lógica do jogo, manipulação do DOM em tempo real, validação de formulários e comunicação assíncrona via
- Back-end:
- PHP 8 (Procedural): Gerenciamento de rotas, controle de sessão (
$_SESSION), autenticação e fornecimento de dados (endpoints) para o front-end. - Segurança: Criptografia de senhas com
password_hash/verifye proteção robusta contra SQL Injection utilizando Prepared Statements.
- PHP 8 (Procedural): Gerenciamento de rotas, controle de sessão (
- Banco de Dados:
- MySQL: Modelagem relacional normalizada (3FN) para assegurar a integridade referencial entre usuários, partidas e ligas.
Arquivos principais: db_connect.php, create_db_tables.php
O banco typinggame foi estruturado seguindo a normalização relacional (3FN), com as seguintes tabelas e relacionamentos:
users: Tabela mestre de usuários.- Constraints:
nameeemaildefinidos como UNIQUE para evitar duplicidade.
- Constraints:
matches: Histórico de pontuações.- Relacionamento: 1:N (Um usuário possui muitas partidas).
- Foreign Key:
user_idreferenciandousers(id).
leagues: Salas de competição criadas pelos usuários.- Atributos:
codigo(Unique) para compartilhamento ekeyword(senha de acesso). - Propriedade: Armazena o
owner_id(Dono da liga).
- Atributos:
league_members: Tabela associativa (pivô).- Relacionamento: Resolve a relação N:N entre Usuários e Ligas.
- Foreign Keys: Vincula
league_ideuser_id.
- Ambiente Servidor: XAMPP, WAMP ou LAMP instalado.
- Ferramentas: Git (para clonar o repositório).
- Clone o projeto para a pasta do servidor. Acesse a pasta
htdocs(dentro da instalação do XAMPP) e execute:git clone https://github.com/thiagomagh/fast-typing-game.git - Configure o Banco de Dados: Edite o arquivo
db/db_connect.phpe ajuste as credenciais (usuário e senha) conforme a sua configuração do MySQL no XAMPP. - Inicie o Servidor: Abra o painel do XAMPP e inicie os serviços Apache e MySQL.
- Crie o Banco e Tabelas: Abra o navegador e acesse o link de instalação automática: http://localhost/fast-typing-game/db/create_db_tables.php (Isso criará o banco
typinggamee todas as tabelas necessárias). - (Opcional) Gere dados de teste: Para popular o banco com dados fictícios, acesse: http://localhost/fast-typing-game/teste.php
- Acesse o Projeto: Navegue até a página inicial para fazer login: http://localhost/fast-typing-game/index.php
Arquivos principais: login.php, login_action.php, auth.php, logout.php
O controle de acesso foi implementado utilizando PHP Sessions nativas, seguindo rigorosas práticas de segurança:
- Criptografia de Senhas: Uso da função
password_hash()(algoritmos Bcrypt/Argon2) no registro. As senhas nunca são armazenadas em texto plano. - Verificação Segura: O login utiliza
password_verify(), que mitiga ataques de timing ao comparar o hash armazenado com a entrada do usuário. - Gestão de Sessão (State Management): O estado de login é persistido via
$_SESSION. O scriptauth.phpatua como um Route Guard (guardião de rotas), sendo incluído no topo de arquivos protegidos para redirecionar usuários não autenticados. - Validação e Sanitização:
- Integridade: Verificação prévia de duplicidade (E-mail e Username) no banco antes do cadastro.
- Filtros: Uso de
filter_var()para validar e-mails,empty()para campos obrigatórios estrlen()para garantir requisitos mínimos de senha. Fluxo de Dados:Formulário➔Sanitização➔Verificação de Hash➔Início da Sessão➔Acesso Liberado
Arquivos principais: script.js, save_score.php
O núcleo do jogo funciona como uma aplicação Event-Driven (orientada a eventos), otimizada para evitar gargalos de renderização no navegador.
- Renderização Otimizada: Utilização de
DocumentFragmentpara montar o lote de palavras na memória e injetá-las no DOM de uma única vez, minimizando reflows e repaints. - Motor de Digitação: Um único Event Listener gerencia a validação. Inclui mecânica Start-on-Type (o timer só inicia na primeira interação) e validação granular (classe CSS aplicada letra por letra).
- Buffer Infinito: O estado do jogo monitora o progresso do usuário. Se o buffer de palavras cair abaixo de um limite (threshold), um novo lote é gerado e anexado automaticamente, criando um fluxo infinito.
- Persistência Assíncrona: Ao fim do timer, o input é bloqueado e a pontuação é enviada via Fetch API (JSON) para o back-end PHP, garantindo que o registro no MySQL ocorra sem recarregar a página.
Fluxo de Dados:
Input➔Validação Visual➔Buffer Check (Gera Palavras)➔Timer=0➔Fetch(POST)➔MySQL
Arquivos principais: create_league.php, join_league.php
O sistema de salas privadas utiliza uma lógica robusta de identificação e controle de acesso:
- Geração de Código Único: Algoritmo que gera IDs alfanuméricos de 6 dígitos (ex:
A1B2C3) com verificação de colisão no banco de dados. Isso garante que nunca existam duas ligas com o mesmo código de acesso. - Controle de Acesso: Validação dupla (Código da Liga + Senha definida pelo dono/keyword) para entrada de novos membros.
- Vinculação Automática (Atomicidade): O criador da liga é inserido automaticamente como membro e proprietário na mesma operação de criação, garantindo consistência dos dados.
Fluxo de Criação:
Input Configuração➔Gerar Código(Random)➔Check Colisão(Loop)➔Insert Liga➔Insert Membro(Dono)