Você está na página 1de 14

7 Parte: Funes Matemticas

Agora comea a parte chata para muita gente: a matemtica! No tem jeito, fazer jogos sem esbarrar com a matemtica impossvel. Nesta parte iremos aprender a trabalhar com as principais funes matemticas presentes nos compiladores QB e FB. Alm dessas funes nativas, outros comandos sero explorados que permitir a manipulao de variveis numricas. Tambm veremos o uso da gerao de nmeros aleatrios, muito til em jogos. Se voc ainda no viu em seus estudos todas as funes apresentadas aqui, no se preocupe, isto no ir impedi-lo de fazer seus jogos. Se for um aluno do ensino fundamental ou iniciante do ensino mdio, no tardar a estudar tais funes na escola. As funes que no conhece podero ser puladas e vistas no futuro sem qualquer comprometimento ao andamento do curso. Vamos aos principais comandos: ABS :: Retorna o valor absoluto de um nmero. Ou seja, o valor positivo do nmero no interior do argumento de ABS. Ento, se fizer ABS(1) ou ABS(-1) o valor retornado pela funo ser 1. Ex:
DIM N AS INTEGER PRINT ABS ( -1 ) PRINT ABS ( -3.1415 ) PRINT ABS ( 42 ) PRINT ABS ( N ) N = -69 PRINT ABS ( N )

Observao: O primeiro PRINT com argumento N retornar zero pois a varivel N, apesar de j ter sido declarada, no possui valor algum atribudo a ela, portanto, vale 0. S depois o valor -69 foi atribudo a N e ento o PRINT ABS(N) retornar o valor absoluto de N, no caso, 69 (sem o sinal). Se preferir, pode entender ABS desta forma: ele transforma qualquer nmero negativo em positivo. Muito til em jogos. Veremos algumas aplicaes mais adiante.

FIX :: Funo matemtica que retorna a parte inteira truncada de um nmero de ponto flutuante. Ex:
CLS A=FIX(-65.12312) PRINT A :rem // retorna um nmero inteiro

O programa acima vai retornar -65. Voc pode entender o FIX como aquele comando que vai jogar tudo que tiver depois da vrgula fora. Observao: O compilador no reconhece a vrgula (,) como separador decimal e sim o (.). Ento se voc escrever um nmero como -65,12312 o compilador vai acusar erro. O correto escrever com ponto, ou 71

seja, -65.12312. Outra coisa, nada de usar separao de milhar, milho, bilho, etc. Por exemplo, o nmero 12.345.123 (doze milhes trezentos e quarenta e cinco mil e cento e vinte e trs), no deve jamais ser escrito desta forma (com os pontos). Escreva somente 12345123.

INT :: Retorna um nmero inteiro de ponto flutuante arredondado para o valor mais baixo do nmero informado. Por exemplo, se voc informar 4.5 o nmero inteiro de ponto flutuante arredondado mais baixo desse valor 4.0. Se fornecer -6.9, o inteiro de ponto flutuante mais baixo ser -7.0. Ex:
CLS A=INT(-6.7) B=INT(-7.1) C=INT(4.5) PRINT A;B;C

:rem // vai retornar -7.0, -8.0 e 4.0

Se estiver com dificuldade de enxergar o que est acontecendo no exemplo acima, observe a figura abaixo:

Observao: Numero de ponto flutuante significa nmero decimal, ou seja, que apresenta o ponto de separao da parte inteira da parte fracionria. Aqui utilizamos o termo nmero inteiro de ponto flutuante, isto significa que apesar de INT estar devolvendo a parte inteira do nmero ele ainda tratado como nmero de ponto flutuante apresentando a parte decimal como sendo 0 (zero). Ento, os nmeros retornados so -7.0, -8.0, 4.0, etc. Diferente de -7, -8 e 4, que seriam nmeros inteiros (sem ponto flutuante). Observe isto na hora de declarar as variveis.

CINT :: Faz praticamente a mesma coisa que INT, s que retorna um INTEIRO de 32 bits. Cuidado para no colocar nmeros muito grandes que esto fora da faixa de inteiros de 32 bits, caso contrrio acusar over flow (estouro).

72

