terça-feira, 15 de outubro de 2019

Trabalho MAMI - Parte I

O jogo escolhido para o trabalho foi o Blip, lançado em 1977, da primeira geração de jogos eletromecânicos comercializados pela Tomy. É bastante similar ao Pong da Atari, sendo a maior diferença o fato de ser um jogo de matriz mecânica, ao invés de eletrônica, como o primeiro.

Link do vídeo: https://www.youtube.com/watch?v=iBoe3yM9IKs

Mecânicas e jogabilidade: 

O jogo possui dois modos de jogo, individual e de dois jogadores, que pode ser alternado por um switch na tela.

→Bola:

Quando é iniciado, uma bola, que é uma luz de LED, adquire uma velocidade inicial fixa e viaja de um lado da tela para outro.

→Pás:

Os jogadores precisam antecipar onde a bola irá parar e selecionar um dos três slots disponíveis conforme a sua escolha, que são posições predefinidas das "pás" do jogo, com o objetivo de aparar a bola e retornar ao seu adversário.

→Pontuação:

Se um dos jogadores escolher errado a posição da pá, a bola passa e conta pontuação para o adversário. Caso escolha certo, é retornada ao adversário.

→Condições de Vitória:

O jogo continua até que um dos jogadores alcance 10 pontos ou o quando timer parar. Nesse último caso, ganha o jogador que tiver feito a maior pontuação.

→Término do jogo:

Quando o jogo termina, as pontuações, o timer e a posição da bola são reiniciados.



Recriação:

Pelas limitações técnicas da época, Blip é um jogo simples e os movimentos da bola são relativamente fáceis de prever. As técnicas usadas no jogo original para simular colisão da bola e a movimentação limitada das pás o deixa entendiante rapidamente. Dessa forma, a minha versão aproxima o jogo mais do Pong da Atari para torná-lo mais interessante, mas mantendo as características e regras do Blip.

Modelo Natural:



O modelo natural consiste em duas pás, representando os dois jogadores, a bola, que é utilizada para marcar a pontuação, os marcadores de tempo, cronômetro e a tela de game over.



Componentes


HUD

Controles:

Jogador 1:
W: Movimenta a pá para cima
S: Movimenta a pá para baixo


Jogador 2:

↑: Movimenta a pá para cima
↓: Movimenta a pá para baixo


Assim como jogos similares, tais como o Pong, faz-se um paralelo com o tênis de mesa: as pás são as raquetes físicas dos jogadores mas, ao contrário deste, assume-se que a bola sempre irá passar por cima da rede, ou que não exista rede interpondo os dois jogadores. Além disso, no tênis de mesa não há colisão lateral com a bola.


Imagem relacionada
Componentes do Tênis


Também é similar aos aero-hóqueis ou air game de fliperama. Neles também há a colisão lateral, mas a área de colisão é estendida às laterais das extremidades, sendo a parte central o "gol".



Componentes de aero-hóquei

Modelo Matemático:

Para medidas espaciais
1 unidade = 1 pixel


X(pá direita) = 40
X(pá esquerda) = X-40
Y(ambas pás) = Y/2 = -250

vel (pás) = 5 px/fr
velX (bola) = 8 px/fr
velY (bola) = 8 px/fr

Caso a bola ricocheteie nas paredes ou nas pás:
velX (bola) = -(velX (bola)) (horizontalmente)
velY (bola) = -(velY (bola)) (verticalmente)

Caso um jogador marque um ponto:
ponto(jogador) = ponto(jogador) + 1

Se o jogo acabar (para cada frame):
tempo = tempo + 0

Reinício:
tempo = 0
tempo = tempo + 0,01666...

Modelo Computacional:

Tipos de Funções:

Criação de objetos - As mais simples, são de grande ajuda para desenhar os componentes do jogos na tela e estabelecer seus parâmetros.

desenhaBola(): Cria a bola seguindo os parâmetros de diâmetro e posicionamento.

desenhaPa(): Cria as pás seguindo os parâmetros de largura, altura e posicionamento.

Movimentação - Funções que incrementam ou decrementam os valores iniciais dos objetos que se movem na tela.

movePa(): Acresce ou decresce o valor da velocidade da pá aos seus respectivos valores verticais.



moveBola(): Acresce os valores da velocidades X e Y da bola ao seus respectivos valores de posicionamento.

Colisão - Funções que limitam o espaço de atuação e/ou modificam a velocidade da bola.

limitaPa(): Limita a posição das pás para que elas não saiam da tela.



contatoPa(): Ao entrar em contato com a pá, a variável de velocidade da bola torna-se negativa.

