Programação de Jogos com SDL
Este é um tutorial 2 em 1, vamos programar passo a passo dois jogos. O primeiro jogo será um jogo de labirinto e o segundo um snake (jogo da cobrinha). Os jogos serão feitos usando linguagem C e a biblioteca SDL.
[ Hits: 26.683 ]
Por: Samuel Leonardo em 18/11/2013 | Blog: https://nerdki.blogspot.com.br/
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
/* Definicoes, para facilitar o uso da funcao para desenhar o mapa */
#define PAREDE 1
#define VOCE 2 /* não usado */
#define GRAMA 3
#define SAIDA 4
/* Desfinicoes da configuracao do Video */
#define LARGURA 800 /* Numero total de colunas*largura_da_parede */
#define ALTURA 200 /* Numero total de linhas*altura_da_parede */
#define BPP 0 /* A Flag SDL_ANYFORMAT se encaregara da resolucao */
SDL_Surface * tela, * piso, * parede, * player, * final, * grama;
int coluna_atual = 1, linha_atual = 1, fim = 0;
/* O Mapa */
int mapa[10][40] = {
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,3,3,3,
1,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,3,3,3,
1,3,1,3,3,1,1,1,0,1,1,1,1,1,1,1,1,0,0,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,0,0,0,1,0,1,
1,3,3,1,3,3,3,3,0,1,1,0,0,0,0,0,0,1,1,1,1,1,0,1,3,3,1,1,1,1,1,0,1,1,1,1,0,1,0,1,
1,3,3,1,3,3,3,3,0,1,1,0,1,1,1,1,1,1,1,1,1,1,0,1,3,3,0,0,0,1,1,0,1,1,1,1,0,1,0,1,
1,3,3,3,3,1,3,3,0,1,1,0,1,1,1,1,1,1,0,1,1,1,0,1,3,3,1,1,0,1,1,0,0,0,0,0,0,1,0,1,
1,3,3,3,3,3,3,3,0,0,0,0,1,1,1,1,1,0,1,1,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,0,1,
1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,0,1,1,1,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,
1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,4,1,1,1,1,1,1,1,1,1,1,1
};
/*==========================FUNCOES==========================*/
/* Funcao que controla o fps */
void controla_fps ( int tempo_inicial )
{
int fps = 1000/60; // converte 60 FPS para milissegundos
int tempo_agora = SDL_GetTicks() - tempo_inicial;
if(tempo_agora < fps)
SDL_Delay(fps - tempo_agora);
}
/* Funcao de inicializacao */
int carrega_imagens ( )
{
/* Carrega as Imagens */
parede = SDL_LoadBMP("parede_muro.bmp");
if (parede == NULL)
{
printf("Não carregou parede_muro.bmp\n");
return 0;
}
player = SDL_LoadBMP("gamer.bmp");
if (player == NULL)
{
printf("Não carregou gamer.bmp\n");
return 0;
}
final = SDL_LoadBMP("fim.bmp");
if (final == NULL)
{
printf("Não carregou fim.bmp\n");
return 0;
}
grama = SDL_LoadBMP("gramado.bmp");
if (grama == NULL)
{
printf("Não carregou gramado.bmp\n");
return 0;
}
return 1;
}
/* Funcao para desenhar o Mapa */
void desenha_mapa ( )
{
SDL_Rect destino;
int linha, coluna;
for (linha = 0; linha < 10; linha++)
{
destino.y = linha * 20;
for (coluna = 0; coluna < 40; coluna++)
{
destino.x = coluna * 20;
if (mapa[linha][coluna] == PAREDE)
{
/* pegue a imagem parede completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(parede, NULL, tela, &destino);
}
else if (mapa[linha][coluna] == GRAMA)
{
/* pegue a imagem grama completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(grama, NULL, tela, &destino);
}
else if (mapa[linha][coluna] == SAIDA)
{
/* pegue a imagem final completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(final, NULL, tela, &destino);
}
}
}
}
void move_jogador ( SDL_Event event )
{
/*=============== Deslocamento do jogador =====================*/
switch (event.key.keysym.sym)
{
/* Na vertical */
case SDLK_UP:
/* Se o usuario aperta a seta para cima e linha_atual for maior que 0 ... */
if (linha_atual > 0) /* 0 = primeira linha */
{
/* ...subtraia 1 de linha_atual, ou seja, suba uma linha... */
linha_atual = linha_atual - 1;
/* ... e verifique a localizacao do jogador ...*/
if (mapa[linha_atual][coluna_atual] == PAREDE)
linha_atual = linha_atual + 1; /* ... Se for sobre a PAREDE volte para a posição anterior. */
}
break;
case SDLK_DOWN:
if (linha_atual < 9)
{
linha_atual = linha_atual + 1;
if (mapa[linha_atual][coluna_atual] == PAREDE)
linha_atual = linha_atual - 1;
}
break;
/* Na horizontal */
case SDLK_LEFT:
/* Se o usuario aperta a seta para esquerda e coluna_atual for maior que 0 ... */
if (coluna_atual > 0) /* 0 = primeira coluna */
{
/* ...subtraia 1 de coluna_atual, ou seja, recue uma coluna ... */
coluna_atual = coluna_atual - 1;
/* ... e verifique a localizacao do jogador ...*/
if (mapa[linha_atual][coluna_atual] == PAREDE)
coluna_atual = coluna_atual + 1; /* ... Se for sobre a PAREDE adicione 1 a coluna_atual. */
}
break;
case SDLK_RIGHT:
if (coluna_atual < 39)/* 39 = última coluna */
{
coluna_atual = coluna_atual + 1;
if (mapa[linha_atual][coluna_atual] == PAREDE)
coluna_atual = coluna_atual - 1;
}
break;
default:
break;
}
}
int main ( )
{
/*inicializando a SDL e verificando possiveis erros */
if(SDL_Init(SDL_INIT_VIDEO) != 0)
{
printf("Erro: %s\n", SDL_GetError());
exit(-1);
}
SDL_Rect destino; /* para blitar o jogador */
SDL_Event evento; /* para os eventos */
/* Carrega as imagens */
if (carrega_imagens() == 0) /* Se não carregou uma ou outra imagem */
{
return 1; /* encerre o programa */
}
/* Configura o Video */
tela = SDL_SetVideoMode(LARGURA, ALTURA, BPP, SDL_SWSURFACE | SDL_ANYFORMAT);
if(tela == NULL)
{
printf("Erro: %s\n", SDL_GetError());
return 1; /* encerre o programa */
}
int tempo_inicial;
/* Loop principal */
while (fim == 0) /* Enquanto NÃO for verdadeiro o fim */
{
/* Para a funcao controla_fps */
tempo_inicial = SDL_GetTicks();
/* Loop de eventos */
while(SDL_PollEvent(&evento))
{
if(evento.type == SDL_QUIT)
fim = 1;
/* move o jogador */
if (evento.type == SDL_KEYDOWN)
move_jogador(evento);
}
/* Verifica se o jogador chegou ao ponto final */
if (mapa[linha_atual][coluna_atual] == SAIDA)
{
printf("Chegou ao ponto final\n");
}
/* Pinta a tela inteira de branco antes de desenhar o mapa, esse branco eh o caminho */
SDL_FillRect(tela, NULL, SDL_MapRGB(tela->format, 255, 255, 255));
/* Desenha o mapa sobre a tela */
desenha_mapa();
/* blita o jogador na tela */
/* para o jogador: destino.x = coluna_atual*largura_da_imagem e destino.y = linha_atual*altura_da_imagem */
destino.x = coluna_atual * 20;
destino.y = linha_atual * 20;
/* pegue a imagem player completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(player, NULL, tela, &destino);
SDL_UpdateRect(tela,0,0,0,0); /* Atualiza a tela inteira */
controla_fps(tempo_inicial); // controla o FPS
}
/* Finalizando o SDL */
SDL_Quit();
return 0;
}
/* Funcao de inicializacao */
int carrega_imagens ( )
{
/* Carrega as Imagens */
parede = SDL_LoadBMP("parede_muro.bmp");
if (parede == NULL)
{
printf("Não carregou parede_muro.bmp\n");
return 0;
}
player = SDL_LoadBMP("gamer.bmp");
if (player == NULL)
{
printf("Não carregou gamer.bmp\n");
return 0;
}
final = SDL_LoadBMP("fim.bmp");
if (final == NULL)
{
printf("Não carregou fim.bmp\n");
return 0;
}
grama = SDL_LoadBMP("gramado.bmp");
if (grama == NULL)
{
printf("Não carregou gramado.bmp\n");
return 0;
}
return 1;
}
/* Funcao para desenhar o Mapa */
void desenha_mapa ( )
{
SDL_Rect destino;
int linha, coluna;
for (linha = 0; linha < 10; linha++)
{
destino.y = linha * 20;
for (coluna = 0; coluna < 40; coluna++)
{
destino.x = coluna * 20;
if (mapa[linha][coluna] == PAREDE)
{
/* pegue a imagem parede completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(parede, NULL, tela, &destino);
}
else if (mapa[linha][coluna] == GRAMA)
{
/* pegue a imagem grama completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(grama, NULL, tela, &destino);
}
else if (mapa[linha][coluna] == SAIDA)
{
/* pegue a imagem final completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(final, NULL, tela, &destino);
}
}
}
}
void move_jogador ( SDL_Event event )
{
/*=============== Deslocamento do jogador =====================*/
switch (event.key.keysym.sym)
{
/* Na vertical */
case SDLK_UP:
/* Se o usuario aperta a seta para cima e linha_atual for maior que 0 ... */
if (linha_atual > 0) /* 0 = primeira linha */
{
/* ...subtraia 1 de linha_atual, ou seja, suba uma linha... */
linha_atual = linha_atual - 1;
/* ... e verifique a localizacao do jogador ...*/
if (mapa[linha_atual][coluna_atual] == PAREDE)
linha_atual = linha_atual + 1; /* ... Se for sobre a PAREDE volte para a posição anterior. */
}
break;
case SDLK_DOWN:
if (linha_atual < 9)
{
linha_atual = linha_atual + 1;
if (mapa[linha_atual][coluna_atual] == PAREDE)
linha_atual = linha_atual - 1;
}
break;
/* Na horizontal */
case SDLK_LEFT:
/* Se o usuario aperta a seta para esquerda e coluna_atual for maior que 0 ... */
if (coluna_atual > 0) /* 0 = primeira coluna */
{
/* ...subtraia 1 de coluna_atual, ou seja, recue uma coluna ... */
coluna_atual = coluna_atual - 1;
/* ... e verifique a localizacao do jogador ...*/
if (mapa[linha_atual][coluna_atual] == PAREDE)
coluna_atual = coluna_atual + 1; /* ... Se for sobre a PAREDE adicione 1 a coluna_atual. */
}
break;
case SDLK_RIGHT:
if (coluna_atual < 39)/* 39 = última coluna */
{
coluna_atual = coluna_atual + 1;
if (mapa[linha_atual][coluna_atual] == PAREDE)
coluna_atual = coluna_atual - 1;
}
break;
default:
break;
}
}




/* Loop principal */
while (fim == 0) /* Enquanto NÃO for verdadeiro o fim */
{
/* Para a funcao controla_fps */
tempo_inicial = SDL_GetTicks();
/* Loop de eventos */
while(SDL_PollEvent(&evento))
{
if(evento.type == SDL_QUIT)
fim = 1;
/* move o jogador */
if (evento.type == SDL_KEYDOWN)
move_jogador(evento);
}
/* Verifica se o jogador chegou ao ponto final */
if (mapa[linha_atual][coluna_atual] == SAIDA)
{
printf("Chegou ao ponto final\n");
}
/* Pinta a tela inteira de branco antes de desenhar o mapa, esse branco eh o caminho */
SDL_FillRect(tela, NULL, SDL_MapRGB(tela->format, 255, 255, 255));
/* Desenha o mapa sobre a tela */
desenha_mapa();
/* blita o jogador na tela */
/* para o jogador: destino.x = coluna_atual*largura_da_imagem e destino.y = linha_atual*altura_da_imagem */
destino.x = coluna_atual * 20;
destino.y = linha_atual * 20;
/* pegue a imagem player completa(NULL) e jogue na tela em destino */
SDL_BlitSurface(player, NULL, tela, &destino);
SDL_UpdateRect(tela,0,0,0,0); /* Atualiza a tela inteira */
controla_fps(tempo_inicial); // controla o FPS
}
Programa IRPF - Guia de Instalação e Resolução de alguns Problemas
Dicas para aprender programação
Algoritmo Antissocial - Recuperando o Controle da sua Mente
Como funcionam os alocadores de memória do STD C?
Acessando a porta paralela via Linux
Desenvolvendo aplicativo para autenticação biométrica utilizando a Libfprint
lib cURL - Trabalhe com URLs em C
Como atualizar sua versão estável do Debian
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Script de montagem de chroot automatica
Atualizar Linux Mint 22.2 para 22.3 beta
Jogar games da Battle.net no Linux com Faugus Launcher
Como fazer a Instalação de aplicativos para acesso remoto ao Linux
Conky, alerta de temperatura alta (12)
De volta para o futuro - ou melhor, para o presente (parte 2) (2)
Por que passar nas disciplinas da faculdade é ruim e ser reprovado é b... (7)









