29
6ª Parte: Gráficos no Qbasic Finalmente gráficos! Nesta parte iremos estudar as principais rotinas gráficas utilizando o Qbasic. No FreeBasic temos algumas alterações e estas serão tratadas mais adiante. Comandos estudados até agora: Parte 1 Parte 2 Parte 3 Parte 4 Parte 5 - REM - CLS - PRINT - INPUT - LOCATE - END - COLOR - SLEEP - UCASE$ - LCASE$ - LEN - LEFT$ - RIGHT$ - MID$ - LTRIM$ - RTRIM$ - SPACE$ - STR$ - VAL - ASC - CHR$ - TIME - DATE$ - TIMER - IF / THEN - IF / THEN / ELSE - IF / THEN / ELSEIF -SELECT CASE - GOTO -PRINT SPC(N) -PRINT USING - LINE INPUT - INKEY$ - DO / LOOP - EXIT - WHILE / WEND - FOR / NEXT - GOSUB / RETURN - SUB / END SUB - FUNCTION / END FUNCTION - DEF FN - SCREEN (gráficos) Para que as primitivas gráficas funcionem deve-se executar o programa no modo gráfico, o que é feito utilizando o comando SCREEN. Qualquer dúvida, dê uma olhada na 5ª parte para rever as principais janelas gráficas disponíveis. Os exemplos ilustrados aqui serão executados em SCREEN 9 ou SCREEN 12. Mas sinta-se a vontade para utilizar o screen que desejar. PSET :: Esta função desenha um ponto na tela em média ou alta resolução. Sintaxe: PSET (coordenada X, coordenada Y), cor Observação: A coordenada X corresponde as colunas. As coordenadas Y correspondem as linhas. A cor é a cor que o ponto será exibido. Caso seja omitido ele será impresso com a cor corrente do foreground (ou seja, cor da “frente” ou da fonte). Ex: SCREEN 12 DIM t AS INTEGER DIM x, y AS SINGLE FOR t = 1 TO 640: ' tempo y = .1 * t ^ 2: ' função horária do MUV (ajustado ao programa) x = 9 * t: ' função horária do MU PSET (x, y), 3: ' imprime a posição do projétil para cada t NEXT t Observações: 1] O sistema de coordenadas do vídeo é diferente do sistemas que estamos acostumados. Geralmente imprimimos gráficos ou pontos num sistema carteziano ortogonal tomando a origem (posição 0,0) como 42

06-graficos

  • Upload
    js912

  • View
    31

  • Download
    1

Embed Size (px)

Citation preview

Page 1: 06-graficos

6ª Parte: Gráficos no Qbasic Finalmente gráficos! Nesta parte iremos estudar as principais rotinas gráficas utilizando o Qbasic. No FreeBasic temos algumas alterações e estas serão tratadas mais adiante.

Comandos estudados até agora:

Parte 1 Parte 2 Parte 3 Parte 4 Parte 5- REM- CLS- PRINT- INPUT- LOCATE- END

- COLOR- SLEEP- UCASE$- LCASE$- LEN- LEFT$- RIGHT$- MID$- LTRIM$- RTRIM$- SPACE$- STR$- VAL- ASC- CHR$

- TIME- DATE$- TIMER- IF / THEN- IF / THEN / ELSE- IF / THEN / ELSEIF-SELECT CASE- GOTO-PRINT SPC(N)-PRINT USING- LINE INPUT- INKEY$

- DO / LOOP- EXIT- WHILE / WEND- FOR / NEXT

- GOSUB / RETURN- SUB / END SUB- FUNCTION / END FUNCTION- DEF FN- SCREEN (gráficos)

Para que as primitivas gráficas funcionem deve-se executar o programa no modo gráfico, o que é feito utilizando o comando SCREEN. Qualquer dúvida, dê uma olhada na 5ª parte para rever as principais janelas gráficas disponíveis. Os exemplos ilustrados aqui serão executados em SCREEN 9 ou SCREEN 12. Mas sinta-se a vontade para utilizar o screen que desejar. PSET :: Esta função desenha um ponto na tela em média ou alta resolução. Sintaxe: PSET (coordenada X, coordenada Y), cor Observação: A coordenada X corresponde as colunas. As coordenadas Y correspondem as linhas. A cor é a cor que o ponto será exibido. Caso seja omitido ele será impresso com a cor corrente do foreground (ou seja, cor da “frente” ou da fonte). Ex:SCREEN 12DIM t AS INTEGERDIM x, y AS SINGLE FOR t = 1 TO 640: ' tempo y = .1 * t ^ 2: ' função horária do MUV (ajustado ao programa) x = 9 * t: ' função horária do MU PSET (x, y), 3: ' imprime a posição do projétil para cada tNEXT t

Observações:1] O sistema de coordenadas do vídeo é diferente do sistemas que estamos acostumados. Geralmente imprimimos gráficos ou pontos num sistema carteziano ortogonal tomando a origem (posição 0,0) como

42

Page 2: 06-graficos

estando no “canto inferior esquerdo”. Mas no Qbasic, assim como em outros compiladores, a origem do sistema de coordenadas encontra-se no “canto superior esquerdo”. Cuidado para não confundir isto! Veja os screenshots abaixo:

