Jogo Micro Breakout
Publicado por Samuel Leonardo 15/06/2009 (última atualização em 13/08/2009)
[ Hits: 8.923 ]
Homepage: localhost
Download versao2.MicroBreakout.tar.gz (versão 2)
Mais um joguinho meu, um breakout simples.
Controles:
--botão espaço inicia o jogo
--seta esquerda/direita controlam o paddle
--botão escape termina o jogo
Acompanha uma versão pré-compilada (como sempre)
Para compilar:
$ gcc -o breakout breakout.c -lSDL
Para executar:
$ ./breakout
Valeu!
Versão 2 - Enviado por Samuel Leonardo em 13/08/2009
Changelog: Retirada a linha 203: printf("PADDLE_>BALL\n");
Download versao2.MicroBreakout.tar.gz
/* Jogo Micro Breakout Mais um joguinho meu, um breakout simples. Controles: --botão espaço inicia o jogo --seta esquerda/direita controlam o paddle --botão escape termina o jogo Acompanha uma versão pré-compilada (como sempre) Para compilar: $ gcc -o breakout breakout.c -lSDL Para executar: $ ./breakout valeu! OBSERVE: POR FAVOR, SE POSSIVEL DEIXE UM COMENTARIO ;) */ #include <stdio.h> #include <SDL/SDL.h> #define FPS 60 #define BPP 16 #define FLAGS (SDL_SWSURFACE | SDL_HWSURFACE | SDL_ANYFORMAT | SDL_HWACCEL | SDL_RLEACCEL | SDL_DOUBLEBUF) /*para os eventos de teclado*/ #define DOWN 1 /*o usuario apertou um botão*/ #define UP 0 /*o usuario soltou o botão*/ #define MAP_W 10 #define MAP_H 15 #define BRICK_W 96 #define BRICK_H 32 #define B_VELO 5 #define PADDLE_VELO 15 char map[MAP_H][MAP_W] = { {"aaaaaaaaaa"}, {"aee....eea"}, {"aeeeeeeeea"}, {"adddddddda"}, {"acccccccca"}, {"abbbbbbbba"}, {"aa.a.ae.aa"}, {"aea.aa.aea"}, {".........."}, {".........."}, {".........."}, {".........."}, {".........."}, {".........."}, {".........."} }; //botões inicializando int right = UP, left = UP;//, space = UP; void FPS_Control(Uint32 time); int MovePaddle(int *x, int w, int *velo_x, int screen_w); int MoveBall(int *x, int w, int *velo_x, int *y, int h, int *velo_y, int screen_w); int Colli_Hor(int ax, int aw, int bx, int bw); int Colli_Ver(int ay, int ah, int by, int bh); int Colli_Point(int ax, int ay, int bx, int by); int Colli_BallBrick(int ax, int ay, int aw, int ah, int bx, int by); int ChangeBrick(int coor_x, int coor_y, char to_c);//muda um caractere no mapa dos blocos int BrickIndex(char map_c, const char *brickstr); int Blit(SDL_Surface *surf, SDL_Surface *screen, int x, int y); void DrawMap(SDL_Surface *bricks, int w, int h, const char *brickstr, SDL_Surface *b_side, SDL_Surface *screen); int main(int argc, char *argv[]) { SDL_Event event; SDL_Surface *screen, *bricks, *paddle, *b_side, *ball; screen = SDL_SetVideoMode(MAP_W*BRICK_W, MAP_H*BRICK_H, BPP, FLAGS); if(screen == NULL) { printf("%s\n", SDL_GetError()); exit(1); } ball = SDL_LoadBMP("imagens/ball.bmp"); bricks = SDL_LoadBMP("imagens/bricks.bmp"); paddle = SDL_LoadBMP("imagens/paddle.bmp"); b_side = SDL_LoadBMP("imagens/brick_side.bmp"); if(!ball || !bricks || !paddle || !b_side) { printf("%s\n", SDL_GetError()); SDL_Quit(); exit(1); } //transparencia SDL_SetColorKey(ball, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(ball->format, 0, 255, 0)); SDL_SetColorKey(b_side, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(b_side->format, 0, 255, 0)); SDL_SetColorKey(bricks, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(bricks->format, 0, 255, 0)); SDL_SetColorKey(paddle, SDL_SRCCOLORKEY | SDL_RLEACCEL, SDL_MapRGB(paddle->format, 0, 255, 0)); //A forma correta de inicializar o SDL é só depois de configurar o screen if(SDL_Init(SDL_INIT_VIDEO) != 0) { printf("%s\n", SDL_GetError()); SDL_Quit(); exit(1); } int done = 0; //paddle int px, py, velo_x; velo_x = 0; px = (screen->w - paddle->w)/2; py = (screen->h - paddle->h); //bola int move_init = 0; int bx, by, b_velo_x, b_velo_y; bx = (screen->w - ball->w)/2; by = (py - 19);//19 é a largura/altura da bola para colisão b_velo_x = 0; b_velo_y = 0; Uint32 time_now; SDL_WM_SetCaption("MicroBreakout - by Sam L.", NULL); while(!done) { time_now = SDL_GetTicks(); while(SDL_PollEvent(&event)) { if(event.type == SDL_KEYDOWN) { switch(event.key.keysym.sym) { case SDLK_RIGHT: right = DOWN; break; case SDLK_LEFT: left = DOWN; break; case SDLK_ESCAPE: done = 1; break; case SDLK_SPACE: if(move_init == 0) { b_velo_x = -B_VELO; b_velo_y = -B_VELO; move_init = 1; } default: break; } } if(event.type == SDL_KEYUP) { switch(event.key.keysym.sym) { case SDLK_RIGHT: right = UP; break; case SDLK_LEFT: left = UP; break; default: break; } } if(event.type == SDL_QUIT) { done = 1; } } //19 é a largura/altura da bola para colisão MoveBall(&bx, 19, &b_velo_x, &by, 19, &b_velo_y, screen->w); if((by + 19) > screen->h) { velo_x = 0; px = (screen->w - paddle->w)/2; py = (screen->h - paddle->h); bx = (screen->w - ball->w)/2; by = (py - 19);//19 é a largura/altura da bola para colisão b_velo_x = 0; b_velo_y = 0; move_init = 0; } //bate acima do paddle if(Colli_Point(bx + 9, by + 19, px, py) || Colli_Point(bx + 19, by + 9, px, py) || Colli_Point(bx, by + 9, px, py)) { b_velo_y = -b_velo_y; printf("PADDLE_>BALL\n"); } MovePaddle(&px, paddle->w, &velo_x, screen->w); SDL_FillRect(screen, NULL, SDL_MapRGB(screen->format, 255, 255, 255)); //void DrawMap(SDL_Surface *bricks, int w, int h, const char *brickstr, SDL_Surface *b_side, SDL_Surface *screen) DrawMap(bricks, BRICK_W, BRICK_H, ".abcde", b_side, screen); Blit(ball, screen, bx, by); Blit(paddle, screen, px, py); SDL_UpdateRect(screen, 0,0,0,0); FPS_Control(time_now); } SDL_Quit(); return 0; } void FPS_Control(Uint32 time) { static int fps = 1000/FPS; Uint32 time2 = SDL_GetTicks() - time; if(time2 < fps) { SDL_Delay(fps - time2); } } int MovePaddle(int *x, int w, int *velo_x, int screen_w) { //sempre parado se não apertar nenhum botão *velo_x = 0; if(right == DOWN) { *velo_x = PADDLE_VELO; } if(left == DOWN) { *velo_x = -PADDLE_VELO; } //movendo no screen *x = *x + *velo_x; //limitando a posição dentro do screen //Se a posição do paddle for menor que zero... if(*x < 0) { //...fixe a posição do paddle em 0, pois estava indo para esquerda. *x = 0; } //Se não, se aposição do paddle for maior do que a largura do screen... else if(*x + w > screen_w) { //...fixe a posição do paddle em screen_w - w, pois estava indo para direita. *x = screen_w - w;//w é a largura do paddle } return 0; } int MoveBall(int *x, int w, int *velo_x, int *y, int h, int *velo_y, int screen_w) { int lin, col, side; int brick_x, brick_y, colli = 0; //mova a bola no eixo X *x = *x + *velo_x; //verifique se ela não saiu dos limites do screen_w if( (*x < 0) || (*x + w > screen_w) )//se saido a esquerda/direita do screen { *velo_x = -(*velo_x); } //mova a bola no eixo Y *y = *y + *velo_y; //verifique se ela não saiu dos limites do screen_h if(*y < 0)//se saindo por cima do screen { *velo_y = -(*velo_y); } //NOTE: Aqui tá muito mal feito mas funciona for(lin = 0; lin < MAP_H && (colli == 0); lin++) { brick_y = lin*BRICK_H; for(col = 0; col < MAP_W && (colli == 0); col++) { brick_x = col*BRICK_W; if(map[lin][col] != '.') { side = Colli_BallBrick(*x, *y, w, h, brick_x, brick_y); switch(side) { case 0: break; case 1://esquerda/direita *velo_x = -(*velo_x); break; case 2://cima/baixo *velo_y = -(*velo_y); break; case 3://no centro *velo_x = -(*velo_x); *velo_y = -(*velo_y); break; } if(side != 0) { colli = ChangeBrick(col, lin, '.'); } } } } return 0; } int Colli_BallBrick(int ax, int ay, int aw, int ah, int bx, int by) { //nas laterais if(Colli_Point(ax, ay + ah/2, bx, by) || Colli_Point(ax + aw, ay + ah/2, bx, by)) { return 1; } //em cima/baixo if(Colli_Point(ax + aw/2, ay, bx, by) || Colli_Point(ax + aw/2, ay + ah, bx, by)) { return 2; } if(Colli_Point(ax + aw/2, ay + ah/2, bx, by)) { printf("COLLI:::#\n"); return 3; } return 0; } int Colli_Point(int ax, int ay, int bx, int by) { if(ax > bx + BRICK_W) return 0; if(ax < bx) return 0; if(ay > by + BRICK_H) return 0; if(ay < by) return 0; return 1; } int Colli_Hor(int ax, int aw, int bx, int bw) { if(ax > bx + bw) return 0; if(ax + aw < bx) return 0; return 1; } int Colli_Ver(int ay, int ah, int by, int bh) { if(ay > by + bh) return 0; if(ay + ah < by) return 0; return 1; } int ChangeBrick(int coor_x, int coor_y, char to_c) { if(map[coor_y][coor_x] != '.')//'.' é o vazio { map[coor_y][coor_x] = to_c; return 1; } return 0; } int BrickIndex(char map_c, const char *brickstr) { int aux; aux = 0; while(*brickstr) { if(*brickstr == map_c) { return aux; } brickstr++; aux++; } return -1; } int Blit(SDL_Surface *surf, SDL_Surface *screen, int x, int y) { SDL_Rect offset; offset.x = x; offset.y = y; return SDL_BlitSurface(surf, NULL, screen, &offset); } void DrawMap(SDL_Surface *bricks, int w, int h, const char *brickstr, SDL_Surface *b_side, SDL_Surface *screen) { int lin, col, index; SDL_Rect font, dest; font.x = 0; font.y = 0; font.w = w; font.h = h; lin = 0; while(lin < MAP_H) { dest.y = lin*h; col = 0; while(col < MAP_W) { dest.x = col*w; index = BrickIndex(map[lin][col], brickstr); if(index > 0) { font.y = index*h; SDL_BlitSurface(bricks, &font, screen, &dest); SDL_BlitSurface(b_side, NULL, screen, &dest); } col++; } lin++; } }
Estrutura de dados: Lista dinâmica duplamente encadeada
Compartilhando a tela do Computador no Celular via Deskreen
Como Configurar um Túnel SSH Reverso para Acessar Sua Máquina Local a Partir de uma Máquina Remota
Configuração para desligamento automatizado de Computadores em um Ambiente Comercial
Como renomear arquivos de letras maiúsculas para minúsculas
Imprimindo no formato livreto no Linux
Vim - incrementando números em substituição
Efeito "livro" em arquivos PDF
Como resolver o erro no CUPS: Unable to get list of printer drivers
Vou voltar moderar conteúdos de Dicas e Artigos (1)
SysAdmin ou DevOps: Qual curso inicial pra essa área? (3)
É cada coisa que me aparece! - não é só 3% (3)
Melhorando a precisão de valores flutuantes em python[AJUDA] (5)
[Python] Automação de scan de vulnerabilidades
[Python] Script para analise de superficie de ataque
[Shell Script] Novo script para redimensionar, rotacionar, converter e espelhar arquivos de imagem
[Shell Script] Iniciador de DOOM (DSDA-DOOM, Doom Retro ou Woof!)
[Shell Script] Script para adicionar bordas às imagens de uma pasta