Click here to load reader

Biblioteca Allegro

  • View
    703

  • Download
    1

Embed Size (px)

Text of Biblioteca Allegro

Marvson Allan

Ao terminar a leitura do capitulo 20, voc j deve ter uma tima noo de programao. - Essa noo que voc ganhou vale para qualquer linguagem de programao. - Essa noo que voc ganhou vale tambm para iniciar a produo de um jogo em qualquer linguagem. Todas as linguagens usam IF, FOR, arrays e ponteiros.. principalmente funes. Por isso no interessa muito em qual linguagem voc est programando, e sim,o que voc sabe fazer com ela. Se voc est lendo a biblioteca, voc com certeza j escreveu algum cdigo em C++ para treinar sua programao e sua forma de pensar. Antes de sair por ai programando jogos, precisamos ter uma certa organizao do cdigo fon dos te programas, para que consigamos ler o mesmo cdigo algum outro dia.

VOC PRECIS S BER...- A organizao de cdigo necessria para que voc possa entender o que escreveu. - A organizao de cdigo obrigatria para que voc possa reutilizar seucdigo fonte. Para organizar o cdigo voc precisa seguir regras fundamentais e obrigatrias.

1 - Ao declarar variveis, voc deve tomar cuidado para no agrupar uma linha muito grande de variveis. Utilize sempre vrias linhas, dando um enter entre os tipos de variveis.

int a, b, c, valor, numero, xab, contador, teste, coisa; int a = 10, b, c, d=15, valor, coisa, variavel21, contador=0; int numero_jogadores, posicao_peca_x, vari; Exemplo correto: int a = 0; int b = 0; int valor = 0; int xab = 0; int numero_jogadores = 0; int posicao_peca_x = 0;

2 - Observe sempre de separar com espaos variveis que no combinam com as de cima ( por exemplo, posicionamento de peas com nmeros de jogadores ). Isto torna a leitura mais fcil. 3 - Sempre inicie as variveis.

Exemp

Dec

t t mente e

nd

i eis

d que n de e se us d :

21 - O g niz de Cdig

int a=0;b=30;Exem o correto:

int a = 0; int b = 30;

5 - Ao iniciar as variveis mantenha uma ordem nas atribui es;

int aviao = 0; int posicao_x = 0; int posi = 0;Exem o correto:

int aviao int posicao_x int posi

= 0; = 0; = 0;

Usando o exem o acima, variveis que tem nome menor ficam longe das que tem nome maior Isso mantem o c digo ainda mais organizado

int int int int int

aviao = 0; b=0; posicao_x = 0; x=0; posi = 0;

Exem lo correto:

int aviao int posicao_x int posi int b = 0; int a = 0;

= 0; = 0; = 0;

6 - ente sem r e escrever o nome da varivel por exemplo, usando o separador _. Se no for possvel, digite um comentrio sobre o que a varivel faz;

Q H

Exe plo o al en e erra o ue n o eve ser usa oH P I H G F G G F

B 9

Exe plo o al en e erra o ue n o eve ser usa o9 A @ 9 8 7 8 8 7

3 0

Exe plo o al en e erra o ue n o eve ser usa o0 2 1 0 ) ( ) ) (

#

Exe plo o al en e erra o ue n o eve ser usa o" ! & 6 54 E %$ 54 C

'

4 - Sem

e deixe es

s ao iniciar as variveis

D

int pos_per; int px; int py; Exemplo correto: int posicao_personagem; int personagem_px; // posio x do personagem; int personagem_py; // posicao y do personagem;

VOC PRECIS S BER...Abreviar nome das variveis preguia.. se voc tem preguia ao programar, ento desista de programar jogos. 7 - Mantenha distancia em nmeros na hora das operaes matemticas. Utilize mais variveis para ajudar nas operaes, de forma que a operao fique fcil de ler

int num=0; num = 10*(4/2*(3-1)); Exemplo correto: int num = 0; int auxiliar = 0; auxiliar = ( ( 4 / 2 ) * ( 3 1 ) ); num = 10 * auxiliar;

8 - IMPORTANTE: Indentar sempre os cdigos com extruturas de controle.

if(a==1){ ....... } while (ab!=true) { .... } for (i=0;inumero = menor->numero; menor->numero = chave; pprimeiro = pprimeiro ->proximo; } return true; }Exemplo correto:

bool selecao_direta( fila *pprimeiro ) { fila *proximo, *atual, *menor; int chave; while ( pprimeiro != NULL ) { proximo = (*pprimeiro).proximo; atual = pprimeiro; menor = atual; while ( proximo != NULL ) {// nesse caso muito importante usar as chaves " { } " e identar o if if ( (*proximo).numero < (*menor).numero ) { menor = proximo; }

proximo = proximo->proximo; } chave = atual->numero; atual->numero = menor->numero; menor->numero = chave; pprimeiro = pprimeiro->proximo; }

i f

Exe plo o al en e erra o ue n o eve ser usa of h q g f e p d e e d

c

return true; }

10 - No utilizar o comando Do While O comando do while deixa as linguas de programao confusas, por isso, no interessante utilizar Qualquer c d igo em qualquer linguagem pode ser escrito seguido essas observa es importantes.

Recentemente fora levantado um tpico no nosso forum sobre a organizao do cdigo. No captulo 21 ns aprendemos a melhor forma de se programar um jogo, organizando o cdigo como programao e no como um projeto. Com este tutorial adicional, pretendo dar mais dicas para tornar a programao de jogos mais organizada. Fazer um jogo um projeto que contm vrias etapas. Nem sempre precisamos seguir todas as etapas, mais algumas so indispensveis para a concluso sem atrasos ( perda de tempo ) do projeto. Este tipo de contedo discutido em vrios sites e em vrias outras reas, simplesmente por que um assunto relacionado ao tempo! Quanto mais tempo gasto, mais caro se torna a sua idia. Quanto mais organizada for a sua ideia e o seu projeto, melhor ele ser implementado e mais rpido o jogo ser concludo. Eu vou abordar aqui a criao de um jogo no estilo Arkanoid.

Como a idia criar um jogo ao estilo do Arkanoid, precisamos estudar como este jogo funciona e descrever todos os funcionamentos e idias do jogo. Se voc est criando um jogo que ainda no foi inventado, o processo ser o mesmo. A descrio da idia muito importante para sabermos o que realmente queremos fazer e para adotar mudanas no projeto. Exemplo: - Um jogo aonde o jogador controla uma raquete ( ou shape ) que vai rebater uma ou vrias bolas. - O objetivo do jogo ser destruir todas as peas do cenrio, fazendo com que a bola entre em contato com essas peas. - Cada pea vai fazer com que uma ao seja disparada no jogo, criando novas bolas, aumentando a velocidade, etc. - Quanto todas as peas forem destruidas, o jogador enviado diretamente para a proxima fase. - Quando a bola no for rebatida, o jogador perde uma vida. Observe que especificamos detalhes do jogo, sua descrio e regras. A descrio inicia da idia no deveria ser mudada durante a execuo do projeto.

v uv

1 At

a

y

vw

v

Es e ap ulo para ue w

j possu exper n a e

y vu

u

v

y xt

vwvu

21 At

onal 1

r an za

o e

o pro ra a o

s

r

Observe que na minha idia de Arkanoid, mudei alguns conceitos do jogo original. Neste ponto tambm, so definidas algumas historias e cenarios do jogo, no precisam ser completas.

Agora iremos definir as regras do jogo. Essas regras podem sofrer altera e s durante a execuo do projeto, por que as vezes nem sempre conseguimos programar tudo o que queremos. - O Jogo vai ter uma historia ? - O jogo vai ter uma animao inicial ?? Como ela vai ser ? - O Jogo vai ter uma tela inicial ? - Quais sero as op es do menu ? - Quais sero as telas do jogo ? - Descrever as telas do jogo.. - Descrio das regras para o Jogador - Descrio das regras para o Jogador para cada tela ou cenrio - Descrio das regras do jogo para cada tela ou cenario - Descrio das regras para upgrades, inimigos, jogabilidade

Quando voc for definir as regras, voc no precisa levar em considerao tecnologias que sero utilizadas. Isto por que, as regras podero ser alteradas mais tarde. Esta no a hora de pensar em qual linguagem programar ou qual programa de modelagem utilizar.

3 I en f an o a ores e arefasEsta aqui uma das partes mais importantes ao se fazer um projeto pois ela define como ser feita a programao. Voc deve identificar atores de a e s nas regras e idias descritas acima. Nada muito tcnico ainda. Exemplo: - Bola A bola pode se mover pelo cenario A bola pode colidir com uma pea e destrui-la A bola pode colidir com a raquete do jogador, que vai rebatela para outra direo - Raquete do jogador A A A A raquete raquete raquete raquete do do do do jogador jogador jogador jogador pode pode pode pode se mover apenas na horizontal para os lad os se mover mais rapido ou mais devagar ter tamanhos diferentes rebater a bola

- Cenario O O O O cenario cenario cenario cenario pode pode pode pode ter ter ter ter tamanhos diferentes vrias peas uma imagem de fundo apenas um jogador

d

e

e

e d

d

2

Des r

o e e ras

O cenario pode ter vrias bolas O cenario deve controlar para que as bolas no saiam de seus limites

Eu identifiquei alguns atores e tarefas deles acima. Nem sempre se consegue identificar todos os atores, por isso talvez voc v precisar alterar este parte mais tarde.

Este mtodo de desenvolvimento no igual ao UML, Por favor, no confunda! Os atores no UML so usurios e/ou outros meios externos que desenvolvem algum papel em relao ao sistema. Voc pode usar a UML para ajudar no seu projeto tambm. Alm de definir os atores e possveis tarefas, voc vai definir diagramas que iro ajudar voc a identificar quem sero as classes. Estude UML tambm! http://pt.wikipedia.org/wiki/UML Aps identificar os atores do passo 3, podemos procurar quais deles sero classes, e quais fu e s cada n classe vai executar. Pense da seguinte maneira! Voc vai criar uma classe para alguma coisa que ir ter vrias variveis e que ir desempenhar vrias tarefas no seu jogo. Bola, Jogador e Cenrio desempenham vrias tarefas, como vimos acima, ent ficou fcil de saber quem o sero nossas classes. Com as tarefas de cada um, tambm podemos conhecer de antemo quais sero os metodos que cada um vai fazer. Exemplo: Classe Bola metodo metodo metodo metodo mover desenhar no cenario colisao com peas colisao com jogador

Neste ponto, nem sempre vamos descobrir todos os mtodos e todas as classes. . Porm, neste ponto j podemos descidir como vamos fazer as coisas e se conseguimos fazer tais coisas Agora hora de descidir a linguagem de programao e como ser programado o jogo. Agora tambm hora de decidir quais classes se comunicaro com outras classes. Por exemplo: A classe bola vai ter o mtodo que verifica a coliso? ou a classe cenario ? Quem vai controlar as vidas ? O cenrio ou o jogador ?

Exemplo de cdigo:

p pp o

CDIG

n

m

m

j l k

h

j

i hg m m

4

r an o lasses e

o os

f

#ifndef BOLAS_H #define BOLAS_H #include

