Blog destinado ao curso Sistemas e Mídias Digitais - SMD

  • DOUGLAS SILVA ART

    Curta a minha página no Facebook

  • THE CHIBIMAKERS

    Curta também a página do grupo The chibimakers, no qual postamos sempre desenhos no estilo Chibi.

domingo, 26 de novembro de 2017

Atividade 15 - MAMI

A proposta da atividade atual é explicar e implementar uma das transições apresentadas no vídeo: Video Toaster 4000 Demo. Link na descrição.

Eu escolhi a transição que acontece por volta do minuto 2:53 do vídeo, no qual os pixels da segunda imagem vão aparecer da esquerda para a direita da tela, desaparecendo assim a primeira imagem. 


Para fazer essa transição eu primeiro carrego duas imagens usando o loadImage. Depois eu crio e chamo a função transicao( ) no draw( ) que verifica se a variável direita é menor ou igual a 320 (largura da imagem). Se for, então entra em dois laços for() que percorrerão todos os pixels da imagem. Dentro deles verifico se a posição x do pixel está dentro do intervalo. Se estiver, o pixel da imagem 1 é adicionado na imagem destino, e caso não, o pixel da imagem dois é adicionado.

Depois da verificar, a imagem destino é mostrada e acrescenta-se 1 na variável direita, para fazer o efeito da transição.

O resultado pose ser visto abaixo:




DESCRIÇÃO

Share:

Atividade 14 - MAMI

A proposta da atividade atual é criar uma aplicação que, empregando variáveis para controle de valores, realiza o processo similar ao da imagem abaixo:



Resolvi aplicar os efeitos nessa imagem:


Em seguida eu fiz uma função chamada imageRender dentro do, que chama outras 4 funções dentro de si, que são:

noiseFilter( ): para criar o filtro de ruído eu fiz um laço for que vai de 0 até a quantidade de ruído que se deseja aplicar na imagem. Dentro dele eu adiciono cores aleatórias em pixels aleatórios da imagem original.

grayScale( ): para fazer a escala de cinza, criei dois laços for que percorrem todos os pixels da imagem com ruído, e em cada pixel pego o valor correspondente ao brilho dela (brightness) e coloco na variável b. Vale lembrar que estou usando o modo de cor HSB, o que torna esse processo mais simples. Daí usando essa variável eu consigo alterar a imagem para tons de cinza.

redScale( ): essa função é bem parecida com a função grayScale, só que ao invés de eu pegar só o brilho eu pego também a saturação (saturation), e coloco a matiz (hue) sendo igual a 360, que no círculo cromático correspondente a  cor vermelha.

yellowsScale(): o mesmo processo da função redScale é feita aqui, só que a matiz será igual a 60.

Para terminar, e eu chamo a função imageRender no setup. O resultado pode ser visto na imagem abaixo:



Se você quiser ver como foi feito, basta clicar aqui para baixar o código do projeto.
Share:

segunda-feira, 23 de outubro de 2017

Atividade 13 - MAMI

A atividade era criar um jogo seguindo as seguintes características:



Para essa atividade eu usei os seguintes sprites, ambos do jogo Castlevania - Symphony of the Night:




Criei duas variáveis, x e y, que são a posição do canto superior esquerdo do retângulo que representa o personagem. Carreguei os sprites usando o loadImage() no setup.

Criei uma função chamada jump(), que verifica se o personagem está pulando ou não através da variável jumping. Para que isso aconteça, usei a "função MRU” de um exercício anterior. Criei uma variável tempo, que multiplicando com -0.5 faz o pulo desacelerar.

Criei uma função chamada enemy(). Dentro dela há uma elipse (que representa o inimigo em sí) e duas variáveis, inimigoX e inimigoY, que corresponde a posição central da elipse. A cada frame decremento -4 ao inimigoX, fazendo com que ele se desloque para a esquerda. Quando essa variável for menor que 0, o inimigo volta para a posição inicial.

A função colision() faz o bounding box entre o personagem e o inimigo, e quando o personagem colide diminui a variável chamada chances.

Criei também a função walk(). Quando o estado da variável movendo for igual a "DIREITA”, a variável x será incrementada, e quando for igual a "ESQUERDA", x será decrementado.

Na função keyPressed, quando é clicada a seta esquerda ou a direita, altera-se a direção do personagem. Já na função keyReleased ela faz com que o personagem volte ao estado parado quando as teclas não estão sendo pressionadas.


A função gameover() serve para testar se o jogador perdeu por falta de chances, ou se ele ganhou atravessando a fase toda. Isso tudo é feito com a ajuda das variáveis gameover e ganhou, que se tornam true ou false dependendo do que acontecer.



