Obrigado por visitar a The Game Makers Brasil 😁 Use o fórum de Dúvidas para fazer perguntas. Se está em busca de aprender dê uma olhada nos tutoriais.

[GRAF] [Tutorial] Cores

Tutoriais, videoaulas, guias e downloads para te ajudar nos estudos.
Avatar do usuário
Tutoriais & Aulas
Colaborador
Colaborador
Reações: 0
Mensagens: 110

[GRAF] [Tutorial] Cores

Mensagem por Tutoriais & Aulas » Qui Abr 28, 2016 4:49 pm

Autor original: saim
Nome: O tutorial mais colorida da comunidade
Descrição: Um pouco de informação sobre como criar cores
Nível de dificuldade: Em geral, todo mundo vai entender do que estou falando, mas o tutorial pode interessar qualquer nível de programador (que nunca tenha se preocupado com cores antes).
Requerimentos: Não requer nem o game maker, mas os exemplos requerem. Usei a versão 8, pro, mas alguns exemplos podem ser adaptados pra lite.

Introdução

"Como assim, um tutorial sobre cores? Não é só escolher naquela palhetinha de edição do sprite?"
Bom, sim e não. Ao criar um sprite, é bem por aí mesmo. Mas existem as funções de draw e você pode querer desenhar com cores mais elaboradas que aquelas default (c_black, c_white, c_aqua, e por aí vai...). O que eu pretendo fazer aqui é ensinar a criar suas próprias cores a partir de algumas funções.
Primeiro, o mais óbvio. Existem duas funções feitas especificamente pra criar cores. Tão especificamente que a tradução do nome delas (make_color_rgb e make_color_hsv) é cria_cor_rgb e cria_cor_hsv. Sabe o que quer dizer "rgb" e "hsv"? A pergunta é retórica, se isso é um tutorial, eu tenho que explicar.
Só uma breve pausa, antes, pra mencionar que os valores de rgb e hsv variam de 0 a 255. Parece um número pra lá de bizarro, mas existe um motivo pra isso (logo mais eu explico).

RGB

RGB significa "red, green, blue" ou "verde, vermelho, azul". Lembra que a professora do primário te ensinou que as cores básicas eram vermelho, azul e AMARELO? Esqueça, pro computador, as cores básicas são vermelho, azul e VERDE. Existe uma diferença no triângulo de cores quando tratamos de cor-luz e cor-pigmento, sua professora te ensinou a misturar tintas (pigmento) e nós estamos mexendo com pixels numa tela luminosa (luz). Não vou te ensinar a misturar as cores, a wikipedia tá aí pra isso, mas acho importante mencionar que isso é possível.
Então, usando a função "make color_rgb", você entra com a quantidade que quer de vermelho, verde e azul. Essas quantidades são os argumentos das funções e devem ser colocados nessa ordem. 
make_color_rgb(255, 0, 0) - vermelho, make_color_rgb(0, 255, 0) - verde, make_color_rgb(0, 0, 255) - azul escuro, make_color_rgb(255, 255, 0) - amarelo, make_color_rgb(0, 255, 255) - ciano, make_color_rgb(255, 0, 255) - roxo, e por aí vai.
Note que quanto maior o valor de cada cor, mas claro o resultado vai ficando, mais perto do branco. Quanto mais baixos, mais perto do preto. Aquela velha máxima que branco é a mistura de todas as cores e preto, a ausência, vale aqui (mas vai misturar todas as tintas da sua professora pra ver o que vai sair!).
Uma pequena engine pra você brincar:
create:

Código: Selecionar todos

vermelho=0; verde=0; azul=0
step:

Código: Selecionar todos

vermelho=median(0, vermelho+keyboard_check(ord('A'))-keyboard_check(ord('Z')), 255)
verde=median(0, verde+keyboard_check(ord('S'))-keyboard_check(ord('X')), 255)
azul=median(0, azul+keyboard_check(ord('D'))-keyboard_check(ord('C')), 255)
draw:

Código: Selecionar todos