class Bolas { private: // contadores auxiliares int i; int c; public: int posicao_x; int posicao_y; int tamanho; int cor; // controlam a velocidade da bola em x e em y // desta forma ela pode ir para lugares diferentes na tela int velocidade_x; int velocidade_y; // informam a direo de movimentao da bola // pelo cenario // para esquerda bola ->direcao_x = -1; // para cima bola->direcao_y = -1; int direcao_x; int direcao_y; Bolas(); // funo construtor ~Bolas(); // funo destrutor void iniciar( int pos_x, int pos_y ); // inicia objeto void destrutor(); // reinicia variveis do objeto void mostrar( BITMAP * fundo ); // imprime a bola no vetor fundo void refresh(); // atualiza posio da bola void adiciona_velocidade_x(); void remove_velocidade_x(); }; #endif

Agora voc vai criar as classes que encontrou e tentar juntar todas as classes de forma que o jogo rode no final. Bom.. essa minha explicao foi bem superficial, j que isto bem complicado. Ento vou mostrar como isto feito na prtica! - Para programar um jogo voc deve ter noo d Orientao a Objeto bsica para criar as classes. e - Para programar um jogo voc precisa ter alguma noo de UML para identificar eventos e classes.

y y

xw v

y

u

ts

5

ro ra a

rrr q

FIM DE CDIG

o

http://pt.wikipedia.org/wiki/Orienta%C3%A7%C3%A3o_a_objetos http://pt.wikipedia.org/wiki/UML http://bdjogos.com/adrw/c/classes.htm

Eu criei um jogo no estilo do Arkanoid para voc baixar. O cdigo fonte est includo e voc poder alterar como quiser. Neste cdigo fonte existem todos os comentrios que voc vai precisar para entender como ler o cdigo e como organizar o projeto.

Clique aqui para fazer o download do cdigo fonte

Esta forma de programar jogos com certeza no a melhor forma que existe. Eu apenas abordei um modo prtico de programar jogos, procure pesquisar mais sobre isto.

Para esse artigo preparei o cdigo fonte de um jogo da memria simples e objetivo a fim de revisar e fixar os artigos vistos at o momento. Parece bvio, mas mesmo assim bom deixar claro que essa no a nica forma de fazer um jogo da memria. O cdigo varia muito de cada programador. Para quem no lembra o jogo da memria consiste em encontrar o par da carta que voc acabou de virar. Ao final do cdigo, teremos um resultado simples conforme abaixo:

}|~ ~

} |

{

}~}|

21 A{

onal 2 Jo o a

e

ra o

z

z

z

o fon e

O Jo oPrecisamos ter em mente como nosso jogo ir funcionar antes de comear a programar ele. bom sempre fazer alguns rascunhos antes de organizar as idias oficiais. Dessa forma teremos uma viso clara do que iremos precisar durante o desenvolvimento.

Nesse caso, as caractersticas desse jogo devem ser as seguintes: 1. 2. 3. 4. 5. Teremos um baralho de 32 cartas. 16 pares de desenhos. A pontuao base inicial 100. O Jogador inicia com 0 pontos. Logo no inicio o jogo deve mostrar todas as cartas para que o jogador possa memorizar. Assim que o tempo de memorizao das cartas terminar o relgio para marcar o tempo de jogo deve ser disparado. A cada erro o jogador perde uma chance e espera 3 segundos para memorizar as duas cartas erradas. Se zerar as chances o jogo termina e a tabela de Recordes deve ser mostrada. A cada seqncia de acertos a pontuao base deve ser multiplicada pela quantidade de seqncias de acertos at o momento. Por exemplo, se acertar 2 pares seguidos deve ser acrescentado na pontuao 2x100.

6.

7.

O jogo ter 3 nveis de dificuldade. Em cada nvel teremos as seguintes alteraes:

Nvel 1: 1. 2. Pontuao base deve ser 100. Tempo para mostrar as cartas 15 segundos.

Nvel 2: 1. 2. Pontuao base deve ser 150. Tempo para mostrar as cartas 10 segundos.

Nvel 3: 1. 2. Pontuao base deve ser 200. Tempo para mostrar as cartas 5 segundos.

o o o o

A cada troca de nvel devem ser acrescentadas mais duas chances ao jogador. Cada nvel de dificuldade ter um fundo e os desenhos das cartas alterados. Ao fim do jogo quando o jogador zerar os 3 nveis a tabela de recordes deve aparecer. A tabela de recordes deve ter 9 posi e s e ser organizada pelo nvel e pontuao mais altos.

Clique aqui para fazer o download do cdigo fonte

A biblioteca allegro fornece vrias rotinas de baixo n vel para programadores de C/C++, normalmente necessrias na programao de jogos, como entrada do teclado, manipulao de grficos, manipulao de sons e cronmetros (timer). uma plataforma transversal e trabalha com muitos compiladores diferentes. Desenvolvido originalmente por Shawn Hargreaves, agora um projeto com contribuies do mundo inteiro.

Facilidade de utiliza o - Vem com documentao e exemplos detalhados. Porttil - Se a funcionalidade interna no for bastante, h muitos add -ons dispon v eis em todas plataformas sem mudar uma nica linha do cdigo, voc pode criar verses para Windows, OS X, inux, DOS e outros! Trabalhe com muitos compiladores, incluindo DJGPP e VC++ Fonte aberta - qualquer um pode contribuir, inclusive voc! Livre - no lhe custar uma moeda de dez centavos, e no h nenhuma limitao em seu uso. Para mais informaes referente a biblioteca allegro visite o site: http://www.allegro.cc O objetivo de Allegro.cc fornecer uma riqueza da informao moderna que pertence programao e ao gaming Allegro. Eles confiam pesadamente na participao dos colaboradores Allegr e do pblico geral. o Nesse mesmo site existem publicaes de vrios jogos, quase todos so freewares e sharewares. Antes de instalar qualquer jogo o Allegro recomenda ler a documentao completa de cada um porque eles no sero responsveis por qualquer problema que ocorrer aps a instalao.

VOC PRECIS S BER...Em outras palavras Allegro uma biblioteca desenvolvida para ajudar os programadores iniciantes no desenvolvimento de jogos sem que seja necessrio ler toneladas de livros referentes o assunto. Basicamente, para que voc possa desenvolver um jogo simples e divertido necessrio ter um bom conhecimento de qualquer linguagem de programa o , criatividade e um bom conhecimento em bibliotecas grficas como Allegro, Open G , Direct x entre outros.

ENTENDO O L O PRINCIP L DO O Oogo acima vimos que a biblioteca Allegro parece ser uma ferramenta com vrias funcionalidades no processo de desenvolvimento de um jogo. S o fato de no precisarmos ler toneladas de livros sobre matemtica,f sica e APIs j poupa um tempo muito precioso. Isso no quer dizer que para desenvolver um jogo comercial de sucesso basta aprender Allegro. O conhecimento vai muito mais alm da simplicidade. De qualquer forma voc vai precisar estudar muito para

Algu

as caractersticas chaves incluem:

Bib i tec

eg

desenvolver um jogo bom. Vamos comear pelo inicio do inicio, entendendo o lao principal e utilizando a biblioteca Allegro para chamar as funes. O cdigo abaixo j um bom comeo: Ao executar o programa voc vai ver apenas uma tela do windows com a c de fundo em preto. or Para fechar o programa pressione ESC.

CDI O//Exemplo de cdigo em Allegro #include int main() { allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode( GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0 ); // ao principal while( !key[KEY_ESC] ) { //Cdigo } allegro_exit(); return 0; } END_OF_MAIN();

Esse comando o mais importante. Sem declarar essa linha no vamos conseguirusar nenhuma funo da biblioteca Allegro. Ao chamar as funces do Allegro e tentar compilar o jogo sem essa linha o compilador ir apresentar uma mensagem de erro dizendo que no conseguiu encontrar as funes.

VOC PRECIS S BER...Esse comando indica ao compilador onde ele deve encontrar as funes do allegro.

Macro responsvel por iniciar a biblioteca allegro. Sem esse comando no conseguimos utilizar nenhuma funo do allegro. Existem pessoas que utilizam a funo allegro_exit(), mas o manual do allegro 4.2.1 informa que esse comando no precisa ser usado explicitamente. O allegro chama essa funo toda vez que o jogo fechado. Dessa forma o processo de liberao das bibliotecas da memria tornam -se automticos.

int

eg

_init();

#inc ude

Esse comando responsvel por ins l nosso projeto.

Mais adiante vamos ver um topico de como manipular as interrupes do teclado.

Essa funo seta a profundidade das cores de todas as imagens que voc vai carregar durante o projeto. O allegro suporta: 8 bits 16 bits 24 bits 32 bits Exempl : set_color_dept (32); O modo 32 bits proporciona o mesmo nmero de cores que o modo 24 bits mas grficos de 32 bits podem ser manipulados muito mais rapidamente do que grficos de 24 bits. Alm disso grficos de 32 bits requerem cerca de 25% a mais de memria.

in se

fx

ode in

ard, in w, in

O comando acima responsvel por detectar a placa de vdeo setar o tamanho da tela em pi el e o posicionamento inicial x y. Para saber o que utili ar no argumento card segue uma tabela abaixo explicando cada opo: Card GFX_TEXT GFX_AUTODETECT Descri Fecha toda a modalidade de grficos aberta previamente com set_gfx_mode. O allegro escolhe o drive mais apropriado.

GFX_AUTODETECT_FULLSCREEN Fora o allegro a exibir o projeto em tela cheia. GFX_AUTODETECT_WINDOWED GFX_SAFE Fora o allegro a exibir o projeto em uma janela. Modo especial para quando voc quiser ajustar confiantemente uma modalidade de grficos e no quer se importar a resoluo. Modalidade exclusiva de Tela cheia. Suporta definies de pixels somente acima ou igual a 640x480.Suporta tambm acelerao de hardware. Modalidade idntica a anterior mas no suporta acelerao de hardware. Modo grfico rpido para utili ao de janelas porque usa a classe BdirectWindow. Mas nem todas as placas de vdeos suportam.

GFX_BWINDOWSCREEN_ACCEL

GFX_BWINDOWSCREEN GFX_BDIRECTWINDOW

void se

olor dep

in ins all key oar

n

s in

up s d

cl d disp nv is para o

in dep

256 cores 65.536 mil 16 7 mil es 16 7 mil es

, in v w, in v

GFX_BWINDOW GFX_BWINDOW_OVERLAY

Modo normal de trabalho em janela utili ando a classe Bwindow. Esse modo muito lento. Modalidade de tela cheia usando BWindow como uma folha de prova BBitmap. Esta modalidade no suportada por todos as placas de vdeos a profundidade de cores sugeridas 15 16 e 32 bits.

Exempl : set_gfx_mode(GFX_AUTODETECT_WINDOWED 640 480 0 0); O exemplo acima define a tela do jogo como sendo auto detectvel em modo janela do windows 640x480 pixels de resoluo a partir da posio x= 0 e y=0.

void vsyn

Espera para que um retrace vertical comea. O retrace acontece quando o feixe de eltron em seu monitor alcanou o fundo da tela e est movendo para trs para o superior e se apronta para uma outra varredura. Durante este perodo curto o carto dos grficos no est emitindo nenhum dado ao monitor assim voc pode fazer-lhe as coisas que no so possveis em outras vezes tais como alterar o palette de cores sem causar cintilar (neve). O Allegro esperar automaticamente um retrace antes de alterar o palette ou de fazer algum desdobramento da ferragem embora assim que voc no necessita normalmente se incomodar com esta funo. Essa explica mui imp rtante p rque us d c mand vsync n mei d projeto causa uma perda considervel de desempenho.

w ile !key[KEY_ESC]) {}O comando acima trata-se do loop principal do jogo. Ele quer dizer que far o loop enquanto ningum pressionar a tecla ESC. Dessa forma ele executa o cdigo do jogo em velocidade de processamento. Mais adiante veremos tpicos relacionados ao timer para controlar o loop do jogo.

Caro leitor, chegamos ao fim do entendimento do lao principal de um jogo. Se voc Encontrou alguma dificuldade no entendimento desse artigo favor entrar em contato. Agora se prepare porque com essa tela preta d pra fazer muita coisa!!!

23 Con eito X e Y Antes de ler este tutorial, leve em considerao de que voc j leu: - A Biblioteca Allegro

- Instalao do Allegro no Dev-CPP

Os n eros naturaisNmeros naturais ou nmeros que podem ser contados so os primeiros nmeros que aprendemos na escola. A muito tempo atraz a humanidade precisou inventar uma forma de contar seus alimentos, seus habitantes ou suas cria e s, desta forma surgio a oportunidade de escrever nmeros em formas de digitos em algum lugar, e assim surgiram: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, ... Podemos representa-los em nossa programao atravez do tipo inteiro ( usando principalmente unsigned "sem sinal" ). int numero_natural = 6; int array_numeros[3] = { 5, 10, 15 };

