Questo sito utilizza cookies, anche di terze parti, per mostrare pubblicità e servizi in linea con il tuo account. Leggi l'informativa sui cookies.
Username: Password: oppure
C/C++ - SDL : palline che rimbalzano
Forum - C/C++ - SDL : palline che rimbalzano

Avatar
bainos (Normal User)
Newbie


Messaggi: 2
Iscritto: 15/11/2007

Segnala al moderatore
Postato alle 23:30
Giovedì, 15/11/2007
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.

Codice sorgente - presumibilmente C

  1. #if defined(_MSC_VER)
  2. #include "SDL.h"
  3. #else
  4. #include "SDL/SDL.h"
  5. #endif
  6. #include <math.h>
  7.  
  8. const int PIXEL_X = 800;
  9. const int PIXEL_Y = 240;
  10.  
  11. const double DELAY = 0.05; //0.05 oppure 0.1 vanno bene
  12.                            //0.00001 molto lento per vedere
  13.                            //da dove partono le palline (?)
  14.  
  15. SDL_Surface *screen;
  16.  
  17. //pallina :)
  18. const unsigned char sprite[] =
  19. {
  20. 0,0,1,1,1,1,0,0,
  21. 0,1,1,1,1,1,1,0,
  22. 1,1,1,1,1,1,1,1,
  23. 1,1,1,1,1,1,1,1,
  24. 1,1,1,1,1,1,1,1,
  25. 1,1,1,1,1,1,1,1,
  26. 0,1,1,1,1,1,1,0,
  27. 0,0,1,1,1,1,0,0
  28. };
  29.  
  30. //Disegna una "figura" in base a sprite[]
  31. void drawsprite(int x, int y, unsigned int color){
  32.    int i, j, c, yofs;
  33.    yofs = y * (screen->pitch / 4) + x;
  34.    for (i = 0, c = 0; i < 8; i++){
  35.       for (j = 0; j < 8; j++, c++){
  36.          if (sprite[c]){
  37.             ((unsigned int*)screen->pixels)[yofs + j] = color;
  38.          }
  39.       }
  40.       yofs += (screen->pitch / 4);
  41.    }
  42. }
  43.  
  44. //Condizioni iniziali (non vanno quelle sulla posizione..)
  45. //particolare interesse sulle condizioni iniziali delle y
  46. //le coordinate con "_" sono per la pallina che va da destra
  47. //a sinistra.
  48.    int x = 0;
  49.    int y = PIXEL_Y/2;
  50.    int vx = 3;
  51.    int vy = 2;
  52.    int x_ = PIXEL_X-8;
  53.    int y_ = PIXEL_Y/3;
  54.    int vx_ = 2;
  55.    int vy_ = 4;
  56.    int ti = SDL_GetTicks() * DELAY;
  57.    int tf = 0;
  58.    int dt = 0;
  59.    
  60. //muove le palline    
  61. void render(){  
  62.    // Lock surface if needed
  63.    if (SDL_MUSTLOCK(screen))
  64.       if (SDL_LockSurface(screen) < 0)
  65.          return;
  66.  
  67.    // Ask SDL for the time in milliseconds
  68.    int tick = SDL_GetTicks() * DELAY;
  69.  
  70.    // Declare a couple of variables
  71.    int i, j, yofs, ofs;
  72.  
  73.    // Draw to screen
  74.    yofs = 0;
  75.    for (i = 0; i < PIXEL_Y; i++){
  76.       for (j = 0, ofs = yofs; j < PIXEL_X; j++, ofs++){
  77.          ((unsigned int*)screen->pixels)[ofs] = 0;
  78.       }
  79.       yofs += screen->pitch / 4;
  80.    }
  81.    
  82.    //disegna la pallina in base alle coordinate
  83.    drawsprite(x,y,(255<<16|0<<8|0<<0));
  84.    drawsprite(x_,y_,(0<<16|255<<8|0<<0));
  85.    
  86.    //crea un intervallo temporale che serve per l'evoluzione
  87.    //del sistema
  88.    tf = tick;
  89.    dt = (tf - ti);
  90.    ti = tf;
  91.    
  92.    //equazioni del moto da sx a dx
  93.    x = x + vx*dt;
  94.    y = y + vy*dt;
  95.    
  96.    //equazioni del moto da dx a sx
  97.    x_ = x_ - vx_*dt;
  98.    y_ = y_ - vy_*dt;
  99.    
  100.    // Controlla che la pallina abbia urtato uno dei lati dello schermo
  101.    // se la pallina urta uno dei lati, si inverte la direzione
  102.    //rimbalza rispetto y (rimbalza sulle pareti orizzontali)
  103.    //rispetto x quando esce da una parte rientra dall'altra
  104.    
  105.    if(x<0 || x>PIXEL_X-8 ) x = 0;
  106.    if(y<0) {y = 0; vy = -vy;}
  107.    if(y>PIXEL_Y-8) {y = PIXEL_Y-8; vy = -vy;}
  108.    
  109.    if(x_<0 || x_>PIXEL_X-8) x_ = PIXEL_X-8;
  110.    if(y_<0 ) {y_ = 0; vy_ = -vy_;}
  111.    if(y_>PIXEL_Y-8) {y_ = PIXEL_Y-8; vy_ = -vy_;}
  112.    
  113.    /* ------------------------------------------------
  114.       In una "versione precedente" usavo condizioni
  115.       tipo queste:
  116.    
  117.       if(y<0 || y>PIXEL_Y-8) vy=-vy;
  118.       if(y_<0 || y_>PIXEL_Y-8) vy_=-vy_;
  119.      
  120.       perche queste non vanno bene?
  121.       perche devo anche ridargli anche le coordinate
  122.       per y e y_ ?
  123.    --------------------------------------------------*/
  124.    
  125.    // Unlock if needed
  126.    if (SDL_MUSTLOCK(screen))
  127.       SDL_UnlockSurface(screen);
  128.  
  129.    // Tell SDL to update the whole screen
  130.    SDL_UpdateRect(screen, 0, 0, PIXEL_X, PIXEL_Y);    
  131. }
  132.  
  133.  
  134. // Entry point
  135. int main(int argc, char *argv[]){
  136.    // Initialize SDL's subsystems - in this case, only video.
  137.    if ( SDL_Init(SDL_INIT_VIDEO) < 0 ){
  138.       fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
  139.       exit(1);
  140.    }
  141.  
  142.    // Register SDL_Quit to be called at exit; makes sure things are
  143.    // cleaned up when we quit.
  144.    atexit(SDL_Quit);
  145.    
  146.    // Attempt to create a 640x480 window with 32bit pixels.
  147.    screen = SDL_SetVideoMode(PIXEL_X, PIXEL_Y, 32, SDL_SWSURFACE);
  148.  
  149.    // If we fail, return error.
  150.    if ( screen == NULL ){
  151.       fprintf(stderr, "Unable to set 640x480 video: %s\n", SDL_GetError());
  152.       exit(1);
  153.    }
  154.  
  155.    // Main loop: loop forever.
  156.    while (1){
  157.      
  158.       render();
  159.  
  160.       // Poll for events, and handle the ones we care about.
  161.       SDL_Event event;
  162.       while (SDL_PollEvent(&event)){
  163.          switch (event.type){
  164.             case SDL_KEYDOWN:
  165.                break;
  166.             case SDL_KEYUP:
  167.             // If escape is pressed, return (and thus, quit)
  168.             if (event.key.keysym.sym == SDLK_ESCAPE)
  169.                return 0;
  170.             break;
  171.             case SDL_QUIT:
  172.                return(0);
  173.          }
  174.       }
  175.   }
  176.   return 0;
  177. }


PM Quote
Avatar
johntiror (Normal User)
Newbie


Messaggi: 4
Iscritto: 24/11/2007

Segnala al moderatore
Postato alle 11:42
Sabato, 24/11/2007
Ciao, potresti postare il link al tutorial? Grazie

PM Quote
Avatar
bainos (Normal User)
Newbie


Messaggi: 2
Iscritto: 15/11/2007

Segnala al moderatore
Postato alle 16:11
Lunedì, 26/11/2007
il link al tutorial è questo;:

http://sol.gfxile.net/gp/index.html

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 =)

PM Quote