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++ - Istanziare Oggetti Dinamicamente
Forum - C/C++ - Istanziare Oggetti Dinamicamente

Avatar
RiccardoG97 (Member)
Pro


Messaggi: 133
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 10:01
Lunedì, 09/04/2012
Ciao a tutti ragazzi.
Vi mostro il codice del mio programma: (Ci sono 3 files: Ball.h, Ball.cpp e Main.cpp)

:.Ball.h.:
Codice sorgente - presumibilmente C++

  1. //Ball.h
  2. #include "SDL.h"
  3.  
  4. class Ball
  5. {
  6. public:
  7.         Ball ( void );
  8.         ~Ball ( void );
  9.         void makeBall ( SDL_Surface * );
  10.         void moveBall ( void );
  11.         void ballBounce ( void );
  12.  
  13. private:
  14.         SDL_Surface *ball;
  15.         SDL_Rect ballRect;
  16.         enum ballDirections { TOPLEFT = 1, TOPRIGHT, BOTTOMLEFT, BOTTOMRIGHT };
  17.         ballDirections Directions;
  18.         static const int speed;
  19.         int direction;
  20. };



:.Ball.cpp.:
Codice sorgente - presumibilmente C++

  1. //Ball.cpp
  2. #include "Ball.h"
  3. #include "SDL.h"
  4. #include <ctime>
  5.  
  6. Ball::Ball ( void )
  7. {
  8.         ball = SDL_LoadBMP ( "Ball.bmp" );
  9.         ballRect.x = 300;
  10.         ballRect.y = 300;
  11.         direction = 1 + rand() % 4;
  12.         if ( direction == 1 )
  13.                 Directions = TOPLEFT;
  14.         else if ( direction == 2 )
  15.                 Directions = TOPRIGHT;
  16.         else if ( direction == 3 )
  17.                 Directions = BOTTOMLEFT;
  18.         else
  19.                 Directions = BOTTOMRIGHT;
  20. }
  21.  
  22. Ball::~Ball ( void )
  23. {
  24.         SDL_FreeSurface ( ball );
  25. }
  26.  
  27. void Ball::makeBall ( SDL_Surface *screen )
  28. {
  29.         SDL_BlitSurface ( ball, NULL, screen, &ballRect );
  30. }
  31.  
  32. void Ball::moveBall ( void )
  33. {
  34.         if ( Directions == TOPLEFT )
  35.         {
  36.                 ballRect.x -= speed;
  37.                 ballRect.y -= speed;
  38.         }
  39.         else if ( Directions == TOPRIGHT )
  40.         {
  41.                 ballRect.x += speed;
  42.                 ballRect.y -= speed;
  43.         }
  44.         else if ( Directions == BOTTOMLEFT )
  45.         {
  46.                 ballRect.x -= speed;
  47.                 ballRect.y += speed;
  48.         }
  49.         else
  50.         {
  51.                 ballRect.x += speed;
  52.                 ballRect.y += speed;
  53.         }
  54. }
  55.  
  56. void Ball::ballBounce ( void )
  57. {
  58.         if ( ballRect.x <= 0 )
  59.         {
  60.                 if ( Directions == TOPLEFT )
  61.                         Directions = TOPRIGHT;
  62.                 else
  63.                         Directions = BOTTOMRIGHT;
  64.         }
  65.         else if ( ballRect.x >= 600 )
  66.         {
  67.                 if ( Directions == TOPRIGHT )
  68.                         Directions = TOPLEFT;
  69.                 else
  70.                         Directions = BOTTOMLEFT;
  71.         }
  72.         else if ( ballRect.y <= 0 )
  73.         {
  74.                 if ( Directions == TOPLEFT )
  75.                         Directions = BOTTOMLEFT;
  76.                 else
  77.                         Directions = BOTTOMRIGHT;
  78.         }
  79.         else if ( ballRect.y >= 500 )
  80.         {
  81.                 if ( Directions == BOTTOMLEFT )
  82.                         Directions = TOPLEFT;
  83.                 else
  84.                         Directions = TOPRIGHT;
  85.         }
  86. }