Ex: Apenas mude o programa acima colocando CINT no lugar do INT.

MOD :: Este comando devolve o resto da diviso entre dois nmeros. Sintaxe: dividendo MOD divisor No lembra? Xiii... ento vamos relembrar a 5 srie!

Ex1:
cls a=12 b=5 c=a mod b print c sleep

:rem // a resposta ser 2, pois 12 dividido por 5 d 2 com resto 2!

Agora observe o exemplo abaixo com muito cuidado. Ex2:


PRINT 47 MOD 7 PRINT 5.6 MOD 2.1 PRINT 5.1 MOD 2.8 PRINT 5.5 MOD 2.8 SLEEP

Copie e cole no seu editor FreeBasic e execute o programa. O resultado ser: 5, 0, 2 e 0. Por que isto ocorre? Bem, o que o compilador faz arredondar os valores decimais para o inteiro mais prximo e s depois efetua a diviso para encontrar o resto. Vejamos: 47 dividido por 7 d como resultado (inteiro) o valor 6, pois 7x6=42, sobrando 5 para o resto. 5.6 dividido por 2.1, passa por um critrio de arredondamento. 5.6 est mais prximo de 6 e 2.1 est mais prximo de 2, ento o programa faz a diviso de 6 por 2, o que d como resultado inteiro 3 e resto 0. 5.1 dividido por 2.8, passa por um critrio de arredondamento. 5.1 est mais prximo de 5 e 2.8 est mais prximo de 3, ento o programa faz a diviso de 5 por 3, o que d como resultado inteiro 1, pois 3x1=3, sobrando 2 para o resto.

73

Agora, se o nmero estiver na coluna do meio, ou seja, com decimal 5, o programa o arredonda para cima. Ento 5.5 dividido por 2.8, para a ser 6 dividido por 3, o que d como resultado 2 e resto 0.

SGN :: Funo matemtica que retorna o sinal de um nmero. Ou seja, -1 para um nmero negativo, +1 para um nmero positivo e 0 (zero) se o nmero for nulo. Ex:
dim as integer a, b, c dim a,b,c as integer a=-5.6 b=+2.3 c=0 print sgn(a);sgn(b);sgn(c) sleep :rem // a sada ser -1, 1 e 0 // use este se estiver utilizando FREEBASIC // use este se estiver utilizando o QBASIC

SWAP :: Troca o valor de duas variveis. Sintaxe: SWAP 1 varivel, 2 varivel Ex:
' Este exemplo usa SWAP para ordenar dois nmeros Dim as single a, b Dim a as integer Dim b as integer // use este para FREEBASIC // use estes para QBASIC

INPUT "Entre com o primeiro nmero: "; a INPUT "Entre com o segundo nmero: "; b IF a > b THEN SWAP a, b PRINT "Os nmeros em ordem crescente so: "; PRINT a, b

Observao: Como foi ilustrado no exemplo, este comando muito importante quando desejamos ordenar nmeros. Imagine que deseja colocar uma srie de valores em ordem, o SWAP cai como um a luva. Muitssimo importante para jogos!

74

SQR :: Funo que d como resultado a raiz quadrada de um nmero. O nmero fornecido no argumento deve ser maior ou igual a zero para que a funo funcione corretamente. Um valor menor que zero no argumento retornar um erro. (S pra lembrar: No existe raiz quadrada de um nmero negativo!). Ex:
dim as single a, b, c dim a,b,c as single a=5.6 b=4.0 c=0 print sqr(a);sqr(b);sqr(c) sleep // use este para FREEBASIC // use este para QBASIC

Observaes: [1] Tirar a raiz quadrada de um nmero ( x ) o mesmo que elevar este nmero a . Ou seja, x 2 . Portanto, se voc quiser a raz e-nsima de um nmero basta elevar este nmero a 1/n. Isto , x n . Em BASIC fica y=x^(1/n). [2] A funo SQR EXTREMAMENTE importante na programao de jogos. Seja 2D ou 3D. ela que usamos para determinar a distncia entre os objetos numa cena. Veremos como implementar isto mais adiante.
1 1

