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.

terça-feira, 12 de dezembro de 2017

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 ControlP5 (recomendo baixá-la se for usar o projeto), e desenvolvi um vídeo explicando o processo de concepção do mesmo. 




DESCRIÇÃO

Share:

Atividade 21 - MAMI

A proposta da atividade atual consiste em resumir criticamente a palestra "The Beauty of Data Visualization” de David McCandless.




Em sua palestra, David McCandless transforma conjuntos de dados complexos, como gastos militares mundiais, medos da humanidade e atualizações de status do Facebook em diagramas bonitos e simples que provocam a compreensão de padrões e conexões que não haviam sido vistos ou percebidos. O bom design, ele sugere, é a melhor maneira de visualizar e entender o excesso de informação, e pode mudar a maneira como vemos o mundo.

Segundo ele, quando lidamos com uma quantidade gigantesca de dados, às vezes não se consegue ver o que realmente se quer encontrar, mas quando se organiza essas informações de uma maneira visual, e de um jeito que elas consigam interagir entre si formando um novo padrão, é como anda por uma floresta e se deparar com uma clareira, tornando assim a informação mais fácil de compreender.

A maior parte da visão humana recebe as informações inconscientemente. Ela é extremamente sensível a variações de cores, formas e padrões. Enquanto que o cérebro trata dos números, palavras e conceitos. Ele propõe que se juntássemos as duas formas de perceber as coisas, isso mudará nossa forma de pensar sobre elas. Fará com que passemos a entendê-las de uma forma melhor. 

Isso é exatamente a forma que um profissional do curso de SMD deveria pensar, pois é com isso que ele vai ter que lidar nos seus trabalhos. Ele terá que aplicar design para resolver problemas da área da informação mas de forma visual, provendo assim soluções elegantes e de melhor assimilação. E quando digo problemas da informação, eu incluo desde a criação de gráficos gerados à partir de dados estatísticos de quantidades em que uma moeda vai dar cara ou coroa, até fazer um adaptive logo usando um algoritmo.

 DESCRIÇÃO
Share:

Atividade 20 - MAMI

A tarefa era criar versões no Photoshop da imagem de einstein.jpg e cinza.jpg com variações de brilho e contraste, e dizer qual foi o impacto que ocorreu na média e desvio padrão delas.

Inicialmente as imagens “einstein.jpg” e “cinza.jpg” possuem os valores de média e desvio padrão respectivamente correspondentes a: 28 e 63, e 29 e 0.

Original

Modificada

Alterando os valores de brilho e contraste da imagem do “einstein” para 50 e 50 respectivamente, pude notar que a média e o desvio mudaram respectivamente para: 35 e 77. Houve pouca variação nos dois valores. Isso ocorreu pois, a parte cinza que tendia para o preto ficou mais escura, e o cinza que tendia para o branco ficou mais claro, aumentando a distância entre os valores.

Original
Modificada

Já na imagem “cinza” , mudei o brilho e o contrate para 150 e 100 respectivamente, tendo uma mudança apenas na média, que agora é 51. Esse aumento ocorre porque as cores da imagem, estão ficando mais claras, logo está se aproximando do 255, que é o valor máximo. O desvio padrão continuou o mesmo pois não há variação de cores na imagem.


DESCRIÇÃO

Share:

sábado, 9 de dezembro de 2017

Atividade 19 - MAMI

A proposta da atividade atual consiste em criar um olho (círculo preto pequeno no interior de círculo branco grande) que se encontra sempre voltado para o cursor do mouse 

Para fazer com que o circulo preto pequeno se mova em direção do mouse, eu criei uma variável chamada ang, que recebe o valor do cálculo da tangente dos pontos X e Y do mouse subtraídos da largura/2 e altura/2 da tela. Sendo ang a representação de um círculo cuja angulação varia de -PI a +PI, eu passo esse valor como parâmetro para a função rotate ( ), fazendo com que o círculo preto gire.



DESCRIÇÃO

Share:

Atividade 18 - MAMI

A proposta da atividade atual consiste em criar uma aplicação para simular um cronômetro simples, apenas com o ponteiro dos segundos, empregando a função milis() do Processing.

