Jogo Micro Breakout
Publicado por Samuel Leonardo 15/06/2009 (última atualização em 13/08/2009)
[ Hits: 9.143 ]
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++;
}
}
Calculando PI usando série de Leibniz
Arquivos utilizados no artigo: "Desenvolvendo um plugin para o XMMS"
3 EP - Poli USP - Angry Birds (angry bixos)
Árvore B com Arquivos (inserção e pesquisa)
IA Turbina o Desktop Linux enquanto distros renovam forças
Como extrair chaves TOTP 2FA a partir de QRCODE (Google Authenticator)
Linux em 2025: Segurança prática para o usuário
Desktop Linux em alta: novos apps, distros e privacidade marcam o sábado
IA chega ao desktop e impulsiona produtividade no mundo Linux
Atualizando o Fedora 42 para 43
Como saber se o seu e-mail já teve a senha vazada?
Como descobrir se a sua senha já foi vazada na internet?
Warcraft II Remastered no Linux? (6)
O programa assinador digital (5)