draw_set_color(c_red); draw_text(20, 20, "vermelho: "+string(vermelho))
draw_set_color(c_green); draw_text(20, 40, "verde: "+string(verde))
draw_set_color(c_blue); draw_text(20, 60, "azul: "+string(azul))
draw_set_color(make_color_rgb(vermelho, verde, azul))
draw_rectangle(20, 80, 120, 180, 0)
Você pode descobrir o valor de cada parte de uma cor usando color_get_red, color_get_green e color_get_blue.
Os tons de cinza correspondem a valores iguais de vermelho, verde e azul, quanto mais baixos, mais preto e quanto mais altos, mais branco.

HSV
HSV significa "hue, saturation, value" ou "tom, saturação, valor". Dessa vez, você pode mandar caçar o mandato da sua professora do primário.
Por "tom", entenda "cor". Isso mesmo. Todas as cores numa variável só. Muito mais fácil de lidar, não é? Faz tempo que não vejo um arco-íris de verdade, mas acho que varia como no arco-íris. Com certeza o tom zero começa no vermelho, como o arco-íris. Mas e as outras variáveis?
"Saturação" significa o quanto a cor é vívida. Saturações altas dão uma cor vibrante, enquanto saturações baixas fazem parecer parece que a cor gripou e não pode sair pra brincar.
"valor" é o quanto a cor puxa pra luz. Baixos valores significam cor preta, não importa o valor das outras variáveis. Valores altos significam cores mais fortes. Ir do zero ao 255 é como ir saindo da sombra.
Essas descrições são bem subjetivas, mas é pra isso que o sistema hsv foi criado, pra ser subjetivo mesmo. Você pode usar a mesma engine anterior pra brincar, só troque o "make_color_rgb" por "make_color_hsv". Troque os nomes das variáveis e os que aparecem na tela, também.
Ah, tem mais uma engine simples e interessante que você pode fazer, de acender/apagar botão. Faz assim:
create:

Código: Selecionar todos

tom=random(255) //ou você pode escolher manualmente
cor1=make_color_hsv(tom, 255, 255)   //cor do botão aceso
cor2=make_color_hsv(tom, 255, 255/2) //cor do botão apagado
cor=cor1
draw_set_color(cor) //só se você usar lite
evento de apertar alguma tecla:

Código: Selecionar todos

cor=cor1+cor2-cor //alterna entre os 2 valores
draw_set_color(cor) //só se você usar lite
 draw:

Código: Selecionar todos

draw_circle_color(x, y, 20, c_white, cor, 0)
ou, se você usa a versão lite:

Código: Selecionar todos

draw_circle(x, y, 20, 0) //a cor você definiu no evento de apertar a tecla
Você pode descobrir o valor de cada parte de uma cor usando color_get_hue, color_get_saturation e color_get_value.
Os tons de cinza são com qualquer tom, saturação igual a zero e o valor determina o tom de cinza, quanto mais baixo, mais preto, e quanto mais alto, mais branco.

Hexadecimais