Para criar o ponteiro do meu cronômetro, eu usei a função line(), no qual ela recebe os x e y iniciais da linha sendo a metade da minha tela (300, 300), e os x e y finais são os valores da primeira e segunda posição do vetor que a minha função polarToCart retorna. Essa função funciona recebendo um raio (r = 130) e um ângulo (ang = 0), e retornando um vetor com as coordenadas polares convertidas em coordenadas cartesianas. Para deixá-lo colorido eu usei o modo de cor HSB e função stroke( ) eu passo um valor referente ao vermelho em HSB. Para deixar-lo com a espessura mais grossa, eu usei a função strokeWeight( ) com o valor 10.

Para fazer a linha girar como o ponteiro dos segundos, a variável do ângulo (ang) é igual 6.14/12000 * millis(), sendo assim a divisão de uma volta do circulo por 12 segundos. A função millis() é o tempo, em milisegundos, que o programa passa a ter desde que inicia.

Para o resto do cronômetro, eu usei uma imagem mesmo.


DESCRIÇÃO


Share:

Atividade 17 - MAMI

A proposta da atividade atual consiste em criar o movimento de um barco no mar e discutir os resultados no blog. Também era pra utilizar a função rotate para simular o movimento. 

Primeiro, pra criar o movimento das ondas, eu criei um for, que varia de 0 à 500. Se o i do for chegar a 250, a variável inclinação passa a ser igual a variável ang. Depois eu criei outro for, que serviria para fazer várias ondas, mas devido o processamento, que deixava o movimento extremamente lento, eu optei por desenhar apenas 4 linhas, intercalando as cores delas. Nesse for, as linhas são desenhadas usando a variação do seno do ângulo representado pela equação sin(ang)*20. Essa equação faz com que haja variação da posição y das linhas, dando o efeito de movimento da onda. Para que isso ocorra, fora do laço a variável ang é incrementada com 0.05, modificando assim o valor do resultado da equação e em seguida a variável variação também é incrementada em 0.1. Quando variação for maior que uma volta ele zera.

Para fazer o movimento do barco, eu coloquei ele na posição 250. Para saber seu ângulo de inclinação nessa posição, eu criei a variável angInclinacao, que armazena o valor de ang. Usando a função translate(), eu posiciono o barco na posição x =  250, e y = 275 - sin(angInclinacao)*20, e translate(250,275-(sin(angInclinacao)*20)). Agora para que o barco faça o movimento igual ao da onda, eu uso a função rotate((sin(angInclinacao)*0.7)). Isso faz com que o barco fique num ângulo reto quando ele está nos picos de variações.


DESCRIÇÃO




Share:

terça-feira, 5 de dezembro de 2017

Atividade 16 - MAMI

A proposta da atividade atual consiste em, empregando a função rotate(), criar uma aplicação que desenha um polígono regular centralizado na tela com a quantidade de lados informada no próprio código. 

Primeiramente, para criar o polígono eu criei a função slice(), que retorna um float com o ângulo que as fatias do meu polígono vai ter. Depois criei uma variável chamada ang, que vai chamar a função slice() e passar um número de quantidade de fatias, que no caso é a variável num, que está inicialmente definida como 4.

Após isso, eu criei um for no draw, que desenha o polígono através da função triangle( ), onde eu passo os valores do pontos do triângulo (0, 0, cos(ang)*250, sin(ang)*250, cos(ang*2)*250, sin(ang*2)*250). No caso, os valores cos(ang)*250, sin(ang)*250 representam as coordenadas x e y do meu segundo ponto, e o cos(ang*2)*250, sin(ang*2)*250 as coordenadas do meu terceiro ponto. Para que esse for desenhe todos os triângulos do meu polígono centralizado e tomando com base os pontos (0,0) como centro do mesmo, eu usei as funções rotate( ) e translate( ). A primeira função para girar os triângulos em torno do eixo do ponto (0,0) e a segunda para deslocar a posição inicial da tela (0,0) para o centro da tela (300, 300).

Resultado 01

Resultado 02
Resultado 03
Usar a função rotate( ) para fazer polígonos girarem é menos trabalhoso do que por exemplo fazer cada ponto do polígono variar seu valor para que tenha o mesmo efeito visual de uma rotação, como visto em uma das aulas de MAMI. Isso poupa bastante tempo de implementação, e sem contar que deixa o código melhor também.


