Jogo Micro Breakout
Publicado por Samuel Leonardo 15/06/2009 (última atualização em 13/08/2009)
[ Hits: 9.200 ]
Homepage: https://nerdki.blogspot.com.br/
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++;
}
}
Google Code Jam 2010 - Africa Classification Round A
Cirurgia para acelerar o openSUSE em HD externo via USB
Void Server como Domain Control
Modo Simples de Baixar e Usar o bash-completion
Monitorando o Preço do Bitcoin ou sua Cripto Favorita em Tempo Real com um Widget Flutuante
Como fazer a conversão binária e aplicar as restrições no Linux
Como quebrar a senha de um servidor Linux Debian
Como bloquear pendrive em uma rede Linux
Um autoinstall.yaml para Ubuntu com foco em quem vai fazer máquina virtual
Instalar GRUB sem archinstall no Arch Linux em UEFI Problemático
Fiz uma pergunta no fórum mas não consigo localizar [RESOLVIDO] (21)