Os n eros ne ativosAlgum tempo depois a humanidade precisou comercializar ou trocar seus objetos ou comida. Ai foi inventado um dos conceitos mais importantes que o dbito de valores ou os nmeros negativos. Os nmeros negativos so representados com um sinal de - "menos" na frente de cada valor. -1, -2, -3, -4, -5, -6, -7, -8, -9, - ... Podemos representa-los em nossa programao atravez do tipo inteiro tbm. int numero_negativo = -6; int array_negativos[3] = { -5, -10, -15 }; Os nmeros inteiros, so somente constitudos dos nmeros naturais {0, 1, 2, ...} e dos seus opostos {-1, 2, -3, ...}.

Os n eros ra ionais e fra esEm alguma determinada poca, tambm fomos obrigados a dividir comida com os companheiros das cavernas, e foi dai que apareceram as nossas amigas fra e s. Onde um valor divido por out o. r 10 / 2 = 5; Quando uma frao no consegue dividir um nmero, surge os nmeros fracionais. 3 / 2 = 1.5 Estes nmeros so inseridos entre os nmeros inteiros e so representados em nossa programao atravez do tipo float ou double. doube valor = 1.666; Um clssico exemplo de nmero racional o PI, muito utilizado na programao de jogos. No jogo Worms ele utilizado para saber aonde um projetil vai cair dependendo de um angulo e fora de lanamento.

Instalao do Allegro no Visual Studio C

2005

PI = 3.14159

Os n ero eaisOs nmeros reais incluem os nmeros inteiros e os nmeros racionais. Eles so os mais utilizados at hoje pela humanidade, e tambm so bastante complexos. Os nmeros inteiros so contveis e os nmeros reais so nmeros incontveis.

O plano artesianoO Plano cartesiano um espao aonde podes visualizar 2 variveis importantes para a programao de jogos. As variveis X e Y.

No desenho acima temos o plano cartesiano, o plano sempre comea da posio 0 que a origem.Esta origem nem sempre o meio do plano. Esta origem pode ser por exemplo, o comeo de uma fase do jogo Super Mario Bros. Andando para a direita em linha reta, estamos saindo do ponto de origem e adicionando ao ponto X. Andando para a direita e para cima, estamos saindo do ponto de origem e adicionando ao po nto X e Y. Resumindo, os pontos X e Y so coordenadas do plano cartesiano, e com essas coordenadas que iremos escrever grficos na tela do computador ou do video -game.

Todo ponto sempre representado por ( X, Y ), exemplo: ( 2, 3 )

Exemplos de vrios pontos X,Y em um plano cartesiano que poderia ser a tela de um jogo:

Agora vamos brincar de escrever na tela usando os pontos X e Y.

CDIGO...// Coordenadas X e Y //Cdigo de Exemplo #include

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);

// nosso programa atual // Testando coordenadas X e Y int x = 0; int y = 0;

textout_ex(screen, font, "Mensagem em 0,0 da tela", x, y, makecol(255, 0, 0), -1);// Lao principal while( !key[KEY_ESC] ) {

} allegro_exit(); return 0; } END_OF_MAIN();

Neste momento voc no precisa saber os comandos que vc no conhece, apenas teste o programapara entender a funo da varivel X e Y..

VOC PRECIS S BER...Executando o exemplo acima, percebemos que no allegro, a coordenada inicial do monitor bem em cima da tela na esquerda. Isto muito importante, no open gl por exemplo, a coordenadainicial bem no meio da tela. O que acontece se almentar a varivel X ou Y ? Veja o exemplo:

CDI O...// Coordenadas X e Y //Cdigo de Exemplo #include int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);

// nosso programa atual // Testando coordenadas X e Y int x = 0; int y = 0; x = x + 100; textout_ex(screen, font, "Mensagem em 100,0 da tela", x, y, makecol(25, 0, 0), -1); 5 x = 0; y = y + 100; textout_ex(screen, font, "Mensagem em 0,100 da tela", x, y, makecol(255, 0, 0),-1); x = x + 150; y = y + 150; textout_ex(screen, font, "Mensagem em 150,150 da tela", x, y, makecol(255, 0, 0), -1); // ao principal while( !key[KEY_ESC] ) { }

allegro_exit(); return 0; } END_OF_MAIN();

24 -

end um b et n te

FI

DE CDI O...

Neste tutorial iremos ver como mover um objeto na tela usando as coordenadas x e y. Todo desenho, imagem ou objeto que pode ser inserido na tela em qualquer linguagem de programao possui a propriedade X e Y. Muitas vezes essas propriedades podem estar com outros nomes ( no caso do VB Top e Left ). No cdigo abaixo iremos ver alguns comando novos. O mais importante so os comandos de reconhecimento s de teclado. Atravz desses comandos ns modificaremos o valor de X e de Y e redesenhamos um quadrado na tela na nova posio.

CDIGO...// Movendo um objeto nas coordenadas x e y #include

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);// inicio da programao atual int x = 0; int y = 0; // dimensao do quadrado // variveis constantes nunca mudam durante a execuo do programa const int tamanho = 100; // Lao principal while( !key[KEY_ESC] ) { if ( key[KEY_UP] ) { y--; }

if ( key[KEY_DOWN] ) { y++; } if ( key[KEY_LEFT] ) { x--; } if ( key[KEY_RIGHT] ) { x++; }// esta funo limpa a tela ou um objeto que tem buffer no allegro clear( screen ); // escrevemos um quadrado na tela na posio x e y que podem ter sido modificadas rectfill( screen, x, y, x+tamanho, y+tamanho, makecol(255, 0, 0)); // imprimimos as coordenadas x e y na tela para o usurio ver

O cdigo bem fcil de se entender, precione E

para sair do programa quando for testar ele:

textprintf_ex( screen, font, 10, 10, makecol(255,0,0), -1, "Variavel X: %d", x); textprintf_ex( screen, font, 10, 20, makecol(255,0,0), -1, "Variavel Y: %d", y);// essa funo faz o allegro esperar um pouco antes de voltar para o while rest(10);

} allegro_exit(); return 0; } END_OF_MAIN();

Quando comeamos a desenhar vrios objetos primitivos na tela, e movemos ele atraves do teclado ( na execuo do jogo ) ou mesmo animamos figuras .bmp, muitas vezes percebemos que a imagem do jogo fica piscando. O Nome deste efeito flicker, onde o monitor acaba imprimindo uma tela em preto antes da nova imagem do jogo ser desenhada na varivel screen ( varivel que representa o monitor no Allegro ). Formando a impresso de que a tela est piscando. Para resolver este problema, utilizamos a tecnica de Double Buffer, ou seja, criar um buffer ( lugar de armazenamento ) aonde desenhamos tudo o que deve ser desenhado na tela, e s depois que tudo estiver desenhado no buffer, ai sim, imprimimos o buffer na tela ( screen ). Desta forma, a tela ( screen ) vai ter sempre a ultima imagem gerada para ela. E enquanto tudo no for desenhado no buffer, a tela continua sendo a antiga. Assim a tela no ir piscar mais. Esse problema geralmente acontece quando o movimento do objeto for muito rpido ou quando a tela atualizada antes de todos os objetos serem desenh ados no screen. A tecnica de double buffer no allegro bem simples e tambm vale para qualquer outra biblioteca grfica ( aqui estamos dizendo, o exemplo est em allegro, mais voc pode usar em DX ou Open GL )

Exemplo sem Double Buffer: Possivelmente o quadrado vermelho e os textos ficaro piscando em sua tela

CDIGO...// Coliso com os cantos da tela #include

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);// inicio da programao atual int x = 0; int y = 0; // dimensao do quadrado // variveis constantes nunca mudam durante a execuo do programa const int tamanho = 100; // Lao principal

25

Dou le uffer

nica de desen ar na tela

while( !key[KEY_ESC] ) { if ( key[KEY_UP] ) { y--; } if ( key[KEY_DOWN] ) { y++; } if ( key[KEY_LEFT] ) { x--; } if ( key[KEY_RIGHT] ) { x++; }// esta funo limpa a tela ou um objeto que tem buffer no allegro clear( screen ); // escrevemos um quadrado na tela na posio x e y que podem ter sido modificadas rectfill( screen, x, y, x+tamanho, y+tamanh makecol(255, 0, 0) ); o, // imprimimos as coordenadas x e y na tela para o usurio ver textprintf_ex( screen, font, 10, 10, makecol(255,0,0), -1, "Variavel X: %d", x); textprintf_ex( screen, font, 10, 20, makecol(255,0,0), -1, "Variavel Y: %d", y); // essa funo faz o allegro esperar um pouco antes de voltar para o while rest(10);

} allegro_exit(); return 0; } END_OF_MAIN();

FIM DE CDIGO...

CDIGO...// Coliso com os cantos da tela #include

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);

// inicio da programao atual int x = 0;

Exe plo co

Dou le uffer

int y = 0;// dimensao do quadrado // variveis constantes nunca mudam durante a execuo do programa const int tamanho = 100;

// Criando BUFFER, ela um ponteiro para um BITMAP, pode ter qualquer nome BITMAP *buffer = NULL; buffer = create_bitmap(800,800);

// Lao principal while( !key[KEY_ESC] ) { if ( key[KEY_UP] ) { y--; }

if ( key[KEY_DOWN] ) { y++; } if ( key[KEY_LEFT] ) { x--; } if ( key[KEY_RIGHT] ) { x++; }// limpa o nosso novo buffer clear( buffer ); // escreve o quadrado no buffer rectfill( buffer, x, y, x+tamanho, y+tamanho, makecol(255, , 0) ); 0 // imprimimos as coordenadas x e y na tela para o usurio ver no buffer textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "Variavel X: %d", x); textprintf_ex( buffer, font, 10, 20, makecol(255,0,0), -1, "Variavel Y: %d", y); // imprime o buffer na tela blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); // essa funo faz o allegro esperar um pouco antes de voltar para o while rest(10);

}

allegro_exit(); return 0; } END_OF_MAIN();

26

Utilizando ILES

Tiles uma representao grfica de algo na tela, um conjunto de tiles( pedaos de imagens ) que formar uma imagem maior.

VOC PRECIS S BER... importante que voc tenha lido nosso artigo sobre imagens antes de continuar. Caso contrrio voc pode se ter dificuldades no entendimento de algumas funes de manipulao de imagens que iremos utilizar ao longo do cdigo. - Desenhando imagens BMP na tela

Com tiles podemos fazer um cenrio, o que geralmente representar uma reduo de uso de memria e armazenamento em disco do que utilizar um nico bitmap para a tela inteira. Geralmente, o correto trabalhar com tiles para as partes fixas do cenrio ou com pouca mobilidade, por exemplo: paredes e cho de um cenrio, objetos como bas, e outras coisas que no se "mexem" muito e inclusive a gua, havendo ento uma troca seqencial das tiles que fazem parte da gua de forma a dara impresso de movimentao desta.

Nesse artigo iremos mostrar como montar um cenrio usando apenas tiles estticos, ou seja, sem movimentao.

ARTE FINAL

Apenas amostra

TILES

SADOSPronto para ser utilizado

Baixar tiles

Converta as imagens de .jpg para .bmp atravez de algum programa de editorao Com base na ilustrao acima devemos esclarecer os seguintes itens:

y y y

O tamanho do cenrio 640x480. Totalizando 307.200 pixels. Todas as imagens foram salvas com 24bits de profundidade de cores. No entanto configuramos o compilador para enxergar at 32bits. O tamanho de cada Tile 32x32 pixels.

Com base nas informa e s acima voc deve entender que a largura da tela de 640 pixels e a largura do nosso tile 32 pixels. Logo, j que nosso tile tem 32 pixels de largura podemos colocar apenas 20 tiles na horizontal. J na altura, como ns temos 480 pixels podemos colocar apenas 15 tiles. O tamanho dos tiles voc define conforme a necessidade do se projeto. A idia do artigo dar uma viso geral de como montar um cenrio simples e esttico atravs de tiles.

