Oppure

Loading
15/11/07 22:30
bainos
Ciao a tutti,
Sto facendo un programmino con la libreria sdl.. (uso dev-cpp)
dovrebbero esserci due palline che rimbalzano solo sui lati orizzontali
della finestra. Il codice si compila e "apparentemente" funziona, solo
che ci sono delle cose che non mi sono chiare, e non sono sicuro
di quello che ho scritto..

Il problema fondamentale è che le coordinate iniziali da cui partono
le palline non sono rispettate e non capisco perchè (la pallina che va verso
destra parte sempre in alto a sinistra, e quella che va verso sinistra
parte sempre in basso a destra).

U'altra cosa che non capisco sono le condizioni con cui stabilisco il rimbalzo.

Posto il codice con qualche commento che spiega meglio i miei dubbi.

Grazie in anticipo!

PS: ho fatto il programma in questo modo perchè se ho capito bene è il modo più
"leggero" per creare una animazione. è vero? mi piacerebbe saperlo perche questa sarà
l'interfaccia grafica di una simulazione che se riesce bene potrebbe essere eseguita con
100, 1000, palline..
per farlo ho seguito un tutorial.. se necessario posto il link.

#if defined(_MSC_VER)
#include "SDL.h"
#else
#include "SDL/SDL.h"
#endif
#include <math.h>

const int PIXEL_X = 800;
const int PIXEL_Y = 240;

const double DELAY = 0.05; //0.05 oppure 0.1 vanno bene
                           //0.00001 molto lento per vedere 
                           //da dove partono le palline (?)

SDL_Surface *screen;

//pallina :)
const unsigned char sprite[] = 
{
0,0,1,1,1,1,0,0,
0,1,1,1,1,1,1,0,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,
0,1,1,1,1,1,1,0,
0,0,1,1,1,1,0,0
};

//Disegna una "figura" in base a sprite[]
void drawsprite(int x, int y, unsigned int color){
   int i, j, c, yofs;
   yofs = y * (screen->pitch / 4) + x;
   for (i = 0, c = 0; i < 8; i++){
      for (j = 0; j < 8; j++, c++){
         if (sprite[c]){
            ((unsigned int*)screen->pixels)[yofs + j] = color;
         }
      }
      yofs += (screen->pitch / 4);
   }
}

//Condizioni iniziali (non vanno quelle sulla posizione..)
//particolare interesse sulle condizioni iniziali delle y
//le coordinate con "_" sono per la pallina che va da destra 
//a sinistra.
   int x = 0;
   int y = PIXEL_Y/2;
   int vx = 3;
   int vy = 2;
   int x_ = PIXEL_X-8;
   int y_ = PIXEL_Y/3;
   int vx_ = 2;
   int vy_ = 4;
   int ti = SDL_GetTicks() * DELAY;
   int tf = 0;
   int dt = 0;
   
//muove le palline    
void render(){   
   // Lock surface if needed
   if (SDL_MUSTLOCK(screen)) 
      if (SDL_LockSurface(screen) < 0) 
         return;

   // Ask SDL for the time in milliseconds
   int tick = SDL_GetTicks() * DELAY;
  
   // Declare a couple of variables
   int i, j, yofs, ofs;

   // Draw to screen
   yofs = 0;
   for (i = 0; i < PIXEL_Y; i++){
      for (j = 0, ofs = yofs; j < PIXEL_X; j++, ofs++){
         ((unsigned int*)screen->pixels)[ofs] = 0;
      }
      yofs += screen->pitch / 4;
   }
   
   //disegna la pallina in base alle coordinate
   drawsprite(x,y,(255<<16|0<<8|0<<0));
   drawsprite(x_,y_,(0<<16|255<<8|0<<0));
   
   //crea un intervallo temporale che serve per l'evoluzione 
   //del sistema
   tf = tick;
   dt = (tf - ti);
   ti = tf;
   
   //equazioni del moto da sx a dx
   x = x + vx*dt;
   y = y + vy*dt;
   
   //equazioni del moto da dx a sx
   x_ = x_ - vx_*dt;
   y_ = y_ - vy_*dt;
   
   // Controlla che la pallina abbia urtato uno dei lati dello schermo 
   // se la pallina urta uno dei lati, si inverte la direzione
   //rimbalza rispetto y (rimbalza sulle pareti orizzontali)
   //rispetto x quando esce da una parte rientra dall'altra
   
   if(x<0 || x>PIXEL_X-8 ) x = 0; 
   if(y<0) {y = 0; vy = -vy;}
   if(y>PIXEL_Y-8) {y = PIXEL_Y-8; vy = -vy;}
   
   if(x_<0 || x_>PIXEL_X-8) x_ = PIXEL_X-8; 
   if(y_<0 ) {y_ = 0; vy_ = -vy_;}
   if(y_>PIXEL_Y-8) {y_ = PIXEL_Y-8; vy_ = -vy_;}
   
   /* ------------------------------------------------
      In una "versione precedente" usavo condizioni
      tipo queste:
   
      if(y<0 || y>PIXEL_Y-8) vy=-vy; 
      if(y_<0 || y_>PIXEL_Y-8) vy_=-vy_;
      
      perche queste non vanno bene?
      perche devo anche ridargli anche le coordinate
      per y e y_ ?
   --------------------------------------------------*/
   
   // Unlock if needed
   if (SDL_MUSTLOCK(screen)) 
      SDL_UnlockSurface(screen);

   // Tell SDL to update the whole screen
   SDL_UpdateRect(screen, 0, 0, PIXEL_X, PIXEL_Y);    
}


// Entry point
int main(int argc, char *argv[]){
   // Initialize SDL's subsystems - in this case, only video.
   if ( SDL_Init(SDL_INIT_VIDEO) < 0 ){
      fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
      exit(1);
   }

   // Register SDL_Quit to be called at exit; makes sure things are
   // cleaned up when we quit.
   atexit(SDL_Quit);
    
   // Attempt to create a 640x480 window with 32bit pixels.
   screen = SDL_SetVideoMode(PIXEL_X, PIXEL_Y, 32, SDL_SWSURFACE);
  
   // If we fail, return error.
   if ( screen == NULL ){
      fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
      exit(1);
   }
  
   // Main loop: loop forever.
   while (1){
      
      render();

      // Poll for events, and handle the ones we care about.
      SDL_Event event;
      while (SDL_PollEvent(&event)){
         switch (event.type){
            case SDL_KEYDOWN:
               break;
            case SDL_KEYUP:
            // If escape is pressed, return (and thus, quit)
            if (event.key.keysym.sym == SDLK_ESCAPE)
               return 0;
            break;
            case SDL_QUIT:
               return(0);
         }
      }
  }
  return 0;
}

aaa
24/11/07 10:42
johntiror
Ciao, potresti postare il link al tutorial? Grazie
aaa
26/11/07 15:11
bainos
il link al tutorial è questo;:

sol.gfxile.net/gp/…

il problema della posizione di partenza derivava dal fatto che il primo dt veniva calcolato in maniera errata..

se qualcuno è interessato al codice corretto e funzionante lo posto.

ciao =)
aaa