Jogo Micro Breakout
Publicado por Samuel Leonardo 15/06/2009 (última atualização em 13/08/2009)
[ Hits: 9.197 ]
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++;
}
}
AA linux kernel modificado por minhe
Jogo Windows Invaders (com gráficos)
Jogo da Velha com IA invencivel
Rotina para controle de portas paralelas em C. (biblioteca LP.h)
POGRAMA EM C REGISTRO DE CADASTRO ALTERAR E REMOVER CLIENTES PRODUTOS
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 impedir exclusão de arquivos por outros usuários no (Linux)
Cirurgia no Linux Mint em HD Externo via USB
Anúncio do meu script de Pós-Instalação do Ubuntu
Formas seguras de instalar Debian Sid (1)
Alguém executou um rm e quase mata a Pixar! (2)
Duas Pasta Pessoal Aparecendo no Ubuntu 24.04.3 LTS (5)
Alguém pode me indicar um designer freelancer? [RESOLVIDO] (4)
Por que passar nas disciplinas da faculdade é ruim e ser reprovado é b... (6)