DICA...Para criar os tiles usamos o editor de imagens GLIMP. uma ferramenta muito boa e tem uma opo que torna a vida do design iniciante muito mais prtica. Essa opo se chama Tornar encaixavel. Se voc estiver fazendo a textura de uma grama ou um cho,por exemplo, quando voc terminar poder tornar essa textura encaixavel em todos os sentidos. Dessa forma voc no ter problema na hora de visualizar os tiles um do lado do outro. Assim o processo fica mais prtico mas no muito profissional porque a imagem sofre uma pequena distoro. Para quem est comeando vale a pena ver ificar.

Para facilitar o aprendizado voc poder baixar os tiles utilizados no exemplo acima.

CDIGO...#include int main() { allegro_init(); install_keyboard(); set_color_depth(32); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);// COMENTADO NO FINAL - 1 int i=0; int x=0; int y=0;

const int xTile = 32; // Largura do Tile const int yTile = 32; // Altura do Tile// COMENTADO NO FINAL - 2 // Posi es dos tiles no mapa bidimencional. int Mapa[15][20] = { 3,3,3,3,4,5,5,5,5,6,2,2,1,10,10,8,9,9,9,9, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,7,7,9,9,9,9, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,7,7,9,9,9,9, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,7,8,9,9,9,9, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,7,8,8,8,8,8,

3,3,3,3,4,5,5,5,5,6,2,2,1,7,7,7,7,7,7,7, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,7,7,7,7,7,7, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,0,10,7,7,10,0, 3,3,3,3,4,5,5,5,5,6,2,2,1,7,10,0,7,7,10,0, 3,3,3,3,3,4,5,5,5,6,2,2,1,7,0,10,7,7,10,0, 3,3,3,3,3,3,4,5,5,6,2,2,1,7,10,0,7,7, 10,0, 3,3,3,3,3,3,4,5,5,6,2,2,1,7,0,10,7,7,10,0, 3,3,3,3,3,3,4,5,5,6,2,2,1,7,10,0,7,7,10,0, 3,3,3,3,3,3,4,5,5,6,2,2,1,7,0,10,7,7,10,0, 3,3,3,3,3,3,4,5,5,6,2,2,1,7,10,0,7,7,10,0};// COMENTADO NO FINAL - 3 // Carregando o ponteiro com a imagem que possui todos os tiles BITMAP *bmpTiles = NULL; bmpTiles = create_bitmap(224,64); bmpTiles = load_bitmap("tiles.bmp",NULL); // Array que guarda as texturas separadas BITMAP *bmpTexturas[11]; // Definindo o tamanho 32x32 para cada tile for (i=0;i= obj_x && x = o bj_y && y = obj_x && x = obj_y && y = obj_x && x = obj_y && y obj_x && x < obj_x+obj_tam && y+tama ho > obj_y && y < obj_y+obj_tam ) n { return true; }

return false; }

Exerccio pratco

- Utilizando o programa do captulo 27, crie uma classe para imprimir vrios quadrados "objetos" na tela. O quadrado que se move deve detectar coliso nos outros objetos inseridos. Imprima 5 quadrados na tela de tamanho diferentes e verifique a coliso com todos eles. - Faa com que uma bola ande de um lado para outro na tela, de forma que ele se colida com o final da tela e volte para o inicio da tela. - Faa com que uma bola ande por toda tela, colidindo com as paredes. Quando a bola colidir, ela deve alterar para aonde ela vai colidir da prxima vez, de forma que ela fique andando por toda a tela.

Os exerccios acima so bastante interessantes e tambm difceis. Voc pode olhar as respostas caso no conseguir fazer, mais tentar resolver os exerccios vai aumentar seu raciocnio lgico. Para resolver o primeiro exerccio: http://www.bdjogos.com/adrw/c/classes.htm http://www.bdjogos.com/adrw/c/classes_implementacao.htm http://www.bdjogos.com/adrw/c/construtores_destruidores.htm

Respostas dos Exerccios- Utilizando o programa do captulo 27, crie uma classe para imprimir vrios quadrados "objetos" na tela. O quadrado que se move deve detectar coliso nos outros objetos inseridos. Imprima 5 quadrados na tela de tamanho diferentes e verifique a coliso com todos eles.

Preste ateno na forma que a classe foi criada. Quanto mais prtica a classe ficar, melhor para seu jogo. Voc poder usar ela muito mais fcil. Evite complica es.

CDIGO...#ifndef PAREDE_H #define PAREDE_H// ARQUIVO: parede.h // Data: 01/08/2007

class Parede { public: Parede( int, int, int, int ); void imprimir( BITMAP * ); bool colide( int, int, int, int ); private: int int int int }; #endif x; y; tamanho_x; tamanho_y;

FIM DE CDIGO... CDIGO...#include #include "parede.h"// ARQUIVO: parede.cpp // Data: 01/08/2007 // Este o construtor do objeto Parede::Parede( int x, int y, int tam_x, int tam_y ) { this->x = x; this->y = y; this->tamanho_x = tam_x; this->tamanho_y = tam_y; } // Essa funo imprime o objeto na tela, // passamos o local aonde queremos imprimir void Parede::imprimir( BITMAP *screen ) { rectfill( screen, x, y, x+tamanho_x y+tamanho_y, makecol(255, 255, 0) ); , } // Testa a coliso com o objeto atual ( isso quer dizer 1 de cada vez ) bool Parede::colide( int x, int y, int tamanho_x, int tamanho_y ) { if ( ( x+tamanho_x > this->x ) && ( x < this->x+this->tamanho_x ) && ( y+tamanho_y > this->y ) && ( y < this->y+this->tamanho_y ) ) { return true; }

return false; }

FIM DE CDIGO... CDIGO...// Coliso com vrios objetos #include #include "parede.h" // ARQUIVO: main.cpp // Data: 01/08/2007

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);// inicio da programao atual int x = 0; int y = 0;

int x_atual = x; int y_atual = y; const int tamanho_x = 20; const int tamanho_y = 10; const int total_paredes = 5; bool colidindo = false;// forma de iniciar vrios objetos com construtor Parede aparede[total_paredes] = { Parede( 300, 50, 10, 30 ), Parede( 150, 150, 50, 30 ), Parede( 300, 150, 150, 50 ), Parede( 250, 250, 50, 150 ), Parede( 500, 250, 80, 80 ) } ;

int i = 0;// Criando BUFFER para double buffer BITMAP *buffer = NULL; buffer = create_bitmap(800,800); // Lao principal while( !key[KEY_ESC] ) { x_atual = x; y_atual = y;

if ( key[KEY_UP] ) { y -= 5; } if ( key[KEY_DOWN] ) { y += 5; } if ( key[KEY_LEFT] ) { x -= 5; } if ( key[KEY_RIGHT] ) { x += 5; }// Aqui vem o complicado // Ns olhamos objeto por objeto, se colidir com um deles // paramos o for e no deixamos nosso quadrado andar for ( i=0; i SCREEN_W ) { variavel_x = variavel_x * ( -1); } if ( y < 0 ) { variavel_y = variavel_y * ( -1); } if ( (y+tamanho) > SCREEN_H ) { variavel_y = variavel_y * (-1); } // imprime o buffer na tela vsync(); blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); // essa funo faz o allegro esperar um pouco antes de voltar para o while rest(10); } allegro_exit(); return 0; } END_OF_MAIN();

Todo jogo possui animao, isto fato. Animaes so geralmente quadros de desenhos que vo se mudando ( sobrepondo a antiga )gerando assim uma animao. Este o exemplo de uma animao e alguns de seus quadros, que juntos formam a animao.

=

Esta animao originalmente tem 12 quadros e ela executada a 100 milisegundos. Se aumentarmos a taxa de milisegundos de cada quadro em separado, a animao vai ficar ainda mais lenta. Se diminuirmos a taxa de 100 milisegundos de cada quadro, a animao vai ficar bem mais rpida. Essa mudana de tempo nos quadros da animao influencia muito os jogos feitos para computadores. Geralmente, nosso programa roda na velocidade de clock tick do nosso processador. Isto quer dizer que o programa pode rodar mais rpido em algumas mquinas e mais lento em outras mquinas. Isso influncia no s as animaes como tambm a jogabilidade.

28 - FPS - Qu d

sp

segund , Frames per sec nd u Frame Rate

Para que o jogo rode igual em qualquer mquina, precisamos criar um controle de Frame Rate ( ou controle de FPS ). Para isto, primeiro precisamos descobrir como contar os FPS de nosso programa.

DICA...Esta tcnica de contar FPS e fazer o programa rodar em um FPS igual para todas as mquinas pode e deve ser aplicado em qualquer tipo de linguagem de programao para jogos ou animaes. Cada linguagem tem uma forma diferente de se chegar nesse resultado, mais a tecnica a mesma.Vamos aprender em Allegro um c digo completo. Em DirectX podemos fazer a mesma coisa usando a funo do windows GetTickCount(); que pega o total de ticks. Em OpenG podemos fazer a mesma coisa usando as funes do G UT .

VOC PRECISA SABER... importante que voc tenha lido nosso artigo sobre como instalar timers no Allegro. - Controle de tempo

CDI O...#include // Exemplo da bolinha com contador de Frames por segundos // global int fps = 0; int fps_antigo = 0; // prototipo do contador de frames void frame_rate(); int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0);

BITMAP *buffer = NULL; int x = 0; int y = SCREEN_H/2; int tamanho = 20; install_timer(); // a cada 1 segundo mostra quantas vezes a imagem foi impressa na tela install_int( frame_rate, 1000 );

bool colide = false; int variavel_x = 10; int variavel_y = 10;// Criando BUFFER para double buffer buffer = create_bitmap(800,800);

// Lao principal while( !key[KEY_ESC] ) {

if ( variavel_x == 1 ) { x += variavel_x; } else { x -= variavel_x; } if ( variavel_y == 1 ) { y += variavel_y; } else { y -= variavel_y; }// limitando o quadrado dentro da tela if ( x < 0 ) { variavel_x = variavel_x * ( -1); }

if ( (x+tamanho) > SCREEN_W ) { variavel_x = variavel_x * ( -1); } if ( y < 0 ) { variavel_y = variavel_y * ( -1); } if ( (y+tamanho) > SCREEN_H ) { variavel_y = variavel_y * ( -1); }// limpa o nosso novo buffer clear( buffer ); // escreve a bola no buffer ellipsefill(buffer, x, y, tamanho, tamanho, makecol (255,255,0) );

textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "FPS: %d", ::fps_antigo );

blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); vsync(); ::fps++; } destroy_bitmap( buffer ); allegro_exit();

return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; }

FIM DE CDIGONo exemplo acima, criamos uma varivel global fps que incrementada sempre aps que a imagem imprimida na tela. Usando um timer do Allegro, sempre que passar 1 segundo, ns mostramos o total de FPS que o Allegro conseguiu imprimir, tendo assim o total de frames impressos em 1 segundo. Legal.. j sabemos a quantos quadros nosso programa r oda, agora precisamos controlar a taxa de quadros, sem influnciar na jogabilidade. Nos exemplos anteriores do site, estavamos usando o comando rest() que fazia o compilador esperar.Esta funo no deve ser usanda, por que durante a execuo do comando res as teclas do teclado no so t() detectadas. Agora precisamos controlar a taxa de frames de nosso programa. A desciso da quantidade de frames por segundo o jogo vai rodar sua, voc pode usar 30 FPS que o limite mnimo para que o olho detecte transao da animao, ou 60 que o valor mostrado no manual da Allegro.

CDIGO...#include // Exemplo da bolinha com limitador de FPS // global int fps = 0;

int fps_antigo = 0; int fps_speed = 0;// prototipo do contador de frames void frame_rate(); // prototipo do contador de velocidade void incrementa_speed();

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); BITMAP *buffer = NULL; int x = 0; int y = SCREEN_H/2; int tamanho = 20; install_timer();// a cada 1 segundo mostra quantas vezes a imagem foi impressa na tela

install_int( frame_rate, 1000 ); install_int_ex( incrementa_speed, BPS_TO_TIMER(60) ); bool colide = false; int variavel_x = 10; int variavel_y = 10;// Criando BUFFER para double buffer buffer = create_bitmap(800,800);

// Lao principal while( !key[KEY_ESC] ) { while ( ::fps_speed > 0 ) { if ( variavel_x == 1 ) { x += variavel_x; } else { x -= variavel_x; }