Se você quiser ver como foi feito, basta clicar aqui para baixar o código do projeto.
Share:

Trabalho Final MAMI - Pt 1

O trabalho final da disciplina de Matemática Aplicada à Multimídia I (MAMI) é um gerador automático de arte. Esse gerador deve levar em conta 3 ou mais obras de uma serie de um artista, e criar um programa capaz de reproduzir variações originais de tais obras.

Modelo Natural
Foto tirada na casa da artista



Artista escolhida:


Karina Paula é uma designer gráfica cearence, nascida em 1995. Um de seus trabalhos como designer foi criar uma série de quadros focados em formas geométricas, com influência no movimento da vanguarda moderna holandesa conhecido como De Stijl (ou Neoplasticismo).

Analisando a série, da obra C-03 até C-05, podemos perceber algumas características:

Obras originais
Características analisadas:
  • 2 linhas diagonais, ou 2 linhas, sendo uma na vertical e a outra na horizontal;
  • 1 circulo central, seguido de um anel ao redor do circulo;
  • 2 à 4 blocos, compostos por quadrados divididos em “triângulos” de cores diferentes;
  • 4 arcos de círculos, compostos por cor chapada ou compostos por um arco de círculo e um arco de “anel” ao redor, dispostos nos quatro cantos do quadro, que possui forma quadrática;
  • 3 cores principais (vermelho, azul e amarelo), e duas de base (preto e branco); 
Formas:
  • Os quadros analisados possuem as dimensões de um quadrado;
  • Dentro do quadrado, existem elementos como: círculos, anéis, quadrados, triângulos e arcos.
  • No centro de cada quadro, há um círculo seguido de um anel ao seu redor.
  • Ainda na parte central, há a presença de blocos. Esses blocos podem variar de 2 à 4 blocos. Cada bloco pode ser formado por um quadrado, ou por dois triângulos de cores distintas;
  • Cada quadro possui nos seus 4 cantos arcos de círculos, que podem vir seguidos de arcos de anéis;
Cores:
  • As cores são compostas sempre por uma cor mais forte e viva, e outra que é a cor preta, geralmente usada para gerar contraste. Além do branco que está presente em todas as obras escolhidas como cor de fundo.
  • Abaixo a paleta de cores das obras escolhida



Modelo Matemático
  • A largura e a altura da tela é de 600x600px. A partir daí é feito um módulo, que eu chamei de A = altura da tela/6. 
Figura 01

Figura 02
  • Como é mostrado nas figuras acima, os círculos centrais são posicionados no centro da tela. Primeiro um círculo menor, que tem a altura de um módulo A. Depois um outro por de trás dele, que tem a altura de A + 35% do módulo. Em seguida outro círculo, com altura A + 70% do módulo, e por último um círculo com altura de 2 * A.
  • Em seguida vem as linhas, que tem a espessura de A/4.
  • Depois os blocos são feitos com largura e altura de 2 * A.
  • Já o primeiro arco dos conjuntos dos arcos, é feito com tamanho de A - 30% de um módulo. O segundo arco que vem por baixo do primeiro é construído com tamanho de A - 15% do módulo. E o último com o tamanho de A.
Modelo Computacional:

Primeiramente, eu comecei criando as variáveis que possibilitarão que aconteça a geração automática de artes. Criei as variáveis: 

  • int linhas: define o tipo de orientação das linhas. Se será horizontal e vertical ou diagonais.
  • int corSelect: define a cor principal da obra, entre vermelho, azul e amarelo.
  • int quantBlocos: define a quantidade de blocos da obra entre 2 à 4.
  • int tipoBloco: define se o bloco será formado por um quadrado ou dois triângulos.
  • int tipoArco: define a quantidade de arcos entre com ou sem anéis.
  • int numArcos: define a quantidade de arcos coloridos ou com uma cor só (que eu também chamo de arco chapado).
Depois eu comecei a construir a estrutura do quadro conforme as Figuras 01 e 02 mostraram anteriormente. Então eu criei uma função chamada middleCircles( ), que desenhas os círculos da parte central do quadro, usando dentro um fill( ) para cada um dos 4 círculos que formam essa parte, pois como pudemos notar, são 4 círculos, sendo o interno colorido ou preto, o segundo que fica envolto do primeiro é sempre branco, o próximo pode ser colorido ou preto, e o ultimo também será sempre branco. No fill( ) de cada um é passado os 3 arrays de cores chamados red, green e blue, no qual dentro deles tem um outro array chamado colorTones. O propósito do colorTones é fazer com que as cores sejam geradas de acordo com a função cretePallete( ), que vou explicar mais para frente.