2] Podemos imprimir pontos por referência, ou seja, em relação a um ponto já desenhado. Para isto utilizamos o termo STEP depois do PSET. STEP significa “passo”, é o mesmo que dizer: ande tantos “passos” em relação ao ponto original.Ex1: PSET STEP (5,-5) ´ Desenha um ponto 5 colunas à direita e 5 linhas acima do ponto ativado. A esse tipo de representação dá-se o nome de representação relativa. Ex2:SCREEN 12PSET (320, 240), 7: 'desenha um ponto no centro do v¡deo ' vamos desenhar um ponto a 10 pixels a esquerda do ponto original na cor vermelhaPSET STEP(-10, 0), 4 ' vamos desenhar um ponto a 30 pixels acima do ponto anterior na cor amareloPSET STEP(0, -30), 14 '////////// Observacao ////////////'Note que o segundo PSET foi relativo ao último PSET e não ao primeiro End

3] Quase todas as primitivas terão opções de cor. Abaixo segue o número das cores disponíveis para o parâmetro cor (para alguns screens, veja tabela do tutorial 6).

Número Cor

43

Page 3: 06-graficos

0 Preto

1 Azul

2 Verde

3 Azul-ciano

4 Vermelho

5 Magenta

6 Marrom

7 Branco

8 Cinza

9 Azul brilhante

10 Verde brilhante

11 Ciano claro

12 Vermelho brilhante

13 Magenta brilhante

14 Amarelo

15 Branco (alta intensidade)

Vale uma ressalva aqui. No comando COLOR, se você somar 16 a qualquer cor da tabela acima para a cor da fonte, a fonte será exibida na cor escolhida só que piscando (é o que chamamos de cor intermitente). 4] O comando PRESET (X,Y), COR é similar a PSET. A diferença é que se nenhuma cor for especificada para PRESET, a cor de fundo 0 (zero) é selecionada. Assim, PRESET (X,Y) vai desenhar um ponto sobre o screen (vídeo) na cor zero (0). Não é difícil perceber que PSET (X,Y),0 é idêntico a PRESET (X,Y). LINE :: Esta instrução permite desenhar linhas, retângulos vazios ou preenchidos. Sintaxe: LINE (X1,Y1) – (X2,Y2) [, COR, [B|BF], [ESTILO]] Onde: - (X1,Y1) :: coordenadas do primeiro ponto da linha. Lembre-se X1 (coluna 1) e Y1 (linha 1). - (X2,Y2) :: coordenadas do último ponto da linha. - COR :: cor da linha (veja a tabela) - B|BF :: se o parâmetro for B irá desenhar um retângulo vazio e se BF irá desenhar um retângulo preenchido na cor escolhida. - ESTILO :: estilo da linha. Ex:SCREEN 12CLS LOCATE 29, 1: PRINT "Desenha uma linha da posicao 2,2 at‚ 100,100";COLOR 2: LOCATE 30, 1: PRINT "Tecle algo"; : COLOR 15LINE (2, 2)-(100, 100), 4SLEEP

44

Page 4: 06-graficos

GOSUB limpacampo LOCATE 29, 1: PRINT "Desenha uma linha da posicao 340,220 at‚ 680,220";COLOR 2: LOCATE 30, 1: PRINT "Tecle algo"; : COLOR 15LINE (340, 220)-(680, 220), 14SLEEPGOSUB limpacampo LOCATE 29, 1: PRINT "Desenha um quadrado início posicao 2,2 e t‚rmino 100,100";COLOR 2: LOCATE 30, 1: PRINT "Tecle algo"; : COLOR 15LINE (2, 2)-(100, 100), 2, BSLEEPGOSUB limpacampo LOCATE 29, 1: PRINT "Desenha um quadrado preenchido";COLOR 2: LOCATE 30, 1: PRINT "Tecle algo"; : COLOR 15LINE (101, 101)-(200, 200), 6, BFSLEEPGOSUB limpacampo LOCATE 29, 1: PRINT "Finalmente, desenha uma linha com estilo...";COLOR 2: LOCATE 30, 1: PRINT "Tecle algo"; : COLOR 15LINE (201, 201)-(300, 100), , , &HF00FSLEEPGOSUB limpacampo ENDlimpacampo: LOCATE 29, 1: PRINT SPC(70); LOCATE 30, 1: PRINT SPC(70);RETURN

Observações:1] É possível desenhar linhas por referência, ou seja, o ponto inicial da linha começar a ser traçado a partir do ultimo ponto da linha anterior. Isto é muito útil pois permite a criação de curvas, a impressão de gráficos, etc. Sintaxe: LINE –(X2,Y2), COREx: Eis uma modificação do primeiro exemplo que imprime pontos (PSET) SCREEN 12DIM t AS INTEGERDIM x, y AS SINGLE PSET (0, 0), 3: ' coloca a referˆncia na posicao 0,0FOR t = 1 TO 640: ' tempo y = .1 * t ^ 2: ' função horária do MUV (ajustado ao programa) x = 9 * t: ' função horária do MU LINE -(x, y), 3: ' imprime uma linha após a outra, desenhando a trajetória do projétil

45

Page 5: 06-graficos

NEXT t

Outra maneira seria, ao invés de escrever LINE –(X2,Y2), COR escrever LINE STEP(0,0)-(X2,Y2), COR. 2] O estilo da linha é um parâmetro que deve ser passado ao comando em hexadecimal. O Qbasic reconhece os valores hexadecimais através do prefixo “&H”. Abaixo segue alguns estilos.