if ( variavel_y == 1 ) { y += variavel_y; } else { y -= variavel_y; }// limitando o quadrado dentro da tela if ( x < 0 ) { variavel_x = variavel_x * ( -1); }

if ( (x+tamanho) > SCREEN_W ) { variavel_x = variavel_x * ( -1); } if ( y < 0 ) { variavel_y = variavel_y * ( -1); } if ( (y+tamanho) > SCREEN_H ) { variavel_y = variavel_y * (-1); }// limpa o nosso novo buffer clear( buffer ); // escreve o quadrado no buffer ellipsefill(buffer, x, y, tamanho, tamanho, makecol(255,255,0) );

textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "FPS: %d", ::fps_antigo ); ::fps_speed--; ::fps++; } blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H);

vsync(); } destroy_bitmap( buffer ); allegro_exit(); return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; } void incrementa_speed() { ::fps_speed++; }

FIM DE CDIGOO programa acima pode parecer confuso. Ns criamos um timer para que, a cada 60 clock tick ( usando a macro BPS_TO_TIMER ) o contador de speed seja incrementado. Quando acontecer os primeiros 60 clocks, o compilador vai entrar no while que atualiza a lgica do jogo. Enquanto o fps_speed no for menor que 0 ( o whil vai fazer ele chegar bem rpido ) ele vai atualizando a e lgica do jogo, mais no a tela. Esta lgica faz com que o contador de FPS fique constante. Execute o cdigo acima e faa testes alterando o valor que est na macro BPS_TO_TIMER para conferir. Para fazer com que o teclado obedea a velocidade em FPS preciso utilizar um Buffer de teclado, que pode ser lido aqui: http://www.bdjogos.com/biblioteca_conteudo.php?id=17

Com este tutorial suprimos uma das dvidas mais cabulosas na criao de jogos, a partir deste captulo iremos demonstrar outras tcnicas importantes na programao de jogos. Qualquer dvida entre em contato pelo forum.

Sprites um conjunto de imagens que organizadas em uma determinada seqncia simulam o movimento de algum objeto ou personagem. Praticamente todos os jogos 2D possuem algum tipo de sprites. Podemos definir como sprites a movimentao do jogador principal, as folhas caindo no cho, os inimigos em movimento e principalmente os efeitos entre os objetos do cenrio. A seguir iremos selecionar alguns sprites prontos de jogos e coloc-los em movimento. Se voc proferir escolher algum outro sprite segue uma seqncia de sites abaixo com uma infinidade de sprites de jogos. Links para prites

http://tsgk.captainn.net/ http://www.panelmonkey.org/category.php?id=1&theme=1 http://www.molotov.nu/?page=graphics

29 Movimenta

o de Sprites

dragao.bmp

Especificaes Qtde de Qtde de Largura Largura Altura: Desenhos em x[0]: Desenhos em y[0]: total: individual: 6 0 360 pixels 60 pixels 55 pixels

robocop.bmp

Especificaes Qtde de Qtde de Largura Largura Altura: Desenhos em x[0]: Desenhos em y[0]: total: individual: 6 0 415 pixels 69 pixels 80 pixels

No se esquea de converter as imagens acima para bitmap. O cdigo que iremos usar para movimentar o Robocop e o drago o mesmo. Porm, antes de executar cada um necessrio fazer algumas configura es com relao s especifica e s citadas acima.

CDIGO...#include int main() { allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); BITMAP *imgSprites = NULL; imgSprites = load_bitmap("robocop.bmp",NULL); BITMAP *Buffer = NULL; Buffer = create_bitmap(SCREEN_W,SCREEN_H); const const const const int int int int iSprite_Largura = 69; // Largura de um sprite iSprite_Altura = 80; // Altura de um sprite Qtde_Spritesx = 6; // Qtde de Desenhos em x[0] - Horizontal Qtde_Spritesy = 0; // Qtde de Desenhos em y[0] - Vertical

const int iCiclo = 30; // Ciclo de troca de sprite int iPosx = 0; // Posio x do corte.

int iPosy = 0; // Posio y do corte. Como apenas uma fileira ento y sempre vai ser 0 int buffer_animacao = 0; // Buffer para controle do ciclo while (!key[KEY_ESC]) { clear_bitmap( Buffer ); textprintf_ex(Buffer, font, 0, 0, makecol(0, 255, 255), 1,"ANIMACAO SPRITES"); // Controle para mudar o sprite if(buffer_animacao == 0) { if (iPosx > 0 && iPosx == Qtde_Spritesx -1) { iPosx = 0; }

if (Qtde_Spritesx > 0) { iPosx++; } buffer_animacao = iCiclo; } else { buffer_animacao--; }// Corta e desenha o sprite masked_blit(imgSprites,Buffer,iPosx*iSprite_Largura,iPosy,SCREEN_W/2,SCREEN_H/2,iSprit e_Largura,iSprite_Altura);

blit(Buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); vsync(); } destroy_bitmap(imgSprites); destroy_bitmap(Buffer); allegro_exit(); return 0; } END_OF_MAIN();

FIM DO CDIGOLogo acima temos um cdigo genrico para a movimentao dos sprites na horizontal. No processo para a movimentao dos sprites na vertical a nica coisa que muda o eixo x para y. Basicamente, o cdigo possui a informao da largura, altura e quantidade de sprites na horizontal. Com essas informa es possvel fazer um corte nas imagens com a funo blit vista em outro artigo. Para que as imagens no fossem trocadas na velocidade de processamento de cada computador adicionamos um buffer de animao i iclo. Dessa forma nossa animao ter um movimento mais pausado e uma impresso de movimento muito melhor. Caro leitor chegamos ao fim do entendimento da movimentao de sprites. Se houver alguma dvida ou dificuldade favor entrar em contato com o pessoal pelo Forum.

Nesse artigo vou ilustrar o cdigo para movimentao do pacman em todas as dire es utilizando sprites. Antes de iniciar o cdigo ser necessrio entender como esto organizados os sprites no arquivo. A tabela abaixo mostra que na vertical esto definidas as dire es dos desenhos, Direita, Esquerda, Cima e Baixo. J na horizontal esto definidas as seqncias dos sprites que iro definir o movimento do pacman. Posies dos prites Animao (x), Direo (y).

Sprite 1Direita Esquerda Cima Baixo 0,0 0,25 0,50 0,75

Sprite 225,0 25,25 25,50 25,75

Sprite 350,0 50,25 50,50 50,75

Sprite 475,0 75,25 75,50 75,75

Sprite 5100,0 100,25 100,50 100,75

Ao selecionar a posio 0,0 voc dever desenhar na tela o pacman virado para a direita e de boca fechada. J na posio 100,0 o pacman est virado para a direita e de boca aberta. Para fazer a simulao de movimento e de troca de direo necessrio juntar a tabela acima com os direcionais do teclado. Abaixo segue as especifica e s dos sprites. pacpac.bmp

Especificaes Qtde de Qtde de Largura Largura Altura: Desenhos em x[0]: Desenhos em y[0]: total: individual: 5 4 125 pixels 25 pixels 25 pixels

OBS: Salvar a imagem acima como .BMP. O allegro no aceita o tipo jpg.

O cdigo que iremos usar para movimentar o Robocop e o drago o mesmo. Porm, antes de executar cada um necessrio fazer algumas configura es com relao s especifica e s citadas acima. O cdigo ser dividido em 3 arquivos. So eles:

y y y

main.cpp Jogador.h Jogador.cpp

Trocar de dire

o usando Sprite

CDIGO...#include #include "cjogador.h"// Arquivo: main.cpp

int main() { allegro_init(); set_color_depth(32); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); CJogador Jogador; // Instacia o Pacman BITMAP *Buffer = NULL; Buffer = create_bitmap(SCREEN_W,SCREEN_H); while (!key[KEY_ESC]) { clear_bitmap(Buffer); textprintf_ex(Buffer, font, 0, 0, makecol(0, 255, 255), 1,"SPRITE EM MOVIMENTO"); //Atualiza o Pacman na tela Jogador.Atualiza(Buffer); //Controle para Movimentao do Pacman na tela Jogador.Controle(25);

blit(Buffer,screen,0,0,0,0,SCREEN_W,SCREEN_H); vsync(); } destroy_bitmap(Buffer); delete Buffer; allegro_exit(); return 0; } END_OF_MAIN();

FIM DO CDIGO

main.cpp Dentro desse arquivo possvel encontrar:

y y y y y y

Referncia aos arquivos de recursos. Inicializao da biblioteca allegro. Referncia a classe Jogador (Pacman) Loop principal do jogo. Liberao dos ponteiros. Encerramento do programa.

CDIGO...

#ifndef CJOGADOR_H #define CJOGADOR_H #include // Arquivo: cjogador.h

class CJogador { private: BITMAP *imgJogador; int iPosx; int iPosy; int iSpritex; int iSpritey; public: int iLargura; int iAltura; CJogador(); ~CJogador(); void Setax(int); void Setay(int); void Atualiza(BITMAP *buffer); void Controle(int); }; #endif

FIM DO CDIGOJocador.h Arquivo de recurso responsvel por armazenar apenas a definio da classe Jogador. Todas as caractersticas que o pacman vai possuir esto definidas nesse arquivo. So elas: Varivel BITMAP *imgJogador int iPosx int iPosy int iSpritex int iSpritey int iLargura int iAltura Descrio Guarda imagem do Pacmam Posio x do pacman na tela Posio y do pacman na tela Posio da animao do sprite Posio da direo do sprite Armazena a largura de um sprite Armazena a altura de um sprite

Varivel CJogador(); ~CJogador(); void Setax(int); void Setay(int);

Descrio Construtor para iniciar as variveis da classe. Destrutor responsvel por liberar a imagem do pacman da memria. Seta a posio x do pacman a partir de uma velocidade passada por argumento. Seta a posio y do pacman a partir de uma velocidade passada por argumento.

void Atualiza(BITMAP *buffer); void Controle(int);

Renderiza o pacman na tela. Controla a direo do pacman atravs das setas do teclado.

CDIGO...#include "cjogador.h"// Arquivo: cjogador.cpp

static int iVelSprite = 4; CJogador::CJogador() { this->imgJogador = load_bitmap("pacpac.bmp",NULL); // Sprites do PacPac this->iPosx = 0; // Posio x do pacman na tela this->iPosy = 0; // Posio y do pacman na tela this->iLargura = 25; // Define a largura do sprite this->iAltura = 25; // Define a altura do sprite this->iSpritex = 0; // Inicia animao na posio zero. this->iSpritey = 0; // Inicia virado para a direita } CJogador::~CJogador() { delete this->imgJogador; } void CJogador::Setax(int vx) { this->iPosx += vx; if (vxiSpritey = 25; // Vira Sprite para esquerda if (vx>0) this->iSpritey = 0; // Vira o Sprite para a direita } void CJogador::Setay(int vy) { this->iPosy += vy; if (vyiSpritey = 50; // Vira o Sprite para Cima if (vy>0) this->iSpritey = 75; // Vira o Sprite para Baixo } void CJogador::Atualiza(BITMAP *buffer) { if (iSpritex >= 100) iSpritex = 0; masked_blit(imgJogador,buffer,this ->iSpritex,this->iSpritey,this->iPosx,this->iPosy,this>iLargura,this->iAltura); iVelSprite--; if (iVelSpriteiSpritex += 25; iVelSprite = 4; } } void CJogador::Controle(int Vel) { static int Buffer_Teclado =0; // A cada movimento reinicia o buffer do teclado. if (Buffer_Teclado == 0) {

if (key[KEY_UP]) { this->Setay(-Vel); Buffer_Teclado = 10; } else if (key[KEY_DOWN]) { this->Setay(Vel); Buffer_Teclado = 10; } else if (key[KEY_LEFT]) { this->Setax(-Vel); Buffer_Teclado = 10; } else if (key[KEY_RIGHT]) { this->Setax(Vel); Buffer_Teclado = 10; } } else { Buffer_Teclado--; } }

