C++, SDL2 Particle Project: Particles Won't Move

I am completely new to programming and I am following a C++ tutorial for beginners. I am using Eclipse IDE 2020 06 with MinGW-64, SDL2 on a Windows 10 machine.

We’ve been building the project in stages. The first part was to create a window, then to create particles and then have the particles move. I successfully completed the first two parts, but I’m stuck with the particle movement. The project builds and runs without error, but the particles will not move. I have been googling and searching YouTube for two days and I just cannot find anything to help. And since there are no error messages, I have no idea why it won’t work.
The project includes 3 separate classes. I’m posting the main.cpp, Particle and Swarm classes. I’m thinking the problem has to be in there somewhere, since everything worked beautifully up to the point where I tried to get the particles to move.

I apologize in advance for posting so much code, but I just don’t know what else to do.

Animating_Particles.cpp: (main)

    #include "Screen.h" 
    #include "Swarm.h" 
    #include "Particle.h" 
    #include <math.h> 
    #include <time.h> 
    #include <stdlib.h>

using namespace std;
using namespace screenanimation;

int main(int argc, char **argv) { 
     srand (time (NULL));

     Screen screen;

     if (screen.init () == false) {
        cout << "SDL_Init failed." << endl;
     }

     Swarm swarm; 

     while (true) {
             int elapsed = SDL_GetTicks ();
             screen.clear (); 
             swarm.update ();

             unsigned char red = (1 + sin (elapsed * 0.0011)) * 128; 
             unsigned char green = (1 + sin (elapsed * 0.0011)) * 128; 
             unsigned char blue = (1 + sin (elapsed * 0.0011)) * 128;

             const Particle *const pParticles = swarm.getParticles ();

             for (int i = 0; i < Swarm::NPARTICLES; i++) { 
                  Particle particle = pParticles [i];
                  int x = (particle.m_x + 1) * Screen::SCREEN_WIDTH / 2; 
                  int y = (particle.m_y + 1) * Screen::SCREEN_HEIGHT / 2;

                 screen.setPixel(x, y, red, green, blue);
             }

             screen.update();

             if (screen.processEvents () == false) { 
                break;
             } 
      }

       screen.close ();

      return 0; 
}

Particle.cpp

#include "Particle.h" 
#include <stdlib.h>

namespace screenanimation {

Particle::Particle() {
     m_x = ((2.0 * rand ()) / RAND_MAX) -1; 
     m_y = ((2.0 * rand ()) / RAND_MAX) -1;

     m_xspeed = 0.001 * ((2.0 * rand ()) / RAND_MAX) -1; 
     m_yspeed = 0.001 * ((2.0 * rand ()) / RAND_MAX) -1;

} 
Particle::~Particle() {
}

void Particle::update () {
     m_x += m_xspeed; m_y += m_yspeed;

     if (m_x <= -1.0 || m_x >= 1.0) { 
        m_xspeed = -m_xspeed;
     }

     if (m_y <= -1.0 || m_y >= 1.0) {
        m_yspeed = -m_yspeed;
     } 
}

} /* namespace screenanimation */

Particle.h

#ifndef PARTICLE_H_ 
#define PARTICLE_H_
#include <math.h> 
namespace screenanimation { 

struct Particle {
      double m_x; double m_y;
      double m_xspeed; double m_yspeed;
public:
     Particle();
     virtual ~Particle(); 
     void update ();
};
} /* namespace screenanimation */ 
#endif /* PARTICLE_H_ */

Swarm.cpp

#include "Swarm.h" 
namespace screenanimation { 
Swarm::Swarm() {
     m_pParticles = new Particle [NPARTICLES];
}

Swarm::~Swarm() {
     delete [] m_pParticles;
}

void Swarm::update() {
     for (int i = 0; i < Swarm::NPARTICLES; i++) {
          m_pParticles [i].update ();
     } 
}

} /* namespace screenanimation */

Swarm.h

#ifndef SWARM_H_ 
#define SWARM_H_

#include <iostream> 
#include "Particle.h"

namespace screenanimation {

class Swarm { 
public:
     const static int NPARTICLES = 2000;

private:
     Particle * m_pParticles;

public:
     Swarm();
     virtual ~Swarm(); 
     void update ();

     const Particle * const getParticles () { return m_pParticles; };
};
} /* namespace screenanimation */

Edit: code already fixed.

I’m sorry I don’t understand this response.

Yeah, sorry. I wrote to you regarding fixing your code by covering it in code tags. Then when I posted the message, you had already edited your post and fixed the code. Therefore I edited my post. So just ignore my previous post.