Fiz também a função drawLine( ), que de acordo com a orientação que é passada através da variável global linhas, dá a orientação horizontal/vertical ou diagonal. Tudo isso é feito dentro de um switch( ), e caso for 0 (horizontal/vertical), as linhas são desenhadas com a função rect( ). Caso seja 1 (diagonal), são desenhadas com a função quad( ).

E, seguida eu construi os blocos. Primeiro eu fiz as funções firstSquare( ), secondSquare( ), thirdSquare( ) e fourthSquare( ), que criam os quadrados a partir de dois triângulos, como também foi explicado visualmente nas Figuras 01 e 02. Depois eu crio um função chamada drawBlocks( ), que chama as funções anteriormente citadas de acordo com a quantidade de blocos que for sorteada na variável quantBlocos. Variando assim de 2 à 4 blocos que serão gerados. Contudo, a drawBlocks só é chamada dentro da função createBlocks( ), que recebe dois valores inteiros. Um é a orientação da linha, e o outro é a quantidade de blocos. Se a orientação for referente a horizontal/vertical, e a quantidade de blocos for referente a dois, então a orientação passa a ser na diagonal e então é chamada as funções drawBlocks( ) e drawLines( ). Agora se não for, então elas são chamadas normalmente.

Para construir os arcos, também fiz quatro funções separadas: firstArc( ), secondArc( ), thirdArc( ) e fourthArc( ). Elas criam 3 arcos com a função arc( ), e fill( ), que também segue o mesmo princípio dos círculos. Só que ele são desenhados através da função drawArc( ), que recebe um parâmetro, que nesse caso é a variável global numArcos, e desenha de acordo com os casos: se for 0, desenha quatro arcos coloridos (intenda por coloridos um arco menor formado por uma cor colorida, o do meio branco e o externo também colorido), se for 1 desenha dois arcos coloridos e dois chapados(todos os arcos são da mesma cor), e se for 2 apenas um arcos é colorido e os outros 3 são chapados.

Já a função createPallete( ), é gerada de acordo com a cor principal selecionada, que é armazenada na variável global corSelect. A partir daí, caso seja 1, a cor principal será vermelha, caso seja 2 será azul e caso seja 3 será amarela. Contudo, em cada caso, são armazenadas nas posições 0 dos arrays red, green e blue, os valores referentes as cores vermelha, azul ou amarela, e nas posições 1 e 2 as cores branca e preta respectivamente. Gerando assim uma paleta.

Agora, na função randomizeTones( ), é onde será atribuído as cores da paleta aos arrays colorTones e arcTones, que será de acordo com o padrão de cores que tem nas obras originais. Sendo elas: 

  • se o circulo central interno for colorido,  o central externo é preto, e vice-versa;
  • se um triângulo do bloco for preto, o outro será colorido e vice-versa;
  • se os arco interno for colorido, o externo é preto e vice-versa;
  • os arcos podem ser todos de uma cor, sendo todos coloridos ou tpretos;

Por ultimo eu chamo as funções no setup, e cada vez que abrir o programa, é gerado uma obra diferente.

Resultados do programa:







Se você quiser ver como foi feito, basta clicar aqui para baixar o código do projeto.




Share:

Atividade 12 - MAMI

A atividade era pra desenvolver e explicar uma aplicação que apresenta um mapa isométrico com base em dois tiles à sua escolha 

Eu resolvi escolher 3 tiles, para poder gerar um mapa mais interessante.


Primeiro criei as variáveis PImage que guardarão as imagens e defino-as no setup(). Após isso, criei uma matriz chamada mapa, que organiza e recebe a posição de cada tilaste que será mostrado na tela.

Em seguida criei uma função chamada mapa (), que realmente vai desenhar o mapa. Nela dois laços for() percorrerão todas as posições da matriz. Dentro dos laços, há um switch() para saber o valor de cada posição e desenhar o tileset correspondente. 



Os tiles possuem o tamanho da metade da largura igual a 50 e da metade da altura igual a 25, sendo que para posicioná-los na tela, eu uso 350-i*50+j*50 (para o eixo x), e 50+i*25+j*25 (para o eixo y), no qual o 350 é para posicionar na metade da tela. No eixo x, o “i” serve para decidir a posição x inicial do primeiro tile e o ”j” para ajudar a posicionar os demais. Já no eixo y, o “i” serve para ajudar o “j” a determinar a posição y.


Se você quiser ver como foi feito, basta clicar aqui para baixar o código do projeto.
Share:

Atividade 11 - MAMI