FIM DO CDIGOJogador.cpp Esse arquivo faz referencia ao arquivo de recursos Jogador.h. No entanto, ele guarda apenas o cdigo responsvel pela movimentao do pacman na tela. Caro leitor chegamos ao fim do entendimento da troca de sprites durante a animao. Esper ter escrito um o cdigo auto explicativo. Se houver alguma dvida ou dificuldade favor entrar em contato com o pessoal pelo Forum.

30 Rola em de Cen rio Scroll ou Scrollin )Existem vrias formas de se fazer um efeito de Scrolling. Vamos aprender a fazer 3 tipos de Efeitos.

Scrollin falsoUm exemplo de scrolling falso o exemplo do espao aonde as estrelas vo passando, umas bem lentas e outras rpidamente dando o efeito de que o cenrio est andando. Um outro exemplo de um cenrio que tem a mesma imagem de fundo, quando o personagem vai andando a imagem vai andando tambm, mais ela acaba sempre se repetindo. Vamos trabalhar com os 2 exemplos, primeiro, mostraremos nosso programa base que mostra e limita os FPS.

CDIGO...

#include // PROGRAMA BASE // variveis globais int fps = 0; int fps_antigo = 0; int fps_speed = 0; // prototipo do contador de frames void frame_rate(); // prototipo do contador de velocidade void incrementa_speed();

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); install_timer(); install_int( frame_rate, 1000 ); install_int_ex( incrementa_speed, BPS_TO_TIMER(60) ); BITMAP *buffer = NULL;// Criando BUFFER para double buffer buffer = create_bitmap(800,800); // Lao principal while( !key[KEY_ESC] ) { while ( ::fps_speed > 0 ) { clear( buffer );

textprintf_ex( buffer, font, 10 10, makecol(255,0,0), -1, "FPS: %d", ::fps_antigo , ); ::fps_speed--; ::fps++; } blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); vsync(); } destroy_bitmap( buffer ) ; allegro_exit(); return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; } void incrementa_speed() { ::fps_speed++; }

FIM DE CDIGO...

Exemplo do espa o estrelado.O exemplo no tem muita complicao. O resultado se parece muito com os crditos de vrios jogos ( Mega Man ). Criamos uma classe que sempre fica verificando a posio do objeto, se o objeto est fora da tela, ele reposiciona o objeto para o comeo da tela com uma nova velocidad e. Preste ateno na forma como eu aloco cada objeto do array de estrelas, como eu uso eles e como a memria desalocada.

CDIGO...#ifndef STAR_H #define STAR_H// ARQUIVO: star.h // Data: 18/08/2007

const int tamanho_total = 3; const int velocidade_total = 15; class Star { private: int velocidade; int id; public: Star( int ); // construtor ~Star(); // destrutor void iniciar( int ); // inicia o objeto void verificar(); // verifica se no chegou no final da tela int x; int y; int tamanho; }; #endif

FIM DE CDIGO... CDIGO...#include #include #include "star.h"// ARQUIVO: star.cpp // Data: 18/08/2007 // construtor Star::Star( int vid ) {

!

this->id = vid; this->velocidade = 0; this->x = 0; this->y = 0; this->tamanho = 0; this->x = 1 + rand() % SCREEN_W; this->y = this->id + rand() % ( this ->id + 10 ); this->velocidade = ( 1 + rand() % (::velocidade_total) ); this->tamanho = 1 + rand() % (::tamanho_total); }// destrutor Star::~Star() { this->velocidade = 0; this->x = 0; this->y = 0; this->tamanho = 0; } // inicia o objeto void Star::iniciar( int i ) { if ( i == 0 ) { i = 1; }

this->y = i + rand() % ( i + 10 ); this->velocidade = ( 1 + rand() % (::velocidade_total) ); this->tamanho = 1 + rand() % (::tamanho_total); this->x = SCREEN_W; }// verifica se no chegou no final da tela void Star::verificar() { if ( this->x > 0 ) {

this->x -= this->velocidade; } else { this->iniciar( this->id ); } }

FIM DE CDIGO...

CDIGO...#include #include #include #include "star.h"

// ARQUIVO: main.cpp // Data: 18/08/2007 // Exemplo de scrolling falso

// variveis globais int fps = 0; int fps_antigo = 0; int fps_speed = 0; // prototipo do contador de frames void frame_rate(); // prototipo do contador de velocidade void incrementa_speed();

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); srand( time(0) ); // determina a randomizao install_timer(); install_int( frame_rate, 1000 ); install_int_ex( incrementa_speed, BPS_TO_TIMER(60) ); BITMAP *buffer = NULL; int i = 0; int total_estrelas = SCREEN_H; Star *estrelas[total_estrelas];// inicia as estrelas for ( i=0; i< total_estrelas; i++ ) { estrelas[ i ] = new Star( i ); } // Criando BUFFER para double buffer buffer = create_bitmap(800,800); // Lao principal while( !key[KEY_ESC] ) { while ( ::fps_speed > 0 ) { clear( buffer ); // imprime as estrelas na tela e verifica se ela no chegou no final da tela for ( i=0; i< total_estrelas; i++ ) { putpixel(buffer, estrelas[ i ] ->x, estrelas[ i ]->y, makecol(255,255,255)); estrelas[ i ]->verificar(); }

textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "FPS: %d", ::fps_antigo ); ::fps_speed--; ::fps++; } blit(buffer, screen, 0,0,0,0, SCREEN_W, S CREEN_H); vsync(); }

// apaga as estrelas da memoria for ( i=0; i< total_estrelas; i++ ) { delete estrelas[i]; }

destroy_bitmap( buffer ); allegro_exit(); return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; } void incrementa_speed() { ::fps_speed++; }

FIM DE CDIGO... Exemplo cen rio com ima em de fundo repetida.Este um exemplo bastante utilizado em jogos de scroll vertical, como o Ninja Gaiden. Faremos uma imagem de fundo passar lentamente, e uma imagem mais perto passar bem rpido, passando a impresso de velocidade e movimentao do cenrio. Vamos usar as seguintes imagens retiradas do Ninja Gaiden 3.

Este ser o cu, uma imagem que andar bem lentamente. Agora vamos pegar a segunda paisagem que andar rapidamente, dando o efeito de scroll.

Novamente iremos utilizar nosso travador de FPS. A lgica do programa fazer copias das imagens, para que o usurio no perceba que elas temum inicio e

#

"

um fim. Iremos concatenar a imagem para fazer isso.

CDIGO...#include // ARQUIVO: main.cpp // Data: 20/08/2007 // Exemplo de scrolling falso // variveis globais int fps = 0; int fps_antigo = 0; int fps_speed = 0; // prototipo do contador de frames void frame_rate(); // prototipo do contador de velocidade void incrementa_speed();

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); install_timer(); install_int( frame_rate, 1000 ); install_int_ex( incrementa_speed, BPS_TO_TIMER(60) );// Criando BUFFER para double buffer BITMAP *buffer = NULL; buffer = create_bitmap(800,800); // Load das imagens .bmp ( converter de jpg para bmp ) BITMAP *img_fundo1 = NULL; BITMAP *img_fundo2 = NULL;

img_fundo1 = load_bitmap("ceu1.bmp", NULL ); img_fundo2 = load_bitmap("cenario2.bmp", NULL );// essas variveis so variveis auxiliares que ajudaro muito BITMAP *fundo1 = NULL; BITMAP *fundo2 = NULL;

fundo1 = create_bitmap( 1022, 180 ); fundo2 = create_bitmap( 780, 149 );// estou criando o fundo em uma variavel auxiliar blit(img_fundo1, fundo1, 0, 0, 0, 0, 511, 180 ); blit(img_fundo1, fundo1, 0, 0, 511, 0, 511, 180 ); // estou usando masked para ficar incolor a area rosa masked_blit(img_fundo2, fundo2, 0, 0, 0, 0, 260, 149 ); masked_blit(img_fundo2, fundo2, 0, 0, 260, 0, 260, 149 ); masked_blit(img_fundo 2, fundo2, 0, 0, 420, 0, 260, 149 ); // Lao principal while( !key[KEY_ESC] ) { while ( ::fps_speed > 0 )

{ clear( buffer ); masked_blit( fundo1, buffer, 0, 0, 0, 0, 1022, 180 ); masked_blit( fundo2, buffer, 0, 0, 0, 130, 780, 149 ); textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "FPS: %d", ::fps_antigo ); ::fps_speed--; ::fps++; } blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); vsync(); } destroy_bitmap( buffer ); destroy_bitmap( img_fundo1 ); destroy_bitmap( img_fundo2 ); destroy_bitmap( fundo1 ); destroy_bitmap( fundo2 ); allegro_exit(); return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; } void incrementa_speed() { ::fps_speed++; }

FIM DE CDIGO...Agora vamos implementar no cdigo acima, a rolagem do cenrio. Observe no cdigo abaixo, que colamos 2 imagens iguais de fundo no buffer.. uma ao lado da outra. A lgica funciona da seguinte maneira. Enquanto nosso contador for menor que o tamanho total de 1 imagem ( a mesma imagem montada uma ao lado da outra ), a gente vai incrementando ela e mostrando na tela a imagem na posio do contador. Desta forma a imagem vai andando para o lado. Para que a imagem seja repetida corretamente, a segunda imagem colada na posio (total_fundo1*(-1))+x_fundo1) Que igual a, -1022 + x_fundo1, isso vai fazer com que nossa segunda imagem fique exatamente no final da primeira imagem, e isso tambm vai previnir de que o cenrio seja quebrado.

CDIGO...#include

// ARQUIVO: main.cpp // Data: 20/08/2007 // Exemplo de scrolling falso // variveis globais int fps = 0; int fps_antigo = 0; int fps_speed = 0; // prototipo do contador de frames void frame_rate(); // prototipo do contador de velocidade void incrementa_speed();

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); install_timer(); install_int( frame_rate, 1000 ); install_int_ex( incrementa_speed, BPS_TO_TIMER(30) );// Criando BUFFER para double buffer BITMAP *buffer = NULL; buffer = create_bitmap(800,800); // Load das imagens .bmp ( converter de jpg para bmp ) BITMAP *img_fundo1 = NULL; BITMAP *img_fundo2 = NULL;

img_fundo1 = load_bitmap("ceu1.bmp", NULL ); img_fundo2 = load_bitmap("cenario2.b mp", NULL );// essas variveis so variveis auxiliares que ajudaro muito BITMAP *fundo1 = NULL; BITMAP *fundo2 = NULL;

fundo1 = create_bitmap( 1022, 180 ); fundo2 = create_bitmap( 780, 149 );// estou criando o fundo em uma variavel auxiliar blit(img_fundo1, fundo1, 0, 0, 0, 0, 511, 180 ); blit(img_fundo1, fundo1, 0, 0, 511, 0, 511, 180 ); // estou usando masked para ficar incolor a area rosa masked_blit(img_fundo2, fundo2, 0, 0, 0, 0, 260, 149 ); masked_blit(img_fundo2, fundo2, 0, 0, 260, 0, 260, 149 ); masked_blit(img_fundo2, fundo2, 0, 0, 520, 0, 260, 149 ); //masked_blit(img_fundo2, fundo2, 0, 0, 420, 0, 260, 149 ); // Inicio programao da rolagem int velocidade_fundo1 = 1; int velocidade_fundo2 = 6;

int total_fundo1 = 1022; int total_fundo2 = 780; int x_fundo1 = 0; int x_fundo2 = 0;// Lao principal while( !key[KEY_ESC] ) { while ( ::fps_speed > 0 ) {

clear( buffer );// faz com que, antes que o segundo fundo termine, comee a imprimir o primeiro fundo if ( x_fundo1 < ( total_fundo1 ) ) { x_fundo1 = x_fundo1 + velocidade_fundo1; } else { x_fundo1 = 0; } // vai passando o primeiro fundo masked_blit( fundo1, buffer, x_fundo1, 0, 0, 0, 1022, 180 ); // imprime no final do primeiro fundo, e vai passando masked_blit( fundo1, buffer, ((total_fundo1*(-1))+x_fundo1), 0, 0, 0, 1022, 180 );

