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: 25.906 ]
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 }
Algoritmo Antissocial - Recuperando o Controle da sua Mente
Desenhando fácil um pinguim no Inkscape
Desenhando um avatar do Tux no InkScape
Cuidado com números em Ponto Flutuante
Tratamento de exceções na linguagem C
Alocação dinâmica de memória em C
Como gerar qualquer emoji ou símbolo unicode a partir do seu teclado
Instalar e Configurar o Slackware Linux em 2025
Como configurar os repositórios do apt no Debian 12 em 2025
Passkeys: A Evolução da Autenticação Digital
Instalação de distro Linux em computadores, netbooks, etc, em rede com o Clonezilla
Como dividir duas janelas igualmente e lado-a-lado na sua tela
Configurando o Conky para iniciar corretamente no sistema
3 configurações básicas que podem melhorar muito a sua edição pelo editor nano
Ocomon 6.0.1 - Problemas ao editar configurações estendidas (2)
Mover arquivos entre partições (4)
Ingress NGINX Controller CVSS base score of 9.8 (5)