# Memory Bits

{% hint style="info" %}
**Video apresentação do projeto:** <https://www.youtube.com/watch?v=63Eg0b0iCdk>\
\
**Repositório:** <https://github.com/Merieli/memory-bits>
{% endhint %}

### Sobre o projeto

Este projeto de estudo é de uma aplicação web FullStack do tipo SSR (Server-Side Rendering) com design criado por mim no Figma. A aplicação foi desenvolvida utilizando [Nuxt 3](https://nuxt.com/) com [Typescript](https://www.typescriptlang.org/), [Vue Router](https://router.vuejs.org/), [Pinia](https://pinia.vuejs.org/), [Tailwind CSS](https://tailwindcss.com/), componentes [Radix Vue](https://www.radix-vue.com/overview/introduction.html), [Zod](https://zod.dev/), [Prisma ](https://www.prisma.io/)e banco de dados [MySQL](https://www.mysql.com/).

A proposta do projeto é criar um jogo da memória com banco de dados e API em estilo pixel art, onde cada jogador efetua seu login na aplicação.

<figure><img src="https://2902601599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTv2ogCwEturb6GCPZbVE%2Fuploads%2FWxuPCCupvqlXdKe09gqa%2Fgame-level1.gif?alt=media&#x26;token=ad549ff6-34e7-4b6b-8aef-b77be111a27c" alt=""><figcaption><p>Jogo da memória - Memory Bits</p></figcaption></figure>

O login no app é simplificado e elimina a necessidade de se cadastrar. Ao digitar um nome de usuário único e escolher o nível, a aplicação valida se o usuário já existe no banco de dados. Se existir, obtém os dados do usuário para iniciar; se não, cria um novo usuário com base no username fornecido.

&#x20;Embora esse tipo de login não seja adequado para uma aplicação do mundo real, foi implementado dessa forma apenas para facilitar, focando no mais importante que era aprender sobre API e banco de dados. Em um cenário real, seria necessário criar uma área de cadastro e exigir o uso de senha para garantir a segurança.

<figure><img src="https://2902601599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTv2ogCwEturb6GCPZbVE%2Fuploads%2FRIUTNkerNGSCSqlGaTn1%2Fpage-login.png?alt=media&#x26;token=1964290e-5591-4bd8-992d-0682dbf9a154" alt=""><figcaption><p>Página de login do jogo</p></figcaption></figure>

Todo o esquema de pontuação do jogo é baseado no nível escolhido. Conforme a dificuldade aumenta, o tempo máximo permitido para o jogo diminui. Quando o tempo limite para o nível é atingido, o jogo é finalizado com a derrota do jogador. As tentativas erradas a cada seleção de pares também são contabilizadas e, ao atingirem o limite para o nível, resultam na derrota do jogador.

<figure><img src="https://2902601599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTv2ogCwEturb6GCPZbVE%2Fuploads%2F2D2M3XnZj9I5VUV5apQn%2Fgame-over.png?alt=media&#x26;token=0a7a9986-82eb-44c8-9025-f4a3ed14b91d" alt=""><figcaption><p>Página de game over do jogo</p></figcaption></figure>

Optei por criar um endpoint para cada operação que desejava realizar no banco de dados, sendo assim foi criada a API abaixo:\
\
**Cards:**

* <mark style="color:green;">**`GET`**</mark>` ``/cards` - para obter todas as cartas.  Esse endpoint também permite os query params **group\_id**, **group\_name** e **level\_id** para facilitar a busca de cartas pertencentes a grupos ou níveis específicos.
* <mark style="color:green;">**`GET`**</mark>` ``/cards/:id` - para obter uma determinada carta pelo Id.
* <mark style="color:blue;">**`POST`**</mark>`/cards` - para salvar uma nova carta no banco de dados.
* <mark style="color:red;">**`DELETE`**</mark>`/cards/:id` - para excluir uma carta do banco de dados.

**Group of cards:**

* <mark style="color:green;">**`GET`**</mark>`/group_of_cards` - para obter todos os grupos de cartas.
* <mark style="color:green;">**`GET`**</mark>`/group_of_cards/:name` - para obter os grupos de cartas pelo nome.

**Levels:**

* <mark style="color:green;">**`GET`**</mark>`/levels` - para obter todos os níveis do jogo.

**Matchs:**

* <mark style="color:green;">**`GET`**</mark>`/matchs` - para obter todas as partidas registradas. Também possui o query param **user\_id** que permite a busca de todas as partidas de um determinado usuário.
* <mark style="color:green;">**`GET`**</mark>`/matchs/:id` - para obter uma partida específica por Id.
* <mark style="color:blue;">**`POST`**</mark>`/matchs` - para salvar uma nova partida.
* <mark style="color:red;">**`DELETE`**</mark>`/matchs/:id` - para excluir uma determinada partida por Id.
* <mark style="color:purple;">**`PUT`**</mark>`/matchs/:id` - para atualizar uma determinada partida por Id.

**Users:**

* <mark style="color:green;">**`GET`**</mark>`/users` - para obter todos os usuários. Possui o query param **name** que permite a busca de um usuário pelo nome.
* <mark style="color:green;">**`GET`**</mark>`/users/:id` - para obter um usuário específico por Id.
* <mark style="color:blue;">**`POST`**</mark>`/users` - para salvar um novo usuário.

### Planejamento

O primeiro passo foi definir os requisitos do projeto, criando um **roadmap** detalhado de todas as etapas necessárias para a sua conclusão. A ideia inicial era criar um jogo da memória que permitisse aos jogadores selecionar o nível de dificuldade desejado e efetuar o login com seu usuário. Na tela do jogo, deveria ser possível visualizar detalhes como a pontuação, o nível, a quantidade de tentativas erradas e um contador de duração.

Na segunda etapa, desenvolvi um diagrama de caso de uso do jogo para facilitar a compreensão das funcionalidades e interações necessárias. Em seguida, passei para a definição do design no Figma, onde todas as telas foram cuidadosamente planejadas e desenhadas.

Como um dos objetivos do projeto era aprender a criar um banco de dados, optei por criar uma modelagem conceitual com um diagrama MER (Modelo Entidade-Relacionamento) e um diagrama DER (Diagrama Entidade-Relacionamento) para a modelagem lógica. E todo o script do banco de dados foi criado usando o MySQL Shell, desde os comandos para criar as tabelas até os de inserção de dados.

### **Design do projeto**

A ideia conceitual do projeto era usar o estilo pixel art e fazer referência a jogos conhecidos, como Mario e Tibia. A partir disso, escolhi uma fonte no estilo pixel art, a VT323 do Google Fonts, e selecionei imagens open-source em pixel art que representassem os ícones que queria usar no projeto, de forma a utilizar poucos textos e representar os elementos com ícones.

O nome do projeto, **Memory Bits**, foi inspirado pela escolha do pixel art que usa a coloração de quadrados que representam pontos de pixel, onde cada pixel é composto por "bits", uma unidade para armazenar informações digitais. E o "memory" vem de jogo da memória.

<figure><img src="https://2902601599-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FTv2ogCwEturb6GCPZbVE%2Fuploads%2F4iD7r9PW05DMFGkRdhpC%2Fimage.png?alt=media&#x26;token=cd19f166-620c-442e-a074-9b39b4a6926e" alt=""><figcaption><p>Figma criado para o projeto</p></figcaption></figure>

Foram criadas a página de login e a do jogo, enquanto que as telas de derrota e vitória foram pensadas como uma "cobertura" sobre a página principal, facilitando todo o processo de desenvolvimento.

O fundo escolhido foi uma paisagem em pixel art com céu e grama, de forma simples para não poluir o plano. E as cartas foram escolhidas de acordo com a complexidade das imagens para popular os níveis do jogo. As cartas com desenhos do Mario foram selecionadas para o nível **Easy**, enquanto as cartas do Tibia foram usadas nos níveis **Medium** e **Hard**, por possuírem mais elementos detalhados e alguns semelhantes que aumentam a dificuldade na escolha dos pares.

### O que aprendi com o projeto?

Neste projeto, aprendi a usar o Nuxt, banco de dados MySQL, a biblioteca de componentes Radix Vue, o Zod e o Prisma para desenvolver uma aplicação full-stack.

Com o Nuxt, pude aprender a criar uma aplicação SSR (Server-Side Rendering), que oferece um carregamento mais eficiente, proporcionando uma experiência prática com esse tipo de aplicação e conhecendo seus benefícios.

Aprendi a modelar, criar e manipular o banco de dados MySQL, que foi escolhido devido à sua popularidade e amplo uso no mercado, aplicando também algumas otimizações de tipos.

Com o ORM (Object-Relational Mapping) Prisma, tive a possibilidade de construir queries de forma simplificada para os endpoints da aplicação, facilitando a identificação de tipos e acelerando todo o processo de desenvolvimento.

O Zod permitiu validar os dados do banco de dados no formato pensado para a API, utilizando uma classe abstrata DTO (Data Transfer Object) que também faz a transformação dos dados. Por se tratar de um projeto full-stack, pude usar o mesmo esquema de validação no frontend e no backend, garantindo a aplicação das mesmas regras de validação em ambos os lados, evitando duplicação de código e mantendo a consistência dos dados.

O Radix Vue foi usado com a finalidade de experimentar componentes que proporcionassem acessibilidade. Nesse projeto, por ser simples, seu uso se limitou a selects e inputs.
