Programação para iniciantes

Introdução

Este site foi criado para ensinar programação.
Você não precisa ter nenhum conhecimento prévio. Vamos desvendar os principais conceitos por trás desta área de forma gradual e divertida.
Ao longo do curso você aprenderá a desenhar figuras na tela, criar animações e até desenvolver jogos simples que poderá jogar no seu navegador!

O que é um programa de computador?

Um programa nada mais é do que um texto que segue determinadas regras. O computador irá processar essas instruções e executá-las.

A pessoa que escreve este tipo de texto é chamada de Pessoa Desenvolvedora ou Programadora. E o tipo de texto que esta pessoa escreve, que será lido pelo computador, recebe um nome especial: Código de Programação (normalmente chamado apenas de código ou código fonte). Neste curso, vou me referir a este tipo de texto como código.

O conjunto de regras de como o programa deve ser escrito é definido por uma Linguagem de Programação. Ao longo da evolução da computação diversas linguagens de programação foram criadas. Neste curso vamos utilizar uma linguagem chamada Elm.

No início de cada aula introduzo um novo tema e em seguida proponho alguns desafios. É muito importante que você faça os desafios! É a parte mais importante (e divertida) de toda aula.
Alguns desafios são fáceis, outros mais difíceis. É normal ter um pouco de dificuldade e faz parte do aprendizado. Explore, experimente e não tenha medo de errar. O máximo que pode acontecer é aparecer uma mensagem de erro. 😆

Mas afinal, como é escrito um código?

Abaixo temos nosso primeiro exemplo, o famoso "Olá Mundo!", que apenas exibe um texto na tela.

import Html exposing (text)

main =
  text "Olá Mundo!"

Mas como fazemos para executar este código?
Para facilitar, vamos fazer isso através do navegador! 😄
Abra uma nova aba em seu navegador e acesse o seguinte site: https://elm-lang.org/try.
Em seguida, copie todo o código acima e cole na parte da esquerda do site.

Pressione Rebuild (Refazer em inglês) na parte inferior no centro da tela e você deve ver o resultado da execução na direita de sua tela, conforme imagem abaixo:

Nosso primeiro código

Parabéns! Você acaba de criar seu primeiro programa na linguagem de programação Elm! 🎉

E agora?

Nas próximas aulas vou te mostrar como desenhar figuras na tela e explicar vários fundamentos da programação.
Você aprenderá o que são funções, parâmetros e muito mais!

Agora siga para a Aula 2 e bons estudos.

Aula 2 - Desenhando na tela.

O que você irá aprender nesta aula?

  1. O que é um import?
  2. Desenhar uma esfera.
  3. O que é o main?
  4. O que é o picture?
    4.1 Mas o que é uma lista?
  5. O que é o circle?

1- O que é um import?

A primeira linha de todos os programas que vamos escrever neste curso será:

import Playground exposing (..)

A palavra import significa importar em inglês. Esta linha é necessária pois permite que a gente tenha acesso aos códigos que estão definidos no Playground. Na Aula 5 explicarei mais em detalhes mas, sem ela, não seriamos capazes de desenhar na tela. Por isso, todos nossos programas neste curso vão começar com esta linha.

2- Desenhar uma esfera.

Hora de programar!
Vamos desenhar um círculo na tela?
Abra novamente o site https://elm-lang.org/try em uma outra aba de seu navegador e cole o código abaixo.

import Playground exposing (..)

main =
  picture
    [ circle green 100 ]

Em seguida pressione Rebuild e veja o resultado da execução conforme imagem abaixo.

Desenhando um circulo

Mas o que está acontecendo?!

3- O que é o main?

A palavra main em inglês significa principal. É através dela que indicamos para o computador onde começa nosso programa.
Portanto, todos os nossos programas vão precisar ter essa linha:

main =

E todo o restante representa o que queremos que o computador faça pra gente.
Dica: não pode ter nenhum espaço antes da palavra main.

4- O que é o picture?

A palavra picture em inglês significa desenho. É através dela que expressamos para o computador que queremos desenhar algo na tela.
Em seguida criamos uma lista (representada pelos símbolos [ e ]) de formas geométricas, que vão formar nosso desenho (picture). Neste exemplo nosso desenho é formado por apenas uma forma geométrica: um círculo.

4.1- Mas o que é uma lista?

Quando vou ao supermercado, escrevo uma lista de produtos que quero comprar. Algo como:

  • 5Kg de arroz
  • 1Kg de feijão
  • 3 batatas grandes
  • 2 mangas

O conceito de lista na programação é muito similar: é apenas uma estrutura para organizar e relacionar um conjunto de dados.

Para representarmos em Elm, por exemplo, o conjunto de números entre zero e dez, escrevemos:

[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]

E uma lista pode ser muito grande, pode ter apenas um elemento ou pode até mesmo ser vazia!

Outros exemplos de listas:

Uma lista vazia:

[]

Uma lista com um único elemento:

[ 1 ]

Uma lista com 3 elementos:

[ 8, 13, 311839 ]

Outra lista com 3 elementos:

[ "Batata", "Cenoura", "Abóbora" ]

Ao longo deste curso vamos criar muitas listas.

5- O que é o circle?

Uma lista de formas geométricas pode ter círculos, retângulos, hexágonos entre muitas outras formas. No nosso exemplo, utilizamos um círculo (circle em inglês). Para desenharmos nosso círculo precisamos informar 2 parâmetros:
O primeiro parâmetro representa sua cor. No nosso exemplo, usamos a cor verde (green).
O segundo indica o diâmetro do círculo. Neste caso, 100.

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar um pouco!

Siga para os desafios da Aula 2 e bons estudos!

Aula 2: Desafios

Para fixar o conhecimento é preciso praticar.

Nesta seção são propostos alguns desafios para você tentar fazer sozinho. É muuuito importante que você tente resolve-los antes de ver as respostas!

Antes de mais nada, abra o seguinte endereço em uma outra aba em seu navegador: htts://elm-lang.org/try.

Copie e execute o mesmo código que vimos durante a aula 2:

import Playground exposing (..)

main =
  picture
    [ circle green 100 ]

Agora tente alterar o código para atender os desafios propostos abaixo. E não tenha medo de errar! Experimente, teste, explore, erre. O pior que pode acontecer é aparecer uma mensagem de erro.

DESAFIO 1 (fácil): Mudando tamanho do círculo.

Altere o valor do tamanho do círculo para um número que quiser.
Pode ser um valor pequeno como 1 ou 2, ou um número bem grande como 9999999.
Em seguida clique em Rebuild e veja o resultado!

DESAFIO 2 (fácil): Mudando a cor do círculo.

Altere o valor da cor do círculo para sua cor preferida. Lembre-se que o nome das cores deve ser em inglês. Se tiver dificuldades com inglês, consulte a lista de cores disponíveis abaixo.

Lista de cores:

red, orange, yellow, green, blue, purple, brown, lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown, darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown, white, lightGrey, grey, darkGrey, lightCharcoal, charcoal, darkCharcoal, black, lightGray, gray e darkGray.

DESAFIO 3 (avançado): Crie 2 círculos, um dentro do outro.

Nosso desenho (picture) atualmente tem apenas um círculo. Tente adicionar um segundo círculo de outra cor e um pouco menor que o primeiro.

Dicas:

  • Lembre-se que os símbolos [ e ] indicam uma lista. Então o segundo círculo deve estar dentro destes símbolos.
  • Pense na lista como sendo algo similar à lista de compras no supermercado, mas ao invés de alimentos, nossa lista vai guardar formas geométricas.
  • Utilize uma vírgula para indicar que quer criar um segundo círculo dentro da lista de formas geométricas.
  • Cuidado com a ordem! Se o círculo menor ficar antes do maior na lista, ele ficará atrás do maior e não será possível visualiza-lo.

DESAFIO 4 (avançado): Crie 4 círculos, um dentro do outro.

Bastante similar ao desafio anterior, mas desta vez devem ser 4 círculos, um dentro do outro, com tamanhos e cores diferentes.

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 2: Resposta dos desafios

Abra o seguinte endereço em uma outra aba em seu navegador: htts://elm-lang.org/try.

Copie a resposta de cada exercício abaixo e tente entendê-las antes de pressionar Rebuild.

DESAFIO 1 (fácil): Mudando tamanho do círculo.

Altere o valor do tamanho do círculo para um número que quiser.
Pode ser um valor pequeno como 1 ou 2, ou um número bem grande como 9999999.
Em seguida clique em Rebuild e veja o resultado!

Resposta

Este desafio era muito fácil né?! Bastava alterar o valor do tamanho do círculo.

import Playground exposing (..)

main =
  picture
    [ circle green 5 ]

DESAFIO 2 (fácil): Mudando a cor do círculo.

Altere o valor da cor do círculo para sua cor preferida. Lembre-se que o nome das cores deve ser em inglês. Se tiver dificuldades com inglês, consulte a lista de cores disponíveis abaixo.

Lista de cores:

red, orange, yellow, green, blue, purple, brown, lightRed, lightOrange, lightYellow, lightGreen, lightBlue, lightPurple, lightBrown, darkRed, darkOrange, darkYellow, darkGreen, darkBlue, darkPurple, darkBrown, white, lightGrey, grey, darkGrey, lightCharcoal, charcoal, darkCharcoal, black, lightGray, gray e darkGray.

Resposta

Este também era bem fácil. Bastava mudar o primeiro parâmetro do círculo (circle) para outra cor.

import Playground exposing (..)

main =
  picture
    [ circle red 5 ]

DESAFIO 3 (avançado): Crie 2 círculos, um dentro do outro.

Nosso desenho (picture) atualmente tem apenas um círculo. Tente adicionar um segundo círculo de outra cor e um pouco menor que o primeiro.

Dicas:

  • Lembre-se que os símbolos [ e ] indicam uma lista. Então o segundo círculo deve estar dentro destes símbolos.
  • Pense na lista como sendo algo similar à lista de compras no supermercado, mas ao invés de alimentos, nossa lista vai guardar formas geométricas.
  • Utilize uma vírgula para indicar que quer criar um segundo círculo dentro da lista de formas geométricas.
  • Cuidado com a ordem! Se o círculo menor ficar antes do maior na lista, ele ficará atrás do maior e não será possível visualiza-lo. Para desenhar mais de uma figura geométrica, separamos cada figura com uma vírgula. No exemplo abaixo temos um círculo vermelho dentro de um verde.
    Lembre-se que os símbolos [ e ] indicam uma lista.