Código hexadecimal Estilo

&HF00F Traçado com linhas extendidas

&HF0F0 Traçado com linhas curtas

&H8888 Pontilhado espaçado

&HAAAA Pontilhado

&HFAFA Traçado + pontilhado

&H1111 Pontilhado médio

Ex: SCREEN 12 LINE (0,0)-(400,400),,, &HF00F: ‘// Mude os códigos para ver os efeitos

Para o formato da linha exibido no display, ou simplesmente o “estilo” da linha, é possível criar diferentes estilos obtendo, desta forma, uma reta totalmente personalizada. O estilo é feito de um conjunto de 16 bits, onde o bit “1” significa ligado (pixel aceso) e o bit “0” significa desligado (pixel apagado). Veja a ilustração abaixo:

A palavra acima (conjunto de bits) equivalem em hexadecimal a AAAA, pois A = 1010. Agora ficou fácil! Basta criar a sua combinação de bits, passar a palavra para hexadecimal e pronto! Está criado o estilo. Veja: 1100110011001100 __ __ __ __ __ (&HCCCC) 1110111011101110 ___ ___ ___ ___ (&HEEEE) 1111100011111000 _____ _____ (&HF8F8) 1111111100000000 ________ (&HFF00) 3] É possível desenhar linhas tomando um ponto como referência, ou seja, a partir de coordenadas iniciais traçar retas relativas a esta coordenadas. É semelhante ao que fizemos ao imprimir pontos utilizando coordenadas relativas.

46

Page 6: 06-graficos

Vejamos como isto é feito: LINE (100,100) – STEP(50, - 30) ‘// O comando acima vai desenhar uma linha de (100,100) até (150, 70) LINE (100,100)-STEP(-50,-50) ‘// O comando acima vai desenhar uma linha de (100,100) até (50,50) LINE (340,220)-STEP(100,100),4,B,&HF0F0 ‘// Este comando irá desenhar uma caixa vazia, com bordas traçadas na cor vermelha cuja as coordenadas do canto superior direito são 340,220 e as do canto inferior esquerdo estão a 100 pixels mais “abaixo” e 100 pixels mais a “direita”, ou seja, na coordenada 440, 320. Abaixo segue a listagem de um exemplo interessante utilizando linhas! Ao rodar, o programa irá transformar seu vídeo num radar multicolorido. SCREEN 12cor = 1DO FOR n = 0 TO 679 STEP .1 LINE (340, 220)-(n - 1, 0), 0 LINE (340, 220)-(n, 0), cor NEXT n FOR n = 0 TO 439 STEP .1 LINE (340, 220)-(680, n - 1), 0 LINE (340, 220)-(680, n), cor NEXT n FOR n = 679 TO 0 STEP -.1 LINE (340, 220)-(n + 1, 440), 0 LINE (340, 220)-(n, 440), cor NEXT n FOR n = 439 TO 0 STEP -.1 LINE (340, 220)-(0, n + 1), 0 LINE (340, 220)-(0, n), cor NEXT n cor = cor + 1 IF cor = 15 THEN cor = 1LOOP UNTIL INKEY$ <> ""END

Alguns exemplos do uso do comando LINE podem ser baixados na página criada especificamente para estes tutoriais (visite http://ddj.orgfree.com). CIRCLE :: Desenha círculos, arcos, “pizzas” e elipses. Sintaxe: CIRCLE (X,Y), raio [,cor [,inicio, fim [, aspecto]]]

47

Page 7: 06-graficos

Onde: - (X,Y) :: coordenadas do centro do círculo - raio :: raio do círculo em pixels - cor :: cor do círculo (veja tabela acima) - início e fim :: correspondem ao ângulo inicial e final para o desenho de arcos. Devem ser especificados em radianos. - aspecto :: aspecto do círculo. Dependendo do valor ( >1 ou <1), teremos um círculo “achatado”, ou seja, uma elipse. Ex:CLSSCREEN 12 pi = 3.141593CIRCLE (340, 220), 100CIRCLE (340, 220), 100, , , , 5 / 18CIRCLE (340, 220), 95, 2, 1.2 * pi, 1.7 * piCIRCLE (340, 220), 105, 3, -1.3 * pi, -1.7 * pi

Observações:1] No segundo CIRCLE do exemplo acima, podemos notar uma série de virgulas sem parâmetros. Isto significa que foram ignorados. Repare que todos os parâmetros que, na sintaxe, estão entre colchetes, podem ser ignorados. Para fazer isto, basta não digitar nada entre as vírgulas. Neste caso, o programador desejou mudar o aspecto do circulo mas não quis mexer nas configurações default da cor, início e fim, assim omitiu estes parâmetros não colocando nada entre as virgulas correspondentes a estes parâmetros. 2] Ainda no segundo CIRCLE temos um valor para o “aspect ratio”, ou aspecto. Se o aspecto for omitido, será desenhado um circulo normal, agora, se o aspecto for diferente de 1 (que é o valor default), então teremos uma esfera achatada, ou seja, uma elipse. Um valor para aspecto menor que 1 irá achatar a esfera verticalmente, isto é, ela ficará alongada na direção X. Se aspecto for maior que 1, a esfera ficará achatada horizontalmente e alongada na direção Y.Ex: CIRCLE (340,220), 100 CIRCLE (340,200), 100, 2, , , 1.5 :’ uma elipse alongada na direção Y CIRCLE (340,200), 100, 4, , , 0.5 :’ uma epipse alongada na direção X