A atividade seguinte consiste em reimplementar a máquina de estados finitos anterior (feita na sala de aula), substituindo a variável keyPressed pela função keyPressed () e explicando suas diferenças de uso, vantagens e desvantagens.

A máquina de estados tem 3 estados: PARADO, ANDANDO e MARTELANDO, equivalente aos números 0, 1 e 2 respectivamente. No setup() eu carrego as imagens dos 3 estados usando o loadImage().
Estados: PARADO, ANDANDO e MARTELANDO

Em seguida no draw (), eu declaro as funções:  mostraMario (), passando a variável estadoMario como parâmetro e a função estadoMario().

Na função mostraMario() é onde será verificado qual estado do Mario está sendo processado no momento. Daí então ele mudará o sprite dele de acordo com o estado, que é verificado na função keyPressed (). Nela, caso a tecla LEFT seja apertada, a variável estadoMario recebe o estado ANDANDO. Caso seja a tecla barra de espaço, ela recebe a variável MARTELANDO. Na função estadoMario(), é verificado se o estado ANDANDO ou MARTELANDO estão sendo acionados. Se estiverem, uma variável global chamada tempo é incrementada, e se ela ultrapassar 30 segundos, ela zera, e a variável estadoMario volta a ser PARADO.

keyPressed VS keyPressed()
keyPressed:
A variável do sistema booleano keyPressed é verdadeira se qualquer tecla for pressionada e falso se nenhuma tecla for pressionada. O fato dela ser uma variável é bom porque ela pode ser utilizada em mais de um local. Contudo, por ela ser só uma variável, é preciso implementar toda a lógica da máquina de estados usando-a.

keyPressed():
A função keyPressed () é chamada cada vez que uma tecla é pressionada. Por causa de como os sistemas operacionais suportam repetições de teclas, manter pressionada uma tecla pode causar várias chamadas para keyPressed (). A taxa de repetição é definida pelo sistema operacional e pode ser configurada de forma diferente em cada computador. Em compensação, essa função já funciona como uma máquina de estados, melhorando o seu código.

Se você quiser ver como foi feito, basta clicar aqui para baixar o código do projeto.
Share:

sexta-feira, 20 de outubro de 2017

Atividade 10 - MAMI

A atividade era explicar como se pode detectar cliques do mouse sobre um botão retangular com cantos arredondados.

Primeiro ei fiz o modelo do botão. Para isso ele vai ter 4 círculos nos seus cantos e o preenchimento do botão será dois retângulos, sendo que o primeiro retângulos possui largura maior que o segundo, e o segundo possui altura maior que o primeiro, como na figura abaixo. Os círculos deverão ser criados nos pontos em que há intersecção dos retângulos, para que assim se forme um botão retangular com cantos arredondadas.


Depois eu criei duas funções. A primeira faz o calcula da distância, recebendo dois valores (A e B) e retornando a diferença entre eles. Eu chamei ela de distancia1D( ). Usei a função abs( ) para o valor sempre ser positivo. A outra faz o calculo da distância entre dois pontos, recebendo os valores x1, y1, x2, y2 e retornando o calculo da equação: d = √( (x2 - x1)² + (y2 - y1)² ). Eu chamei ela de distancia2D( ). Vale lembrar que a função distancia2D( ) chama a função distancia1D( ) para poder fazer o calculo da diferença entre os valores.

Em seguida, eu criei os círculos e retângulos no draw( ), usando as funções ellipse( ) e a rectMode(RADIUS), para facilitar na hora de fazer as comparações que serão necessárias posteriormente.



Também criei a função mousePressed(), que checa se o botão está sendo clicado. Para isso, eu criei duas variáveis locais chamadas distX e distY, que recebem respectivamente o valor do calculo da distancia (através da função distancia1D) entre os valores x e y correspondentes aos retângulos do botão e as posições do mouse (mouseX e mouseY). Somente assim eu consigo verificar se o mouse estará clicando dentro da área correspondente a parte retangular do botão. A mesma verificação é feita para os 4 círculos que estão nos cantos do botão, só que para isso eu uso o calculo da função distancia2D, e comparo com as posições do mouse(mouseX e mouseY). Se estiver clicando dentro da área do botão, então a cor do background muda pra ciano. Se não estiver clicando, ela continuará cinza.



Se você quiser ver como foi feito, basta clicar aqui para baixar o código do projeto.
Share:

Trabalho Final MAMI - Pt 2

Nessa segunda e última parte do Trabalho Final da cadeira de MAMI, eu apenas coloquei uma interface gráfica com a ajuda da biblioteca Cont...