Resposta

import Playground exposing (..)

main =
  picture
    [ circle green 100
    , circule red 50
    ]

Você deve ser capaz de ler o código acima e interpreta-lo da seguinte maneira:
A nosso programa (main) é definido com sendo um desenho (picture) que contêm uma lista (indicada pelos símbolos [ e ]) de duas figuras que, neste caso, são dois círculos.

DESAFIO 4 (avançado): Crie 4 círculos, um dentro do outro.

Bastante similar ao desafio anterior, mas desta vez devem ser 4 círculos, um dentro do outro, com tamanhos e cores diferentes.

Resposta

Caso tenha tido dificuldades nos exercícios 3 e 4, agora que já viu a resposta do 3, que tal tentar fazer o 4 antes de ver a resposta? Em seguida veja a resposta abaixo.

Antes de executar o código abaixo, você é capaz de imaginar o que ele irá desenhar na tela?

import Playground exposing (..)

main =
  picture
    [ circle black 200
    , circle green 150
    , circle yellow 100
    , circle red 50
    ]

E agora?

Siga para a Aula 3 e bons estudos!

Aula 3 - Posicionando elementos.

O que você irá aprender nesta aula?

  1. Como desenhar outras figuras geométricas.
  2. Posicionar uma forma geométrica.
    2.1 Movendo a forma geométrica.
    2.2 Rotacionando a forma geométrica.

1- Como desenhar outras figuras geométricas.

Além de círculos, podemos desenhar:

  • Triâgulos (triangle)
  • Quadrados (square)
  • Retângulos (rectangle)
  • Ovais (oval)
  • Pentagonos (pentagon)
  • Hexagonos (hexagon)
  • Octagonos (octagon)
  • Polígonos (polygon)

É possível desenhar também imagens estáticas e animadas, mas isso será abordado em outra aula. ;)
Hoje vamos aprender a desenhar triângulos, quadrados e retângulos.
Primeiro vamos fazer um programa que desenha um círculo com um quadrado dentro, um triângulo dentro do quadrado e por último um pequeno retângulo.

Mais uma vez, abra uma aba em seu navegador o site https://elm-lang.org/try, cole o código abaixo e pressione Rebuild para ver o resultado.

import Playground exposing (..)

main =
  picture
    [ circle blue 200
    , square green 250
    , triangle red 120
    , rectangle yellow 70 30
    ]

Note que no caso do círculo, o segundo parâmetro é o tamanho do raio. Já no quadrado, o segundo parâmetro é o tamanho dos lados (lembre-se que os lados de um quadrado tem sempre o mesmo tamanho, por isso precisamos passar apenas um número).

No caso do triângulo será desenhado um triângulo equilatero (todos os lados de tamanhos iguais). Mas o número do segundo parâmetro não é o tamanho dos lados, mas sim o raio, ou seja, a distância entre o centro do triângulo e os 3 pontos que formam o triângulo (similar ao raio do círculo).
Ficou em dúvida? Altere o tamanho do triângulo para ser igual ao do círculo e veja o que acontece!

Note também que o retângulo recebe, além da cor, dois parâmetros numéricos.
Consegue imaginar o que significam?
O primeiro número representa a largura do retângulo e o último, sua altura.

2 - Posicionar uma forma geométrica.

2.1 - Movendo a forma geométrica.

Você deve ter reparado que toda forma geométrica que desenhamos até agora aparecem bem no meio da tela, certo? Apenas com isso fica difícil de desenharmos coisas mais legais, como uma árvore ou um carro. Para fazer desenhos complexos temos que posicionar os elementos na tela. Para isso, basta logo depois de declarar uma forma geométrica, colocar o simbolo |>, que indica que queremos aplicar uma transformação. Em seguida, podemos pedir para o computador MOVER a forma geométrica com a operação move (mover em inglês).

Para mover algo precisamos passar dois parâmetros: o valor do deslocamento no eixo x e o valor do deslocamento no eixo y.
O valor do eixo x vai deslocar a forma geométrica para direita do centro da tela (caso o valor seja positivo) ou para esquerda (caso o valor seja negativo).
O valor de y irá desloca-la para baixo (caso valor seja negativo) ou para cima (caso positivo).
Dica: o ponto 0,0 encontra-se bem no meio da tela e é a partir dele que vamos deslocar as formas geométricas.

No exemplo abaixo, desenhamos dois círculos, um ao lado do outro. Veja com atenção o código e tente entendê-lo. Em seguida, copie o código para a outra aba de seu navegador e clique em Rebuild para ver o resultado.

import Playground exposing (..)

main =
 picture
   [ circle blue 100
       |> move -100 0
   , circle red 100
       |> move 100 0
   ]

Experimente alterar os valores e veja o resultado.

2.2 Rotacionando a forma geométrica.

Além de mover nos eixos x e y, podemos também rotacionar as formas.
Podemos fazer com que o triângulo fique um pouco torto, por exemplo. Assim temos mais liberdade na hora de desenhar.
Rotacionar uma forma é muito similar ao que fizemos para mova-las. Utilizamos o simbolo |> seguido da palavra rotate (rotacionar em inglês).

O rotate recebe apenas um parâmetro, que é um número entre 0 e 360, que representa o grau do ângulo. Este valor também pode ser negativo.
Valores positivos rotacionam a figura no sentido ANTI-horário. Negativos, no sentido horário.
Você consegue ler o código abaixo e tentar imaginar o que será desenhado?

Copie o código para a outra aba de seu navegador e clique em Rebuild para ver o resultado.

import Playground exposing (..)

main =
  picture
   [ triangle green 100
       |> move -100 0
       |> rotate 45
   , triangle red 100
       |> move 100 0
       |> rotate -45
   ]

Fácil né?! Experimente mudar os número e veja o que acontece.

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar mais um pouco!

Siga para os desafios da Aula 3 e bons estudos.

Aula 3: Desafios

Para fixar o conhecimento é preciso praticar.

Nesta seção são propostos alguns desafios para você tentar fazer sozinho. É muuuito importante que você tente resolve-los antes de ver as respostas!

Antes de mais nada, abra o seguinte endereço em uma outra aba em seu navegador: htts://elm-lang.org/try.

DESAFIO 1 (fácil): Desenhe um carro.

Utilize um retângulo para representar o carro e dois círculos para representar suas rodas.
Utilize a instrução move para posicionar as rodas.

DESAFIO 2 (fácil): Desenhe uma árvore.

Utilize um retângulo marrom para representar o tronco e um círculo verde para representar as folhas.

DESAFIO 3 (avançado): Desenhe uma estrela.

Use triângulos para desenhar uma estrela de 6 pontas.

DESAFIO 4 (avançado): Desenhe um ônibus.

Tente incluir janelas, a frente do ônibus e tudo mais que desejar! Não existe uma resposta errada. Use a imaginação!

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 3: Resposta dos desafios

DESAFIO 1 (fácil): Desenhe um carro.

Utilize um retângulo para representar o carro e dois círculos para representar suas rodas.
Utilize a instrução move para posicionar as rodas.

Resposta

import Playground exposing (..)

main =
  picture
    [ rectangle darkGreen 450 150
    , circle darkRed 60
        |> move -100 -100
    , circle darkRed 60
        |> move 100 -100
    ]

DESAFIO 2 (fácil): Desenhe uma árvore.

Utilize um retângulo marrom para representar o tronco e um círculo verde para representar as folhas.

Resposta

import Playground exposing (..)

main =
  picture
    [ rectangle darkBrown 60 250
        |> move 0 -150
    , circle green 150
        |> move 0 50
    ]

DESAFIO 3 (avançado): Desenhe uma estrela.

Use triângulos para desenhar uma estrela de 6 pontas.

Resposta

import Playground exposing (..)

main =
   picture
     [ triangle blue 150
     , triangle blue 150
         |> rotate 180
     ]

DESAFIO 4 (avançado): Desenhe um ônibus.

Tente incluir janelas, a frente do ônibus e tudo mais que desejar! Não existe uma resposta errada. Use a imaginação!

Resposta

import Playground exposing (..)

main =
   picture
     [ circle black 40
         |> move -120 -90
     , circle gray 20
         |> move -120 -90
     , circle black 40
         |> move 120 -90
     , circle gray 20
         |> move 120 -90
     , rectangle yellow 500 180
     , square white 80
         |> move -190 0
     , square white 50
         |> move -100 0
     , square white 50
         |> move 0 0
     , square white 50
         |> move 100 0
     , square white 50
         |> move 200 0
     , square white 50
         |> move 200 0
     , rectangle black 15 10
         |> move -250 -85
     , square darkYellow 10
         |> move -250 -60
     , rectangle yellow 20 3
         |> move -270 -60
     , rectangle yellow 20 3
         |> move -270 -73
         |> rotate 40
     , rectangle yellow 20 3
         |> move -270 -47
         |> rotate -40
     ]

E agora?

Siga para a Aula 4 e bons estudos!

Aula 4 - Criando funções.

Esta aula será mais teórica, mas o que vamos aprender hoje é fundamental para entender todo o resto que está por vir. Então, bora entender o que é uma função?

O que você irá aprender nesta aula?

  1. O que é uma funcão?
    1.1 Funções matemáticas
    1.2 Funções na programação
  2. Como criar nossas próprias funções?
  3. Vantagens de criar funções

1- O que é uma função?

Conforme nosso código cresce, vai ficando cada vez mais difícil identificar o que significa cada uma de suas partes.
Por exemplo: no código que desenhamos um ônibus no desafio da aula 2, quanto mais detalhes colocávamos no desenho, maior ficava o main.
Mas afinal, o que é esse main? Ela é uma função.
Na linguagem de programação Elm, quase tudo que escrevemos são funcões! Isso por que ela é uma linguagem que segue o paradigma funcional. Existem vários tipos (paradigmas) de linguagens: Orientadas à Objetos, Imperativas, Lógicas e também as Funcionais.

1.1- Funções matemáticas

Provavelmente você já deve ter ouvindo falar em funções nas aulas de matemáticas na escola. Coisas como:

x = y + 2