3] No terceiro círculo, temos um valor para início e fim. Estes valores determinam a faixa do arco que será desenhado. Note que eles foram dados em radianos. Se você não recorda a definição de radiano, sugiro procurar um livro de matemática básica. Para facilitar, veja o screenshot abaixo.

48

Page 8: 06-graficos

Valores positivos para início e fim irão desenhar um arco. Valores negativos para início e fim irá desenhar um arco com linhas ligadas ao centro do círculo, como uma fatia de pizza! Ex:ClsSCREEN 12DIM I AS SINGLE FOR I=0 TO 1 STEP .1 CIRCLE (340,220), 100, , , , INEXT IEND

PAINT :: Pinta uma área “fechada” por pixels bastando identificar um ponto dessa área, a cor desejada e o limite da área. Sintaxe: PAINT (X,Y), COR, BORDA Onde: (X,Y) :: ponto dentro da área fechada por um conjunto de pixels. COR :: cor da tinta. BORDA :: cor da borda da figura (cor do limite) Ex:

49

Page 9: 06-graficos

SCREEN 13 CIRCLE (100, 100), 20, 4 PAINT (100, 100), 2, 4 LINE (200, 50)-(250, 150), 7, b CIRCLE (200, 100), 40, 7 PAINT (201, 51), 8, 7 PAINT (201, 100), 9, 7 PAINT (199, 100), 1, 7

Observações : 1] A cor da borda do comando PAINT deve ser a mesma cor do contorno da figura que deseja pintar. Se você especificar uma cor de borda diferente o PAINT irá ignorar a borda da figura e passar a tinta sobre todo o desenho. 2] O parâmetro COR pode ser substituído por uma string contendo valores hexadecimais correspondendo a uma “mascara” de pintura. A expressão string deve ter no máximo 64 bytes. Isto permite criar TILES com belos efeitos. A combinação de bytes irá gerar um estilo específico de pintura.

Vejamos como isso é feito: Desejamos criar uma “mascara” para pintura de um “TILE” com apenas 3 bytes tendo a seguinte combinação de código: Byte 0 1 1 0 0 0 1 0 1 CHR$(&HC5)Byte 1 0 1 0 1 1 0 1 0 CHR$(&H5A)Byte 0 1 1 1 1 1 1 1 0 CHR$(&H7E) Aqui criamos uma máscara com apenas três bytes, mas lembre-se, uma máscara pode ter no máximo 64 bytes. O código acima é escrito é traduzido para o Qbasic da seguinte maneira: String$ = CHR$(&HC5) + CHR$(&H5A) + CHR$(&H7E) Agora, no lugar do parâmetro COR, basta substituir pela String$. Ex:SCREEN 12 '// Desenha dois circulos com bordas na cor 1 (sera a cor limite para o paint)CIRCLE (340, 200), 100, 1CIRCLE (340, 200), 150, 1

50

Page 10: 06-graficos

'// cria as duas strings que serao as mascaras de pintura '// uma com 3 bytes e outra com 4 bytes. '// sinta-se a vontade para mudar os parƒmetros ou adicionar bytes '// para ver os efeitos gerados tile1$ = CHR$(&HFF) + CHR$(&HF0) + CHR$(&HAA) tile2$ = CHR$(&H11) + CHR$(&H33) + CHR$(&HFF) + CHR$(&H56) '// pinta as reas desejadas (note que o limite ‚ a cor 1) PAINT (340, 200), tile1$, 1 PAINT (380, 340), tile2$, 1End

Modifique o exemplo acima quantas vezes for necessário até pegar a jeito de criar as máscaras do jeito que desejar. Se tiver paciência, crie uma com 64 bytes! Novamente deve ficar claro que a cor limite é muito importante, caso contrário, o PAINT irá cobrir completamente sua figura. DRAW :: Este comando desenha um objeto que foi previamente especificado por uma string. Sintaxe: DRAW string O comando DRAW permite a construção de figuras que uma vez definidas dispensam sua elaboração ponto a ponto cada vez que forem usadas. A string contem uma série de parâmetros que dizem como os pontos serão exibidos criando desta forma uma figura. Esses parâmetros estão listados abaixo:

U n :: norte n pontosD n :: sul n pontosL n :: oeste n pontosR n :: leste n pontosE n :: diagonal norte-leste (nordeste) n pontosF n :: diagonal sul-leste (sudeste) n pontosG n :: diagonal sul-oeste (sudoeste) n pontoH n :: diagonal norte-oeste (noroeste) n pontos

51

Page 11: 06-graficos

O movimento começa a partir do último ponto referenciado. Ex1:CLSSCREEN 12PSET (100, 100), 2 :’// Ajusta o ponto inicial e define qual será a cor da figuraDRAW "d50 r50 u50 l50 d50" :’// desenha um retângulo verde PSET (340, 220), 4 :’// Define o ponto inicial da construção da nova figuraDRAW "g40 r80 h40" :’// Desenha um triângulo vermelho