if ( x_fundo2 < ( total_fundo2 ) ) { x_fundo2 = x_fundo2 + velocidade_fundo2; } else { x_fundo2 = 0; } masked_blit( fundo2, buffer, x_fundo2, 0, 0, 130, 780, 149 ); masked_blit( fundo2, buffer, ((total_fundo2*( -1))+x_fundo2), 0, 0, 130, 780, 149 ); textprintf_ex( buffer, font, 10, 10, makecol(255,0,0), -1, "FPS: %d", ::fps_antigo ); ::fps_speed--; ::fps++; } blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); vsync(); } destroy_bitmap( buffer ); destroy_bitmap( img_f undo1 ); destroy_bitmap( img_fundo2 ); destroy_bitmap( fundo1 ); destroy_bitmap( fundo2 ); allegro_exit(); return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; } void incrementa_speed() { ::fps_speed++; }

FIM DE CDIGO...

Exemplo de scrollin verdadeiroImagine uma fase do Super Mario, quando o personagem chega no limite da tela, a tela comea a andar, e os sprites de fundo comeam a se mover. esse tipo de simulao que iremos mostrar agora. O cdigo abaixo controlado pelo teclado. Utilize as setas para fazer o cenrio andar. Para escrever o cdigo, primeiro precisamos saber que o personagem o centro da tela da nossa rolagem ( ele no precisa estar no centro da tela necessariamente ). Quando o personagem se mover, devemos mover todos os tiles do fundo na posio oposta. Para isso, precisamos tambm ter o tamanho total da tela, no caso, a fase do nosso jogo. Nossa tela medir 500 px. Ns vamos especificar o tamanho do cenario em 250 tiles. Cada tile ter 50 px de tamanho total; Iremos usar tambm a parte central da tela, desta forma, podemos ver o efeito de scrolling. Voc vai perceber que nossos cdigos esto comeando a aumentar hehehe.. Isto normal. A tcnica utilizada abaixo pode ser usada com um construtor de cenrios, basta entender o algoritmo de rolagem que bem simples.

CDIGO...#include // ARQUIVO: main.cpp // Data: 22/08/2007 // Exemplo de scrolling verdadeiro // variveis globais int fps = 0; int fps_antigo = 0; int fps_speed = 0; // prototipo do contador de frames void frame_rate(); // prototipo do contador de velocidade void incrementa_speed();

int main() { allegro_init(); set_color_depth(16); install_keyboard(); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); install_timer(); install_int( frame_rate, 1000 ); install_int_ex( incrementa_speed, BPS_TO_TIMER(30) );// Criando BUFFER para double buffer BITMAP *buffer = NULL; buffer = create_bitmap(800,80 0); // variveis const int const int const int const int comentadas no escopo do programa tamanho_tela = 500; inicial_tela = ( (SCREEN_W/2) -(tamanho_tela/2) ); cenario = 250; // tiles tamanho_tile = 50;

$

// posio de nosso personagem int personagem_pos = inicial_tela + 10; int x = personagem_pos; // auxiliares int i = 0; int total_for = 0; int posicao = 0;

int posicao_cenario_inicial = inicial_tela; int posicao_cenario = 0;

// Lao principal while( !key[KEY_ESC] ) { while ( ::fps_speed > 0 ) {

clear( buffer );// este for faz com que seja mostrado apenas a parte do cenario visivel para o usurio // para isso ele s vai mostrar // os tiles que cabem na tela ( tamanho_tela / tamanho_tile ) // mais a posio atual do cenario ( que incrementado quando se aperta uma tecla ) // usamos o -1 para trocar o sinal da operao total_for = ( tamanho_tela / tamanho_tile )+( posicao_cenario*( -1) ); for ( i=posicao_cenario; i - ( ( cenario ) - (tamanho_tela / tamanho_tile) ) ) { posicao_cenario--;

%

} else { // atualiza a posio do nosso personagem if ( x < (inicial_tela+tamanho_tela) -10 ) { x++; } } } } if ( key[KEY_LEFT] ) { // atualiza a posio do nosso personagem if ( x > ( tamanho _tela + inicial_tela ) / 2 ) { x--; } else { // do cenario // nunca vai poder passar o limite do cenario if ( posicao_cenario < cenario && posicao_cenario < 0 ) { posicao_cenario++; } else { // atualiza a posio do nosso personagem if ( x > ( inicial_tela ) ) { x--; } } } } blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H); vsync(); } destroy_bitmap( buffer );

allegro_exit(); return 0; } END_OF_MAIN(); void frame_rate() { ::fps_antigo = ::fps; ::fps = 0; } void incrementa_speed() { ::fps_speed++; }

30 Scrollin de Tiles

No tutorial 26 "Utilizando Tiles" j foi explicado conceitos bsicos sobre tiles e sua aplicao. Nesse tutorial, estarei mostrando uma tcnica chamada SCROLLING de TILES (No importante que voc tenha lido o

'

&

tutorial 26 antes de continuar neste tutorial, pois estarei mostrando uma abordagem diferente sobre o assunto). Para imprimir tiles na tela, usado um mapa para representar a posio de cada tile. Para preenchermos uma tela de 640x480, e usando tiles de 32x32, precisaramos de 20 tiles na horizontale 15 na vertical. Com SCROLLING DE TILES, podemos ter o mapa do tamanho que quisermos (no preciso nem dizer que o mapa representado por uma matriz multidimensional). SCROLING DE TILES amplamente usado em jogos 2d, como Mario ou Metroid. Portanto, poderemos ter um mapa de tamanho qualquer, no importa a altura nem a largura, nosso algoritmo deve imprimir os tiles na tela perfeitamente. Voc pode estar pensando: " s imprimir todos os tiles na tela". Nada impede que voc faa isso, mas seu jogo ficar extremamente lento. O correto imprimir somente a rea correspondente ao tamanho da tela.

BsicoO tutorial 26 mostrou um jeito fcil de imprimir tiles na tela. Nessa parte bsica, vou mostrar outra forma de obter o mesmo resultado, ou seja, imprimir tiles carregando o mapa a partir de um arquivo. Primeiro, precisamos declarar algumas constantes e estruturas bsicas:

CDIGO.../* Tamanho do tile */

#define TILEWH 32 typedef struct { BITMAP * bitmap; } SPRITE; typedef struct { SPRITE * sprite; } TILE; typedef struct { int w; int h; TILE ** tiles; } MAP; typedef struct { int w; int h; } MAPINFO;

FIM DE CDIGO...A primeira estrutura, SPRITE, armazenar informa e s do tile atual, que no nosso caso vai ser somente esttico (imagem fixa). A segunda estrutura, TILE, armazenar informa e s sobre que tipo de SPRITE iremos imprimir na tela.

(

(

A estrutura MAP armazenar o mapa, contendo a posio x e y da cada tile. MAPINFO um estrutura adicional e ser explicada mais frente.

Os TilesUsarei tiles de 32x32px de tamanho neste tutorial. Portanto, o arquivo Bitmap deve ser mltiplo de 32. Poderamos carregar os tiles manualmente, mas um processo automatizado sempre melhor, ento, criaremos uma funo para carregar os tiles a partir de um arquivo Bitmap. A funo ir retornar um vetor de SPRITE.

CDIGO.../* Funo para carga de tiles */

SPRITE * load_tiles(const char * filename) {/* Armazenando o bitmap em uma varivel temporria */

BITMAP * tmp = load_bitmap(filename, NULL);/* Verificando se o bitmap foi carregado */

if (tmp == NULL) return NULL;/* Pegando o nmero de tiles na horizontal e na vertical */

int xtiles = tmp ->w / TILEWH; int ytiles = tmp ->h / TILEWH;/* Total de tiles no bitmap */

int total = xtiles * ytiles;/* Criando o vetor de SPRITE */

SPRITE * spr = (SPRITE *) malloc(sizeof(SPRITE) * total); int x; int y;/* ndice para o vetor de SPRITE */

int i = 0;/* Faa enquanto houver tiles na horizontal e na vertical */

for (y = 0; y < ytiles; y++) { for (x = 0; x < xtiles; x++) {/* Criando o BITMAP que vai armazenar o tile */

spr[i].bitmap = create_bitmap(TILEWH, TILEWH );/* Copiando o pedao da imagem para o SPRITE */

blit(tmp, spr[i].bitmap, x * TILE, y * TILE, 0, 0, TILE, TILE);/* Prximo ndice */

i++; } }/* Libere a memria alocada para o bitmap */

destroy_bitmap(tmp);/* Retorne o vetor de SPRITE */

return spr; }

FIM DE CDIGO... ExplicandoNo cdigo acima, criamos uma rotina de carga de tiles. Um arquivo Bitmap requerido. Para obtermos o nmero de tiles na horizontal e na vertical, basta pegar a altura e largura do Bitmap e dividir pelo tamanho do tile.

int xtiles = tmp ->w / TILEWH; int ytiles = tmp ->h / TILEWH;Calculamos o total de tiles no bitmap

int total = xtiles * ytiles;J temos condio de criar o vetor de SPRITE, que armazenar os tiles:

SPRITE * spr = (SPRITE *) malloc(sizeof(SPRITE) * total);E o final: carregar os tiles do bitmap "tmp" no vetor.

int x; int y; int i = 0; for (y = 0; y < ytiles; y++) { for (x = 0; x < xtiles; x++) { spr[i]->bitmap = create_bitmap(TILE, TILE); blit(tmp, spr[i] ->bitmap, x * TILE, y * TILE, 0, 0, TILE, TILE); i++; } }Primeiro, declaramos uma varivel i, que armazenar o ndice no vetor de SPRITE (nosso vetor de SPRITE linear). Os dois laos de repetio FOR so usados para percorrer o bitmap "tmp" de cima para baixo e da esquerda

para a direita. Para cada vez que o lao y for executado, o lao x ser executado N vezes. Na prtica ficaria:

+-------+-------+-------+ | | | | | 1 | 2 | 3 | +-------+-------+-------+Isso se tivssemos um BITMAP de 96x32. Se tivssemos um BITMAP de 96x96:

+-------+-------+-------+ | | | | | 1 | 2 | 3 | +-------+-------+-------+ | | | | | 4 | 5 | 6 | +-------+-------+-------+ | | | | | 7 | 8 | 9 | +-------+-------+-------+Os tiles ficariam organizados nessa ordem no vetor. Para finalizar, criamos realmente o BITMAP da estrutura SPRITE e "blitamos" o tile nele:

spr[i]->bitmap = create_bitmap(TILEWH, TILEWH); blit(tmp, spr[i] ->bitmap, x * TILEWH, y * TILEWH, 0, 0, TILEWH, TILEWH);Lembrando que a posio do tile definida pelos parmetros x e y dos laos. Como nossos TILES tem 32x32 de tamanho, fica fcil encontrar sua posio no BITMAP tmp, pois s multiplicar por 32.

O MapaNormalmente, tudo em um jogo colocado dentro de arquivos, no caso de mapas, mais simples e voc ainda tem a possibilidade de criar outros mapas para seu j ogo. Pode-se usar programas como o Mappy ou Tile Studio, mas a verdade que VOC deve fazer seu prprio editor de mapas. O mapa pode ser armazenado em arquivos texto ou binrio. Para usarmos arquivos texto, precisaramos criar um ANALISADOR LXICO para ler os tokens. Escrever um analisador lxico (descente) no fcil, e outra coisa, o mapa ficaria exposto (com qualquer editor de texto poderamos editar o mapa). Com arquivos binrios, mais simples e para alterar o mapa ser necessrio um editor hexadecimal. Usaremos o Mappy para criar os mapas, mas no usaremos sua API para imprimi lo na tela. Baixe o Mappy no endereo: http://www.tilemap.co.uk/mappy.php Basta descompact-lo e executar normalmente. Abra-o e uma tela como essa ser apresentada:

Para criar um mapa, basta ir ao menu "File / New Map". Altere o tamanho do tile se quiser, mas a configurao padro a de tiles de 32x32. Mais abaixo, coloque o tamanho na horizontal (tiles wid e na e) vertical (tiles high), lembrando que isso significa o tamanho da tela em tiles, no em pixels. Crie um mapa com tiles de 32x32 e a tela com 40 tiles na horizontal e 15 na vertical. Depois de criar o mapa, s importar o tiles. Baixe os seguintes tiles (clique em cima da imagem para fazer o download):

Agora, para importar, v no menu "File / Import", e escolha um arquivo .bmp contendo os tiles que voc baixou ou os de sua escolha. Selecione o tile na janela direita e depois pinte o mapa. Faa um mapa parecido com este:

Depois que o mapa estiver pronto, precisaremos gerar um arquivo. Como no usaremos a API do Mappy, precisaremos exportar para um outro formato de arquivo que seja fcil de abrirmos. V no menu "Custom / Export binary file". Uma janela abrir, basta clicar em OK e outra janela abrir. Nela diz se voc quer ajustar os valores dos tiles (pode-se ajustar tanto para cima quanto para baixo). O valor "-1" o padro, mas devemos alterar para "0" pelo seguinte fato: os tiles vazios so representados pelo nmero "0", e o nosso primeiro tile representado pelo nmero "1", se colocarmos o valor de ajuste como "-1", nosso primeiro tile ser "0", ou seja, ele ser um tile vazio! Ao final, um arquivo .map ser criado. Segue-se a estrutura desse tipo de arquivo:

+---------------------- + | Cabealho | +---------------------- + | Dados sobre a fase | | | | | | | +---------------------- +As primeiras informa es no arquivo referem-se ao tamanho do mapa (em tiles) na horizontal e na vertical. Usaremos a estrutura MAPINFO para obter essas informa es para depois ler o mapa. Segue a rotina de carga de mapa:

CDIGO.../* Rotina para carga de mapa */

MAP * load_map(const char * filename, SPRITE * spr) {/* Abrindo o arquivo de mapa */

FILE * file = fopen(filename, "rb");/* Verificando se ele existe */

if (!file) return NULL;/* Alocando memria para o mapa */

MAP * map = (MAP *) malloc(sizeof(MAP));/* Pegando informa e sobre o mapa */

MAPINFO info; fread(& info, sizeof(MAPINFO), 1, file);/* Altura e largura do mapa */

map->w = info.w; map->h = info.h;/* Crie a matriz na vertical */

)

0

)

map->tiles = (TILE **) malloc(sizeof(TILE) * map ->h); int x; int y; int value; for (y = 0; y < map ->h; y++) {/* Crie a matriz na horizontal */

map->tiles[y] = (TILE *) malloc(sizeof(TILE) * map ->w); for (x = 0; x < map->w; x++) {/* Lendo o tipo de tile */

fread(& value, sizeof(int), 1, file);/* Se o valor do tile for diferente de 0, atribua o SPRITE, seno, NULL */

map->tiles[y][x].sprite = value != 0 ? & spr [value - 1] : NULL; } }/* Feche o handle de arquivo */

fclose(file);/* Retorne o mapa */

return map; }