Mas o que significa x = y + 2? Essencialmente significa que em qualquer lugar que tiver o simbolo x, podemos substitui-lo por y + 2, e vice versa. Por exemplo, se tivermos o seguinte conjunto de equações:

x = 5
y = 10
z = x + y

Para descobrirmos o valor de z, substituímos o valor de y e em seguida o de x.

Sendo a função z original:

z = x + y

Podemos primeiro substituir o valor de y:

z = x + 10

E em seguida o valor de x:

z = 5 + 10

Assim chegamos a conclusão que 15 é o único valor possíve de z.

1.2 Funções na programação

Em programação (em especial em linguagens funcionais, como Elm ou Haskell), o conceito de funcão é muito parecido.
No nosso exemplo anterior, o valor de z dependia de y e de x.
Podemos fazer algo similar com nossa função main, tornando-a dependente de outras funções menores e mais simples. Isso deixa o código muito mais fácil de compreender e alterar.

Achou confuso? Vai ficar mais fácil de entender com o exemplo a seguir.

2- Como criar nossas próprias funções?

Vamos partir de uma função que desenha uma árvore para então decompô-la em várias funções menores.

Função main original:

import Playground exposing (..)

main =
  picture
    [ rectangle darkBrown 60 250
        |> move 0 -150
    , circle green 150
        |> move 0 50
    ]

Podemos decompor nossa árvore colocando a definição de suas folhas em uma outra função:

import Playground exposing (..)

main =
  picture
      [ rectangle darkBrown 60 250
        |> move 0 -150
    , folhas
    ]

folhas =
  circle green 150
    |> move 0 50

Este novo código é equivalente ao anterior. Apenas extraí parte dela para outra funcão.

Para definirmos uma nova função, basta darmos um nome para ela (uma palavra qualquer, neste caso, folhas) seguida do simbolo =, da mesma forma que na matemática.
Tudo que estiver depois do símbolo de igual fará parte da nossa nova função.
Mas isso apenas define a função. Precisamos em seguida utilizá-la em um ou mais lugares do código.

Para utilizar uma função, assim como na matemática, basta escrever seu nome. No exemplo anterior a função folhas é utilizada como parte da função main.

É muito importante enteder este conceito. Analise com calma o código acima para ter certeza que compreendeu.

Dica: em Elm, a ordem em que as funções são definidas é irrelevante. Você pode definir primeiro a função main e depois a função folhas ou primeiro a função folhas e depois a main.

Agora vamos separar o tronco da árvore em uma outra função:

import Playground exposing (..)