Wish I could be more help, but I can’t build and run your code, though I think you should look into main() where you calculate the new x and y values also look into the initial Particle.m_x/y values. It could be your x, y values are out-of-bounds for your screen size and the call to setPixel() is “fixing” the values by moving them back on screen (always to the same location.) You didn’t include the code for screen.cpp/.h so I don’t know if it is doing bounds checking on the new x, y values.

It could also be you screen.update() isn’t working, but you’d have to post screen code.

You might find it easier to work through if you get rid of all the calls to rand() and try setting the Particles in fixed starting locations with known speeds, then you’d be able to tell if they are displayed where you expect and moving correctly.

Thank you for response. I will try your suggestions. Here is the Screen class.

Screen.cpp

#include "Screen.h" 
namespace screenanimation { 
Screen::Screen() :

m_window(NULL), m_renderer(NULL), m_texture(NULL), m_buffer(NULL) {
}

bool Screen::init () {
if (SDL_Init (SDL_INIT_VIDEO) < 0) {
return false;
}

m_window = SDL_CreateWindow ("Particle Fire Explosion", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);

if (m_window == NULL) { SDL_Quit ();
return false;
}

m_renderer = SDL_CreateRenderer (m_window, -1, SDL_RENDERER_PRESENTVSYNC);

m_texture = SDL_CreateTexture (m_renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STATIC, SCREEN_WIDTH, SCREEN_HEIGHT);

if (m_renderer == NULL) { 
SDL_DestroyWindow (m_window); 
SDL_Quit ();
return false;
}

if (m_texture == NULL) { 
SDL_DestroyRenderer (m_renderer); 
SDL_DestroyWindow (m_window); 
SDL_Quit ();
return false;
}

m_buffer = new Uint32 [SCREEN_WIDTH * SCREEN_HEIGHT]; 
memset (m_buffer, 0x00, SCREEN_WIDTH * SCREEN_HEIGHT * sizeof (Uint32));

return true;
}

void Screen::clear () {
memset (m_buffer, 0, SCREEN_WIDTH * SCREEN_HEIGHT * sizeof (Uint32)); 
}

void Screen::setPixel (int x, int y, Uint8 red, Uint8 green, Uint8 blue) {
if (x < 0 || x >= SCREEN_WIDTH || y < 0 || y >= SCREEN_HEIGHT) { 
return;
}

Uint32 color = 0;

color += red; 
color <<= 8; 
color += green; 
color <<= 8; 
color += blue; 
color <<= 8; 
color += 0xFF;

m_buffer [(y * SCREEN_WIDTH) + x] = color;
}

void Screen::update () {
SDL_UpdateTexture (m_texture, NULL, m_buffer, SCREEN_WIDTH * sizeof (Uint32));
SDL_RenderClear (m_renderer); 
SDL_RenderCopy (m_renderer, m_texture, NULL, NULL); 
SDL_RenderPresent (m_renderer);
}

bool Screen::processEvents() { 
SDL_Event event; 

while (SDL_PollEvent (&event)) {
if (event.type == SDL_QUIT) {
return true;
}

}
}

return true;

void Screen::close() { 
delete [] m_buffer;
SDL_DestroyRenderer (m_renderer); 
SDL_DestroyTexture (m_texture);
SDL_DestroyWindow (m_window); 
SDL_Quit ();
}

Screen::~Screen() {
}

}
/* namespace screenanimation */ 

Screen.h

#ifndef SCREEN_H_ 
#define SCREEN_H_

#include <SDL.h>

using namespace std; 
namespace screenanimation {

class Screen { public:
const static int SCREEN_WIDTH = 800; const static int SCREEN_HEIGHT = 600;

private:
SDL_Window *m_window;
SDL_Renderer *m_renderer; 
SDL_Texture *m_texture; 
Uint32 *m_buffer;

public:
Screen();

bool init ();
void update ();
void setPixel (int x, int y, Uint8 red, Uint8 green, Uint8 blue); bool processEvents ();
void close ();
void clear ();

virtual ~Screen();
};
} /* namespace screenanimation */ 
#endif /* SCREEN_H_ */

Hi. So, I took a break from the project for a few days. I went back to it today and tried changing some of the values and realized that no matter what I did, the run outcome wasn’t changing! In Launch Configuration, I changed Build Configuration from “Use Active” to “Select Automatically” and finally, the project is running the way it’s supposed to - at least I think it is. I am going to move on to the next step in the tutorial.

You might find it easier to work through if you get rid of all the calls to rand() and try setting the Particles in fixed starting locations with known speeds, then you’d be able to tell if they are displayed where you expect and moving correctly.

@FlyingSquirrel, I will have to do some research to learn how to do this. Thank you, it was your suggestion to change some values that made me realize what was going on.