Pular para o conteúdo principal

BIblioteca SDL e o desenvolvimento de jogos 2D - Parte 1

Bom, semanas atrás lá na faculdade, aula de algoritmos, foi proposto um projeto para desenvolver um jogo 2D utilizando linguagem C e a biblioteca SDL. O propósito do jogo é acertar um navio no mar utilizando os disparos de um canhão posicionado em terra.
Faz uns dias que comecei a fazer o projeto e daqui pra frente vou descrever alguns tópicos na medida em que eu for também aprendendo a utilizar a biblioteca.
Nesta primeira parte vou dar um pequeno resumo sobre a biblioteca SDL, dicas de como instalar a mesma no compilador DevC++ e também introduzir algumas funções.

Simple DirectMedia Layer (SDL) é uma biblioteca multimídia e multiplataforma escrita em C (mas diretamente compatível com C++ e possui interfaces para outras linguagens de programação, como Ada, Eiffel, Java, Lua, ML, Perl, PHP, Pike, Python, e Ruby), que cria uma abstração em várias plataformas de gráficos, sons, e entrada de APIs, tornando possível ao programador escrever um jogo de computador ou outra aplicação multimedia já que ela pode rodar em GNU/Linux, Windows, Mac OS Classic, Mac OS X, BeOS, FreeBSD, OpenBSD, Solaris, QNX, IRIX, e muitas outras plataformas não oficialmente suportadas. Ela gerencia video, eventos, audio digital, CD-ROM, som, threads, processamento de objetos compartilhados, rede e tempo.
Fonte: Wikipedia
Instalação:
O download da SDL pode ser obtido no endereço www.libsdl.org. Têm versões runtime (apenas para rodar aplicativos que dependem da SDL) e versões desenvolver aplicativos.

O Dev-C++ (IDE e compilador C++ gratuito para Windows, e que irei utilizar, pode ser encontrado em www.bloodshed.net) possui pacotes prontos e configurados corretamente para desenvolvimento de aplicativos SDL. Para isso basta baixá-los e instalá-los através do próprio gerenciador de pacotes/atualizações do Dev-C++ (caso ocorra alguma dúvida na instalação da biblioteca SDL no Dev-C++ deixe um comentário).

Um detalhe importante fica por conta do arquivo SDL.dll. Ele deve constar em algum diretório do sistema (como C:\Windows\system) ou no próprio diretório do aplicativo. É uma dll necessária para que você consiga rodar o seu aplicativo.exe.

Início:

Todos os programas escritos utilizando a biblioteca SDL (em linguagem C) deve incluir no cabeçalho a declaração de inclusão da biblioteca, ou seja:

#include "SDL/SDL.h"

Declarada a biblioteca o próximo passo é inicializar a SDL com a seguinte função:

SDL_Init();

Essa função pode ser declarada fora da função principal [main()].

Existem alguns parâmetros que devem ser passados à função SDL_Init(), esses parâmetros servem para informar à função quais partes da SDL serão iniciadas, por exemplo:

SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO);

//Nos parâmetros dessa função, note que foi pedida a inicialização do vídeo e do áudio.

Existem outros parâmetros que podem ser passados à função SDL_Init que você pode conferir na documentação presente no site da própria biblioteca SDL (http://www.libsdl.org/).

Antes de descrever a rotina de carregar imagem primeiro é preciso que vocês entendam o conceito de superfície, ou, surface: ou seja, para falar em imagens é preciso falar também de surfaces, que são áreas da memória utilizadas para armazenar imagens. É fato que a maioria das tarefas desenvolvidas utilizando SDL se utilizam de superfícies. Cada imagem carregada no seu jogo (no caso do nosso: o canhão, navio, fundo e a bala) são surfaces.

Uma surface pode ser desenhada dentro, ou por cima, de outra. Basta a gente notar na tela de fundo, temos a imagem de fundo e por cima desta serão carregadas as outras imagens (canhão, bala e navio). Mas aí você deve tá pensando "e daí?!! eu quero carregar as imagens na minha tela!!", bom então é simples:

As surfaces da bala, canhão, navio e fundo são declaradas inicialmente:

SDL_Surface *screen = NULL;
SDL_Surface *fundo = NULL
SDL_Surface *bala = NULL;
SDL_Surface *canhão = NULL;
SDL_Surface *navio = NULL

O NULL pelo que andei pesquisando é um padrão da boa programação em C que é configurar os ponteiros para nulos quando eles não estiverem apontando para nenhum lugar.

Bom, declaradas as surfaces podemos agora implementar a função de carregar imagens:




Ressaltando que a função usada: SDL_LoadBMP serve apenas para carregar imagens do tipo bitmap. Para carregar imagens em outros formatos utilize a função IMG_Load da biblioteca SDL_Image.h (o procedimento para instalar é o mesmo da biblioteca SDL padrão).

Bom, como a imagem carregada está em bitmap ela é do tipo 24-bit, mas a tela do nosso jogo vai ter 32-bit (esses números são relacionados a quantidade de cores) não é recomendado utilizar a imagem ainda, porque a SDL vai até transformar a imagem em 32-bit, mas isso vai acontecer durante a execução do jogo, o que vai tornar o jogo lento.

Então, continuando nosso código:
  1. //Se nada der errado no carregamento da imagem
  2. if( imagemcarregada != NULL )
  3. { //Cria a imagem otimizada
  4. imagemotimizada = SDL_DisplayFormat( imagemcarregada );
  5. //Libera a antiga "imagem" da superfície
  6. SDL_FreeSurface( imagemcarregada );
  7. }
O que essa parte do código faz dá pra entender até lendo o mesmo: se ocorrer tudo bem no carregamento da imagem a função SDL_DisplayFormat() é chamada e cria uma nova versão da "imagemcarregada" no mesmo formato da tela (32-bit). A razão pra se fazer isso é porque quando você tenta usar uma imagem em um diferente formato, a SDL converte a surface para o mesmo, ficando ambas então com o mesmo formato.

  1. //Faz a função retornar a imagem otimizada
  2. return imagemotimizada;
  3. }