main =
  picture
    [ tronco
    , folhas
    ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

Tente imaginar que a palavra folhas, dentro da função main, será substituida pelo conteúdo definido logo abaixo na função folhas. E o mesmo para a palavra tronco.

E podemos dar um passo além, se quisermos, e criar a função arvore:

import Playground exposing (..)

main =
  picture
    arvore

arvore =
  [ tronco
  , folhas
  ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

Neste último exemplo a função arvore retorna uma lista de formas geométricas contendo um tronco e uma folha.

3- Vantagens de criar funções

Existem duas grandes vantagens em dividir os códigos em várias funções.
A primeira é que torna mais fácil de expressar nossas intenções. Observe e compare a função main definida no primeiro e últimos exemplos. Desta última forma ficou muito mais explícito o que estamos tentando desenhar.

Outra grande vantagem de programar assim é que agora o tronco e folhas estão desacoplados.
Posso, por exemplo, reutilizar a função tronco para desenhar outros tipos de árvores ou criar um novo tipo de tronco e reaproveitar as folhas.
Em programação este é outro conceito muito importante: reaproveitamento de códigos.

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar um pouco!

Siga para os desafios da Aula 4 e bons estudos.

s## Aula 4: Desafios

DESAFIO 1 (fácil): Termine de desenhar o carro.

Abaixo temos um trecho incompleto de um código para desenhar um carro.
Escreva as três funções que estão faltando para desenhar o carro.

import Playground exposing (..)

main =
  picture
    carro

carro =
  [ carroceria
  , rodaFrontal
  , rodaTraseira
  ]

DESAFIO 2 (fácil): Desenhe frutas na árvore.

O código abaixo representa uma árvore sem frutas.

import Playground exposing (..)

main =
  picture
    arvore

arvore =
  [ tronco
  , folhas
  ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

Adione mais algumas funções para representar 4 frutas na árvore. As frutas podem ser simples esferas vermelhas.
Dica: A forma mais fácil é criar 4 novas funções: fruta1, fruta2, fruta3 e fruta4.
Na próxima aula vamos ver uma forma melhor para resolver este tipo de problema.

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 4: Resposta dos desafios

DESAFIO 1 (fácil): Termine de desenhar o carro.

Escreva as três funções que estão faltando para desenhar o carro.

Resposta

import Playground exposing (..)

main =
  picture
    carro

carro =
  [ carroceria
  , rodaFrontal
  , rodaTraseira
  ]

carroceria =
  rectangle darkGreen 450 150

rodaFrontal =
  circle darkRed 60
    |> move -100 -100

rodaTraseira =
  circle darkRed 60
     |> move 100 -100

DESAFIO 2 (fácil): Desenhe frutas na árvore.

Resposta

import Playground exposing (..)

main =
  picture
    [ tronco
    , folhas
    , fruta1
    , fruta2
    , fruta3
    , fruta4
    ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

fruta1 =
  circle red 20
    |> move 50 50

fruta2 =
  circle red 20
    |> move -40 20

fruta3 =
  circle red 20
    |> move -50 100

fruta4 =
  circle red 20
    |> move 40 130

Fácil né? Mas talvez você esteja se perguntando: Quando devemos criar uma nova função?
Perceber quando é uma boa ideia "quebrar" uma função em diversas pequenas funções é algo que aprendemos com a experiência.
Em geral, é uma boa ideia "quebrar" uma função em outras menores quando o código começa a ficar confuso e torna-se difícil distinguir qual parte do código faz o que.

Em breve vamos aprender a resolver este mesmo tipo de problema de formas mais elegantes, reaproveitando melhor o código.

E agora?

Siga para a Aula 5 e bons estudos!

Aula 5 - Passagem de parâmetros.

O que você irá aprender nesta aula?

  1. Passagem de parâmetro.
  2. Bibliotecas de software.
  3. Como criar suas próprias funções parametrizadas.
  4. Parâmetros nomeados.

1- Passagem de parâmetro

Como já disse em outras aulas, quase tudo em Elm são funções. Isso inclui as palavras circle, triangle, square, entre outras.
Quando digitamos por exemplo:

circle yellow 100

circle é o nome de uma função que tem dois parâmetros: uma cor e um diâmetro. Por isso, sempre que vamos criar um círculo, precisamos passar 2 argumentos (em ordem).

Esta função circle está definida dentro do Playground, que é uma biblioteca do Elm.

2- Bibliotecas de software

Ao desenvolvermos um software vamos nos deparar com vários problemas que outras pessoas já enfrentaram e solucionaram.
Nestes casos podemos reutilizar as soluções pré-existentes, facilitando assim nosso trabalho.
Por exemplo: desenhar um elemento na tela é uma tarefa recorrente e utilizada para vários programas diferentes.
Por isso, outra pessoa desenvolvedora já solucionou este problema e podemos nos aproveitar do trabalho dela para desenvolvermos o nosso programa.
Este conjunto de código escrito por outras pessoas é o que chamamos de bibliotecas. Até agora utilizamos uma biblioteca, a Playground, que contém funções que podemos utilizar para desenhar e animar figuras na tela.

3- Como criar suas próprias funções parametrizadas

As funções que definimos em nossos códigos também podem ter parâmetros.
Observe o exemplo abaixo e tente entender o que está acontecendo:

import Playground exposing (..)

main =
  picture
    [ tronco
    , folhas
    , fruta 50 50
    , fruta -40 20
    , fruta -50 100
    , fruta 40 130
    ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

fruta x y =
  circle red 20
    |> move x y

O resultado final é o mesmo que tínhamos no desafio da aula passada: uma árvore com frutas. Mas o código está menor e mais simples.
Além disso, agora é mais fácil criar novas frutas em nossa árvore!

Na função frutas definida no código acima, temos dois parâmetros: x e y.
Isso significa que sempre que formos utilizar esta função, vamos ter que passar 2 argumentos (valores).

Em algumas linguagens de programação precisamos especificar explicitamente qual o tipo de cada variável.
Em Elm isso não é necessário. A linguagem é esperta o suficiente para descobrir que x e y, neste caso, são números.

Observe também que dentro da função fruta repassamos os valores de x e y para outra função na seguinte linha:

move x y

4- Parâmetros nomeados

Embora em nosso exemplo o nome dos parâmetros sejam apenas um caracter, eles podem ser grandes e mais expressivos. Poderia ser, por exemplo:

fruta posicaoX posicaoY =
 circle red 20
   |> move posicaoX posicaoY

Dica: dar bons nomes para nossas variáveis e funções é uma das tarefas mais difíceis na programação! Por isso, reflita bastante antes de escolher um nome e, se necessário, troque por um mais descritivo sempre que achar que o código está ficando confuso.

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar mais um pouco!

Siga para os desafios da Aula 5 e bons estudos.

Aula 5: Desafios

DESAFIO 1 (fácil): Crie mais frutas.

import Playground exposing (..)

main =
  picture
    [ tronco
    , folhas
    , fruta 50 50
    , fruta -40 20
    , fruta -50 100
    , fruta 40 130
    ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

fruta x y =
  circle red 20
    |> move x y

Altere o código definido acima e crie mais três frutas em nossa árvore.

DESAFIO 2 (intermediário): Tamanho de folhas parametrizável.

No mesmo código do desafio 1, crie um parâmetro para a função folhas que represente o tamanho do círculo.
Tente aumentar e diminuir o tamanho do círculo.
Dica: Se você passar um valor muito grande ou muito pequeno provavelmente sua árvore ficará estranha, já que as folhas não estarão tocando o tronco. Não se preocupe com esses cenários por enquanto.

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 5: Resposta dos desafios

DESAFIO 1 (fácil): Crie mais frutas.

Resposta

Para resolvermos este desafio, bastava chamarmos a função fruta mais algumas vezes.

import Playground exposing (..)

main =
  picture
    [ tronco
    , folhas
    , fruta 50 50
    , fruta -40 20
    , fruta -50 100
    , fruta 40 130
    , fruta 10 10
    , fruta -10 -50
    , fruta 70 -40
    ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas =
  circle green 150
    |> move 0 50

fruta x y =
  circle red 20
    |> move x y

O que aconteceria se tentassemos desenhar frutas fora da árvore? Por enquanto não temos nenhuma forma de bloquear isso, mas em um sistema real, teríamos que pensar em formas de evitar que isso acontecesse.

DESAFIO 2 (intermediário): Tamanho de folhas parametrizável.

No mesmo código do desafio 1, crie um parâmetro para a função folhas que represente o tamanho do círculo.
Tente aumentar e diminuir o tamanho do círculo.
Dicas: Se você passar um valor muito grande ou muito pequeno provavelmente sua árvore ficará estranha. Não se preocupe com esses cenários por enquanto.

Resposta

Para resolver este desafio, criei um novo parâmetro na função folhas chamado diametro. Em seguida, repassei o valor desta variável ao acionar a função circle.

import Playground exposing (..)

main =
  picture
    [ tronco
    , folhas 150
    , fruta 50 50
    , fruta -40 20
    , fruta -50 100
    , fruta 40 130
    , fruta 10 10
    , fruta -10 -50
    , fruta 70 -40
    ]

tronco =
  rectangle darkBrown 60 250
    |> move 0 -150

folhas diametro =
  circle green diametro
    |> move 0 50

fruta x y =
  circle red 20
    |> move x y

E agora?

Siga para a Aula 6 e bons estudos!

Aula 6 - Sua primeira animação.

Esta aula será um pouco mais teórica pois você irá aprender os fundamentos para conseguir criar animações.

O que você irá aprender nesta aula?

  1. Como criar uma animação.
  2. O que é a função animation.
  3. Como rotacionar uma figura de acordo com o tempo.
    3.1 Entendendo melhor o controle do tempo.

1- Como criar uma animação.

Ao final desta aula, você será capaz de entender este código:

import Playground exposing (..)

main =
  animation view

view time =
    [ triangle red 100
          |> rotate (spin 8 time)
    ]

2. O que é a função animation.

animation (animação em inglês) é o nome da função que você deve acionar para que o computador entenda que o desenho que quer criar é uma imagem animada.

A função animation recebe um parâmetro diferente do que aprendeu nas aulas anteriores: ela espera que seja passado como argumento uma função. Ou seja, é uma função que recebe como parâmetro uma outra função.

Isso é algo que costuma gerar dúvidas. Em Elm (e também JavaScript e muitas outras linguagens de programação) isso é bastante comum: às vezes nossas funções vão receber valores como números ou textos, mas em outros casos receberá uma função como argumento.

No nosso exemplo a função animation está recebendo como argumento a função view (que significa vista ou ver em inglês).
Em Elm este costuma ser o nome padrão dado para a função onde iremos definir o que será exibido na tela.

Perceba que a função view recebe um parâmetro chamado time (que significa tempo ou hora em inglês).
Poderíamos dar qualquer outro nome mas, por convenção, este é o nome que costumamos usar neste parâmetro.

Através de uma animação podemos alterar o nosso desenho ao longo do tempo. Por isso, precisamos deste parâmetro para sabermos qual o valor atual do tempo e, assim, especificarmos como o desenho deve ser apresentado.

Pense assim: imagine que você chutou uma bola de futebol em linha reta. Conhecendo a direção que ela está indo e a intensidade do seu chute, como poderíamos saber qual a posição atual da bola? A resposta é: depende! Depende do tempo. Zero segundos após você chutar, ela ainda estará encostada em seu pé. Um segundo depois estará um pouco mais longe. Ou seja, para descobrirmos onde deveríamos desenhar esta bola precisaríamos saber o tempo decorrido desde o momento do seu chute.

Voltando para nosso código, a nossa função view será executada (automaticamente pelo computador) diversas vezes, e em cada execução o valor da variável time será diferente (contendo a hora atual no momento daquela execução).
É isso que permite que na primeira vez que esta função seja acionada nosso triângulo seja desenhado de uma forma e nas demais, conforme o valor da hora (time) muda, a forma como nosso triângulo é desenhado também.

Todas as animações deste curso serão feitas seguindo esta lógica: nossas funções vão precisamos do tempo (time) decorrido para saber qual o momento atual da animação.

3. Como rotacionar uma figura de acordo com o tempo.

Já havíamos utilizado a função rotate antes, para rotacionarmos as imagens. Como você deve lembrar, ela recebe um parâmetro com o ângulo que queremos rotacionar (um número entre -360 e 360). No nosso exemplo o valor passado como parâmetro é este:

rotate (spin 8 time)

A primeira obervação importante que preciamos fazer aqui é o uso dos parânteses. Se os retirarmos, nosso programa não vai funcionar.
Eles são importantes pois indicam para o computador que ele deve dar prioridade em resolver tudo que está dentro do parânteses para só em seguida pegar o resultado destas operações e usar o valor deste resultado como argumento da função rotate.
Você pode fazer uma associação com a matemática:

x = 2 * 1 + 1  
y = 2 * (1 + 1)  

No exemplo acima, x é igual a 3 e y é igual a 4.
Assim como na matemática, os parânteses são muito importantes na programação.

Voltando pro nosso exemplo, primeiro será avaliado o valor de spin 8 time para em seguida usar este valor como argumento para a função rotate.

Spin em inglês significa girar.
Você consegue imaginar o que ela faz? Pare e reflita um pouco antes de continuar lendo.

Mais uma vez, como quase tudo em Elm, spin é uma função. E como você deve ter observado, ela recebe dois parâmetros. O primeiro é o período, indicando quantos segundos deve demorar cada rotação da imagem. Quanto menor o valor, mais rápida será a velocidade de rotação. No nosso exemplo, este valor é 8. Isso significa que nosso triângulo irá rodar por completo 1 vez a cada 8 segundos.
O segundo parâmetro é o tempo decorrido. Em geral vamos apenas repassar o valor que já recebemos como argumento da nossa função. Quem controla o tempo é o computador e ele repassa esta informação pra gente.

3.1 Entendendo melhor o controle do tempo.

Nosso programa começa na função main. Mas quem aciona esta função? O computador! Ou mais tecnicamente falando, a runtime do Elm.

Neste nosso exemplo, a função main foi definida da seguinte forma:

main =
  animation view

A função animation em algum momento irá acionar a função view e, como já víamos antes, a função view recebe um parâmetro indicando o tempo (no nosso exemplo, o parâmetro time):

view time =

Você não precisa se preocupar com o controle desta variável, o computador vai fazer este trabalho pra você. Precisa apenas saber que irá receber este valor e o que ele representa.

Se toda esta explicação ficou muito confusa, não se preocupe! Tudo vai ficar mais claro conforme você treina.

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar um pouco!

Siga para os desafios da Aula 6 e bons estudos.

Aula 6: Desafios

DESAFIO 1 (fácil): alterando a velocidade.

import Playground exposing (..)

main =
  animation view

view time =
    [ triangle red 100
          |> rotate (spin 8 time)
    ]

Altere o código definido acima para que o triângulo gire 2x mais rápido.
Em seguida altere-o para que gire 2x mais lento.

DESAFIO 2 (intermediário): mais formas geométricas.

No mesmo código do desafio 1, adicione ao fundo do triângulo um quadrado amarelo. O quadrado deve girar 2x mais lento que o triângulo.

DESAFIO 3 (avançado): rotacionando no sentido horário.

Até agora nossas animações estão girando no sentido anti-horário (para esquerda). Altere o código do desafio 2 para que o triângulo gire no sentido horário (para direita) e o quadrado continue girando no sentido anti-horário.

DICAS:

  • Lembre-se que a função rotate pode receber valores positivos ou negativos. Valores positivos fazem com que a figura seja rotacionado no sentido anti-horário e valore negativos no sentido horário.
  • Para girar no sentido anti-horário o resultado do valor (spin 8 time) precisa ser negativo.

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 6: Resposta dos desafios

DESAFIO 1 (fácil): alterando a velocidade.

import Playground exposing (..)

main =
  animation view

view time =
    [ triangle red 100
          |> rotate (spin 8 time)
    ]

Altere o código definido acima para que o triângulo gire 2x mais rápido.
Em seguida altere-o para que gire 2x mais lento.

Resposta

Para que o triângulo gire 2x mais rápido, basta dividir pela metade o primeiro parâmetro do método spin. Lembre-se: o primeiro parâmetro indica quantos segundos vai demorar para que a figura faça uma rotação completa. Logo, quanto menor o tempo, mais rápido será a velocidade de rotação da figura.

Código com rotação 2x mais rápida:

import Playground exposing (..)

main =
  animation view

view time =
    [ triangle red 100
          |> rotate (spin 4 time)
    ]

Código com rotação 2x mais devagar:

import Playground exposing (..)

main =
  animation view

view time =
    [ triangle red 100
          |> rotate (spin 16 time)
    ]

DESAFIO 2 (intermediário): mais formas geométricas.

No mesmo código do desafio 1, adicione ao fundo do triângulo um quadrado amarelo. O quadrado deve girar 2x mais lento que o triângulo.

A nossa função view define uma lista de formas geométricas. Para adicionarmos um quadrado ao fundo do triângulo, basta declarmos um square no inicio da lista de formas geométricas.
Como queremos que ele rotacione na metade da velocidade, precisamos aplicar a transformação através da função rotate de forma similar ao que fizemos com o triângulo, mas passando um valor maior para a função spin, para que o intervalor de rotação seja maior.
Lembre-se que em uma lista, separamos os elementos através da vírgula.

Resposta

Vamos quebrar a resposta em 2 partes. Primeiro vamos adicionar o quadrado (square em inglês) ao fundo da imagem sem animação:

import Playground exposing (..)

main =
  animation view

view time =
    [ square yellow 300
    , triangle red 100
          |> rotate (spin 16 time)
    ]

Agora vamos completar o desafio, rotacionando nosso quadrado:

import Playground exposing (..)

main =
  animation view

view time =
    [ square yellow 300
          |> rotate (spin 16 time)
    , triangle red 100
          |> rotate (spin 8 time)
    ]

DESAFIO 3 (avançado): rotacionando no sentido horário.

Até agora nossas animações estão girando no sentido anti-horário (para esquerda). Altere o código do desafio 2 para que o triângulo gire no sentido horário (para direita) e o quadrado continue girando no sentido anti-horário.

DICAS:

  • Lembre-se que a função rotate pode receber valores positivos ou negativos. Valores positivos fazem com que a figura seja rotacionado no sentido anti-horário e valore negativos no sentido horário.
  • Para girar no sentido anti-horário o resultado do valor (spin 8 time) precisa ser negativo.

Resposta

Existem algumas formas de resolver este problema. Talvez a mais simples seja partirmos do valor 360 (graus) e subtraírmos deste valor o resultado da operação (spin 8 time).
Desta forma, quando o valor da operação (spin 8 time) for 0, vamos transformar este resultado em 360. E quando ele for 360, vamos transforma-lo em 0. Quando for 180, transformaremos em -180, e assim por diante.

Lembre-se de colocar um novo parênteses para que o valor seja calculado primeiro, caso contrário irá receber uma mensagem de erro.

import Playground exposing (..)

main =
  animation view

view time =
    [ square yellow 300
          |> rotate (spin 16 time)
    , triangle red 100
          |> rotate (360 - (spin 8 time))
    ]

E agora?

Siga para a Aula 6 e bons estudos!

Aula 7 - Fazendo movimentos de onda.

O que você irá aprender nesta aula?

  1. Como animar uma figura usando movimento ondular.
    1.1 A função wave.

1- Como animar uma figura usando movimento ondular.

Antes, vamos relembrar como desenhamos um círculo na tela:

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue 100 ]

Imagine que você queira criar uma animação nesta figura, fazendo com que ela fique "pulsando" (aumentando e diminuindo seu diâmetro ao longo do tempo).

No exemplo acima o diâmetro do círculo está fixo em 100. Para atingir seu objetivo, é preciso fazer com que este valor seja variável e mude de acordo com o tempo (aquela variável time que vimos na aula passada).

Uma das formas de implementar isso é utilizando uma função chamada wave (que significa onda em inglês).

Abra mais uma vez o site https://elm-lang.org/try, copie e execute o código a seguir.
Por enquanto não se preocupe em interpretar tudo, apenas veja o resultado para entender melhor o comportamento desta função.

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 50 100 7 time)
  ]

1.1 - A função wave.

Como você deve ter observado, agora é acionada a função wave e o resultado desta chamada irá definir o tamanho do diâmetro do círculo.

A função wave recebe 4 parâmetros. Os 2 primeiros correspondem ao valor mínimo e o tamanho máximo da onda. Já os 2 últimos parâmetros estão relacionados com a velocidade que os valores devem ser alterados.
Neste exemplo, o valor 7 indica quantos segundos deve demorar o ciclo total da anição (ou seja, o intervalo de tempo que deve transcorrer para que o valor varie entre o valor mínimo e o máximo e volte até o valor mínimo novamente). E e o time é a hora atual (que recebemos como parâmetro na função view e apenas repassamos o mesmo valor).

O valor de time será atualizado automaticamente e a função view será acionada muitas e muitas vezes, cada vez com um valor diferente para a variável time. Mas você não precisa se preocupar com ela: basta repassa-la como parâmetro para a função wave e ela saberá retornar qual deve ser o tamanho do circulo para o momento atual.

Agora releia o código anterior e tente entender melhor o que está acontecendo. Altere os valores 50, 100 e 7 para outros valores quaisquer e veja o resultado. Mas antes de executar, tente imaginar como ficará a animação.

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar mais um pouco!

Siga para os desafios da Aula 7 e bons estudos.

Aula 7: Desafios

DESAFIO 1 (fácil): alterando a velocidade.

Leia o código abaixo e tente imaginar o que irá aparecer na tela. E o que significam os valores 10, 100 e 12?

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 10 100 12 time)
  ]

Agora altere o código acima para que o círculo pulse 4 vezes mais rápido.
Em seguida, altere-o para que pulse 4 vezes mais lento que o código original.

DESAFIO 2 (fácil): Adicione um círculo dentro do outro.

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 10 100 10 time)
  ]