DESCRIÇÃO

Share:

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:

Atividade 09 - MAMI

O bounding boxe é uma técnica usada para se detectar a colisão de dois ou mais objetos(ou sprites), no qual os mesmos passam a ser considerados como caixas(retângulos), para se facilitar o cálculo. Como na imagem abaixo, no qual a área correspondente a bolinha e ao quadrado que está inclinado se transforma em duas caixas invisíveis.

Para explicar melhor a técnica de detecção de colisão por bounding box, eu desenvolvi uma versão simplificada do jogo Breakout, que considera a colisão de toda bola com o bastão e com dois ou mais obstáculos. 

Primeiro eu criei a função bastao(), que cria e faz movimentar o bastão que fica na parte inferior da tela. Ela recebe como parâmetro a posição x do bastão. Dentro dela, desenho um retângulo com a posição x indicada pelo parâmetro da função e a posição y recebe um valor de 580px, para que o bastão fique na parte de baixo da tela mais não colada ao fim da tela. Após isso, verifico se alguma tecla foi pressionada, caso a tela RIGHT tenha sido pressionada, incremento mais 5 na variável da posição x. Também verifico se o bastão está ultrapassando a largura da tela. Se a variável x for menor que o width da tela menos 100(o tamanho do bastão no eixo X), então é incrementado 5 à variável bastãoX. O mesmo é feito para o lado esquerdo.

Depois eu criei uma função chamada bola(), que recebe dois parâmetros, x e y. Dentro dessa função, usando esses parâmetros eu desenho uma bola com a função ellipse(). Em seguida, eu faço verificações para quando a bolinha bater nas paredes laterais, em cima e no bastão. Se colidir, ela inverte a sua direção. 

Também criei uma função chamada colisao(), que verifica se a bola colidiu com cada um dos 3 obstáculos que eu criei como variáveis globais. Também criei 3 variáveis do tipo booleano, chamadas de obsDestroyed 1, 2 e 3, que armazenam o estado dos obstáculos(no caso elas são armazenadas inicialmente como false). Se a bola tiver colidido com algum dos obstáculos, então é mudado o valor dessas variáveis para true, possibilitando assim que os obstáculos sejam destruídos. Mas eles só serão destruídos de fato na função destroi(), que verifica se as variáveis obsDestroyed 1, 2 e 3 são true. Se forem, então os obstáculos são criados. Se forem false, então os obstáculos passam a não existir.




Há também uma função chamada gameover(), que verifica caso a bola ultrapassa a altura inferior da tela, parando assim o jogo para, as configurações do jogo volta para a inicial e é dada uma mensagem de “GAME OVER” na tela.

No draw(), eu chamo as funções bastao(), passando o valor bastaoX, que é uma variável global, a função bola(), com os seus valores bolaX e bolaY, que também são variáveis globais, e as funções colisao(), gameover() e destroi().


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

Share:

quinta-feira, 12 de outubro de 2017

Atividade 08 - MAMI


Para a criação da função moveCaixa2(x1, y1, x2, y2, n), que realiza o movimento interpolado de um quadrado de lado 10 pixels, entre (x1, y1) e (x2, y2), em n passos, eu fiz o seguinte:

Primeiro eu defini uma variável (i) para ficar responsável pelo movimento.

Depois criei a função moveCaixa2( ), que recebe os parâmetros da posições iniciais x1 e y1, das posições finais x2, y2, e a quantidade de passos n. Dentro dela, eu faço o calculo da diferença entre as distancias x2 - x1, e y2 - y1, e armazeno o valor em duas variáveis chamadas respectivamente de distx e disty. Em seguida, eu verifico se a variável i é menor ou igual a 1, caso seja, o movimento pode ser executado, desenhando assim o retângulo com a função rect(), onde sua posição x é a posição x inicial (x1) mais o produto de i com a diferença do x final com o x inicial (distx), sua posição y é a posição y inicial (y1) mais o produto de i com a diferença de y final com y inicial (disty). Sua altura e largura eu defini com 10px.

Após o quadrado ser desenhado, incremento à variável i o valor dela mesma mais a divisão de 1 pela quantidade de passos (n).


Por fim, na função draw( ) apenas defino o background como preto e chamei a função moveCaixa2( ).


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...