Muitas vezes queremos desenhar a mesma figura diversas vezes. Neste caso basta atribuirmos a sequência a uma string, assim o código fica mais limpo e fácil de entender. Vejamos: Ex2:CLSSCREEN 12q$ = "d50 r50 u50 l50 d50"t$ = "g40 r80 h40" FOR i = 20 TO 600 STEP 50 PSET (i, 4), 2 DRAW q$ PSET (i, 404), 2 DRAW q$NEXT iFOR i = 54 TO 400 STEP 50 PSET (20, i), 2 DRAW q$ PSET (570, i), 2 DRAW q$NEXT iPSET (340, 220), 4DRAW "g40 r80 h40" END

Rode o exemplo acima e tente desvendar o código! Não é difícil. Os parâmetros do comando DRAW podem ser classificados em MOVER E DESENHAR, PREFIXOS e AÇÕES. A tabela abaixo abrange todos eles:

Comando Formato do comando

Efeito Parâmetros

MOVER E DESENHAR

M x, yM +x, +y

Para um ponto específico (x,y)Para um ponto específico (X + x, Y + y)

x, y = coordenadas absolutasX, Y = último ponto referenciado

52

Page 12: 06-graficos

U nD nR nL nE nF nG nH n

Move para cimaMove para baixoMove para direitaMove para esquerdaDiagonal p/ cima e p/ direitaDiagonal p/ baixo e p/ direitaDiagonal p/ baixo e p/ esquerdaDiagonal p/ cima e p/ esquerda

n linhasn linhasn colunasn colunasn = distância diagonaln = distância diagonaln = distância diagonaln = distância diagonal

PREFIXOS B [mover e desenhar]N [mover e desenhar]

Move sem desenharDesenha linha do ponto corrente ao ponto inicial

AÇÕES A n TA n S n C n P tinta, limite X variável

Gira todos os pontos subsequentes no sentido anti-horário. Gira de um ângulo n Escala distâncias subsequentes Seleciona a cor de uma dada paleta Pinta uma dada área Executa subcomandos de uma string

n = ângulo de rotação0 = 0 1=90 2= 180 3=270 n = ângulo de rotação-360 ≤ n ≤ 360 n > 0 sentido horário n < 0 sentido anti-horário n = fator de escala1 ≤ n ≤ 255 n = 0 ou 1 (modo 640x200)n = 0, 1, 2 ou 3 (modo 320x200) tinta = cor da tintalimite = cor do limite variável = string que contem outros subcomandos

Para que possamos entender perfeitamente como se processa estes comandos, segue alguns exemplos.Ex1:SCREEN 12 '// Desenha uma caixa box$ = "u20 r28 d20 l28" '// define a cor e move o início da construção da caixa para o ponto (340,220)

53

Page 13: 06-graficos

draw "c14; m340,220" '// desenha a caixa draw box$ '// tecle algo sleep '// define uma nova cor e move, em relação ao ponto (340,220), para (370,250) draw "c2; m+30,+30" draw box$ sleep

Observação: Ambos os movimentos com o comando M são feitos sem referência a qualquer prefixo, logo uma linha será desenhada do ponto inicial até o ponto referenciado. Veja o screenshot abaixo.

Experimente colocar o prefixo B antes dos comando Mx,y. As linhas não serão desenhadas. Veja...

54

Page 14: 06-graficos

Ex2:SCREEN 12 '// Desenha uma caixa box$ = "u70 r78 d70 l78" '// define a cor e move o início da construção da caixa para o ponto (340,220) DRAW "c14; bm340,220" '// desenha a caixa DRAW box$ FOR i = 1 TO 360 STEP 10 DRAW "ta" + STR$(i) DRAW box$ NEXT i SLEEP

55

Page 15: 06-graficos

Ex3:SCREEN 12 '// Desenha uma caixa box$ = "u70 r78 d70 l78" '// define a cor e move o início da construção da caixa para o ponto (340,220) DRAW "c14; bm340,220" '// desenha a caixa DRAW box$ DRAW "bm-150,150; s7" DRAW box$ SLEEP

56

Page 16: 06-graficos

Explore estes comandos a exaustão pois, provavelmente, precisará dele na implementações de rotinas gráficas mais elaboradas. WINDOW :: Permite a redefinição das coordenadas do vídeo (screen). Sintaxe: WINDOW [[SCREEN] (X1,Y1)-(X2,Y2)] Onde: SCREEN :: Parâmetro opcional. Se referenciado, mantém as coordenadas iniciais no canto superior esquerdo da janela. (X1,Y1) :: Coordenadas do canto superior esquerdo da janela (X2,Y2) :: Coordenadas do canto inferior direito da janela. O WINDOW irá nos permitir desenhar objetos num novo sistema de coordenadas espaciais (sistema de coordenadas globais) que não apresenta ‘limite lógico’ do sistema de coordenadas do screen (sistema de coordenadas físico). Os gráficos são “re-escalados” para o novo sistema de coordenadas quando o comando é referenciado.

57

Page 17: 06-graficos

Sem o comando WINDOW o screen do PC é configurado de tal maneira que o canto superior esquerdo corresponde a origem do sistema de coordenadas, ou seja, o ponto (0,0). Sendo o canto inferior direito as coordenadas da resolução máxima que está sendo usada (RESXMAX, RESYMAX). Veja o exemplo abaixo:Ex1:screen 12window (-10,-10)-(10,10) :’// Agora a janela inicia com o canto inferior esquerdo como (-10,-10) e superior direito como (10,10). A coordenada (0,0) line (0,0)-(10,10),1 :’// está no centro do vídeo. Repare o comando line.sleep