Inclua no código acima um novo círculo vermelho que fique estático/parado.
Este novo círculo deve ficar sob o círculo azul e deve ter um diâmetro igual a 200.

DESAFIO 2 (Intermediário): Crie 2 círculos pulsando.

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 20 80 2 time)
  ]

Altere o código acima para atender os seguintes critérios:

  • Mova o circulo para a esquerda em 200 unidades.
  • Crie um novo círculo azul com a mesma ondulação deste e o mova para direita em 200 unidades.

O resultado final esperado são dois círculos pulsando no mesmo ritmo, um ao lado do outro. Talvez dê para imaginarmos isso como sendo a animação de dois olhos piscando?

DESAFIO 3 (Avançado): Crie um triângulo entre os círculos.

Complemente o código do desafio 2 e crie um triângulo amarelo estático/parado entre os dois círculos.

Se imaginarmos que os círculos são 2 olhos, o triânulo seria como se fosse um nariz! Ele deve obedecer as seguintes regras:

  • Deve ser na cor amarela.
  • Deve ter um diâmetro igual a 50.
  • Deve ficar 75 unidades para baixo no eixo vertical (eixo y) em relação ao centro e bem no meio (0 unidades) no eixo vertical.
  • Deve ficar rotacionado de forma que a parte de cima seja plana e a parte de baixo forme um ângulo.

O resultado final esperado são dois círculos pulsando no mesmo ritmo, um ao lado do outro e um triângulo amarelo simulando um nariz. Ou talvez o bico de um pássado! Use sua imaginação :)

DESAFIO 4 (Avançado/livre): Desenhe a figura de uma animal.

Ao longo das aulas aprendemos como desenhar triângulos, círculos, retângulos e quadrados. Aprendemos também como rotacioná-los, posicioná-los na tela e hoje aprendemos nossa primeira forma de animação: movimento de ondulação (wave).

Use este conhecimento todo que você adquiriu até o momento e tente desenhar a figura de um animal qualquer na tela.

Se estiver sem inspiração, você pode tentar: desenha um pássaro, um macaco, um cachorro, um gato... não se preocupe em deixar o desenho perfeito. O importante é treinar!

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 7: Resposta dos desafios

DESAFIO 1 (fácil): alterando a velocidade.

Leia o código abaixo e tente imaginar o que irá aparecer na tela. E o que significam os valores 10, 100 e 12?

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 10 100 12 time)
  ]

Agora altere o código acima para que o círculo pulse 4 vezes mais rápido.
Em seguida, altere-o para que pulse 4 vezes mais lento que o código original.

Resposta

A parte do código 12 time é que define qual será a velocidade da animação. Lembre-se: quanto menor o valor, mais rápida será a animação.
Isso acontece pois este valor indica a quantidade de segundos que queremos que demore a animação completa. Quanto menor o tempo total da animação, mais rápida ela irá ser exibida.

Para que a animação ocorra 4 vezes mais rápido, basta dividirmos o valor 12 time por 4:

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 10 100 3 time)
  ]

Para que seja 4 vezes mais devagar, multiplicamos o valor original por 4:

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 10 100 48 time)
  ]

Agora nossa animação vai ficar beeeeem devagar, demorando 48 segundos para que termine o ciclo todo.

DESAFIO 2 (fácil): Adicione um círculo dentro do outro.

Inclua no código acima um novo círculo vermelho que fique estático/parado. Este novo círculo deve ficar sob o círculo azul e deve ter um diâmetro igual a 200.

Resposta

Desta vez bastava adicionarmos um círculo vermelho na lista de figuras:

import Playground exposing (..)

main =
  animation view

view time =
  [ circle red 200
    , circle blue (wave 20 100 10 time)
  ]

DESAFIO 2 (Intermediário): Crie 2 círculos pulsando.

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 20 80 2 time)
  ]

Altere o código acima para atender os seguintes critérios:

  • Mova o circulo para a esquerda em 200 unidades.
  • Crie um novo círculo azul com a mesma ondulação deste e o mova para direita em 200 unidades.

O resultado final esperado são dois círculos pulsando no mesmo ritmo, um ao lado do outro. Talvez dê para imaginarmos isso como sendo a animação de dois olhos piscando?

Resposta

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 20 80 2 time)
      |> move -200 0
    , circle blue (wave 20 80 2 time)
      |> move 200 0
  ]

DESAFIO 3 (Avançado): Crie um triângulo entre os círculos.

Complemente o código do desafio 2 e crie um triângulo amarelo estático/parado entre os dois círculos.

Se imaginarmos que os círculos são 2 olhos, o triânulo seria como se fosse um nariz! Ele deve obedecer as seguintes regras:

  • Deve ser na cor amarela.
  • Deve ter um diâmetro igual a 50.
  • Deve ficar 75 unidades para baixo no eixo vertical (eixo y) em relação ao centro e bem no meio (0 unidades) no eixo vertical.
  • Deve ficar rotacionado de forma que a parte de cima seja plana e a parte de baixo forme um ângulo.

O resultado final esperado são dois círculos pulsando no mesmo ritmo, um ao lado do outro e um triângulo amarelo simulando um nariz. Ou talvez o bico de um pássado! Use sua imaginação :)

Resposta

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue (wave 20 80 2 time)
      |> move -200 0
    , circle blue (wave 20 80 2 time)
      |> move 200 0
    , triangle yellow 50
      |> move 0 -100
      |> rotate 180
  ]

DESAFIO 4 (Avançado/livre): Desenhe a figura de uma animal.

Ao longo das aulas aprendemos como desenhar triângulos, círculos, retângulos e quadrados. Aprendemos também como rotacioná-los, posicioná-los na tela e hoje aprendemos nossa primeira forma de animação: movimento de ondulação (wave).

Use este conhecimento todo que você adquiriu até o momento e tente desenhar a figura de um animal qualquer na tela.

Se estiver sem inspiração, você pode tentar: desenha um pássaro, um macaco, um cachorro, um gato... não se preocupe em deixar o desenho perfeito. O importante é treinar!

Resposta

Este era um desafio livre e, portanto, não tem respostas certas ou erradas :)

E agora?

Siga para a Aula 8 e bons estudos!

Aula 8 - Fazendo movimentos de zigzag.

