[SDL] randomly changing movement

Hi guys,

right now with the following code, the movements of the rectangle are quite compound, the rectangle doesn't change direction until it hits an edge of the window, I'm trying to obtain a more dynamic fluid movement where the rectangle could change directions at any moment ie the movement of the rectangle is completely random and more accustomed to real life movement

this is the movement I'm trying to achieve - https://www.khanacademy.org/computer-programming/randomly-accelerating-ball-with-mover-object/5520030268653568

I have a feeling it has something to do with the way I change direction but not entirely sure,

thanks

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
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239

#include <iostream>
#include <SDL2/SDL.h>
#include <SDL2/SDL_image.h>
#include <cmath>
#include <stdlib.h>
#include <ctime>

using namespace std;

SDL_Renderer* renderer;
SDL_Window* window;
SDL_Texture* texture;
SDL_Surface* surface;
SDL_Event event;
const int WIDTH = 800;
const int HEIGHT = 600;

class Vector2{

   public:
       double x;
       double y;

       Vector2(double x,double y): x(x),y(y){}
       Vector2(){x = 0;y = 0;}

       void add(Vector2& other){

          x += other.x;
          y += other.y;
       }

       void scale(double scalar){

          x*=scalar;
          y*=scalar;
       }

       double magnitude(){

         return sqrt( (x * x) +  (y * y) );
       }

       Vector2 normalize(){

           double mag = magnitude();
           return Vector2(x/mag,y/mag);
       }

       int dotProduct(Vector2& other){

          return (x * other.x) + (y * other.y);
       }

       friend Vector2 subtractVectors(const Vector2& one,const Vector2& two);

       bool limit(Vector2& position,double magSize){

         Vector2 futurePosition(0,0);
         futurePosition.x = position.x;
         futurePosition.y = position.y;
         futurePosition.add(*this);
         Vector2 distanceVector = subtractVectors(futurePosition,position);

         double mag = distanceVector.magnitude();
         cout << "mag == " << mag << endl;

         if(mag < magSize)
            return false;
         else
            return true;
       }
};

Vector2 subtractVectors(const Vector2& one,const Vector2& two){

   Vector2 difference;
   double x = -(two.x);
   double y = -(two.y);
   difference.x = one.x + x;
   difference.y = one.y + y;
   return difference;
}

class Rect{

  public:
      bool objectLeft = false;
      bool objectRight = true;
      bool objectUp = false;
      bool objectDown = true;
      Vector2 vec;
      SDL_Rect spriteOneRect;
      SDL_Surface* spriteOneSurface;
      SDL_Texture* spriteOneTexture;


      Rect(int x,int y,string fileName){

         vec.x = x;
         vec.y = y;
         spriteOneSurface = IMG_Load(fileName.c_str());
         spriteOneTexture = SDL_CreateTextureFromSurface(renderer,spriteOneSurface);
         spriteOneRect.x = x;
         spriteOneRect.y = y;
         SDL_QueryTexture(spriteOneTexture,NULL,NULL,&spriteOneRect.w,&spriteOneRect.h);
      }
      BlackRect(){

        vec.x = 250;
        vec.y = 250;
      }

      void update(){

        spriteOneRect.x = vec.x;
        spriteOneRect.y = vec.y;
      }
};

void render(Rect& rect){

    SDL_RenderClear(renderer);
    SDL_SetRenderDrawColor(renderer,255,255,255,255);
    SDL_RenderCopy(renderer,rect.spriteOneTexture,NULL,&rect.spriteOneRect);
    SDL_RenderPresent(renderer);
}


bool collisionBoundsSides(SDL_Rect &rect){

  if(rect.x <= 0)
    return true;
  if(rect.x + rect.w >= 800)
    return true;

  return false;
}

bool collisionBoundsEnds(SDL_Rect &rect){

  if(rect.y <= 0)
    return true;
  if(rect.y + rect.h >= 600)
    return true;

  return false;
}

void moveObject(Rect& rect,Vector2& velocity,Vector2& acceleration,int magSize){

  if(collisionBoundsSides(rect.spriteOneRect)){

       if(rect.objectRight){

          rect.objectRight = false;
          rect.objectLeft = true;
       }else{
         rect.objectLeft = false;
         rect.objectRight = true;
       }
   }

   if(collisionBoundsEnds(rect.spriteOneRect)){

       if(rect.objectUp){
        rect.objectUp = false;
        rect.objectDown = true;
       }else{
         rect.objectDown = false;
         rect.objectUp = true;
       }
   }
        double randomX = (rand()%99);
        double randomY = (rand()%-99);

        randomX *= 0.00025;
        randomY *= 0.00025;
        acceleration.x = randomX;
        acceleration.y = randomY;

        if(rect.objectRight)
        rect.vec.x += velocity.x;

        if(rect.objectLeft)
        rect.vec.x -= velocity.x;

        if(rect.objectUp)
        rect.vec.y += velocity.y;

       if(rect.objectDown)
        rect.vec.y -= velocity.y;

  // wrapAround(rect);

    rect.update();

    if(!velocity.limit(rect.vec,magSize))
        velocity.add(acceleration);


}

int SDL_main(int argc,char* argv[]){

   init();
   bool quit = false;
   srand(time(NULL));

   Rect br(WIDTH/2,HEIGHT/2,"blockone.png");

   Vector2 velocity(0,0);
   Vector2 acceleration(-0.001,0.01);

   //Vector2 acceleration(randomX,randomY);


   while(!quit){

      SDL_PollEvent(&event);

      if(event.type == SDL_QUIT)
        break;

       if(event.type == SDL_KEYDOWN){

          int key = event.key.keysym.sym;
          if(key == SDLK_b)
            cout << "yeah" << endl;

       }
      moveObject(br,velocity,acceleration,7);
      render(br);
      SDL_Delay(2);

   }
}
Last edited on
I have a feeling it has something to do with the way I change direction but not entirely sure,
Yes. No. Maybe.
You haven't actually stated what the problem is, if any.

Also, stop calling SDL_Delay() after refreshing the screen. If you want to limit the CPU usage then turn on v-sync.
https://wiki.libsdl.org/SDL_CreateRenderer
the problem is I want the rectangle to change direction randomly, I would like the rectangles x and y direction to change randomly, at the moment the only way they change directions is for the rectangle to collide with the edges of the window,

pretty much this movement as demonstrated in this link - https://www.khanacademy.org/computer-programming/randomly-accelerating-ball-with-mover-object/5520030268653568
at the moment the only way they change directions is for the rectangle to collide with the edges of the window,
Maybe you create a pseudo wall randomly every once in a while. I. e. in thie function where you detect the hit you return randomly true instead of false.
Thanks coder777 I got the desired effect for a small fraction of the time, well not quite.

let me show you a video of the movement - https://youtu.be/C2ESvMMeiHY

so as you can see it's almost like the rectangle runs into an invisible force( very much like wind) and the wind slowly pushes the rectangle into the right edge of the window until it gets stuck.

do you know why and how this invisible force is pushing it against the wall? I'm still just experimenting,

I would like the force to be less and even more random than it is now, so the force could randomly be applied in any direction,

also magnitude seems to be quite small and keeps slowly decreasing, I want don't really want this effect

thanks
Last edited on
Whenever the 'virtual' wall appears the rectangle is rejected. I would thiink that it happens to frequently. So the issue is: how do you decide whether that virtual wall appears or not. Using a timer?
Topic archived. No new replies allowed.