bolinha que rebate nas bordas da janela (com SDL)

Publicado por Marcos Melo 20/02/2005

[ Hits: 11.019 ]

Download bolinha.c




Resultado do meu primeiro contato com SDL, o programa utiliza poucos recursos desta biblioteca:
- a tela
- um timer
- o desenho de pixels na tela
Talvez a SDL tenha meios mais eficientes de desenhar um criculo, mas o programa roda um loop que passa por todos os pontos do círculo e manda pintar um pixel para cada ponto.
Falta uma interface para encerrar o programa(use kill)

  



Esconder código-fonte

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#define TICK_INTERVAL   30 /* intervalo de tempo do timer */

Uint32
deuTempo(void)
{
   static Uint32 next_time = 0;
   Uint32 now;
   now = SDL_GetTicks();
   if (next_time <= now) {
      next_time = now + TICK_INTERVAL;
      return (0);
   }
   return (next_time - now);
}

main()
{
   if (SDL_Init(SDL_INIT_VIDEO) < 0) {
      fprintf(stderr, "não foi possível inicializar SDL: %s\n",
         SDL_GetError());
      exit(1);
   } else {
      printf("OK SDL");
   }
   /*tamanho da tela*/
   int largura=400;
   int altura=300;
   /********************/
   SDL_Surface *screen;
   screen = SDL_SetVideoMode(largura, altura, 32, SDL_SWSURFACE);
   if (screen == NULL) {
      fprintf(stderr,
         "Impossível ajustar ao vídeo em  %ix%i : %s\n",
         largura,altura,SDL_GetError());
      exit(1);
   }
   int tempo = 0;
   int posicaoX, posicaoY;
   posicaoY = posicaoX = 60;
   int posicaoY_anterior = 60, posicaoX_anterior = 60, raio = 8;
   int velocidadeX = 10, velocidadeY = 10;
   while (1 > 0) {      /*loop infinito, cuida da movimentação da bolinha */
      if (deuTempo() == 0) {   /* se for zero, entao ointervalo de tempo ja se completou */
         
         /* ***************************************** **
          * verifica se os limites da                 **
          * tela ja  foram alcaçados.                 **
          * se    foram,   inverte   a                **
          * velocidade x ou y                         **
          * ***************************************** **/
         if (posicaoY  >= (altura - raio*2))
            velocidadeY = velocidadeY * (-1);
         if (posicaoX >= largura  - raio)
            velocidadeX = velocidadeX * (-1);
         if (posicaoX < raio)
            velocidadeX = velocidadeX * (-1);
         if (posicaoY < raio*2)
            velocidadeY = velocidadeY * (-1);

         /* ***************************************** * */
         bola(posicaoX_anterior, posicaoY_anterior , raio,
              screen, 0, 0, 0); /* apaga posicao anterior*/
         bola(posicaoX, posicaoY , raio, screen, 86051435,
              256323, 56546);
         posicaoX_anterior = posicaoX;
         posicaoY_anterior = posicaoY;
         posicaoX += velocidadeX;
         posicaoY += velocidadeY;
         SDL_UpdateRect(screen, 0, 0, 0, 0);
      }
   }
   atexit(SDL_Quit);
}

bola(int x, int y, int r, SDL_Surface * screen, Uint8 R, Uint8 G, Uint8 B)
{            /* cuida de definir as coordenadas da bolinha com base no */
   {
      int a, b;
      int vari;
      unsigned int cateto1, cateto2;
      for (a = x - r ; a <= x + r ; a++) {
         cateto1 = x - a;
         cateto2 = sqrt((r * r) - (cateto1 * cateto1));/*pitágoras*/
         int altu;
         for (altu = y - cateto2 ; altu <= y + cateto2 ; altu++)
            desenhaPonto(screen, R, G, B, a, altu);
      }

   }
}

desenhaPonto(SDL_Surface * screen, Uint8 R, Uint8 G, Uint8 B, int x, int y)
{            /* desenha um ponto na tela de acordo com as coordenadas fornecidas */
   Uint32 color = SDL_MapRGB(screen->format, R, G, B);
   Uint32 *bufp;
   bufp = (Uint32 *) screen->pixels + y * screen->pitch/4 + x;
   *bufp=color;

}

Scripts recomendados

Matriz em C

Abrindo e fechando a bandeja do cd.

Gerador de variáveis

Inverte valor das variáveis

Encontrar string em ficheiro


  

Comentários
[1] Comentário enviado por genioloco em 20/02/2005 - 22:03h

Legal esta dica meu... quem sabe não é o primeiro passo para um joguinho (rs)

[2] Comentário enviado por acefalo em 20/02/2005 - 22:49h

