Guilherme: Olá! Meu nome é Guilherme Silveira e eu serei um de seus instrutores no curso de ChatGPT e JavaScritpt: Inteligência artificial aplicada a programação.
Eu sou uma pessoa não binária, de cabelos castanhos e encaracolados. Tenho uma "covinha" artificial de um piercing que usei na bochecha. Ao meu fundo, há alguns objetos de decoração, em especial, um quadro de arte interativa.
Monica: Olá! Eu sou a Moni Hillman!
Sou uma mulher de cabelos castanhos, com mexas roxas na frente e franja. Estou usando um fone de ouvido rosa. Ao meu fundo, há alguns livros em cima de uma mesa e objetos decorativos.
Guilherme: Juntos, neste curso, vamos trabalhar em um projeto muito bacana, em dois sentidos:
Criaremos um jogo divertido e poderemos explorá-lo a partir de variações de som, imagem e outras surpresas.
Trabalhar com código usando uma ferramenta externa de ajuda: a inteligência artificial no estilo de chat.
Estamos visualizando a página do jogo sem o áudio. Ele acontece no espaço sideral. Há uma bola que se movimenta aleatoriamente pela tela e entra em choque com uma barra lateral esquerda. Podemos mover essa barra para cima e para baixo, movimentando, consequentemente, a bola.
No ChatGPT, isso tudo será feito com muita conversa. A maior parte do código será gerado em diversas conversas: vamos, analisar a resposta e repetir a pergunta, escrita de outra forma, quando a resposta não é exatamente o que esperávamos.
Encontraremos formas e táticas de conversar com a inteligência artificial, assim, obteremos melhores resultados.
Monica: O único pré-requisito para este curso é saber um pouco de JavaScript, assim, você entenderá as funcionalidades do p5.js que utilizamos e não explicamos com profundidade.
Nos encontramos durante as aulas! Não deixe de se matricular!
Guilherme: Tudo bem, pessoal? Vamos começar?
Acessaremos o site do ChatGpt, que é a versão do Generative Pre-Trained Transformer ou Transformador pré-treinado generativo (GPT) via chat. Existem outras ferramentas que fazem o mesmo tipo de operação com chat, você pode escolher a de sua preferência.
Estamos usando o modelo GPT-4, versão paga, mas você pode usar a versão 5 Default (GPT-3.5) que é gratuita. Vamos escrever nosso primeiro pedido, lembrando de indicar a linguagem:
Eu quero um jogo de pong em JavaScript
Moni: Mesmo que o ChatGpt esteja nos respondendo, ele ainda não é uma pessoa, por isso, não toma iniciativas com base no que acha que queremos, mas, sim, a partir do que foi ensinado.
Guilherme: Ele vai responder sobre o pong considerando o que teve contato. Por exemplo, se existir muitos pongs em Python, a resposta provavelmente será em Python.
Continuando, também precisaremos de uma biblioteca. Uma boa opção para esse tipo de simulador/jogo é a p5js.
Eu quero um jogo de pong em Javascript. Eu quero usar a biblioteca p5js.
O nosso jogo é single player, ou seja, de apenas um jogador contra o computador.
Eu quero um jogo de pong em Javascript. Eu quero usar a biblioteca p5js. É um jogo de um jogador versus o computador.
Vamos usar uma inteligência de computador simples, assim evitamos problemas.
Eu quero um jogo de pong em Javascript. Eu quero usar a biblioteca p5js. É um jogo de um jogador versus o computador. A inteligência do computador é bem simples: quando o jogador toca na bola, a raquete do computador escolhe uma posição aleatória e vai para aquela posição.
Não queremos marcar pontos, nem nada complexo. A ideia é construir algo simples, inicial.
Eu quero um jogo de pong em Javascript. Eu quero usar a biblioteca p5js. É um jogo de um jogador versus o computador. A inteligência do computador é bem simples: quando o jogador toca na bola, a raquete do computador escolhe uma posição aleatória e vai para aquela posição. Não quero pontos. Quando tem gol, a bola volta ao centro com um novo movimento aleatório.
Não vamos pedir o código de uma vez só. Ele poderia vir cortado na resposta, por conta do tamanho, e no processo de copiar e colar, provavelmente teríamos um erro. A ideia é pedir só o HMTL.
Eu quero um jogo de pong em Javascript. Eu quero usar a biblioteca p5js. É um jogo de um jogador versus o computador. A inteligência do computador é bem simples: quando o jogador toca na bola, a raquete do computador escolhe uma posição aleatória e vai para aquela posição. Não quero pontos. Quando tem gol, a bola volta ao centro com um novo movimento aleatório. Me mostre primeiro somente o arquivo hmtl. Sem css, sem javascript.
Monica: O ChatGpt é bem instável. Pode ser que no futuro ele fique super rápido. Por enquanto, ele tem travado no meio do processo de formulação da resposta. Não é exatamente um corte, aparecem duas linhas de resposta e ele trava.
Guilherme: Agora o ChatGpt abriu uma janela de código e está gerando o HTML, segundo o nosso pedido. Podemos copiar e colar o resultado em um arquivo HTML. Como ele não disse o nome do arquivo, vamos nomeá-lo como index.hmtl
. Vamos conferir!
<!DOCTYPE html>
<html lang="pt">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Pong Game</title>
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> src="sketch.js"></script>
</head>
<body>
</html>
Como estou acostumado a usar o p5js, sei que esse arquivo é o de sempre. Todos os arquivos do p5js são um script HTML, em que há um script que inclui o p5js e outro que inclui o nosso script: sketch ou rascunho.
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script> src="sketch.js"></script>
Ele entendeu o que queremos. É um passo importante. Agora vamos acessar o site do Editor p5js. Nele, encontraremos o básico de um arquivo p5js.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
}
Apertando o botão de "Play", ele rodará o sketch.js
e desenhará um quadrado cinza, 400x400 (400 por 400), na função setup()
. Um Canvas está sendo criado e roda uma única vez. Depois, com a função draw()
(desenha) ele "printa" o fundo, background()
, com a cor 220, que é um tom de cinza-claro.
Vamos adicionar outro comando após o background()
para que um retângulo branco, na posição 50 e tamanho 100x200 seja criado: rect(50, 50, 200)
.
function setup() {
createCanvas(400, 400);
}
function draw() {
background(220);
rect(50, 50, 200);
}
Agora, quando rodamos o comando, aparece um retângulo branco dentro do quadrado cinza, posicionado à esquerda. É no scketch.js
que escreveremos o JavaScript. Na parte superior do campo de edição do comando, há uma seta posicionada para a direita. Apertando essa seta, ela mostrará, à esquerda, os "Arquivos do esboço": index.html
; sketch.js
; style.css
.
Abrindo o index.html
, será possível conferir que é o script
quem adiciona o p5.js
em uma versão mais atualizada, o css
, que está usando apenas como reset mínimo, e o sketch.js
. É no sketch.js
que vamos trabalhar.
Moni: O p5 até importa as bibliotecas de sons, p5.sound.min.js
, mas, não precisamos usá-las necessariamente. Além disso, ele também realiza o trabalho de configuração do ambiente. Mas, se você quiser usar o VSCode, Sublime ou outro editor, basta copiar o código que foi gerado pelo ChatGpt e colar e colocar no index.html
.
Guilherme: Estamos usando o editor do p5 para não precisarmos instalar o VSCode ou outro editor. Mas poderia rodar também no CodePen, por exemplo.
Prosseguindo, fecharemos o sketch.js
e retornaremos à página do chat. Vamos pedir o arquivo sketch.js
.
Agora por favor me de o arquivo sketch.js
Moni: O resultado será tão grande quanto uma bíblia.
Guilherme: O ChatGpt está criando as variáveis para as raquetes e para a bola. Isso faz sentido, porque temos duas raquetes e elas estão em determinada posição da tela. A bola também fica em alguma posição.
// Variaveis para as raquetes e bola
let playerPadle, computerPadle, ball;
function setup() {
createCanvas(800, 400);
playerPadle = new Padle(30, height / 2, 10, 60);
computerPadle = new Padle(width - 40, heigth / 2, 10, 60);
ball = new Ball(width / 2, height / 2, 10);
}
function draw() {
background(0);
Há um objeto chamado Padle()
, que é "raquete" em português. Ele está definindo a posição dessa raquete, por exemplo, "30" no X, isto é, à direita, bem no meio da tela e na vertical. Com o computerPadle
ele está criando também o lado da direita, a grossura é 10 e a altura é 60.
A classe bola, ball()
, na posição do meio, com valor 10, que deve se referir ao raio da esfera. A função draw()
atualiza as raquetes e a bola. Depois, verifica colisões e mostra.
function draw() {
background(0);
// Atualiza as posições das raquetes e da bola
playerPaddle.update();
computerPadlle.update();
ball.update();
// Vericia colisões entre a bola e raquetes
ball.checkPaddleCollision(playerPaddle);
ball.checkPaddleCollision(computerPadle);
// Desenha as raquetes e a bola
playerPaddle.display();
computerPaddle.display();
ball.display();
}
A classe da raquete "seta" muitas variáveis e outras tarefas. A classe da bola também. O código ainda está sendo gerado.
class Raquete {
constructor(x, y, w, h) {
this.x = x;
this.y = y;
this.w = w;
this.h = h;
}
Um detalhe interessante é que a classe da raquete está usando o mouse. Significa que se mexermos o mouse para cima e para baixo, a raquete segue a posição do mouse.
atualizar() {
if (this === raqueteJogador) {
this.y = mouseY;
} else {
if (bola.y > this.y + this.h / 2) {
this.y += 3;
} else if (bola.y < this.y - this.h / 2) {
this.y -= 3;
}
}
this.y = constrain(this.y, this.h / 2, height - this.h / 2);
}
display() {
fill(255);
rectMode(CENTER);
rect(this.x, this.y, this.w, this.h);
}
}
Sobre a bola, uma inteligência está sendo criada para movimentar a bola para cima e para baixo. O constrain()
serve para limitar a tela e mostrar "desenhe um retângulo":
rectMode(CENTER);
rect(this.x, this.y, this.w, this.h);
Na classe da bola, Ball
, ele chama um constructor()
, reset()
, o update()
acontece de acordo com a velocidade. Se foi gol, ela "reseta" o jogo. Lembrando que, no comando, está especificado gol para a direita e para a esquerda:
if (this.x + this.r / 2 >= width) {
this.reiniciar();
} else if (this.x - this.r / 2 <= 0) {
raqueteComputador.y = random(height - raqueteComputador.h);
this.reiniciar();
}
}
Seguindo, ele verifica colisão e mostra.
checkPadleCollision(paddle) {
if (
this.x - this.r / 2 <= paddle.x + paddle.w / 2 &&
this.x + this.r / 2 >= paddle.x - paddle.w / 2 &&
this.y + this.r / 2 >= paddle.y - paddle.h / 2 &&
this.y - this.r / 2 <= paddle.y + paddle.h / 2
) {
this.velocidadeX *= -1;
}
}
display() {
fill(255);
ellipseMode(CENTER);
ellipse(this.x, this.y, this.r);
}
}
O ChatGpt parou no meio da resposta e, fora da janela de código, exibiu a mensagem: "Este código cria um jogo de Pong simples, onde o usuário joga".
Monica: Aconteceu o que eu tinha avisado: ele travou no meio da resposta.
Guilherme: Tudo bem, o código gerado até agora é suficiente. Vamos apertar "Coy code" na parte superior da janela para copiar, colar na área de edição do p5. arquivo scketch.js
, salvar com o comando "Ctrl + S" e rodar.
Na lateral direita, visualizaremos uma prévia: temos um Pong funcionando. O fundo é preto, há duas raquetes brancas, uma do lado direito e outra do lado esquerdo.
Elas são representadas por barras verticais que se movimentam para cima e para baixo, segundo a movimentação do mouse. Há também uma pequena bola branca que se movimenta aleatoriamente e entra em choque com as raquetes.
Funcionou mesmo! Estou muito feliz que está funcionando muito bem, porque quando preparei o curso, não estava tão bom.
Monica: O ChatGpt está mais treinado!
Guilherme: Alguma sugestão de feature (recurso) que podemos adicionar?
Monica: Poderíamos substituir o que está escrito em inglês para português no comando.
Guilherme: Vamos trocar para português. Basta pedir ao ChatGpt:
Por favor, o nome das classes e o nome das variáveis deveriam estar em português
Ele estava gerando a mudança para português e travou. O ChatGpt gera uma quantidade limite de caracteres. Se ele parar, é porque, provavelmente, atingiu esse limite e temos que pedir que continue.
Mas, se pedimos que ele continue, pode acontecer um erro e ele não saber o que continuar ou gerar uma resposta que não tem nada a ver com o que estamos fazendo.
Temos um contexto e é importante considerá-lo. Precisamos pensar nas melhoras formas de comunicação com o chat para que ele entenda o que queremos. Se simplesmente dissermos "continue", provavelmente não receberemos a continuação correta.
Ele já gerou a raquete, o setup()
e o draw()
. Vamos copiar esse trecho, colar no editor do p5, retornar ao chat e pedir o que está faltando: a função da bola. Então, vamos escrever:
Me mostre a classe Bola completa, somente ela
Agora ele está gerando o código, mantendo o texto em português e mantendo a coerência com o texto de código anterior. Vamos copiá-lo e testar se vai funcionar.
A ideia não é aprender a copiar o código, mas, entender como podemos nos comunicar com o ChatGpt, isto é, como devemos escrever as mensagens para alcançarmos os resultados desejados.
O código está pronto. Vamos copiá-lo e colá-lo no p5, logo após o comando da raquete. Depois de salvá-lo, podemos rodar e testar se o gol funciona. Ao lado direito da tela, há uma pré-visualização do jogo de Pong. Quando acontece o gol, o jogo continua. Está funcionando!
Nos encontramos no próximo vídeo para resolver outros problemas do nosso jogo de Pong.
Monica: Vamos enfrentar os novos desafios!!
Monica: O que podemos implementar no nosso jogo de Pong para que ele fique cada vez mais bonito?
Guilherme: Uma das funcionalidades clássicas, é: quando a bolinha bate nas extremidades da tela, tanto embaixo quanto em cima, não faz sentido ela quicar no "nada". Se ela bate nas raquetes (laterais), é necessário que existam barras em cima e embaixo para justificar que a bola bata e volte.
Monica: É super importante dar um feedback visual para os usuários. Se a bola é lançada pela raquete para cima e não existe nenhuma barreira que pare seu movimento, em tese, ela deveria continuar a se movimentar infinitamente.
Sabemos que existe um limite, mas se existir uma representação visual dessa barreira, o que está acontecendo ficará mais compreensível.
Guilherme: Então, vamos pedir que o ChatGpt adicione barras ao jogo de Pong:
Queremos duas barras horizontais, uma no topo e uma embaixo da tela para mostrar que quando a bola chega nessas bordas, ela quica. Isso significa que ao invés de quicar no limite do Y do canvas, vai quicar agora nessas bordas finas.
Podemos especificar a espessura. Talvez, a mesma da barra da raquete. O que você acha, Moni?
Monica: Acho que poderia ser um pouco mais fina.
Guilherme: Vamos retornar ao p5 e verificar a espessura da raquete.
createCanvas(800, 400);
raquete(30, height, 2, 10, 60);
Raquete(30, height / 2, 10, 60);
A espessura da raque é 10. Vamos pedir 5 pixels. Continuando a escrever no ChatGpt:
Queremos duas barras horizontais, uma no topo e uma embaixo da tela para mostrar que quando a bola chega nessas bordas, ela quica. Isso significa que ao invés de quicar no limite do Y do canvas, vai quicar agora nessas bordas finas. A espessura delas é de 5.
Monica: É interessante analisar os prompts (comandos) que outras pessoas criam para pesquisar no ChatGpt, porque eu não saberia ser tão específica.
Quem me conhece a partir de grupos de estudos e cursos sabe que tenho dificuldade com números, computação gráfica, dentre outros. Neste sentido, especificar y, x e demais valores para criar a raquete e outros elementos do jogo acaba sendo uma dificuldade.
Guilherme: Na próxima eu vou parar de fazer o prompt e você assume. Assim, não influenciarei, com a minha experiência, a construção do p5js.
Monica: Vamos saber como é criar um prompt para quem tem dificuldade em geometria.
Guilherme: Perfeito! Eu posso ajudar, sem problemas!
Vamos continuar. O ChatGpt está o comando para adicionar duas barras horizontais, uma no topo e outra na parte inferior da tela do jogo de Pong. Ele criou mais duas variáveis: barraSuperior
e barraInferior
.
// Variáveis para as raquetes, bola e barras horizontais
let raqueteJogador, raqueteComputador, bola, barraSuperior, barraInferior;
function setup() {
createCanvas(800, 400);
raqueteJogador = new Raquete(30, height / 2, 10, 60);
raqueteComputador = new Raquete(width - 40, height / 2, 10, 60);
bola = new Bola(width / 2, height / 2, 10);
barraSuperior = new Barra(0, 5, width, 5);
barraInferior = new Barra(0, height - 5, width, 5);
}
Após as variáveis, temos o setup()
, a função draw()
para desenhar as duas barras. Em seguida, ele sinaliza código omitido com reticências para a classe da bola.
class Raquete {
// ...
}
class Bola {
// ...
Monica: Sinal de que ele não está escrevendo nada que não seja necessário.
Guilherme: Vamos copiar esse trecho das variáveis até a classe Raquete()
e colar no editor do p5. Se a classe Raquete()
está como antes, por que a classe da bola está diferente? Você sabe o motivo?
Monica: Acho que é para calcular por onde a bola vai voltar ou quando vai bater.
Guilherme: É a colisão!
if (
this.y - this.r / 2 <= barraSuperior.y + barraSuperior.h ||
this.y + this.r / 2 >= barraInferior.y - barraInferior.h
) {
this.velocidadeY *= -1;
}
Antes a bola colidia com o limite do canvas. Agora, ela precisa colidir com a barra, ou seja, 5 pixels antes. Para calcular essa distância de colisão 5 pixels antes, o chatGpt pegou o y da barra, barraSuperior.y
, que é o ponto vertical e calculou menos ou mais (a depender de qual das barras) a espessura dessa barra.
Ele construiu o comando de forma dinâmica. Assim, se mudarmos a espessura da barra para 13, por exemplo, ele funcionará. Antes, a bola colidia com o this.y
, sendo o tamanho zero e height. Ou seja, o y menor era zero e o y maior era a altura do canvas.
if (this.y - this.r / 2 <= 0 || this.r /2
>= height) {
this.velocidadeY *= -1;
}
Agora, isso não acontece mais. Agora a bola bate na barra.
Monica: Pensei que ele colocaria apenas visualmente a barra, porque não pedimos uma barra tão grossa. Mas, ele fez até uma verificação de colisão com ela.
Guilherme: Mas esse é o meu truque: no meu prompt, eu pedi que ele fizesse isso. Vamos retornar ao pedido:
Queremos duas barras horizontais, uma no topo e uma embaixo da tela para mostrar que quando a bola chega nessas bordas, ela quica. Isso significa que ao invés de quicar no limite do Y do canvas, vai quicar agora nessas bordas finas. A espessura delas é de 5.
Foi proposital a escolha pela frase: "Isso significa que ao invés de quicar no limite do Y do canvas, vai quicar agora nessas bordas finas". Se não especificarmos o que queremos, o resultado dificilmente será o esperado.
Neste caso, a bola passaria pela barra e bateria na borda. Nós perceberíamos esse movimento de entrada e saída, o que não é tão legal.
Monica: Isso está bastante interligado ao que estava pensando. Disse que no meu prompt eu não especificaria esse detalhe da barra, pois não saberia da necessidade de especificar.
O resultado seria o que estava esperando: apenas uma mudança visual, mas não no impacto da barra.
Guilherme: Estamos no p5. Vamos rodar o código e conferir o resultado com as duas barras. Na lateral direita da tela, temos a janela de prévia do jogo de Pong. Está funcionando: temos duas barras horizontais, uma no topo e outra na parte inferior da tela, e a bola bate nelas e volta.
Ele acabou gerando uma margem também, isto é, uma faixa preta entre a barra branca e o final da tela.
Monica: Só acho que a bola está muito devagar. Assim, o jogo fica um pouco entediante. Podemos pensar nisso agora.
Guilherme: Ótimo! Alguma sugestão de prompt?
Monica: Será dinâmica ou fixa a velocidade?
Guilherme: Acho que poderia ser dinâmica, isto é, ir aumentando aos poucos.
Monica: Minha sugestão de prompt é:
Altere o código para a velocidade da bola mudar a cada vez que ocorrer um impacto com a raquete.
Guilherme: Durante o processo de geração do código, tenho uma sugestão a fazer. Considerando que o tempo para gerar os códigos é longo, seria útil saber antecipadamente qual impacto esse código deve ter.
Por exemplo, o código deve afetar a classe "bola", mais precisamente a função de impacto dessa bola, ou talvez a classe Raquete()
, onde ocorre a colisão (mesmo que seja na bola).
Com isso, evitamos gerar comandos desnecessários que não produzem alterações significativas. Podemos especificar explicitamente: "quero o código da classe bola" e indicar qual trecho do código precisa ser atualizado.
No nosso caso, fica mais fácil identificar onde serão as alterações, porque a velocidade é usada em apenas um trecho. Mas, em códigos maiores, talvez o design fique muito ruim, incompreensível, embora funcione. Então, se você já tem uma sugestão de onde colocar o trecho de código, indique para o chat.
Após a classe bola, ele criou uma função aumentarVelocidade()
. O fator de aumento é 10% (dez por cento) no x e no y. Vamos copiar essa função, colar na classe bola, editor do p5.
class Bola {
// ...
aumentarVelocidade() {
const fatorAumento = 1.1;
this.velocidadeX *= fatorAumento;
this.velocidadeY *= fatorAumento;
}
Também vamos copiar a função verificarColisaoRaquete(raquete)
. Agora ela está verificando e aumentando a velocidade.
verificarColisaoRaquete(raquete) {
if (
this.x - this.r / 2 <= raquete.x + raquete.w / 2 &&
this.x + this.r / 2 >= raquete.x - raquete.w / 2 &&
this.y + this.r / 2 >= raquete.y - raquete.h / 2 &&
this.y - this.r / 2 <= raquete.y + raquete.h / 2
) {
this.velocidadeX *= -1;
this.aumentarVelocidade();
}
}
No p5, vamos salvar, rodar e testar. É possível notar, na janela de visualização prévia, que a velocidade está aumentando de 10 em 10%, cada vez que a bola bate nas raquetes. Se deixarmos o fator mais rápido, conseguiremos acompanhar melhor esse aumento.
Monica: Acho que está suficiente. Mais que isso, ficará impossível ganhar.
Guilherme: Assim já está bem difícil ganhar. Está ótimo!
Monica: Podemos deixar o Pong ainda melhor: mais dinâmico, complexo, bonito e jogável. No próximo vídeo, continuaremos nos desafiando no jogo de Pong, usando o ChatGpt. Até lá!!
O curso ChatGPT e JavaScript: construa o jogo Pong possui 102 minutos de vídeos, em um total de 34 atividades. Gostou? Conheça nossos outros cursos de IA para Programação em Inteligência Artificial, ou leia nossos artigos de Inteligência Artificial.
Matricule-se e comece a estudar com a gente hoje! Conheça outros tópicos abordados durante o curso:
Impulsione a sua carreira com os melhores cursos e faça parte da maior comunidade tech.
1 ano de Alura
Assine o PLUS e garanta:
Formações com mais de 1500 cursos atualizados e novos lançamentos semanais, em Programação, Inteligência Artificial, Front-end, UX & Design, Data Science, Mobile, DevOps e Inovação & Gestão.
A cada curso ou formação concluído, um novo certificado para turbinar seu currículo e LinkedIn.
No Discord, você tem acesso a eventos exclusivos, grupos de estudos e mentorias com especialistas de diferentes áreas.
Faça parte da maior comunidade Dev do país e crie conexões com mais de 120 mil pessoas no Discord.
Acesso ilimitado ao catálogo de Imersões da Alura para praticar conhecimentos em diferentes áreas.
Explore um universo de possibilidades na palma da sua mão. Baixe as aulas para assistir offline, onde e quando quiser.
Acelere o seu aprendizado com a IA da Alura e prepare-se para o mercado internacional.
1 ano de Alura
Todos os benefícios do PLUS e mais vantagens exclusivas:
Luri é nossa inteligência artificial que tira dúvidas, dá exemplos práticos, corrige exercícios e ajuda a mergulhar ainda mais durante as aulas. Você pode conversar com a Luri até 100 mensagens por semana.
Aprenda um novo idioma e expanda seus horizontes profissionais. Cursos de Inglês, Espanhol e Inglês para Devs, 100% focado em tecnologia.
Transforme a sua jornada com benefícios exclusivos e evolua ainda mais na sua carreira.
1 ano de Alura
Todos os benefícios do PRO e mais vantagens exclusivas:
Mensagens ilimitadas para estudar com a Luri, a IA da Alura, disponível 24hs para tirar suas dúvidas, dar exemplos práticos, corrigir exercícios e impulsionar seus estudos.
Envie imagens para a Luri e ela te ajuda a solucionar problemas, identificar erros, esclarecer gráficos, analisar design e muito mais.
Escolha os ebooks da Casa do Código, a editora da Alura, que apoiarão a sua jornada de aprendizado para sempre.