Constructing an indefinite amount of objects out of the same class

Hey there,

I've been writing a program with SDL and what I want it to do is to create a dot on the screen wherever I click. What I have (Code in the bottom of the post) is a function makeDot within a class Mouse that will use the constructor to create a new dot, then I have a function update within the class dot which changes the position of the dots and blits them to the screen. Now, these functions work by themselves but I cant figure out a way to make them work together. I remember something from PyGame where you would create an array with all the objects so you can manipulate them all, like blitting and freeing them. Is There something similar in SDL for C++?

Here's my code(sorry about the mess):
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <cstdlib>
#include <SDL.h>
#include <math.h>
#include <iostream>

double square (double x){return x*x;}
int square (int x){return x*x;}

class dot
{
    SDL_Surface* img;
    SDL_Rect rect;
    double xVel, yVel;
    double s;
    public:
        SDL_Surface* image;
        dot (double,double,double,SDL_Surface*);
        double x, y;
        void follow (double, double);
        void follow (int, int);
        void randmove ();
        void update (SDL_Surface*);
};

dot::dot (double a, double b, double c = 1, SDL_Surface* d = SDL_LoadBMP("dot.bmp"))
{
    x = a;
    y = b;
    s = c;
    img = d;
}

void dot::follow (double x2, double y2)
{
    double dist = sqrt((square(x2-x))+(square(y2-y)));
    if (dist!=0)
    {
        xVel = (s*(x2-x))/dist;
        yVel = (s*(y2-y))/dist;
        x += xVel;
        y += yVel;
    }
}

void dot::follow (int x2, int y2)
{

    double dist=sqrt((square(x2-x))+(square(y2-y)));
    if(dist!=0){
        xVel = (s*(x2-x))/dist;
        yVel = (s*(y2-y))/dist;
        x += xVel;
        y += yVel;
    }

}

void dot::randmove()
{
    int count = 1;
    if (rand()%20 == 0)
    {
        if(rand()%count==0)
        {
            xVel = rand() % 3;
            yVel = rand() % 3;
            if (rand()%2 == 1){xVel = -xVel;}
            if (rand()%2 == 1){yVel = -yVel;}
        }else{count = 1;yVel=0;xVel=0;}
    }else{count++;}
    if ((x > 640-16 && xVel > 0)||(x < 0 && xVel < 0)) {xVel = -xVel;}
    if ((y > 480-16 && yVel > 0)||(y < 0 && yVel < 0)) {yVel = -yVel;}
    x += xVel;
    y += yVel;
}

void dot::update (SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16,SDL_HWSURFACE|SDL_DOUBLEBUF))
{
    x += xVel;
    y += yVel;
    rect.x = x;
    rect.y = y;
    SDL_BlitSurface(img, 0, screen, &rect);
}

class Mouse
{
    int x, y;
    public:
        int getX();
        int getY();
        void makeDot();
};

int Mouse::getX()
{
    SDL_GetMouseState(&x, NULL);
    return x;
}
int Mouse::getY()
{
    SDL_GetMouseState(NULL, &y);
    return y;
}

bool dots = 0;

void Mouse::makeDot()
{
    SDL_PumpEvents();
    if(SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
    {
        dot dot (getX(), getY());
        dots = 1;
    }
}

int main ( int argc, char** argv )
{
    Mouse mouse;
    // initialize SDL
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }


    // program main loop
    bool done = false;
    while (!done)
    {
        //problem
        mouse.makeDot();
        if (dots)
        {
        dot.update();
        }
        //problem

        for(unsigned long i=0;i<1000000;i++){int bbb=0;}//This is here to slow down the program. I know there are better ways to do this but I'm too lazy to look it up.

        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            } // end switch
        } // end of message processing

        // DRAWING STARTS HERE

        // clear screen
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255));

//        A.follow (C.x, C.y);
//        C.randmove ();

        // finally, update the screen :)
        SDL_Flip(screen);
    } // end main loop

    // free loaded bitmap
//    SDL_FreeSurface(dots);

    // all is well ;)
    printf("Exited cleanly\n");
    return 0;
}
You could try just making a vector of dots.

In your main add this:
std::vector<dot> dots;