LOG :: A funo LOG retorna o logaritimo de base e de um nmero (conhecido como logaritmo natural). O logaritmo natural de um nmero na notao matemtica escrita com LN e o LOG usado para o logaritmo de base 10, s que o BASIC usa o comando LOG para expressar o LN na matemtica, portanto, cuidado! Este comando requer um argumento que deve ser maior que zero. Se o nmero fornecido for zero, FreeBasic returnar infinity (menos infinito). Se o nmero for menor que zero, o FreeBasic retornar erro. Se o nmero uma varivel ainda no iniciada (que nenhum valor foi atribudo a ela) o FB retornar infinity ( ) . Abaixo segue o grfico da funo y ln x .

75

Ex:
' Esta funo permite que encontre o logaritmo de qualquer base FUNCTION LogBaseX (BYVAL Numero AS DOUBLE, BYVAL BaseX AS DOUBLE) AS DOUBLE LogBaseX = LOG( Numero ) / LOG( BaseX ) END FUNCTION PRINT "O logaritmo de 20 na base 10 : "; LogBaseX ( 20 , 10 ) PRINT "O logaritmo de 16 na base 2 : "; LogBaseX ( 16 , 2 ) SLEEP

EXP :: Esta funo retorna o valor da potncia e n onde n o argumento e e conhecido como nmero transcendental (o mesmo da base do logaritmo natural). O nmero e irracional e representado com 20 casas dado por 2.7182818284590452354. Para que o comando funcione um argumento deve obrigatoriamente fornecido. Se o argumento for muito grande, o FB retornar infinito. Se o argumento for muito pequeno o FB retornar zero. O limite exato baseado no processamento. Se o argumento ainda no foi inicializado, ele vale 0 (zero), ento a funo retornar 1. Abaixo ilustramos a funo y e x

76

Ex:
SCREENres 640,480,32 pi = 3.1415 DIM AS SINGLE x,y // Use para FREEBASIC (ser explicado no futuro)

Window (-10,-10)-(10,10) LINE (-10, 0)-(10, 0), &hffff00, , &HF0F0 LINE (0, -10)-(0, 10), &hffff00, , &HF0F0 pset (0, exp(-10.0)), &hff0000 FOR x = -10.0 TO 10.0 STEP .1 y=exp(x) LINE -(x, y), &hff0000 NEXT x SLEEP

Observao: O exemplo acima foi implementado para o FREEBASIC. Deixo como exerccio fazer o mesmo exemplo com o QBASIC. Se estiver tendo problemas para executar os programas grficos no QBASIC no Windows XP voc poder utilizar o Q64.

SIN :: Funo que retorna o seno do argumento como um nmero de preciso dupla entre -1 e 1. O nmero do argumento dado em radianos e no graus. O argumento pode ser qualquer expresso numrica vlida. Se o argumento for uma varivel ainda no inicializada, o resultado ser zero. Abaixo ilustramos a funo y sen(x)

Ex1: SCREENRES 640,480,32 pi = 3.1415 DIM AS SINGLE x,y Window (-10,-10)-(10,10)

77

LINE (-10, 0)-(10, 0), &hffff00, , &HF0F0 LINE (0, -10)-(0, 10), &hffff00, , &HF0F0 PSET (-10, 2 * SIN(-10)), &hff0000 FOR x = -10.0 TO 10.0 STEP .1 y = 6 * SIN(x) LINE -(x, y), &hff0000 NEXT x SLEEP

Ex2:
CONST PI AS DOUBLE = 3.1415926535897932 DIM a AS DOUBLE DIM r AS DOUBLE INPUT "Por favor, fornea o ngulo em graus: ", a r = a * PI / 180 :rem // Converte graus para radianos (o argumento deve estar em radianos) PRINT "" PRINT "O seno do angulo de " ; a; " graus "; SIN ( r ) SLEEP

ASIN :: a funo inversa do SIN, ou seja, se no seno fornecemos o ngulo em radianos para o argumento e obtermos o seno, no arco-seno fornecemos o seno no argumento e ele retorna o ngulo em radianos. Para o estudante mais avanado e que j viu trigonometria no 2 grau, torna-se conveniente dar uma revisada nessas funes trigonomtricas.