colisao(): Assim como a última, quando alcança a altura máxima da tela, a velocidade Y da bola se torna negativa, o que acontece respectivamente com a velocidade X, se alcançar a largura máxima.


Caso não haja a colisão nas bordas, e o X máximo seja ultrapassado, será contabilizado 1 ponto para o jogador que marcou,

Condição de Vitória - Função que valida as possíveis vitórias.

gameOver(): Encerra o jogo, caso as condições estabelecidas sejam cumpridas. Assim como no Blip, as condições de vitórias são as mesmas. Ganha quando o contador de pontos chegar em 10, ou o de tempo alcançar 60.





HUD - Funções que mostram informações relacionadas ao jogo, tais como: tempo, pontuação, etc.

hud(): Exibe a pontuação dos jogadores e o tempo.

paginaGameOver(): Congela a bola e exibe a tela de vencedor, permitindo o reinício do jogo clicando com o mouse aonde pede. Caso reinicie, reseta os valores de tempo, pontuação e posição da bola.



Controles - Funções que permitem a realização do movimento das pás.

keyPressed(): Quando uma das teclas relacionadas ao movimento é pressionada, muda sua respectiva variável booleana para "true", acionando o movimento.

keyReleased(): Quando uma tecla pressionada é solta, muda sua respectiva variável booleana para "false", encerrando o movimento.

Foi a única forma que eu encontrei de deixar que os jogadores jogassem sem interferir no movimento da pá do outro.

Link do código: https://drive.google.com/open?id=1pR89AZAEx2doztYCVoduVylvoolYcfuQ

Atividade 8 - Proporções

A função map() recebe como parâmetros o valor a ser convertido, o menor e o o maior valor da extensão atual, e o menor e o maior valor da extensão que é desejada.

Dessa forma, a função recebe a posição de mouse X como valor a ser convertido e a remapeia, confinando-a dentro da largura do retângulo. O mesmo acontece com o mouse Y e a altura do retângulo.

Vale ressaltar que, nesse caso, dX e dY poderiam ser substituídos por mouseX e mouseY sem alterações, uma vez que essas variáveis do sistema têm função parecida ao dist, sempre calculando a posição atual do mouse em função da sua distância da origem.





Link do código: https://drive.google.com/open?id=1hct0aOplnOxSxtaaWpdxGv_AGJNKjPWt

segunda-feira, 14 de outubro de 2019

Atividade 7 - Fibonacci e a Proporção Áurea

A sequência de Fibonacci tornou-se conhecida mundialmente pelo nome do matemático italiano Leonardo de Pisa, que durante o final da Idade Média descreveu o crescimento de uma população de coelhos a partir desta.

Em termos gerais, cada número que compõe a sequência é igual a soma de seus dois antecessores, sendo definida pela fórmula:

sendo os dois primeiros valores iniciais:


A sequência está intrisecamente relacionada à Proporção Áurea, que aparece constantemente em padrões de crescimento dos seres vivos e na anatomia humana, recebendo a alcunha de "a marca de Deus". Nos ofícios humanos é observado extensamente na pintura, arquitetura, música, etc.

A aplicação mais comum do número de Fibonacci na Proporção Áurea está no Retângulo de Ouro, que é considerado o retângulo mais agradável a olhar humano.

Se definirmos um quadrado de lado 1 como unidade básica e construirmos de acordo com a sequência, obteremos o Retângulo de Ouro. (0, 1, 1, 2, 3, 5, 8)



Além disso, ao calcularmos o coeficiente de duas medidas sucessivas da Série de Fibonacci, obtém-se o número irracional denominado de PHI, com o valor aproximado de 1,618. O PHI pode ser alcançado dividindo diversas medidas do corpo humano entre si, como as falanges dos dedos e distâncias das partes do rosto.

Atividade 6 - Bandeira do Brasil

Um dos fatores que dificultam a criação de objetos geométricos proporcionais no Processing, é a lei diferenciada na criação das formas básicas. Nesse caso, o método padrão de formação de um retângulo, por exemplo, se dá pelo vértice superior esquerdo da forma.

No entanto, ao aplicar o rectMode(RADIUS), observamos que tal método pode ser simplificado. Em vez do retângulo ser formado a partir do vértice dito acima, ele é criado a partir do centro da forma (x, y), simplificando o processo de centralização do retângulo, por ser parecido com o da formação da ellipse.

A função beginShape() permite a criação de formas a partir do traçamento de pontos dos vértices do objeto, podendo criar qualquer polígono regular ou irregular. Já o quad() permite a criação de qualquer quadrilátero a partir de coordenadas, sendo utilizado na criação do losango.





terça-feira, 1 de outubro de 2019

Atividade 5 - Lançamento Balístico

