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.165 ]
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
Desenhando um avatar do Tux no InkScape
Algum humor e C++ Design Patterns (parte 2)
Parâmetros interessantes do scanf e do printf em C
Atualizando o Passado: Linux no Lenovo G460 em 2025
aaPanel - Um Painel de Hospedagem Gratuito e Poderoso
O macete do Warsaw no Linux Mint e cia
Um modo leve de ouvir/ver áudio/vídeo da internet em máquinas pererecas
Resolver algumas mensagens de erro do SSH
Instalar módulo de segurança do Banco do Brasil Warsaw do tipo .run
Sem espaço na partição home (2)
O que você está ouvindo agora? [2] (190)
Procrastinação e autossabotagem são problemas muito comuns na sociedad... (5)