:.Main.cpp.:
Codice sorgente - presumibilmente C++

  1. //Main.cpp
  2.  
  3. #include "SDL.h"
  4. #include <iostream>
  5. #include "Ball.h"
  6. #include <vector>
  7. using namespace std;
  8.  
  9. //Surfaces
  10. SDL_Surface *screen = NULL;
  11. SDL_Surface *background = NULL;
  12.  
  13. SDL_Event evento, testEvento;
  14. Uint8 *keys;
  15.  
  16. //Variabili
  17. const int xDialog = 600;
  18. const int yDialog = 500;
  19. const int bpp = 32;
  20. const int frameSkip = 10;
  21. int objects = 0;
  22. int newobj = 0;
  23.  
  24. //Funzioni
  25. void makeBackground ( void );
  26. void freeSurfaces ( void );
  27.  
  28. //Definizione delle funzioni
  29. void makeBackground ( void )
  30. {
  31.         SDL_BlitSurface ( background, NULL, screen, NULL );
  32. }
  33.  
  34. void freeSurfaces ( void )
  35. {
  36.         SDL_FreeSurface ( background );
  37. }
  38.  
  39.  
  40. int main ( int argc, char *argv[] )
  41. {
  42.  
  43.         if ( SDL_Init ( SDL_INIT_EVERYTHING ) != 0 )
  44.                 return 1;
  45.  
  46.         screen = SDL_SetVideoMode ( xDialog, yDialog, bpp, NULL );
  47.  
  48.         if ( screen == NULL )
  49.                 return -1;
  50.  
  51.         SDL_WM_SetCaption ( "Instanziare Dinamicamente Oggetti", NULL );
  52.        
  53.  
  54.         //Dichiarazione del vettore oggetti
  55.         vector<Ball> oggetti;
  56.        
  57.         Ball palla;
  58.         oggetti.push_back ( palla );  //FINO A QUA FUNZIONA, INFATTI SULLO SCHERMO APPARE UNA PALLA CHE SI MUOVE E RIMBALZA
  59.  
  60.         objects = 1;
  61.  
  62.         //Carica le immagini
  63.         background = SDL_LoadBMP ( "Background.bmp" );
  64.        
  65.         SDL_LockSurface ( screen );
  66.  
  67.         while ( true )
  68.         {
  69.                 SDL_Delay ( frameSkip );
  70.                 if ( newobj < 100 )
  71.                         newobj += 10;
  72.                 if ( SDL_PushEvent ( &testEvento ) == 0 )
  73.                 {
  74.                         SDL_PollEvent ( &evento );
  75.                         keys = SDL_GetKeyState ( NULL );
  76.  
  77.                         if ( ( keys[SDLK_SPACE] == SDL_PRESSED ) && newobj == 100 )
  78.                         {
  79.                                 objects++;
  80.                                 oggetti.push_back ( Ball() ); //IL PROBLEMA PENSO SIA QUA... INFATTI QUANDO PREMO SPACE VADO INCONTRO AD UN ERRORE FATALE
  81.                                 newobj = 0;
  82.                         }
  83.  
  84.                         if ( evento.type == SDL_QUIT )
  85.                         {
  86.                                 freeSurfaces();
  87.                                 SDL_Quit();
  88.                         }
  89.                 }
  90.  
  91.                 SDL_UnlockSurface ( screen );
  92.  
  93.                 makeBackground();
  94.                
  95.                 for ( int i = 0; i < oggetti.size(); i++ )
  96.                 {
  97.                         oggetti[i].makeBall ( screen );
  98.                         oggetti[i].moveBall();
  99.                         oggetti[i].ballBounce();
  100.                 }
  101.                
  102.                 SDL_LockSurface ( screen );
  103.                 SDL_Flip ( screen );
  104.         }
  105.        
  106.  
  107.         freeSurfaces();
  108.         SDL_Quit();
  109. }



