| |
Respostas dos Exercícios
- Utilizando o programa do capítulo 27, crie uma classe para imprimir vários quadrados "objetos" na tela.
O quadrado que se move deve detectar colisão nos outros objetos inseridos.
Imprima 5 quadrados na tela de tamanho diferentes e verifique a colisão com todos eles.
Preste atenção na forma que a classe foi criada.
Quanto mais prática a classe ficar, melhor para seu jogo. Você poderá usar ela muito mais fácil.
Evite complicações.
CÓDIGO...
#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 x;
int y;
int tamanho_x;
int tamanho_y;
};
#endif
FIM DE CÓDIGO...
CÓDIGO...
#include <allegro.h>
#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 função 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 colisão 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 CÓDIGO...
CÓDIGO...
// Colisão com vários objetos
#include <allegro.h>
#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 programação 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 vários 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);
// Laço 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
// Nós olhamos objeto por objeto, se colidir com um deles
// paramos o for e não deixamos nosso quadrado andar
for ( i=0; i<total_paredes; i++ )
{
colidindo = aparede[i].colide( x, y, tamanho_x, tamanho_y );
if ( colidindo == true )
{
i = total_paredes;
}
}
if ( colidindo == false )
{
x_atual = x;
y_atual = y;
}
else
{
// volta para os valores antigos
x = x_atual;
y = y_atual;
}
// limpa o nosso novo buffer
clear( buffer );
// escreve o quadrado no buffer
rectfill( buffer, x_atual, y_atual, x_atual+tamanho_x, y_atual+tamanho_y, makecol(255, 0, 0) );
// imprimimos as coordenadas x e y na tela para o usuário 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);
textprintf_ex( buffer, font, 10, 50, makecol(255,0,0), -1, "colide: %d", colidindo);
// imprime todos os quadrados no destino ( buffer )
for ( i=0; i<total_paredes; i++ )
{
aparede[i].imprimir( buffer );
}
// imprime o buffer na tela
vsync();
blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H);
// essa função faz o allegro esperar um pouco antes de voltar para o while
rest(10);
}
allegro_exit();
return 0;
}
END_OF_MAIN();
FIM DE CÓDIGO...
Preste muita atenção a forma que as paredes foram criadas.
Também preste atenção em como fazemos a colisão, olhando um objeto de cada vez.
Será que em um jogo grande isso seria válido??
Imagine testar a colisão desta forma em toda uma fase do Super Mario Bros ?
Quantos testes seriam necessários?
Por enquanto não se preocupe com otimização de código, poderiam ter 5 mil objetos na tela que o C++ iria
dar conta do recado. Utilize sua imaginação sem pensar que seu jogo irá ficar lento.
- Faça 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.
CÓDIGO...
// Bolinha andadora
#include <allegro.h>
int main()
{
allegro_init();
set_color_depth(16);
install_keyboard();
set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);
// inicio da programação atual
int x = 0;
int y = SCREEN_H/2;
int tamanho = 20;
bool colide = false;
int variavel = 1;
// Criando BUFFER para double buffer
BITMAP *buffer = NULL;
buffer = create_bitmap(800,800);
// Laço principal
while( !key[KEY_ESC] )
{
if ( variavel == 1 )
{
x += 5;
}
else
{
x -= 5;
}
// limpa o nosso novo buffer
clear( buffer );
// escreve o quadrado no buffer
ellipsefill(buffer, x, y, tamanho, tamanho, makecol(255,255,0) );
// imprimimos as coordenadas x e y na tela para o usuário 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);
// limitando o quadrado dentro da tela
if ( x < 0 )
{
variavel = variavel * (-1);
}
if ( (x+tamanho) > SCREEN_W )
{
variavel = variavel * (-1);
}
// imprime o buffer na tela
vsync();
blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H);
// essa função faz o allegro esperar um pouco antes de voltar para o while
rest(10);
}
allegro_exit();
return 0;
}
END_OF_MAIN();
FIM DE CÓDIGO...
- Faça 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 próxima vez, de forma que ela fique andando por toda a tela.
CÓDIGO...
// Bolinha colisão
#include <allegro.h>
int main()
{
allegro_init();
set_color_depth(16);
install_keyboard();
set_gfx_mode(GFX_AUTODETECT_FULLSCREEN, 640, 480, 0, 0);
// inicio da programação atual
int x = 0;
int y = SCREEN_H/2;
int tamanho = 20;
bool colide = false;
int variavel_x = 10;
int variavel_y = 10;
// Criando BUFFER para double buffer
BITMAP *buffer = NULL;
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;
}
// limpa o nosso novo buffer
clear( buffer );
// escreve o quadrado no buffer
ellipsefill(buffer, x, y, tamanho, tamanho, makecol(255,255,0) );
// imprimimos as coordenadas x e y na tela para o usuário 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);
// 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);
}
// imprime o buffer na tela
vsync();
blit(buffer, screen, 0,0,0,0, SCREEN_W, SCREEN_H);
// essa função faz o allegro esperar um pouco antes de voltar para o while
rest(10);
}
allegro_exit();
return 0;
}
END_OF_MAIN();
FIM DE CÓDIGO...
Contribuidor
Adriano Waltrick
01/08/2007
|
|