Then change your makedot function to this:
1
2
3
4
5
6
7
8
void Mouse::makeDot(std::vector<dot>& Dots)
{
    SDL_PumpEvents();
    if(SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
    {
        Dots.push_back( dot (getX(), getY() );
    }
}


Finally, replace:
1
2
3
4
        if (dots)
        {
        dot.update();
        }

with:
1
2
for (std::vector<dot>::iterator it = dots.begin(); it!= dots.end(); ++it)
    it->update();
Last edited on
Thanks, it looks like that works but the dots don’t seem to appear on the screen. I think I might have to do with the positioning of the update() in my code. here is it:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
#include <cstdlib>
#include <SDL.h>
#include <math.h>
#include <iostream>
#include <vector>

double square (double x){return x*x;}
int square (int x){return x*x;}

class dot
{
    SDL_Surface* img;
    SDL_Rect rect;
    double xVel, yVel;
    double s;
    public:
        SDL_Surface* image;
        dot (double,double,double,SDL_Surface*);
        double x, y;
        void follow (double, double);
        void follow (int, int);
        void randmove ();
        void update (SDL_Surface*);
};

dot::dot (double a, double b, double c = 1, SDL_Surface* d = SDL_LoadBMP("dot.bmp"))
{
    x = a;
    y = b;
    s = c;
    img = d;
}

void dot::follow (double x2, double y2)
{
    double dist = sqrt((square(x2-x))+(square(y2-y)));
    if (dist!=0)
    {
        xVel = (s*(x2-x))/dist;
        yVel = (s*(y2-y))/dist;
        x += xVel;
        y += yVel;
    }
}

void dot::follow (int x2, int y2)
{

    double dist=sqrt((square(x2-x))+(square(y2-y)));
    if(dist!=0){
        xVel = (s*(x2-x))/dist;
        yVel = (s*(y2-y))/dist;
        x += xVel;
        y += yVel;
    }

}

void dot::randmove()
{
    int count = 1;
    if (rand()%20 == 0)
    {
        if(rand()%count==0)
        {
            xVel = rand() % 3;
            yVel = rand() % 3;
            if (rand()%2 == 1){xVel = -xVel;}
            if (rand()%2 == 1){yVel = -yVel;}
        }else{count = 1;yVel=0;xVel=0;}
    }else{count++;}
    if ((x > 640-16 && xVel > 0)||(x < 0 && xVel < 0)) {xVel = -xVel;}
    if ((y > 480-16 && yVel > 0)||(y < 0 && yVel < 0)) {yVel = -yVel;}
    x += xVel;
    y += yVel;
}

void dot::update (SDL_Surface* Screen)
{
    x += xVel;
    y += yVel;
    rect.x = x;
    rect.y = y;
    SDL_BlitSurface(img, 0, Screen, &rect);
}

class Mouse
{
    int x, y;
    public:
        int getX();
        int getY();
        void makeDot(std::vector<dot>&);
};

int Mouse::getX()
{
    SDL_GetMouseState(&x, NULL);
    return x;
}
int Mouse::getY()
{
    SDL_GetMouseState(NULL, &y);
    return y;
}

bool dots = 0;

void Mouse::makeDot(std::vector<dot>& Dots)
{
    SDL_PumpEvents();
    if(SDL_GetMouseState(NULL, NULL)&SDL_BUTTON(1))
    {
        Dots.push_back( dot (getX(), getY() ));
    }
}

int main ( int argc, char** argv )
{
    Mouse mouse;
    std::vector<dot> dots;
    // initialize SDL
    if ( SDL_Init( SDL_INIT_VIDEO ) < 0 )
    {
        printf( "Unable to init SDL: %s\n", SDL_GetError() );
        return 1;
    }

    // make sure SDL cleans up before exit
    atexit(SDL_Quit);

    // create a new window
    SDL_Surface* screen = SDL_SetVideoMode(640, 480, 16, SDL_HWSURFACE|SDL_DOUBLEBUF);
    if ( !screen )
    {
        printf("Unable to set 640x480 video: %s\n", SDL_GetError());
        return 1;
    }


    // program main loop
    bool done = false;
    while (!done)
    {

        mouse.makeDot(dots);

        for(unsigned long i=0;i<1000000;i++){int bbb=0;}//This is here to slow down the program. I know there are better ways to do this but I'm too lazy to look it up.

        // message processing loop
        SDL_Event event;
        while (SDL_PollEvent(&event))
        {
            // check for messages
            switch (event.type)
            {
                // exit if the window is closed
            case SDL_QUIT:
                done = true;
                break;

                // check for keypresses
            case SDL_KEYDOWN:
                {
                    // exit if ESCAPE is pressed
                    if (event.key.keysym.sym == SDLK_ESCAPE)
                        done = true;
                    break;
                }
            } // end switch
        } // end of message processing

        // DRAWING STARTS HERE
        for (std::vector<dot>::iterator it = dots.begin(); it!= dots.end(); ++it)
        {
            it->update(screen);
        }

        // clear screen
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255));

//        A.follow (C.x, C.y);
//        C.randmove ();

        // finally, update the screen :)
        SDL_Flip(screen);
    } // end main loop

    // free loaded bitmap
//    SDL_FreeSurface(dots);

    // all is well ;)
    printf("Exited cleanly\n");
    return 0;
}
1
2
3
4
5
6
7
8
        // DRAWING STARTS HERE
        for (std::vector<dot>::iterator it = dots.begin(); it!= dots.end(); ++it)
        {
            it->update(screen);
        }

        // clear screen
        SDL_FillRect(screen, 0, SDL_MapRGB(screen->format, 255, 255, 255));


You are clearing the screen after you draw your dots.
Topic archived. No new replies allowed.