Ex2:screen 12window screen (-10,-10)-(10,10) ‘:// se for referenciado o parâmetro opcional SCREEN então as coordenadas iniciais, no caso, (-10,-10) estaráline (0,0)-(10,10),1 ‘// no canto superior esquerdo e as coordenadas (10,10) no canto inferior direito. Veja como ficou o line agora!sleep

58

Page 18: 06-graficos

O WINDOW é bastante útil na construção de programas que devem exibir gráficos com funções matemáticas, por exemplo. Ex3:SCREEN 12pi = 3.1415DIM x, y AS SINGLE WINDOW (-10!, -10!)-(10!, 10!)LINE (-10, 0)-(10, 0), 14, , &HF0F0LINE (0, -10)-(0, 10), 14, , &HF0F0 PSET (-10, 2 * SIN(-10)), 2FOR x = -10! TO 10! STEP .1 y = 2 * SIN(x) LINE -(x, y), 2NEXT xSLEEP

Além disso, o WINDOW, nos dá a liberdade de fazermos um ZOOM ou PAN (mover) imagens sobre o screen, bastando que se mude as coordenadas da janela. Se aumentarmos os valores dos “corners” a imagem

59

Page 19: 06-graficos

parecerá menor, se diminuirmos, ela ficará maior. Se mudarmos as coordenadas dos cantos igualmente, iremos criar um efeito de movimento da figura. Deixarei esta implementação para o leitor como treino. VIEW :: Este comando permite criar portas de visualização na janela. Sintaxe: VIEW [[SCREEN] [(X1,Y1)-(X2,Y2)[,COR][,BORDA]]]] ] Onde: - SCREEN :: é opcional. Se for referenciado os pontos serão absolutos e podem estar dentro ou fora do limite da janela. - (X1,Y1) :: coordenadas do canto superior esquerdo da janela. - (X2,Y2) :: coordenadas do canto inferior direito da janela. - COR :: cor de preenchimento da janela - BORDA :: cor da borda da janela O comando VIEW irá escalar os objetos dependendo do tamanho das “viewports” (portas de visualização). As coordenadas das janelas de visualização são determinadas pelo último comando WINDOW executado, desta forma, os objetos são escalados e exibidos nas “viewports”. Execute o exemplo abaixo:Ex:SCREEN 12WINDOW (0, 0)-(1000, 1000)LOCATE 2, 2: PRINT "Pense nas possibilidades"LINE (0, 0)-(1000, 1000), , BGOSUB circuloVIEW (340, 10)-(630, 160), 1, 3GOSUB circuloVIEW (340, 170)-(630, 470), 8, 14GOSUB circuloSLEEPEND circulo:CIRCLE (240, 150), 40, 2, , , 5 / 18CIRCLE (240, 150), 40, 2, , , 1RETURN

60

Page 20: 06-graficos

GET / PUT :: São recursos usados para capturar uma imagem no vídeo e exibí-la. Estes comandos são usados em animações gráficas. O GET permite capturar um sprite e o PUT permite exibir o sprite no vídeo. Para animar o sprite, basta colocar uma sequência de PUTs. Sintaxe: GET (X1,Y1)-(X2,Y2), matriz PUT (X1,Y1), matriz [, ação] Onde: Para o GET: - (X1,Y1) :: coordenadas do canto superior esquerdo. - (X2,Y2) :: coordenadas do canto inferior direito. - matriz :: matriz onde a imagem será armazenada. Para o PUT: - (X1,Y1) :: coordenada do canto superior esquerdo da imagem capturada. A imagem será colocada no vídeo com esta coordenada. - matriz :: matriz onde a imagem está armazenada. - ação :: parâmetro opcional. Determina como a imagem será exibida.

61

Page 21: 06-graficos

Observações:1] Se você deseja usar sprites em seu programa utilizando GET e PUT, a primeira coisa que deve fazer é dimensionar a matriz do sprite ou tile. Veja como:

DIM bola(tamanho)

Onde tamanho corresponde a memória que será reservada para guardar a figura capturada. Este valor depende da resolução utilizada. Algumas fórmulas para a determinação deste valor podem ser utilizadas. Veja a tabela abaixo:

SCREEN 1 tamanho = INT((c_pixels + 1) * 1.125) * (l_pixels + 1)

SCREEN 2, 11 tamanho = (c_pixels + 1) * (l_pixels + 1)

SCREEN 7, 9, 12 tamanho = (c_pixels + 1) * 4 * (l_pixels + 1)

SCREEN 13 tamanho = INT((c_pixels + 1) * 1.875) * (l_pixels + 1)

Existe uma outra equação que pode ser usada para determinar o número de bytes que devem ser reservados para o tamanho da imagem:

Tamanho = 4 + INT[(c_pixels*B + 7) / 8] * l_pixels

Onde: - B :: bits por pixel (2 para média resolução, e 1 pra alta resolução) - c_pixels :: tamanho da coluna em pixels (horizontal). - l_pixels :: tamanho da linha em pixels (vertical). Existem várias equações acima. As quatro primeiras consegui em pesquisa na internet e a última num livro sobre computação gráfica (no final do curso estará disponível a bibliografia consultada). Fiz alguns testes com a última equação mas ocorreu erros. A equação que melhor funcionou foi a terceira equação da tabela. De um modo geral, utilizei a equação c_pixels*l_pixels e funcionou muito bem. 2] As opções de ação para o comando PUT são:

PSET Desenha a imagem exatamente como foi capturada por GET, incluindo o fundo (background). Se você colocar uma imagem com esta opção com um fundo diferente da cor do fundo de captura irá aparecer o retângulo com o fundo original que foi capturado com GET.

PRESET Desenha cada pixel invertido da cor original, incluindo o background. A imagem aparece como um retângulo com cores de fundo invertidas. Difícil explicar, faça um teste!

AND Calculos de pixel. A imagem colocada sobre o background não irão aparecer. A imagem irá aparecer como é no original quando colocada numa área branca.

OR Calculos de pixel. A imagem colocada sobre o background irão aparecer

62

Page 22: 06-graficos

normalmente, mas não irá aparecer em áreas brancas.

XOR Este é o método default.

Ex:SCREEN 12 WINDOW (-4, -4)-(4, 4) :’ Redefine o sistema de coordenadas do screen VIEW (10, 20)-(630, 470), , 3 :’ Cria uma janela de visualização CIRCLE (0, -1), 1, 3 :’ Cria circulos CIRCLE (-.87, .5), 1, 3 CIRCLE (.87, .5), 1, 3 PAINT (0, 2), 1, 3 :’ Pinta os círculos PAINT (0, -1), CHR$(&HAA), 3 PAINT (-.87, .5), CHR$(&H55), 3 PAINT (0, 1), CHR$(&H11), 3 PAINT (-.87, -.5), CHR$(&HFF), 3 PAINT (.87, -.5), CHR$(&H22), 3 PAINT (0, 0), CHR$(&HCC), 3 PRINT "Tecle algo" SLEEP WINDOW: VIEW :’ Reseta a janela e a viewport DIM array(13204) :’ dimensiona a matriz onde será colocada a imagem GET (190, 90)-(450, 350), array :’ Captura a imagem CLS PUT (50, 50), array, PSET :’ coloca a imagem na posição 50,50 com o ajuste PSET LOCATE 1, 1: PRINT "PUT com PsET. [[ Tecle algo ]] " SLEEP CLS LINE (80, 80)-(200, 200), 2, BF LINE (190, 190)-(300, 300), 15, BF PUT (50, 50), array, PRESET LOCATE 1, 1: PRINT "PUT com PRESET. [[ Tecle algo ]] " SLEEP CLS LINE (80, 80)-(200, 200), 2, BF LINE (190, 190)-(300, 300), 15, BF PUT (50, 50), array, AND LOCATE 1, 1: PRINT "PUT com AND. [[ Tecle algo ]]" SLEEP CLS LINE (80, 80)-(200, 200), 2, BF LINE (190, 190)-(300, 300), 15, BF PUT (50, 50), array, OR

63

Page 23: 06-graficos

LOCATE 1, 1: PRINT "PUT com OR. [[ Tecle algo ]]" SLEEP CLS LINE (80, 80)-(200, 200), 2, BF LINE (190, 190)-(300, 300), 15, BF PUT (50, 50), array, XOR LOCATE 1, 1: PRINT "PUT com XOR. [[ Tecle algo ]]" SLEEP END

O exemplo acima ilustra bem todas as combinações do comando PUT. Rode o exemplo abaixo... Ex2:SCREEN 12LINE (2, 2)-(8, 8), 2, BFLINE (1, 1)-(9, 9), 14, B DIM quadrado(400)GET (0, 0)-(10, 10), quadrado FOR i = 1 TO 300 PUT (RND(1) * 600, RND(1) * 400), quadrado, XOR :’ Troque por PSET, PRESET, AND, OR e depois XOR. Veja os efeitos…NEXT iSLEEP

Veja alguns screenshots do exemplo acima.

Com PSET

64

Page 24: 06-graficos

Com PRESET

Com AND

65

Page 25: 06-graficos

Com OR

66

Page 26: 06-graficos

Com XOR

Espero que tenha ficado bem claro para o leitor o que vem a ser um SPRITE e como manipulá-los utilizando GET e PUT. Treine bastante estes comando residentes do Qbasic. Para quem está acompanhando também o DirectQB já deve ter percebido que existem diversos DQBput, cada um com uma finalidade específica para a manipulação de sprites. Alguns para escalar, outros para girar o sprite, combinação de cores, etc. Quem manda é a imaginação do programador combinar os efeitos de modo a gerar um visual bacana ou uma animação. Como já foi mencionado, uma animação em 2D nada mais é do que uma sequência de PUTs com matrizes de imagens diferentes (em posições diferentes), que passadas muito rápido dá a idéia de movimento. Iremos aprender a criar personagens 2D e a animá-los em tutoriais futuros. BSAVE / BLOAD :: O BSAVE é um comando que salva dados binários na forma de um arquivo no computador. A sintaxe do BSAVE é: BSAVE “arquivo”, endereço, tamanho Onde: - arquivo :: é o nome do arquivo que deseja salvar. - endereço :: é o endereço onde os dados serão salvos. Se for 0 (nulo) os dados serão armazenados na página de trabalho. - tamanho :: é o tamanho dos dados que deseja salvar em bytes. :: O BLOAD lê os dados anteriormente salvos com BSAVE, ou seja, carrega arquivos no formato binário e também BMP. A sintaxe do BLOAD é: BLOAD “arquivo” [, endereço]