COS :: Funo que retorna o cosseno do argumento como um nmero de preciso dupla entre -1 e 1. O nmero do argumento dado em radianos e no graus. O argumento pode ser qualquer expresso numrica vlida. Se o argumento for uma varivel ainda no inicializada, o resultado ser 1. Abaixo ilustramos a funo y cos(x)

78

Ex1:
SCREENRES 640,480,32 pi = 3.1415 DIM AS SINGLE x,y Window (-10,-10)-(10,10) LINE (-10, 0)-(10, 0), &hffff00, , &HF0F0 LINE (0, -10)-(0, 10), &hffff00, , &HF0F0 PSET (-10, 2 * cos(-10)), &hff0000 FOR x = -10.0 TO 10.0 STEP .1 y = 6 * cos(x) LINE -(x, y), &hff0000 NEXT x SLEEP

Ex2:
CONST PI AS DOUBLE = 3.1415926535897932 DIM a AS DOUBLE DIM r AS DOUBLE INPUT "Por favor, entre com o ngulo em graus: ", a r = a * PI / 180 : rem // converte graus para radianos PRINT "" PRINT "O cosseno do ngulo de " ; a; " graus "; COS ( r ) SLEEP

Observao: As funes senos e cossenos so muito utilizadas em jogos, principalmente nos jogos 3D. So ideais para fazer manipulao de cmeras e esto presentes no sistema de coordenadas escolhido para a visualizao de objetos. Alm disso, pode ser utilizado como recurso de movimentao de certas peas de um jogo, por exemplo, uma pea que parece estar flutuando no ar, oscilando de cima a baixo. Geralmente tal rotina implementada pela funo seno ou cosseno, j que so funes peridicas (oscilantes).

79

ACOS :: a funo inversa do COS, ou seja, se no cosseno fornecemos o ngulo em radianos para o argumento e obtermos o cosseno, no arco-cosseno fornecemos o cosseno no argumento e ele retorna o ngulo em radianos. Deixo para o estudante a criao de exemplos do ASIN e ACOS com a sugesto nos exerccios propostos.

TAN :: Esta funo retorna a tangente do argumento como um valor de preciso dupla na faixa de menos infinito a mais infinito (,) . O argumento deve ser dado em radianos e no graus. O argumento pode ser qualquer expresso matemtica vlida. Se o nmero ainda no foi inicializado a funo retornar 0 (zero). Abaixo ilustramos a funo y tg (x)

Ex1:
SCREENRES 640,480,32 pi = 3.1415 DIM AS SINGLE x,y Window (-10,-10)-(10,10) LINE (-10, 0)-(10, 0), &hffff00, , &HF0F0 LINE (0, -10)-(0, 10), &hffff00, , &HF0F0 PSET (-10, 2 * TAN(-10)), &hff0000 FOR x = -10.0 TO 10.0 STEP .1 y = 6 * TAN(x) LINE -(x, y), &hff0000 NEXT x SLEEP

80

Ex2:
CONST PI AS DOUBLE = 3.1415926535897932 DIM a AS DOUBLE DIM r AS DOUBLE INPUT "Por favor, entre com o ngulo em graus: ", a r = a * PI / 180 : rem // Converte graus para radianos PRINT "" PRINT "A tangente do ngulo de " ; a; " graus "; TAN ( r ) SLEEP

ATAN :: a funo inversa do TAN, ou seja, se na tangente fornecemos o ngulo em radianos para o argumento e obtermos o tangente, no arco-tangente fornecemos a tangente no argumento e ele retorna o ngulo em radianos. Veja exerccios propostos.

CONST :: No uma funo, mas apenas um comando que diz o compilador que um determinado valor no programa ser sempre constante. Ex:
Rem // define o valor para a temperatura mxima e mnima do sistema CONST temperatura_minima AS INTEGER = 1 CONST temperatura maxima AS INTEGER = 10

Observao: Toda vez que iniciar um projeto de um jogo, provavelmente ter variveis e constantes a serem declaradas. Iremos adotar o critrio neste curso de sempre declarar as variveis usadas e o tipo bem como as constantes. Depois de adotada a resoluo do vdeo, escolha de pginas, etc, o prximo passo a ser feito.