O que você irá aprender nesta aula?

  1. Como animar uma figura usando movimento de zigzag.
    1.1 A função zigzag.

1- Como animar uma figura usando movimento de zigzag.

Vamos partir do desenho de um círculo na tela, deslocando-o um pouco para esquerda.

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue 100 
        |> move -200 0
  ]

Imagine que você queira criar uma animação nesta figura, fazendo com que ela fique fazendo "zigzag" (alternando sua direção).

No exemplo acima a posição do círculo está fixa em -200 no eixo horizontal e 0 no vertial.
Para fazer o movimento de "zigzag", este valor precisa ser alterado conforme o tempo passa (aquela variável time que você conheceu na aula passada).

Para, por exemplo, criar uma animação onde o círculo fique se movendo da esquerda para direita, é necessário variar sua posição na horizontal. Ou seja, substituir o valor -200 por um valor que se altere de forma linear ao longo do tempo. E a função zigzag cumpre justamente esta tarefa.

1.1 - A função zigzag.

zigzag é uma função parecida com a wave. Ela também recebe quatro parâmetros, sendo que os dois primeiros indicam os valores mínimo e máximo e o terceiro indica a quantidade de segundos que a animação deve demorar para completar.

Agora que você já conhece a função zigzag e sua finalidade, consegue imaginar como seria o código para que um círculo fique se movendo da esquerda para direita entre a posição -200 e 200 em um intervalo de 5 segundos?

import Playground exposing (..)

main =
  animation view

view time =
  [ circle blue 100 
        |> move (zigzag -200 200 5 time) 0
  ]

Mais uma vez, você não podem esquecer os parênteses, já que o primeiro parâmetro da função move deve ser o resultado da função zigzag. Para isso, é preciso indicar para o computador (através do uso dos parênteses) que você quer primeiro processar e calcular o valor da função zigzag para em seguida processar a função move.

E aí? Já está começando a imaginar as possibilidades para criar animações mais complexas e quem sabe até jogos com essas funções? 😃

E agora?

Agora chegou a hora de você colocar as mãos na massa e praticar mais um pouco!

Siga para os desafios da Aula 8 e bons estudos.

Aula 8: Desafios

DESAFIO 1 (fácil): Movendo na vertical.

Altere o código abaixo para que o quadrado se mova na vertical (de cima para baixo) variando sua posição no eixo y entre -100 e 100.
A animação deve demorar 2 segundos para completar o ciclo.

import Playground exposing (..)

main =
  animation view

view time =
  [ square darkGreen 100 
        |> move -0 0
  ]

DESAFIO 2 (fácil): Movendo na diagonal.

Altere o código do exercício 1 para que o quadrado se mova na diagonal. O movimento deve começar no ponto -100, -100 e terminar em 100, 100.

DESAFIO 3 (livre): Misture movimentos.

Utilizando as funções zigzag e wave, desenhe figuras se movendo pela tela.
Você pode animar as rodas de um carro, os olhos de um animal, ou simplesmente desenhar várias figuras se movendo freneticamente pela tela! Use a imaginação.

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 8: Desafios

DESAFIO 1 (fácil): Movendo na vertical.

Altere o código abaixo para que o quadrado se mova na vertical (de cima para baixo) variando sua posição no eixo y entre -100 e 100.
A animação deve demorar 2 segundos para completar o ciclo.

import Playground exposing (..)

main =
  animation view

view time =
  [ square darkGreen 100 
        |> move -0 0
  ]

Resposta

Basta fixar o eixo x sempre no valor 0 e deixar o eixo y variando entre -100 e 100 usando a função zigzag.

import Playground exposing (..)

main =
  animation view

view time =
  [ square darkGreen 100 
        |> move 0 (zigzag -100 100 2 time)
  ]

DESAFIO 2 (fácil): Movendo na diagonal.

Altere o código do exercício 1 para que o quadrado se mova na diagonal. O movimento deve começar no ponto -100, -100 e terminar em 100, 100.

Resposta

Existem algumas formas de resolver este exercício.
A mais simples seria replicarmos a mesma chamada que usamos no eixo y do exercício anterior para o eixo x. Assim, movemos os 2 eixos sempre da mesma forma, tendo como resultado o movimento na diagonal.

import Playground exposing (..)

main =
  animation view

view time =
  [ square darkGreen 100 
        |> move (zigzag -100 100 2 time) (zigzag -100 100 2 time)
  ]

DESAFIO 3 (livre): Misture movimentos.

Utilizando as funções zigzag e wave, desenhe figuras se movendo pela tela.
Você pode animar as rodas de um carro, os olhos de um animal, ou simplesmente desenhar várias figuras se movendo freneticamente pela tela! Use a imaginação.

Repostas

Exercícios livres não possuem respostas certas ou erradas! O importante é praticar e se divertir.

E agora?

Siga para a Aula 9 e bons estudos!

Aula 9 - Entendendo o que são os Records.

Quando você tem muitas informações em seus programas, precisa começar a se preocupar em como organiza-las.

Você já aprendeu a criar listas usando os símbolos [ e ]. Esta é uma das formas de organizar. Outra é através dos Records.

Esta aula será bastante teórica, mas você precisa entender alguns conceitos importantes para conseguir dar continuidade aos estudos.

O que você irá aprender nesta aula?

  1. O que são os Records.
  2. Como criar uma função que recebe um Record como parâmetro.

1- O que são os Records.

Record é uma forma de organizar nossos dados na linguagem de programação Elm.

Vamos partir de um código criado sem o uso de Records para entender o tipo de problemas que possivelmente vamos enfrentar.

Com o que aprendemos até agora, para criar uma função que recebe como parâmetro um ponto no espaço, passamos dois argumentos numéricos separados: x e y, como no exemplo abaixo:

import Playground exposing (..)

main =
  picture
  [ circuloVerde 10 20
  ]

circuloVerde x y =
  circle green 50
    |> move x y

Você consegue entender o que está acontecendo no código acima?
Caso tenha dificuldades, volte para a aula 4 para revisar como criar uma função parametrizada.

Neste exemplo nossa função circuloVerde recebe dois parâmetros numéricos que chamamos de x e y. Neste caso isso é suficiente e funciona bem. Mas podemos fazer de uma outra maneira: podemos criar uma estrutura (ou um Record) que representa um Ponto. A ideia é deixar mais explícito no código o que essa informação representa.

Então Record é uma estrutura de dados com rótulos. Abaixo temos um exemplo de um Record.

{ x = 10, y = 15 }

Na linguagem Elm, tudo que estiver entre { e } é um record.

2. Como criar uma função que recebe um Record como parâmetro.

Podemos agora alterar o código anterior para que nossa função circuloVerde receba um Record:

import Playground exposing (..)

main =
  picture
  [ circuloVerde {x = 10, y = 20}
  ]

circuloVerde {x, y} =
  circle green 50
    |> move x y

Se preferirmos, podemos também armazenar estes valores em uma variável, como no exemplo abaixo:

import Playground exposing (..)

posicao = {x = 10, y = 20}

main =
  picture
  [ circuloVerde posicao
  ]

circuloVerde {x, y} =
  circle green 50
    |> move x y

Agora ficou um pouco mais claro o que significa o 10 e o 20, mas podemos dar um passo além. É possível dar um nome (um alias) para esta estrutura.

Criando um alias.

No código abaixo definimos o que é um Ponto2D. Podemos dar um qualquer nome, mas ele deve começar obrigatóriamente com uma letra maiúscula.

type alias Ponto2D =
  { x : Number 
  , y : Number
  }

Neste código, explicamos para o computador que um Ponto2D é uma estrutura de dados que contém dois campos: o x e o y. Desta vez também avisamos o computador que estes campos devem armazer dados do tipo Number (número em inglês).

A linguagem de programação Elm possui uma série de tipos de dados que podemos utilizar. Alguns exemplos são: Number, Int, String, Bool, List, Float, entre outras. Mas não se preocupe em decorar isso! Ao longo do curso vamos aprender quando utilizá-las.

Ao criar um novo alias Ponto2D apenas definirmos o que ele representa, mas ainda não criamos um ponto efetivamente. A linguagem Elm automatizamente disponibilizará uma nova função chamada Ponto2D (esperando os respectivos parâmetros definidos no alias), que chamamos de construtor (ou Type Constructor - Construtor de Tipos em inglês). Acionando esta função podemos construir um novo ponto:

import Playground exposing (..)

type alias Ponto2D =
  { x : Number 
  , y : Number
  }

posicao = Ponto2D 10 20

main =
  picture
  [ circuloVerde posicao
  ]

circuloVerde {x, y} =
  circle green 50
    |> move x y

Neste exemplo a função circuloVerde continua recebendo um Record de forma mais simples, usando as chaves. Mas podemos ir além e dar um mome para este parâmetro:

import Playground exposing (..)

type alias Ponto2D =
  { x : Number 
  , y : Number
  }

posicao = Ponto2D 10 20

main =
  picture
  [ circuloVerde posicao
  ]

circuloVerde ponto =
  circle green 50
    |> move ponto.x ponto.y

Agora ficou muito claro na nossa função circuloVerde que o parâmetro esperado é um ponto e que este ponto possui dois campos (x e y) e que ambos são números. Para acessar estes campos utilizamos o símbolo de ponto final. Logo, para acessar o campo x basta digitar ponto.x.

Conclusão

É provável que você esteja se perguntando o por que disso tudo! Esta nova versão do nosso código é maior e talvez um pouco mais confusa. E eu diria que... você está certa! Neste exemplo, complicamos uma solução que era simples e isso não é uma boa prática. Mas precisei fazer isso para explicar os conceitos pra você. Em outras situações o uso de Records irá simplificar muito o código. Por isso é muito importante entender este conceito.

E agora?

Esta aula foi bastante teórica, então chegou a hora de você colocar as mãos na massa e praticar mais um pouco!

Siga para os desafios da Aula 9 e bons estudos.

Aula 9: Desafios

DESAFIO 1 (fácil): abstraindo o conceito de Árvore.

Observe o código abaixo e tente entender o que está acontecendo.

import Playground exposing (..)

type alias Arvore =
  { altura : Number 
  , largura : Number
  , raioCopa: Number
  }

minhaArvore = Arvore 150 40 75