67

Page 27: 06-graficos

Onde: - arquivo :: é o nome do arquivo que deseja carregar. - endereço :: é o endereço onde os dados estão contidos. Se for 0 (nulo) os dados serão carregados a partir da página de trabalho. Observações:1] Foi utilizado o termo “endereço” acima, mas em muitos livros e tutoriais a palavra utilizada é “offset”. Um offset nada mais é que um endereço de memória. Para que se possa trabalhar bem com esses endereços é necessário ter conhecimento do mapa de memória. Isto não será explorado aqui (caso seja necessário em tutoriais futuros, ai falaremos sobre como trabalhar com este mapa). 2] O BLOAD e BSAVE são comandos usuais para ler e salvar programas feitos em linguagem de máquina. Isto mesmo que você está lendo! É possível implementar rotinas em linguagem de máquina diretamente do QB. Estes programas em linguagem de máquina são chamados com a função CALL. 3] Em computação gráfica BSAVE e BLOAD pode ser utilizado para salvar e recuperar uma imagem no screen. 4] Em BSAVE, o offset 0 e o tamanho &H4000 especifica que a entrada de 16Kb do “buffer screen” é salvo por default no disco rígido. Uma vez que o arquivo foi criado com BSAVE ele pode ser carregado a qualquer momento com o comando BLOAD.Ex1: DIM Cube(1 TO 675)SCREEN 1 ' desenha uma caixa.LINE (140, 25)-(140 + 100, 125), 3, BDRAW "C2 BM140,50 M+50,-25 M+50,25 M-50,25"DRAW "M-50,-25 M+0,50 M+50,25 M+50,-25 M+0,-50 BM190,75 M+0,50" ' Salva o desenho na matriz “cube”GET (140, 25)-(240, 125), Cube ' Ajusta o segmento de memória onde sera armazenado a matriz cubeDEF SEG = VARSEG(Cube(1))BSAVE "figura.bmp", VARPTR(Cube(1)), 2700DEF SEG :' restaura a posição da memória default

Uma vez que salvamos a figura, podemos carregá-la.Ex2: DIM Cube(1 TO 675) ' Ajusta o modo de vídeo. O modo de vídeo precisa ter a mesma resolução do modo utilizado no desenho original.SCREEN 1

68

Page 28: 06-graficos

' Ajusta a posição do segmento de memória da matriz cubo para ler o gráfico contido na matriz cubo.DEF SEG = VARSEG(Cube(1))BLOAD "figura.bmp", VARPTR(Cube(1))DEF SEG :' recupera a figura armazenada no exemplo 1. ' Imprime o desenho sobre o screen.PUT (80, 10), Cube

Com esses comandos é possível fazer muitas coisas. Agora, cabe ao leitor treinar bem todos eles. O BSAVE e o BLOAD são os mais enjoados para se trabalhar. Tem que saber utilizar bem o BSAVE senão o BLOAD não irá conseguir carregar o arquivo. Existem diversas maneiras de contornar este problema. Algumas “ginásticas” são possíveis. Eu fiz uma destas “ginásticas” quando criei um editor de sprites a alguns anos atrás (na época tinha um 486). Atualmente não vale a pena utilizá-lo, mas na época eu não tinha editores disponíveis, além do PAINT. Neste curso você irá aprender a criar o seu próprio editor de SPRITES ou um PAINT, se preferir. É sempre bom saber criar as próprias ferramentas para apoio na criação de jogos.

EXERCÍCIOS:

1] Faça um programa que exiba no vídeo o símbolo das olimpíadas (aqueles cinco círculos coloridos). 2] Faça um programa que mostre um esboço da bandeira do Brasil no vídeo. [Seja criativo] 3] Idem para o programa anterior. Pinte a bandeira. 4] Faça um programa que imprima o gráfico de uma função qualquer do 2º grau. 5] Idem para o item anterior. Que imprima a função seno e cosseno. Mude os argumentos do seno e cosseno e veja o que acontece. Compare os resultados. Adote como função: y = A*sin (x) e y=A*cos(x).

69

Page 29: 06-graficos

6] Escreva um programa que imprima uma linha dado as coordenadas iniciais e finais, sem utilizar o LINE, utilizando somente o comando PSET. Compare a execução do seu programa com o comando LINE. 7] Escreva um programa que usa o comando PSET para desenhar um circulo centrado em (a,b) com raio r. A equação do círculo é dada abaixo:

X = r*cos(θ) + aY = r*sin(θ) + b

8] Tente implementar um editor de sprites simples.

9] Implemente um jogo da velha utilizando os recursos gráficos ensinados até aqui.

10] Monte um jogo de quebra cabeça em que se deve colocar os números de 1 a 8 em ordem numa rede quadrada de 9 lugares (matriz 3x3), sendo que um “espaço” da rede deverá estar sempre vazio para mover os números.

11] Monte um “gênius” (antigo brinquedo da Estrela) [Se vira nos trinta!!!] Obs: “Gênius” é um brinquedo que possui cinco cores. Ele acende uma cor e você deve apertar o botão da cor que acendeu. Em seguida ele acende aquela cor e mais uma, e você repete, então vai três cores, quatro, cinco e você deve repetir a seqüência corretamente. Ele vai contabilizando seus acertos, o jogo acaba quando você erra!

70