Já viu as cores sendo definidas como um jogo-da-velha (# - como chama esse símbolo?) e uma sequência de seis números e/ou letras? Na verdade, aquilo é um número em formato hexadecimal e o símbolo "#" está lá pra explicar ao computador que aquele número deve ser tratado como hexadecimal.
"O que é um hexadecimal?" Ai, caramba, eu precisaria de outro tutorial só pra explicar isso. Olha, escreva os números de zero pra frente. Pare quando chegar no primeiro número que você precisar de mais de um símbolo. Vou facilitar: pare no 10. Porque esse número precisa de dois símbolos (1 e 0)? Porque não existe um símbolo pra ele? Será que é porque temos 10 dedos nas mãos? Será porque quem inventou os símbolos numéricos estava sem criatividade? Não importa. Agora eu quero chegar até 16 (daí o nome hexadecimal) usando só um símbolo e vou pegar as letras do alfabeto pra isso!
Então #a=10, #b=11, #c=12, #d=13, #e=14, #f=15 e 16 seria o primeiro número a precisar de dois símbolos. Assim, em formato hexadecimal, #10=16.
Como transformar um hexadecimal em decimal (já que você ainda não se acostumou a trabalhar com hexadecimais)? Pegue o número da casa decimal (ou hexadecimal, se preferir) e multiplique seu valor por 16 elevado ao número da casa (hexa)decimal. #100, por exemplo. 1 está na segunda (e não terceira) casa (hexa)decimal, então #100=1*16^2=256.
"E o que isso tem a ver com cores?" Ah, é, o tutorial é a respeito de cores, né? Só mais um exemplo, então: que número, em formato decimal, seria #ff? Lembrando que #f=15, seria 15*16^1+15*16^0=255. 255!!! Qual a escala de cores? Varia de 0 a 255! Show de bola, né?
Então, pros computadores, fica tranquilo trabalhar com cores num sistema hexadecimal em que cada par de algarismos significa uma cor. #ff0000 é vermelho (255, 0, 0). #00ff00 é verde (0, 255, 0). Por aí vai.
Não falei que a escala de cores não terminava num número TÃO aleatório?

Só que o game maker, nesse ponto, é meio maluco. Ao invés de "#", ele usa "$" e, ao invés de usar a ordem vermelho-verde-azul, ele inverte pra azul-verde-vermelho. Não me pergunte porque, o Mark Overmars deve ter seus motivos. Daí, $0000ff é vermelho (255, 0, 0). Viva com isso ou mude de programa, mas o fato é que trabalhar com hexadecimais é mais fácil que usar make_color_rgb.

misturando cores prontas ou "merge_color"

Lembra que eu falei que tinha algumas funções pra criar cores? make_color_rgb e make_color_hsv não são as únicas, tem também o merge_color. Deixa eu traduzir a explicação do manual, aqui:
manual escreveu:merge_color(cor1, cor2, quantidade) Retorna uma cor misturada entre cor1 e cor2. A mistura é determinada pela quantidade. Um valor de 0 corresponde à cor1, um valor de 1, à cor2, e valores intermediários, às cores mescladas.
É isso. Eu acho que é mais fácil que fazer um monte de matemática pra fazer uma cor. Na prática, seria algo do tipo:

Código: Selecionar todos

//faz a mesma coisa que merge_color(cor1, cor2, quantidade)
make_color_rgb(color_get_red(cor1)*(1-quantidade)+color_get_red(cor2)*quantidade, color_get_green(cor1)*(1-quantidade)+color_get_green(cor2)*quantidade, color_get_blue(cor1)*(1-quantidade)+color_get_blue(cor2)*quantidade)
Algumas funções avançadas usam cores para misturar, como draw_sprite_ext. A forma que essa mistura acontece é um pouco mais complexa que considerar 50% de cada cor. Vamos deixar isso pro tutorial de blending, [strike]num futuro não tão próximo assim[/strike] (blending é um assunto [strike]complicado[/strike] menos simples). Por enquanto, considere que misturar uma cor sobre um desenho em tons de cinza te dá um desenho colorido. Pense em passar uma camada fina de tinta de dedo sobre um papel branco com um desenho impresso. Agora sua professora do primário ajudou, não ajudou?

alpha

Ok, quem vai me dizer o que quer dizer alpha?
"Alpha significa transparência. Ou melhor, opacidade! Quanto maior o alpha, mais opaco, quanto menor, mais transparente. Um alpha igual a zero significa que o objeto é invisível. Um alpha igual a um significa que ele é totalmente opaco."
Muito bom. Nota 9. Esse conhecimento serve pra muita coisa. Mas deixa eu te falar porque não dei nota 10. Porque NÃO EXISTE transparência. Sério, coloque TUDO com alpha igual a zero, inclusive os backgrounds. Você passou a ver através do monitor? Lógico que não.
Então o que é alpha? Lembra da função merge_color? Acabei de explicar, vai, lembra sim! A quantidade de cada cor varia de 0 a 1, não é? E o alpha, também varia de 0 a 1, não é? Coincidência?
Lembra que no tutorial de surfaces eu disse que a tela que vemos TAMBÉM é uma surface, que tudo é desenhado nela? O alpha é um merge_color entre a cor do fundo e a cor da instância. Alpha=0 significa cor do fundo. Alpha=1 significa cor da instância.
Aposto que isso abalou suas estruturas. Você está se sentindo fora da matrix. Nem tanto? Ah, você é duro na queda!
Na prática, isso não é tão importante, mas ajuda a entender o tutorial sobre blending, num futuro já não tão distante.

O código arco-íris
A turminha gay vai adorar essa. É só um codigozinho pra criar um sprite com todas as cores. Com um pouco de criatividade e mais algumas surfaces, você vai acabar usando isso pra personalizar seus personagens (tá, eu faço um tutorial sobre isso depois...).
O código cria a sprite variando os tons e saturação e, depois, aplica a cor sob o mouse numa outra sprite, com um degradê de branco pra preto, simulando o valor. Clique na cor pra fixar ela na sprite cinza com o degradê. Pra criar as sprites, eu uso surfaces, então leia o tutorial sobre surfaces (ou só copie e cole, sem entender nada, mas quem sai perdendo é você)
>obj_iris<
create:

Código: Selecionar todos

var Surf, i, j, cor;
Surf=surface_create(256, 256) //esses números não são coincidência (lembre-se que o "0" também ocupa um pixel)
surface_set_target(Surf)

draw_clear_alpha(0, 0) //apaga tudo o que tem e que não tem na surface
for(i=0; i<=255; i+=1){
 for(j=0; j<=255; j+=1){
 cor=make_color_hsv(i, j, 255) //cria as cores, variando tom e saturação
 draw_point_color(i, j, cor)   //desenha um pixel dessa nova cor
 }
 }
spr_iris=sprite_create_from_surface(Surf, 0, 0, 256, 256, 0, 0, 0, 0) //cria o sprite, todo colorido

surface_reset_target()
surface_free(Surf)

sprite_index=spr_iris //define o sprite criado como sprite_index
>obj_pb<
create:

Código: Selecionar todos

var Surf;

Surf=surface_create(64, 128)
surface_set_target(Surf)

draw_clear_alpha(0, 0) //apaga tudo o que tem e que não tem na surface
draw_rectangle_color(0, 0, 64, 64, $ffffff, $888888, $000000, $888888, 0)   //lembra da parte de hexadecimais?
draw_rectangle_color(0, 64, 64, 128, $ffffff, $ffffff, $ffffff, $ffffff, 0) //um retângulo branco, pra ver a cor pura
spr_cinza=sprite_create_from_surface(Surf, 0, 0, 64, 128, 0, 0, 0, 0)       //cria uma sprite com um degradê e uma parte toda branca

surface_reset_target()
surface_free(Surf)

sprite_index=spr_cinza //define o sprite criado como sprite_index
fixacor=false          //permite escolher a cor
cor=$ffffff            //começa com a cor totalmente branca
step:

Código: Selecionar todos

if instance_position(mouse_x, mouse_y, obj_iris){ //se o mouse está sobre o obj_iris
 if fixacor==false                            //se não escolheu a cor ainda
 cor=draw_getpixel(mouse_x, mouse_y)  //pega a cor sob o mouse
 }
 else if fixacor==false //se o mouse não está sobre o obj_iris e a cor não está fixada
 cor=$ffffff    //pega a cor branca

if mouse_check_button_pressed(mb_left) //se clicou
 fixacor=!fixacor               //fixa a cor atual (alterna entre true e false)
draw:

Código: Selecionar todos

draw_sprite_ext(sprite_index, 0, x, y, 1, 1, 0, cor, 1) //desenha o sprite mesclado com a cor atual
if fixacor{                                             //se escolheu alguma cor
 draw_rectangle_color(x-5, y-5, x+64+5, y+128+5, cor, cor, cor, cor, 1) //desenha um retângulo em volta do sprite
 }
Pronto. Crie uma instância de cada um desses objetos na room e divirta-se. Lembre-se de dar um espaço razoável entre elas, porque o sprite do obj_iris terá 256x256 pixels e você não quer sobreposição de sprites.

Responder

Quem está online

Usuários navegando neste fórum: Nenhum usuário registrado e 3 visitantes