main =
  picture (desenharArvore minhaArvore)

-- Esta função está incompleta.
desenharArvore arvore =
  [ circle green arvore.raioCopa
  ]

Você consegue imaginar o que vai acontecer ao executar este código?

Utilizando um type alias estamos primeiro explicando para o computador o que é uma árvore. Neste caso uma árvore é formada por 3 campos: altura, largura e raioCopa. Os dois primeiros representam informações do tronco e o último da copa/folhas.
Com estas informações somos capazes de, a partir desta estrutura, desenharmos árvores parecidas com as que fizemos na aula 3e aula 4 deste curso.

Como deve ter observado, a função desenharArvore está incompleta e estamos desenhando apenas a copa/folhas de nossa árvore.

Antes de continuar, abra o seguinte endereço em uma outra aba em seu navegador: htts://elm-lang.org/try e execute o código definido mais acima.

Agora altere a função desenharArvore para que ela desenhe também o tronco de nossa árvore.

DESAFIO 2 (difícil): desenhando olhos.

Vamos criar uma maneira de desenhar olhos na tela de forma parametrizada.

Você deve criar uma função chamada olho que irá receber como parâmetro um Record. Para isso, crie um type alias chamado Posicao contendo os campos x e y, ambos do tipo Number.

A função olho deve retornar uma lista de círculos que representará um olho na tela. Nosso olho será composto por pelo menos 2 círculos, um dentro do outro. Use sua imaginação para desenha-lo!

Em seguida crie 2 outras funções chamadas olhoEsquerdo e olhoDireito. Estas funções devem acionar a função olho passando a posição dos olhos. O olho esquerdo deve ser desenhado a partir do ponto (-100, 20) e o olho direito a partir do ponto (100, 20).

Por último a sua função main deve acionar as funções olhoEsquerdo e olhoDireito para desenhar as figuras na tela.

Dica: ambas as funções olhoEsquerdo e olhoDireito retornam uma lista de figuras. Será necessário juntar estas duas listas em uma só antes de acionar a função main (que espera uma única lista de figuras). Para fazer isso você pode usar o simbolo ++. Exemplo:

numerosPequenos = [1,2,3]
numerosGrandes = [100,101,102]
listaDeNumeros = numerosPequenos ++ numerosGrandes

No código acima, listaDeNumeros irá conter a seguinte lista: [1,2,3,100,101,102]

Teste resolver o exercício. Caso tenha muita dificuldade você pode seguir a estrutura criada abaixo:

import Playground exposing (..)

type alias Posicao =
  -- defina aqui os campos x e y

olhoEsquerdo = 
  -- aqui você deve acionar a função olho (lembre-se dos parânteses!)

olhoDireito =
  -- aqui você deve acionar a função olho novamente

main =
  -- Passe como parâmetro da função picture o resultado da concatenação 
  -- do resultado das função olhoEsquero e olhoDireito.
  picture

olho posicao =
  [ -- desenhe aqui um olho usando pelo menos 2 círculos.
  ]

DESAFIO 3 (livre): desenhando o restante do rosto.

Crie outras função para demais partes do rosto. Por exemplo: nariz, orelha, boca, sombrancelha... use a imaginação!

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 9: Desafios

DESAFIO 1 (fácil): abstraindo o conceito de Árvore.

Observe o código abaixo e tente entender o que está acontecendo.

import Playground exposing (..)

type alias Arvore =
  { altura : Number 
  , largura : Number
  , raioCopa: Number
  }

minhaArvore = Arvore 150 40 75

main =
  picture (desenharArvore minhaArvore)

-- Esta função está incompleta.
desenharArvore arvore =
  [ circle green arvore.raioCopa
  ]

Você consegue imaginar o que vai acontecer se executarmos este código?

Utilizando um type alias estamos primeiro explicando para o computador o que é uma árvore. Neste caso, uma árvore é formada por 3 campos: altura, largura e raioCopa. Os dois primeiros representam informações do tronco e o último da copa/folhas.
Com estas informações somos capazes de, a partir desta estrutura, desenharmos árvores parecidas com as que fizemos na aula 3e aula 4 deste curso.

Como deve ter observado, a função desenharArvore está incompleta e estamos desenhando apenas a copa/folhas de nossa árvore.

Antes de continuar, abra o seguinte endereço em uma outra aba em seu navegador: htts://elm-lang.org/try e execute o código definido mais acima.

Agora altere a função desenharArvore para que ela desenhe também o tronco de nossa árvore.

Resposta

Existem várias várias formas de resolver este desafio. A parte mais difícil não tem a ver com programação, mas com matemática! :)

Precisamos definir onde será desenhado o retângulo que representa o tronco de nossa árvore e, dessa vez, este valor é parametrizado. Desenhar o retângulo é a parte fácil:

import Playground exposing (..)

type alias Arvore =
  { altura : Number 
  , largura : Number
  , raioCopa: Number
  }

minhaArvore = Arvore 100 20 50

main =
  picture (desenharArvore minhaArvore)

desenharArvore arvore =
  [ circle green arvore.raioCopa
  , rectangle darkBrown arvore.largura arvore.altura
  ]

Mas se executarmos este código, vamos ver que o tronco é desenhado em cima das folhas. Precisamos move-lo para baixo para que fique na borda do círculo.

Aqui, você poderia ter adotado diferentes estratégias. Eu optei por calcular o ponto exato onde termina o círculo para mover meu tronco até este local. Para isso preciso somar 2 valores: o raio do círculo mais metade da altura do tronco. Desta forma o tronco ficará posicionado exatamente no final das folhas:

import Playground exposing (..)

type alias Arvore =
  { altura : Number 
  , largura : Number
  , raioCopa: Number
  }

minhaArvore = Arvore 150 40 75

main =
  picture (desenharArvore minhaArvore)

desenharArvore arvore =
  [ circle green arvore.raioCopa
  , rectangle darkBrown arvore.largura arvore.altura
    |> move 0 -(arvore.raioCopa + (arvore.altura / 2))
  ]

DESAFIO 2 (difícil): desenhando olhos.

Vamos criar uma maneira de desenhar olhos na tela de forma parametrizada.

Você deve criar uma função chamada olho que irá receber como parâmetro um Record. Para isso, crie um type alias chamado Posicao contendo os campos x e y, ambos do tipo Number.

A função olho deve retornar uma lista de círculos que representará um olho na tela. Nosso olho será composto por pelo menos 2 círculos, um dentro do outro. Use sua imaginação para desenha-lo!

Em seguida crie 2 outras funções chamadas olhoEsquerdo e olhoDireito. Estas funções devem acionar a função olho passando a posição dos olhos. O olho esquerdo deve ser desenhado a partir do ponto (-100, 20) e o olho direito a partir do ponto (100, 20).

Por último a sua função main deve acionar as funções olhoEsquerdo e olhoDireito para desenhar as figuras na tela.

Dica: ambas as funções olhoEsquerdo e olhoDireito retornam uma lista de figuras. Será necessário juntar estas duas listas em uma só antes de acionar a função main (que espera uma única lista de figuras). Para fazer isso você pode usar o simbolo ++. Exemplo:

numerosPequenos = [1,2,3]
numerosGrandes = [100,101,102]
listaDeNumeros = numerosPequenos ++ numerosGrandes

No código acima, listaDeNumeros irá conter a seguinte lista: [1,2,3,100,101,102]

Teste resolver o exercício. Caso tenha muita dificuldade você pode seguir a estrutura criada abaixo:

import Playground exposing (..)

type alias Posicao =
  -- defina aqui os campos x e y

olhoEsquerdo = 
  -- aqui você deve acionar a função olho (lembre-se dos parânteses!)

olhoDireito =
  -- aqui você deve acionar a função olho novamente

main =
  -- Passe como parâmetro da função picture o resultado da concatenação 
  -- do resultado das função olhoEsquero e olhoDireito.
  picture

olho posicao =
  [ -- desenhe aqui um olho usando pelo menos 2 círculos.
  ]

Resposta

Existem infinitas formas de resolver este exercício! O importante é praticar. Abaixo deixo como o exemplo a minha resposta. Nela, usei 3 círculos para representar cada olho.

import Playground exposing (..)

type alias Posicao =
  { x : Number
  , y : Number
  }

olhoEsquerdo = 
  olho (Posicao -100 20)

olhoDireito =
  olho (Posicao 100 20)
main =
  picture (olhoEsquerdo ++ olhoDireito)

olho posicao =
  [ circle gray 50 
    |> move posicao.x posicao.y
  , circle black 20
    |> move (posicao.x - 10) (posicao.y - 5)
  , circle white 5
    |> move (posicao.x - 15) (posicao.y - 8)
  ]

DESAFIO 3 (livre): desenhando o restante do rosto.

Crie outras função para demais partes do rosto. Por exemplo: nariz, orelha, boca, sombrancelha... use a imaginação!

Repostas

Exercícios livres não possuem respostas certas ou erradas! O importante é praticar e se divertir.

E agora?

Este curso ainda está sendo criado e por enquanto possui uma quantidade reduzida de aulas. Novas aulas vão ser publicadas ao longo das próximas semanas!

Gostou da ideia deste projeto? Quer mandar alguma sugestão ou tirar alguma dúvida? Entre em contato com o autor enviando um e-mail para marcio@segunda.tech.

Aula 10 - True, False e condicionais.

O que você irá aprender nesta aula?

  1. Pra que servem as condicionais?
  2. Usando condicionais.
  3. Tornando o código mais legível.

1- Pra que servem as condicionais?

Imagine que você esteja desenvolvendo um jogo de plataforma 2D, parecido com o da imagem abaixo.

Imagem do jogo SuperTux

As regras de um jogo vão impor certas condições. Por exemplo:

Se a jogadora encostar em uma moeda, então:
    a moeda deve desaparecer e
    a quantidade de moedas que a jogadora possui deve ser incrementado em 1.
Senão:
    a moeda deve continuar aparecendo e
    a quantidade de moedas deve permanecer a mesma.

Podemos separar o exemplo acima em 3 partes:

  • A condição, que pode ser Verdadeira (true em inglês) ou Falsa (false em inglês);
  • As consequências caso aquela condição seja verdadeira e;
  • As consequências caso a condição seja falsa.