Aqui são as variáveis envolvidas no cálculo das velocidades:

x → coordenada inicial do eixo X
y → coordenada inicial do eixo Y
vx → velocidade X
vy → velocidade Y
grav → gravidade
dx → distância X
tempo → tempo mostrado na tela
t → tempo usado no cálculo




A velocidade Y é calculada adicionando-se o valor da gravidade a cada frame, e o y é calculado acrescentando-se o valor da velocidade a cada frame. Quando a bolinha atinge o "piso" da tela, ela ricocheteia, perdendo 10% da sua energia cinética.


O tempo real (a ser exibido na tela) é obtido dividindo o 1 segundo pelo número de frames padrão do Processing (60). Já a distância X é obtida multiplicando a velocidade X pelo tempo.


A velocidade X é imutável durante todo o processo.



Atividade 4 - Simulador MRU

Para alterar o código original de modo que o simulador considere intervalos menores que um segundo, mesmo sendo executado a 60 fps e mantendo o tempo real, temos que seguir os seguintes passos:

1 - Transformar todas as variáveis int envolvidas para float. Dessa forma, números fracionados irão ser suportados no cálculo da distância.



2 - Dessa forma, para deixar simular o tempo do mundo real, mesmo rodando a 60 fps, é só dividir 1 por 60 (não se esquecer do ponto depois do 1, porque senão não irá dividir, já que deve ser float/float) e somar à variável de tempo no draw, assim irá adicionar essa fração a cada frame, dando o tempo correto em segundos.


Atividade 3 - Círculos Coloridos

Para fazer um Gerador de Círculos Coloridos, primeiramente criamos uma função para desenhar círculos "void circulo" e acrescentamos a capacidade de ser preenchida com cores aleatórias, e alocamos seus parâmetros como parâmetros da função "ellipse" com variáveis locais (x da esfera, y da esfera, 2*r para os diâmetros).

Após isso, criamos uma função "bloco", para desenhar as unidades da figura. Usando "rect", para desenhar um quadrado e três vezes a função "circulo" para os círculos interiores, cada um mantendo proporção de, respectivamente, 1/2, 1/3 e 1/6 com o primeiro.

Nessa atividade, acrescentei a biblioteca ControlP5 para gerar uma slidebar com o objetivo de controlar os parâmetros diretamente, sendo que os valores das barra "Horizontal" varia de 1 até 9, e o da "Vertical", de 1 até 7.

Para vincular a barra de rolamento com os parâmetros, foi criado quatro variáveis "hor", "ver", "h", "v" e o teste booleano "pintar" = verdadeiro. As variáveis "h" e "v" recebem os valores atuais da barra, e inicialmente são iguais às variáveis "hor" e "ver".

Contudo, se arrastarmos a barra de rolamento, e o programa receber valores diferentes para "hor" e "ver", conforme arrastamos a barra, "pintar" é verdadeiro, e o programa começa a gerar os blocos, de acordo com o número recebido por intermédio de um laço de repetição, que são dispostos de acordo com as coordenadas recebidas.

Caso a slidebar esteja parada, os valores são iguais, portanto "pintar" é falso e nada acontece.





Link do código: https://drive.google.com/open?id=0B3-iqp7LYuNJS3FrTVhLWTFjQVk

Atividade 2 - Debugger

O debugger é uma ferramenta que permite testar os programas com o objetivo de encontrar erros e bugs. No Processing há uma ferramenta com essa função, e para ativá-la, é preciso realizar os seguintes passos:

1 - Clique no ícone de borboleta no canto superior da janela do Processing.


O ícone irá ficar azul claro se estiver habilitado.
Também é possível ativar pela barrar de tarefas, em "Debug"→"Enable debugger"


2 - Então, antes de rodar o programa, selecione as linhas de código que irá querer monitorar. Normalmente, são as linhas que rodam na função draw e que modificam com a passagem dos frames.



3 - Clique em play para rodar o programa. A grande diferença da ferramenta debugger, é que, além de mostrar a tabela com as variáveis em uma tela separada, ela também mostrará os passos de execução das funções a cada frame.


Aqui as variáveis antes do laço começar.



O botão step funciona para avançar nos passos de execução das linhas selecionadas, antes de pular para o próximo frame.


O debugger dá detalhes de como são executadas as linhas de código. Nesse caso, as imagens só aparecem depois que os laços são executados e terminados.

Assim, dá para descobrir em qual frame e em qual linha da execução houve algum problema, identificá-lo e resolvê-lo com maior facilidade.

Link do código: https://drive.google.com/open?id=1kbKULMFNAgy9KjAfcST0k70ebU4-w4q_