FIM DE CDIGO... ExplicandoNo cdigo acima, um arquivo de mapa requerido e o vetor de SPRITE contendo os tiles. Primeiramente, pegamos as informa e s referentes ao mapa (altura e largura em tiles). A partir da, s carregar o mapa. A leitura do mapa feita sequencialmente, quem define a posio de cada tile so os laos de repetio FOR. Lemos um inteiro de cada vez e verificamos se o seu valor no 0. Se for 0, o valor NULL atribudo, seno, atribua o ponteiro para o vetor de SPRITE (lembrando que na rotina de carga de tiles, os SPRITEs so carregados linearmente, comeando pelo ndice 0, que o primeiro tie). l Obs.: No Mappy, o primeiro tile representa o ndice 1, por isso a subtrao por 1.

Imprimindo o mapaA rotina de impresso de mapa deste tutorial difere um pouco do tutorial 26. Se voc reparar bem, o cdigo mostrado at agora parece ser uma extenso do allegro. Eis a rotina de impresso de mapa:

CDIGO...

1

/* Rotina de impresso de mapa */

void draw_map(BITMAP * bitmap, MAP * map, int xpos, int ypos) {/* Posio inicial */

int xbegin = abs(xpos / TILEWH); int ybegin = abs(ypos / TILEWH);/* Verificando se no ultrapassa o mapa */

if (xpos > 0) xbegin = 0; if (ypos > 0) ybegin = 0;/* Posio final */

int xend = SCREEN_W / TILEWH + xbegin + 1; int yend = SCREEN_H / TILEWH + ybegin + 1;/* Verificando se no ultrapassa o mapa */

if (xend > map ->w) xend = map ->w; if (yend > map ->h) yend = map ->h; int x; int y;/* Imprima o mapa! */

for (y = ybegin; y < yend; y++) for (x = xbegin; x < xend; x++) if (map->tiles[y][x].sprite) draw_sprite(bitmap, map ->tiles[y][x].sprite ->bitmap, x * TILEWH + xpos, y * TILEWH + ypos); }

FIM DE CDIGO... ExplicandoA rotina acima se prope a imprimir um MAPA no "BITMAP bitmap". As posies x e y so tambm requeridas. Primeiro, pegamos as posies iniciais x e y de pintura da tela. Como dito anteriormente, a tela fica sendo dividida em tiles, ento, devemos pegar a posio do tile e no a posio na tela, portanto, devemos dividir a s posies x e y pelo tamanho do tile que estamos usando (32x32). Se xpos for 16, dividido por 32, fica sendo 0,5. Arredondando d 0. Ento essa a posio x inicial. O mesmo para ypos (abs() foi usando pois no adianta imprimir antes da posio 0,0 da tela). os dois IF's verificam se as posies xpos e ypos so maiores que 0, ento, a posio inicial x e y ficam sendo 0. J encontramos as posies iniciais x e y, agora falta encontrar as posies finais. As posies finais so fceis de encontrar: basta pegar o tamanho da tela em tiles (tanto na horizontal quanto na vertical) e somar com o x e y inicial. O "+ 1" para que a rotina de impresso imprima at para fora da tela (somente 1 tile a mais). Sem isso, os tiles no sero impressos at que preencham a tela toda.

Sabendo as posies iniciais e finais, basta imprimir na tela. Antes de imprimir, verificamos se o SPRITE nulo (NULL), e se no for, imprimimos ele na tela. Encontramos a posio correta de cada tile multiplicando pelo tamanho do mesmo, ou seja: Tile: 0,0 - Posio: 0, 0 Tile: 0,1 - Posio: 0, 32 ... Tile: 1,1 - Posio: 32, 32 ... Acrecentamos tambm xpos e ypos posio do tile, para no dar um efeito de MOSAICO na tela.

O Cdigo CompletoPara executar o cdigo abaixo, baixe o seguinte a rquivo : mapa.map

CDIGO...#include #include #include #include

#define TILEWH 32 #define SPEED 1 typedef struct { BITMAP * bitmap; } SPRITE; typedef struct { SPRITE * sprite; } TILE; typedef struct { TILE ** tiles; int w; int h; } MAP; typedef struct { int w; int h; } MAPINFO; BITMAP * buffer; SPRITE * load_tiles(const char *);

MAP * load_map(const char *, SPRITE *); void draw_map(BITMAP *, MAP *, int, int); int main(int argc, char ** argv) { allegro_init(); install_keyboard(); set_color_depth(16); set_gfx_mode(GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); buffer = create_bitmap(SCREEN_W, SCREEN_H); SPRITE * spr = load_tiles("tiles.bmp"); if (!spr) { allegro_message("Falha ao carregar SPRITES!"); return 1; } MAP * map = load_map("mapa.map", spr); if (!map) { allegro_message("Falha ao carregar MAPA!"); return 1; } int xmap = 0; int ymap = 0; int x = 0; int y = 0; while (!key[KEY_ESC]) { if (key[KEY_LEFT]) xmap += SPEED; if (key[KEY_RIGHT]) xmap -= SPEED; clear(buffer); draw_map(buffer, map, xmap, 0); blit(buffer, screen, 0, 0, 0, 0, SCREEN_W, SCREEN_H); } destroy_bitmap(buffer); allegro_exit(); return 0; } END_OF_MAIN();

SPRITE * load_tiles(const char * filename) { BITMAP * tmp = load_bitmap(filename, NULL); if (!tmp) return NULL; int xtiles = tmp ->w / TILEWH; int ytiles = tmp ->h / TILEWH; int total = xtiles * ytiles; SPRITE * spr = (SPRITE *) malloc(sizeof(SPRITE *) * total); int x; int y; int i = 0; for (y = 0; y < ytiles; y++) { for (x = 0; x < xtiles; x++) { spr[i].bitmap = create_bitmap(TILEWH, TILEWH); blit(tmp, spr[i].bitmap, x * TILEWH, y * TILEWH, 0, 0, TILEWH, TILEWH); i++; } } destroy_bitmap(tmp); return spr; } MAP * load_map(const char * filename, SPRITE * spr) { FILE * file = fopen(filename, "rb"); if (!file) return NULL; MAP * map = (MAP *) malloc(sizeof(MAP)); MAPINFO info; fread(& info, sizeof(MAPINFO), 1, file); map->w = info.w; map->h = info.h; map->tiles = (TILE **) malloc(sizeof(TILE **) * map ->h); int x; int y; int value; for (y = 0; y < map ->h; y++) { map->tiles[y] = (TILE *) malloc(sizeof(TILE *) * map ->w);

for (x = 0; x < map ->w; x++) { fread(& value, sizeof(int), 1, file); map->tiles[y][x].sprite = value != 0 ? & spr[value } } fclose(file ); return map; } void draw_map(BITMAP * bitmap, MAP * map, int xpos, int ypos) { int xbegin = abs(xpos / TILEWH); int ybegin = abs(ypos / TILEWH); if (xpos > 0) xbegin = 0; if (ypos > 0) ybegin = 0; int xend = SCREEN_W / TILEWH + xbegin + 1; int yend = SCREEN_H / TILEWH + ybegin + 1; if (xend > map ->w) xend = map ->w; if (yend > map ->h) yend = map ->h; int x; int y; for (y = ybegin; y < yend; y++) for (x = xbegin; x < xend; x++) if (map->tiles[y][x].sprite) draw_sprite(bitmap, map ->tiles[y][x].sprite ->bitmap, x * TILEWH + xpos, y * TILEWH + ypos); }Fim Chegamos ao final deste EXTENSO tutorial. Se houver alguma dvida, crtica ou sugesto s obre o tutorial s ir no frum, ficarei muito grato. Num prximo tutorial, estarei escrevendo sobre coliso com o cenrio (um dos assuntos mais comentados sobre desenvolvimento de jogos). Mais uma coisa: se voc quer ver a rotina de impresso de mapa tra balhar, altere o cdigo da seguinte forma:

- 1] : NULL;

for (y = ybegin + 1; y < yend - 1; y++) for (x = xbegin + 1; x < xend - 1; x++) if (map->tiles[y][x].sprite) draw_sprite(bitmap, map ->tiles[y][x].sprite ->bitmap, x * TILEWH + xpos, y * TILEWH + ypos);Voc pode incrementar o cenrio, imprimindo uma imagem de fundo atrs do mapa, como um cu ou uma caverna. Espero que tenham gostado do tutorial e at mais...

Chegamos em um dos captulos mais interessantes e tambm muito importante para nossa linha de aprendizado. Iremos aprender como fazer nosso personagem pular e subir morros. Este captulo importante por que iremos introduzir a partir de agora um dos assuntos mais complicados na programao de jogos: Matemtica e Fsica. Nosso objetivo sempre deixar tudo muito claro, e por causa disso no iremos dar aulas de fsica avanada aqui. A idia deixar claro como certas coisas em jogos so feitas. Muito jogos utilizam fsica, mais certamente, todos utilizam matemtica. Nenhum dos dois assuntos difcil, basta que ele seja bem explicado e bem compreendido por quem l. O Algoritmo para fazer um personagem pular bem simples e ao mesmo tempo sensacional. Sensacional por que nele vemos como a fsica utilizada claramento nos jogos. Para fazer um personagem pular, primeiro precisamos pensar como no mundo real. O que faz com que a gente n