Sem as condicionais seria inviável aplicarmos as nossas regras e a personagem principal nunca iria perder ou ganhar. Assim, nosso jogo seria muito chato!

2- Usando condicionais.

A forma mais simples de criarmos uma condição é utilizando o if (que significa se, em inglês).

Vamos supor que precisamos fazer uma condição para saber se nosso jogo deve ou não continuar. A regra deve ser: Se a jogadora tive mais de 0 vidas, então o jogo deve continuar. Senão, devemos interromper o jogo.

Para simplificar nossa implementação caso a condição indique que o jogo deve continuar exibiremos um círculo verde na tela. Caso não deva continuar, exibiremos um círculo vermelho.

Vamos começar desenhando um círculo vermelho no centro da tela:

import Playground exposing (..)

main =
  picture [
    circle red 100
  ]

Por enquanto desenhamos sempre um círculo vermelho. Precisamos agora adicionar uma condição. Mas antes, vamos criar uma variável onde iremos definir qual a quantidade de vidas da jogadora:

import Playground exposing (..)

quantidadeDeVidas = 1

main =
  picture [
    circle red 100
  ]

Pronto! Agora temos tudo que precisamos para criar nossa condicional. Caso a quantidadeDeVidas contenha um valor maior que 1, desenhamos um cículo verde. Caso contrário, um cículo vermelho.

import Playground exposing (..)

quantidadeDeVidas = 1

main =
  picture [ 
    if quantidadeDeVidas > 0 then
      circle green 100 
    else 
      circle red 100
  ]

Note que sempre que definirmos uma condição (if) colocamos em seguida a palavra then (que significa então em inglês) e por último, definimos um segundo bloco, utilizando a palavra else (senão em inglês).

O tipo do conteúdo que é definido entre as palavras then e else e o conteúdo definido a partir da palavra else precisam ser iguais. Neste caso, ambos são uma figura.

Experimente mudar o valo da quantidadeDeVidas para 0 ou -1 e execute o programa novamente.

3- Tornando o código mais legível.

No nosso exemplo talvez seja fácil uma outra pessoa olhar a seguinte linha de código e entender nossa intenção:

if quantidadeDeVidas > 0 then

Mas é comum que nossas regras condicionais fiquem bem mais complexas que isso. E é muito importante que outras pessoas entendam o que motivou a criação daquela condição.

Nestes cenários é recomendado extrairmos esta parte do código para uma função. Assim, podemos deixar mais explicito qual a real intenção daquela condição, como no exemplo abaixo.

import Playground exposing (..)

quantidadeDeVidas = 1

jogadoraAindaPossuiVidas =
  quantidadeDeVidas > 0

main =
  picture [ 
    if jogadoraAindaPossuiVidas then
      circle green 100 
    else 
      circle red 100
  ]

Neste último exemplo, a função jogadoraAindaPossuiVidas irá retornar true caso quantidadeDeVidas seja superior a 0 e false caso contrário.

Existem várias formas de organizar este código. Esta é apenas uma delas.

E agora?

Esta aula foi bastante teórica, então chegou a hora de você colocar as mãos na massa e praticar mais um pouco!

Siga para os desafios da Aula 10 e bons estudos.

Aula 10: Desafios

DESAFIO 1 (intermediário): Desenhando um balão.

O código abaixo desenha um balão verde na tela.

Execute o código para ver seu resultado.

import Playground exposing (..)

tamanhoDoFioDoBalao = 50

larguraDoFioDoBalao = 3

corDoBalao = green

raioDoMeuBalao = 60

main =
  picture
   (balao raioDoMeuBalao)


balao raio =
  [ circle corDoBalao raio
  , rectangle lightRed larguraDoFioDoBalao tamanhoDoFioDoBalao
    |> move 0 (-raio - (tamanhoDoFioDoBalao / 2))
  ]

Desta vez optei por definir os valores em variáveis, para poder dar nomes e tornar assim o seu significado mais explícito.

Eu admito, meu balão não se parece muito um balão, mas... tente usar sua imaginação! ;)

A parte mais difícil deste código provavelmente é a seguinte linha:

|> move 0 (-raio - (tamanhoDoFioDoBalao / 2))

Já vimos um código muito parecido com esse nos desafios da aula 9. Não se preocupe se ainda não conseguir entendê-lo muito bem. Tudo que está fazendo é apenas posicionar o fio do balão em sua parte inferior.

Agora altere o código anterior para que o balão tenha a cor verde (green) se o seu raio for inferior a 50 e a cor vermelha caso seu raio supere este valor.

DESAFIO 2 (intermediário): Adicionando mais uma cor.

Altere a sua resposta do exercício anterior para contemplar uma terceira cor, obedecendo as seguintes regras:

  • O balão deve ser verde (green) caso tenha um raio inferior a 50;
  • O balão deve ser da cor amarela (yellow) caso tenha um raio superior ou igual a 50 e inferior a 65;
  • O balão deve ser da cor vermelha (red) caso tenha um raio superior a 65.

Depois de escrever o código, altere o valor de raioDoMeuBalao para que ele fique primeiro verde, depois amarelo e por último vermelho.

E agora?

Conseguiu fazer todos os exercícios? Teve dificuldade em algum?

Siga para as respostas dos desafios para ver a solução.

Aula 10: Desafios

DESAFIO 1 (intermediário): Desenhando um balão.

O código abaixo desenha um balão verde na tela.

Execute o código para ver seu resultado.

import Playground exposing (..)

tamanhoDoFioDoBalao = 50

larguraDoFioDoBalao = 3

corDoBalao = green

raioDoMeuBalao = 60

main =
  picture
   (balao raioDoMeuBalao)


balao raio =
  [ circle corDoBalao raio
  , rectangle lightRed larguraDoFioDoBalao tamanhoDoFioDoBalao
    |> move 0 (-raio - (tamanhoDoFioDoBalao / 2))
  ]

Desta vez optei por definir os valores em variáveis, para poder dar nomes e tornar assim o seu significado mais explícito.

Eu admito, meu balão não se parece muito um balão, mas... tente usar sua imaginação! ;)

A parte mais difícil deste código provavelmente é a seguinte linha:

|> move 0 (-raio - (tamanhoDoFioDoBalao / 2))

Já vimos um código muito parecido com esse nos desafios da aula 9. Não se preocupe se ainda não conseguir entendê-lo muito bem. Tudo que está fazendo é apenas posicionar o fio do balão em sua parte inferior.

Agora altere o código anterior para que o balão tenha a cor verde (green) se o seu raio for inferior a 50 e a cor vermelha caso seu raio supere este valor.

Resposta

Precisamos alterar a função corDoBalao para que ela receba o valor do raio como parâmetro. Assim, fica fácil altermos esta função para que ela retorne green caso este valor seja inferior a 50 e red caso seja igual ou superior a este número.

import Playground exposing (..)

tamanhoDoFioDoBalao = 50

larguraDoFioDoBalao = 3

corDoBalao raio = 
  if raio < 50 then
    green
  else 
    red

raioDoMeuBalao = 60

main =
  picture
   (balao raioDoMeuBalao)


balao raio =
  [ circle (corDoBalao raio) raio
  , rectangle lightRed larguraDoFioDoBalao tamanhoDoFioDoBalao
    |> move 0 (-raio - (tamanhoDoFioDoBalao / 2))
  ]

Uma parte do código que talvez você tenha tido dificuldades para entender é esta aqui:

circle (corDoBalao raio) raio

Consegue entender por que temos duas referências ao raio nesta linha?

Na primeira estamos apenas passando o seu valor para a função corDoBalao, que agora precisa desta informação para decidir qual será a cor do nosso balão. O retorno da execução de (corDoBalao raio) será uma cor: ou green ou red. Este retorno será usado como sendo o primeiro argumento da função circle.
Já o raio que aparece no final da linha é o segundo argumento que também será passado para a função circle.

Experimente alterar o valor da variável raioDoMeuBalao e veja o que acontece quando este valor é inferior a 50.

DESAFIO 2 (intermediário): Adicionando mais uma cor.

Altere a sua resposta do exercício anterior para contemplar uma terceira cor, obedecendo as seguintes regras:

  • O balão deve ser verde (green) caso tenha um raio inferior a 50;
  • O balão deve ser da cor amarela (yellow) caso tenha um raio superior ou igual a 50 e inferior a 65;
  • O balão deve ser da cor vermelha (red) caso tenha um raio superior a 65.

Depois de escrever o código, altere o valor de raioDoMeuBalao para que ele fique primeiro verde, depois amarelo e por último vermelho.

Resposta

Para resolver este exerício precisamos criar uma condição dentro da outra. Primeiro verificamos se o valor é inferior a 50. Se for, já sabemos que a cor é verde.
Caso contrário, é necessário fazer uma segunda verificação: precisamos saber se é inferior a 65.
Se neste momento o valor for inferior a 65, sabemos que ele é um número entre 50 e 65, afinal, já havíamos feito a primeira validação (se era inferior a 50) antes.
E se esta segunda validação também for falsa, sabemos que trata-se de um valor acima de 65 e, portanto, devemos utilizar a cor vermelha.

Ou, em outra palavras, precisamos fazer um if dentro do nosso if:

import Playground exposing (..)

tamanhoDoFioDoBalao = 50

larguraDoFioDoBalao = 3

corDoBalao raio = 
  if raio < 50 then
    green
  else 
    if raio < 65 then
      yellow
    else
      red

raioDoMeuBalao = 64

main =
  picture
   (balao raioDoMeuBalao)


balao raio =
  [ circle (corDoBalao raio) raio
  , rectangle lightRed larguraDoFioDoBalao tamanhoDoFioDoBalao
    |> move 0 (-raio - (tamanhoDoFioDoBalao / 2))
  ]

Repare na indentação dos ifs. O segundo está um pouco mais a direita e se necessário poderíamos adicionar outros ifs aninhados. Mas precisamos tomar cuidado pois isso pode tornar nossos códigos muito difíceis de entender.

E agora?

Este curso ainda está sendo criado e por enquanto possui uma quantidade reduzida de aulas. Novas aulas vão ser publicadas ao longo das próximas semanas!

Gostou da ideia deste projeto? Quer mandar alguma sugestão ou tirar alguma dúvida? Entre em contato comigo enviando um e-mail para marcio@segunda.tech ou me procure no twitter: @marciofrayze