conheço dois jogos que rodam com bolinhas assim. Um acho que chama pong. o outro é com duas bolinhas, acho, que você vai isolando ao criar barreiras na tela.
Fiz esse programa depois de ter feito algo parecido em vb na sexta feira. Fui mostrar, para um estagiário, que dá para desenhar só por código, e fiz a bolinha num picturebox. aí mostrei como ela poderia se mover. Ele se lembrou do jogo em que as bolinhas vão se isolando, e eu adicionei esse recurso (no VB). tudo em menos de meia hora.
Faz tempo que tento aprender uma forma fácil de fazer essas coisas para linux, e acho que o SDL tápode me atender. Preciso ver se dá para fazer em gtk.

[3] Comentário enviado por acefalo em 21/02/2005 - 00:24h

me esqueci de avisar que deve ser compilado assim:
gcc -lm -lSDL bolinha.c -o bolinha
-lm e para a math.h. -lSDL e para a SDL

[4] Comentário enviado por amarildorod em 06/02/2006 - 12:46h

Para que possa sair do programa sem o kill usei um evento para que ao teclar ESC sairá do programa ficou assim:

#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#define TICK_INTERVAL 30 /* intervalo de tempo do timer */
Uint32
deutempo(void)
{
static Uint32 next_time = 0;
Uint32 now;
now = SDL_GetTicks();
if (next_time <= now) {
next_time = now + TICK_INTERVAL;
return (0);
}
return (next_time - now);
}
main()
{
if (SDL_Init(SDL_INIT_VIDEO) < 0)
{
fprintf(stderr, "não foi possível inicializar SDL: %s\n", SDL_GetError());
exit(1);
}
else
{
printf("OK SDL");
}
/*tamanho da tela*/
int largura=400;
int altura=300;
SDL_Event event;
SDL_keysym keysym;
/********************/
SDL_Surface *screen;
screen = SDL_SetVideoMode(largura, altura, 32, SDL_SWSURFACE);
if (screen == NULL)
{
fprintf(stderr, "Impossível ajustar ao vídeo em %ix%i : %s\n", largura,altura,SDL_GetError());
exit(1);
}
int tempo = 0;
int posicaoX, posicaoY;
posicaoY = posicaoX = 60;
int posicaoY_anterior = 60, posicaoX_anterior = 60, raio = 18;
int velocidadeX = 30, velocidadeY = 30;

{ /*loop infinito, cuida da movimentação da bolinha */
if (deutempo() == 0)
while (1){

{ /* se for zero, entao ointervalo de tempo ja se completou */

/* ***************************************** **
* verifica se os limites da **
* tela ja foram alcaçados. **
* se foram, inverte a **
* velocidade x ou y **
* ***************************************** * */
if (posicaoY >= (altura - raio*2))
velocidadeY = velocidadeY * (-1);
if (posicaoX >= largura - raio)
velocidadeX = velocidadeX * (-1);
if (posicaoX < raio)
velocidadeX = velocidadeX * (-1);
if (posicaoY < raio*2)
velocidadeY = velocidadeY * (-1);

/* ***************************************** * */
bola(posicaoX_anterior, posicaoY_anterior , raio,screen, 0, 0, 0);
bola(posicaoX, posicaoY , raio, screen, 86051435, 256323, 56546); //cor
posicaoX_anterior = posicaoX;
posicaoY_anterior = posicaoY;
posicaoX += velocidadeX;
posicaoY += velocidadeY;
SDL_UpdateRect(screen, 0, 0, 0, 0);
SDL_Event event;
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
break;
case SDL_KEYUP:
if (event.key.keysym.sym == SDLK_ESCAPE)
return 0;
break;
case SDL_QUIT:
return(0);

}

}
}
}
}
atexit(SDL_Quit);

}
bola(int x, int y, int r, SDL_Surface * screen, Uint8 R, Uint8 G, Uint8 B)
{
int a,b;
int vari;
unsigned int cateto1, cateto2;

for (a = x - r ; a <= x + r ; a++)
{
cateto1 = x - a;
cateto2 = sqrt((r * r) - (cateto1 * cateto1));/*pitágoras*/
int altu;
for (altu = y - cateto2 ; altu <= y + cateto2 ; altu++)
desenhaPonto(screen, R, G, B, a, altu);
}

}
desenhaPonto(SDL_Surface * screen, Uint8 R, Uint8 G, Uint8 B, int x, int y)
/* desenha um ponto na tela de acordo com as coordenadas fornecidas */
{
Uint32 color = SDL_MapRGB(screen->format, R, G, B);
Uint32 *bufp;
bufp = (Uint32 *) screen->pixels + y * screen->pitch/4 + x; // angulo
*bufp=color;

}


Contribuir com comentário