RND :: Comando que retorna um decimal (ponto flutuante) que varia entre 0 e 1 (incluindo o 0 mas no incluindo o 1). Este comando utilizado para gerar nmeros aleatrios. Para obtermos nmeros maiores que um basta multiplicarmos o RND por um nmero inteiro. Vejamos: RND(1) RND(1)*10 RND(1)*10+1 = vai retornar um nmero qualquer compreendido entre 0 e 1. = vai retornar um nmero qualquer compreendido entre 0 e 9. = vai retornar um nmero qualquer compreendido entre 1 e 10.

Os nmeros gerados acima so de ponto flutuante. Portanto no primeiro caso poderamos ter como resposta o nmero 0.45667, no segundo o nmero 7.99876 e no terceiro 9.1002. Se desejarmos gerar nmeros inteiros basta utilizarmos o comando INT. INT(RND(1)*10+1) = vai retornar um nmero INTEIRO compreendido entre 1 e 10. Observaes:

81

[1] O computador tem a capacidade de gerar nmeros de forma quase aleatria (por isso o uso das aspas na palavra aleatria empregada acima). Dizemos quase aleatrias pois as sequncias geradas eventualmente se repetiro. Para evitar esta repetio utilizando o comando RANDOMIZE no incio do programa. [2] Entenda muito bem esta funo pois ela utilizada demais em jogos. Dificilmente voc esbarrar com um jogo que no tenha uma funo de gerao de nmeros aleatrios. Ex:
dim i as integer i=int(rnd(1)*10)+1 print "vou pensar num nmero de 1 a 10" print "espere s um segundo, deixe-me ver..." sleep 1000 print "pronto! Eu pensei no ";i sleep

Copie e cole o cdigo acima e veja o que acontece! Agora, execute de novo... e de novo... e de novo... Bom, voc deve estar se perguntando? U, d sempre o mesmo resultado! Isto acontece pois cada vez que executa o programa ele gera a mesma sequncia de nmeros (por isso que no aleatrio). O que voc tem que fazer dizer ao compilador para comear de um ponto diferente da sequncia a cada execuo. Vejamos o exemplo acima modificado. Ex:
randomize 5 dim i as integer i=int(rnd(1)*10)+1 print "vou pensar num nmero de 1 a 10" print "espere s um segundo, deixe-me ver..." sleep 1000 print "pronto! Eu pensei no ";i sleep

Executando o programa acima, o resultado provavelmente ser diferente do primeiro programa. O RANDOMIZE colocado no incio do programa diz para o compilador iniciar por um nmero diferente da seqncia gerada. Mas novamente, se executar o programa de novo ele devolver sempre o mesmo nmero, pois o nmero depois do RANDOMIZE constante, ento ele sempre iniciar a partir do mesmo ponto da seqncia. Resolvemos este problema colocando aps o RANDOMIZE um nmero que constantemente est mudando. Um valor que est constantemente mudando no micro aquele referente ao relgio interno do computador. Para isto vamos utilizar o comando TIMER, que retorna o tempo em segundos da inicializao do micro. Vejamos como fica: Ex:
randomize timer dim i as integer i=int(rnd(1)*10)+1 print "vou pensar num nmero de 1 a 10"

82

print "espere s um segundo, deixe-me ver..." sleep 1000 print "pronto! Eu pensei no ";i sleep

Agora voc pode rodar o programa diversas vezes que ir obter resultados diferentes.

83

EXERCCIOS:
[1] Refaa todos os exemplos deste tutorial que foram criados para o FREEBASIC para o QBASIC. Lembrando que se houver incompatibilidade de execuo das rotinas grficas do QBASIC no Windows XP, use o compilador Q64 (o link para baixar este compilador est disponvel no Blog do DDJ). [2] Crie um programa que calcule as razes de uma equao do 2 grau. [3] Modifique o programa (2) para que ele plote a funo do 2 grau. [4] Desenvolva um programa que faz um circulo ficar oscilando no meio da tela. Seja criativo! [Dicas: Use os comandos aprendidas at aqui: screen, circle, get, put, loopings, sin ou cs] [5] Crie um campo de estrelas utilizando o comando de gerao de nmeros randmicos.

84

Você também pode gostar