| |
28 - FPS - Quadros por segundo, Frames per second ou Frame Rate
Todo jogo possui animação, isto é fato.
Animações são geralmente quadros de desenhos que vão se mudando ( sobrepondo a antiga ) gerando assim uma animação.
Este é o exemplo de uma animação e alguns de seus quadros, que juntos formam a animação.
Esta animação originalmente tem 12 quadros e ela é executada a 100 milisegundos.
Se aumentarmos a taxa de milisegundos de cada quadro em separado, a animação vai ficar ainda mais lenta.
Se diminuirmos a taxa de 100 milisegundos de cada quadro, a animação vai ficar bem mais rápida.
Essa mudança de tempo nos quadros da animação 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 rápido em algumas máquinas e mais lento em outras máquinas.
Isso influência não só as animações como também a jogabilidade.
Para que o jogo rode igual em qualquer máquina, 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 técnica de contar FPS e fazer o programa rodar em um FPS igual para todas as máquinas pode e deve ser aplicado em qualquer tipo de linguagem de programação para jogos ou animações.
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 função do windows GetTickCount(); que pega o total de ticks.
Em OpenGL podemos fazer a mesma coisa usando as funções do GLUT .
|
|
VOCÊ PRECISA
SABER...
É importante que você tenha lido nosso artigo sobre como instalar timers no Allegro.
- Controle de tempo
|
|
CÓDIGO...
#include <allegro.h>
// 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);
// Laço 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 CÓDIGO
No exemplo acima, criamos uma variável global fps que é incrementada sempre após que a imagem é imprimida na tela.
Usando um timer do Allegro, sempre que passar 1 segundo, nós 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 roda, agora precisamos controlar a taxa de quadros, sem influênciar na jogabilidade.
Nos exemplos anteriores do site, estavamos usando o comando rest() que fazia o compilador esperar.Esta função não deve ser usanda, por que durante a execução do comando rest() as teclas do teclado não são detectadas.
Agora precisamos controlar a taxa de frames de nosso programa.
A descisão da quantidade de frames por segundo o jogo vai rodar é sua, você pode usar 30 FPS que é o limite mínimo para que o olho detecte transação da animação, ou 60 que é o valor mostrado no manual da Allegro.
CÓDIGO...
#include <allegro.h>
// 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);
// Laço 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 CÓDIGO
O programa acima pode parecer confuso.
Nós 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 lógica do jogo.
Enquanto o fps_speed
não for menor que 0 ( o while vai fazer ele chegar bem rápido ) ele vai atualizando a lógica do jogo, mais não a tela.
Esta lógica faz com que o contador de FPS fique constante.
Execute o código acima e faça testes alterando o valor que está na macro BPS_TO_TIMER para conferir.
Para fazer com que o teclado obedeça 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 dúvidas mais cabulosas na criação de jogos, a partir deste capítulo iremos demonstrar outras técnicas importantes na programação de jogos. Qualquer dúvida entre em contato pelo forum.
http://www.bdjogos.com/forum
Contribuidor
Adriano Waltrick
15/08/2007
|
|