Agora nós temos que ter uma função que posiciona nossa imagem na tela:


Essa função recebe as coordenadas que você quer colocar sua surface (imagem).

Primeiro nos pegamos as posições (x, y) e colocamos ela dentro da SDL_Rect. É preciso fazer isso porque a função de "pintar" a imagem só aceita posições dentro da SDL_Rect.

Na documentação da SDL é citado que a SDL_Rect é um tipo de dado que representa um retângulo. Tendo quatro membros representados pelas posições X e Y, a largura e a altura de um retâgulo.

Descrevendo um pouco a função SDL_BlitSurface(), temos que o primeiro argumento source é a surface que você está usando. Quanto ao segundo argumento NULL apenas saiba que ele é nulo por enquanto. O terceiro argumento é a superfície onde nós iremos "pintar" a imagem. O quarto argumento recebe as posições de destino da source onde ela vai ser aplicada.

A função principal:


Aqui nós começamos a main().

Quando se está utilizando a SDL, sua função principal sempre deve conter como parâmetros: int main( int argc, char* args[] )

Usando simplesmente int main() | void main() ou qualquer coisa parecida seu programa não irá funcionar.



Agora é hora de fazer nossa screen ser apontada com as propriedades da tela para então "pintar" as imagens nela.

Bom, os três primeiros argumentos da função SDL_SetVideoMode são simples (largura, altura e cores), o quarto argumento cria o fundo (neste caso) na memória do sistema.

Resta adicionar ao conteúdo das variáveis (no caso aqui o fundo) a função de carregar as imagens:
//Carregar as imagens
fundo = carregar_imagem( "fundo.bmp" );
A imagem de fundo foi carregada com a função que nós criamos anteriormente.
Aplicando a imagem de fundo na tela do programa:
//Aplica a imagem de fundo na variável screen que definimos no início
apply_surface( 0, 0, fundo, screen );
Onde os dois primeiros parâmetros significam a posição da imagem.

Para que a imagem carregada apareça é preciso atualizar a tela:
if( SDL_Flip( screen ) == -1 )
{
return 1;
}

Chegando ao fim do programa temos que liberar as superfícies e adicionar o evento saída
//Libera as superfícies (no caso aqui do fundo)
SDL_FreeSurface( fundo );
//Sai da SDL
SDL_Quit();
return 0;
}
Não é preciso liberar a surface screen porque a SDL se encarrega de fazer isso.

Pronto agora resta compilar seu projeto e ver sua primeira aplicação SDL. Com o decorrer do meu projeto vou postando aqui no blog as experiências. Quem tiver conhecimento nessa biblioteca e quiser ajudar é só deixar comentário aqui na postagem.

Até a próxima. []'s!

Comentários

  1. Felipe, extremamente simples, direto ao ponto, e explicativo. parabéns pelo artigo.

    ResponderExcluir

Postar um comentário

Postagens mais visitadas deste blog

Utilizando o padrão de referências da ABNT no Word

Uma importante funcionalidade do Microsoft Word é o seu Gerenciador de Fontes Bibliográficas. Para aqueles que estão escrevendo algum trabalho acadêmico ou científico, é possível cadastrar todas as referências do trabalho e no final gerar a listagem já enumerada dos documentos que foram consultados na pesquisa. Essa postagem traz os arquivos necessários e as instruções para facilitar essa etapa da elaboração.

Como elaborar um TCC em Sistemas de Informação

Alguns meses atrás estive na tão conhecida saga de elaboração do Trabalho de Conclusão de Curso, o TCC, e somente comprovei aquilo que eu via em forma de desabafo nas redes sociais e que tantos outros colegas de faculdade me falavam. Uma das definições mais aceitas por mim sobre o que é um TCC é a citada pela minha orientadora: "é uma gestação". E realmente, apesar de ter feito o meu em cerca de 1 mês (não recomendo isso para ninguém, mas era minha única saída para não ficar desempregado e sem a possibilidade de cursar meu mestrado, mas essa é outra história), um TCC bem feito deve ter seu cronograma definido para 6 meses, no mínimo, e isso deveria ser uma recomendação do Ministério da Saúde para que os graduandos não percam sua saúde mental.

Mininet: Uma Rede Virtual Instantânea no Seu PC

Baseado no texto de introdução presente no site oficial do Mininet (www.mininet.org) apresento esta ferramenta que possibilita a desenvolvedores e pesquisadores a criação de uma rede virtual realista, executando um kernel real, switch e código de aplicação, em uma única máquina (VM, cloud ou nativa), em segundos, com comandos simples.

A rede virtual criada pelo Mininet é escalável, uma rede definida por software em um único PC utilizando processos do Linux. Isso possibilita um meio inteligente de realizar testes e simulações de uma rede antes de implementá-la em meio físico, caso esse seja o objetivo.