Per me non c'è bisogno di guardare tutto il codice, ma semplicemente penso di avere problemi nella riga:
Codice sorgente - presumibilmente Plain Text

  1. oggetti.push_back ( Ball() );



Non ho errori di sintassi, ma un errore fatale durante l'esecuzione..

Grazie a tutti quelli che mi risponderanno :)

Ultima modifica effettuata da RiccardoG97 il 09/04/2012 alle 10:04


"Il sangue ha il sapore del ferro"
PM Quote
Avatar
andrex91 (Member)
Pro


Messaggi: 101
Iscritto: 01/05/2009

Segnala al moderatore
Postato alle 11:34
Lunedì, 09/04/2012
Quando inserisci un elemento nel vector, questo viene copiato ( quindi il puntatore a SDL_Surface punta alla stessa risorsa dell'originale ).
Di conseguenza quando il distruttore dell'oggetto originale chiama la SDL_FreeSurface, ti ritroverai il puntatore a surface della tua copia corrotto.
Potresti fare in modo che le varie istanze dei tuoi oggetti puntino ad un unica risorsa caricata inizialmente ( stai caricando la stessa immagine in memoria per ogni istanza ) che viene rilasciata a fine applicazione e non nel distruttore :)


Provare e riprovare
PM Quote
Avatar
RiccardoG97 (Member)
Pro


Messaggi: 133
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 11:44
Lunedì, 09/04/2012
Io vorrei fare un programma che ogni volta che si clicca SPACE si istanzia un nuovo oggetto della classe Ball. Sullo schermo compara una nuova palla che si muove e rimbalza. E' da un sacco di tempo che sto provando a farlo e non ci salto fuori.. potresti spiegarmi ancora che non ho ben capito? Grazie e scusa per la mia ignoranza 8-|


"Il sangue ha il sapore del ferro"
PM Quote
Avatar
andrex91 (Member)
Pro


Messaggi: 101
Iscritto: 01/05/2009

Segnala al moderatore
Postato alle 12:01
Lunedì, 09/04/2012
Quello mi sembra che lo faccia già il tuo programma.
L'unico difetto è appunto la chiamata SDL_FreeSurface nel distruttore.
Infatti nel main hai:

Codice sorgente - presumibilmente Plain Text

  1. oggetti.push_back ( Ball() )



Questa chiamata ti crea un oggetto, ( per cui viene caricata l'immagine in memoria ), inserisce una copia di questo oggetto nel vector, e ti distrugge l'oggetto originale ( quello ritornato da Ball(), chiamando SDL_FreeSurface sulla risorsa che serve però ancora alla copia nel vector).

Per ora potresti fare così:
- levi dal costruttore e dal distruttore le due chiamate di caricamento e liberamento della surface.
- potresti aggiungere un parametro al costruttore:
Codice sorgente - presumibilmente Plain Text

  1. Ball::Ball( SDL_Surface* sur ):ball( sur ){...}


- nel main ( oppure ti crei un gestore di risorse ) ti dichiari un puntatore a SDL_Surface( es mySurface )per l'immagine della tua palla e la carichi una sola volta prima del game loop.
- ogni volta che devi inserire una nuova palla:
Codice sorgente - presumibilmente Plain Text

  1. oggetti.push_back( Ball( mySurface ) );


- prima di uscire dall'applicazione chiami una sola volta:
Codice sorgente - presumibilmente Plain Text

  1. SDL_FreeSurface( mySurface );



In questo modo se vuoi avere delle palle con surface diverse, basta che passi loro un puntatore ad un' altra surface

Ultima modifica effettuata da andrex91 il 09/04/2012 alle 12:18


Provare e riprovare
PM Quote
Avatar
RiccardoG97 (Member)
Pro


Messaggi: 133
Iscritto: 03/01/2012

Segnala al moderatore
Postato alle 14:16
Lunedì, 09/04/2012
Grazie 1000, ho capito e ci sono riuscito!! Grazieee :k:

Posto il codice funzionante, per quelli che in futuro avranno il mio stesso problema:

<Ball.h>
Codice sorgente - presumibilmente C++

  1. //Ball.h
  2. #include "SDL.h"
  3.  
  4. class Ball
  5. {
  6. public:
  7.         Ball ( SDL_Surface * );
  8.         ~Ball ( void );
  9.         void makeBall ( SDL_Surface * );
  10.         void moveBall ( void );
  11.         void ballBounce ( void );
  12.  
  13. private:
  14.         SDL_Surface *myBall;
  15.         SDL_Rect ballRect;
  16.         enum ballDirections { TOPLEFT = 1, TOPRIGHT, BOTTOMLEFT, BOTTOMRIGHT };
  17.         ballDirections Directions;
  18.         static const int speed = 2;
  19.         int direction;
  20. };



<Ball.cpp>
Codice sorgente - presumibilmente C++

  1. //Ball.cpp
  2. #include "Ball.h"
  3. #include "SDL.h"
  4. #include <ctime>
  5.  
  6. Ball::Ball ( SDL_Surface *ball )
  7. {
  8.         myBall = ball;
  9.         ballRect.x = 300;
  10.         ballRect.y = 300;
  11.         direction = 1 + rand() % 4;
  12.         if ( direction == 1 )
  13.                 Directions = TOPLEFT;
  14.         else if ( direction == 2 )
  15.                 Directions = TOPRIGHT;
  16.         else if ( direction == 3 )
  17.                 Directions = BOTTOMLEFT;
  18.         else
  19.                 Directions = BOTTOMRIGHT;
  20. }
  21.  
  22. Ball::~Ball ( void )
  23. {
  24.        
  25. }
  26.  
  27. void Ball::makeBall ( SDL_Surface *screen )
  28. {
  29.         SDL_BlitSurface ( myBall, NULL, screen, &ballRect );
  30. }
  31.  
  32. void Ball::moveBall ( void )
  33. {
  34.         if ( Directions == TOPLEFT )
  35.         {
  36.                 ballRect.x -= speed;
  37.                 ballRect.y -= speed;
  38.         }
  39.         else if ( Directions == TOPRIGHT )
  40.         {
  41.                 ballRect.x += speed;
  42.                 ballRect.y -= speed;
  43.         }
  44.         else if ( Directions == BOTTOMLEFT )
  45.         {
  46.                 ballRect.x -= speed;
  47.                 ballRect.y += speed;
  48.         }
  49.         else
  50.         {
  51.                 ballRect.x += speed;
  52.                 ballRect.y += speed;
  53.         }
  54. }
  55.  
  56. void Ball::ballBounce ( void )
  57. {
  58.         if ( ballRect.x <= 0 )
  59.         {
  60.                 if ( Directions == TOPLEFT )
  61.                         Directions = TOPRIGHT;
  62.                 else
  63.                         Directions = BOTTOMRIGHT;
  64.         }
  65.         else if ( ballRect.x >= 600 )
  66.         {
  67.                 if ( Directions == TOPRIGHT )
  68.                         Directions = TOPLEFT;
  69.                 else
  70.                         Directions = BOTTOMLEFT;
  71.         }
  72.         else if ( ballRect.y <= 0 )
  73.         {
  74.                 if ( Directions == TOPLEFT )
  75.                         Directions = BOTTOMLEFT;
  76.                 else
  77.                         Directions = BOTTOMRIGHT;
  78.         }
  79.         else if ( ballRect.y >= 500 )
  80.         {
  81.                 if ( Directions == BOTTOMLEFT )
  82.                         Directions = TOPLEFT;
  83.                 else
  84.                         Directions = TOPRIGHT;
  85.         }
  86. }



<Main.cpp>
Codice sorgente - presumibilmente C++

  1. //Main.cpp
  2.  
  3. #include "SDL.h"
  4. #include <iostream>
  5. #include "Ball.h"
  6. #include <vector>
  7. using namespace std;
  8.  
  9. //Surfaces
  10. SDL_Surface *screen = NULL;
  11. SDL_Surface *background = NULL;
  12. SDL_Surface *ball = NULL;
  13.  
  14. SDL_Event evento, testEvento;
  15. Uint8 *keys;
  16.  
  17. //Variabili
  18. const int xDialog = 600;
  19. const int yDialog = 500;
  20. const int bpp = 32;
  21. const int frameSkip = 10;
  22. int objects = 0;
  23. int newobj = 0;
  24. int direction;
  25. int speed;
  26. //Funzioni
  27. void makeBackground ( void );
  28. void freeSurfaces ( void );
  29.  
  30. //Definizione delle funzioni
  31. void makeBackground ( void )
  32. {
  33.         SDL_BlitSurface ( background, NULL, screen, NULL );
  34. }
  35.  
  36. void freeSurfaces ( void )
  37. {
  38.         SDL_FreeSurface ( background );
  39.         SDL_FreeSurface ( ball );
  40. }
  41.  
  42.  
  43. int main ( int argc, char *argv[] )
  44. {
  45.  
  46.         if ( SDL_Init ( SDL_INIT_EVERYTHING ) != 0 )
  47.                 return 1;
  48.  
  49.         screen = SDL_SetVideoMode ( xDialog, yDialog, bpp, NULL );
  50.  
  51.         if ( screen == NULL )
  52.                 return -1;
  53.  
  54.         SDL_WM_SetCaption ( "Instanziare Dinamicamente Oggetti", NULL );
  55.        
  56.  
  57.         //Dichiarazione del vettore oggetti
  58.         vector<Ball> oggetti;
  59.         /*
  60.         Ball palla;
  61.         oggetti.push_back ( palla );  //FINO A QUA FUNZIONA, INFATTI SULLO SCHERMO APPARE UNA PALLA CHE SI MUOVE E RIMBALZA
  62.         */
  63.         //Carica le immagini
  64.         background = SDL_LoadBMP ( "Background.bmp" );
  65.         ball = SDL_LoadBMP ( "Ball.bmp" );
  66.        
  67.         SDL_LockSurface ( screen );
  68.  
  69.         while ( true )
  70.         {
  71.                 SDL_Delay ( frameSkip );
  72.                 if ( newobj < 100 )
  73.                         newobj += 10;
  74.                 if ( SDL_PushEvent ( &testEvento ) == 0 )
  75.                 {
  76.                         SDL_PollEvent ( &evento );
  77.                         keys = SDL_GetKeyState ( NULL );
  78.  
  79.                         if ( ( keys[SDLK_SPACE] == SDL_PRESSED ) && newobj == 100 )
  80.                         {
  81.                                 oggetti.push_back ( Ball(ball) ); //IL PROBLEMA PENSO SIA QUA... INFATTI QUANDO PREMO SPACE VADO INCONTRO AD UN ERRORE FATALE
  82.                                 newobj = 0;
  83.                         }
  84.  
  85.                         if ( evento.type == SDL_QUIT )
  86.                         {
  87.                                 freeSurfaces();
  88.                                 SDL_Quit();
  89.                         }
  90.                 }
  91.  
  92.                 SDL_UnlockSurface ( screen );
  93.  
  94.                 makeBackground();
  95.                
  96.                 for ( int i = 0; i < oggetti.size(); i++ )
  97.                 {
  98.                         oggetti[i].makeBall ( screen );
  99.                         oggetti[i].moveBall();
  100.                         oggetti[i].ballBounce();
  101.                 }
  102.                
  103.                 SDL_LockSurface ( screen );
  104.                 SDL_Flip ( screen );
  105.         }
  106.        
  107.  
  108.         freeSurfaces();
  109.         SDL_Quit();
  110. }



Se ci sono riuscito devo però ringraziare andrex91! Grazie! :D


"Il sangue ha il sapore del ferro"
PM Quote