This is a continuation from Part 2…

**Velocity/Movement:**

Whilst we can move our ‘player’ we will need to make things interesting the computer will probably need to move things as well.

To do this we will add some code to give the particles a random velocity. Velocity consists of a direction and a speed (as it is a vector quantity). We will add variables for these in the Particle class:

self.x = x;

self.y = y;

self.size = size;

self.colour = (255, 0, 0);

self.thickness = 1;

self.speed = 0.03

self.angle = random.uniform(0, math.pi*2)

If we run the code now, nothing different will happen as we have not updated the particle’s position.

To find out how far the a particle has moved we will break the velocity vector down into its x and y components. This is easy using simple trig:

v_x = speed * cos(angle)

v_y = speed * sin(angle)

dx and dy are then the integral of these:

integral(v)dt

We can assume dt is 1 and just add v_x and v_y to the x and y coordinates each main loop iteration:

self.y += math.sin(self.angle) * self.speed

However, since the +ve y direction is actually the downward direction we need to use a -ve to invert the y amount. We will also put the code into the class:

self.x += math.cos(self.angle) * self.speed

self.y -= math.sin(self.angle) * self.speed

We can then call move() before we call display() in the particle loop:

particle.move();

particle.display();

The particles should now all move out of the display window in random directions at a constant speed.

**Bounding Boxes:**

We can check if the particle has reached the edge of the window by checking the following boundaries:

if x > screen_w:

#Bottom of screen

elif x < 0:

#Top of screen

if y > screen_h:

#Right side of screen

elif y < 0:

#Left side of screen

To start with we can make the particle stop once it reaches the edge of the window. To do this we will add a function in the Particle class called reflect() and add the code to make the speed 0:

if self.x > screen_w: #Bottom of Screen

self.speed = 0

elif self.x < 0: #Top of Screen

self.speed = 0

if self.y > screen_h: #Right side of screen

self.speed = 0

elif self.y < 0: #Left side of Screen

self.speed = 0

The problem with this is that it doesn’t accont for the size of the particle. We need to offset the boundaries by self.size:

if self.x > screen_w – self.size: #Bottom of Screen

self.speed = 0

elif self.x < self.size: #Top of Screen

self.speed = 0

if self.y > screen_h – self.size: #Right side of screen

self.speed = 0

elif self.y < self.size: #Left side of Screen

self.speed = 0

Remember to add a call to reflect() after moving the particle and before displaying:

particle.move();

particle.reflect();

particle.display();

Lets make things a little more interesting by bouncing the particles of the walls. This is not quite as simple as we might expect as it is unlikely that a particle will lie exactly on the boundary and will instead overshoot the boundary by a small amount:

if self.x > screen_w – self.size: #Right side of screen

self.x = 2*(screen_w – self.size) – self.x

self.angle = math.pi – self.angle

elif self.x < self.size: #Top of Screen

self.x = 2*self.size – self.x

self.angle = math.pi – self.angle

if self.y > screen_h – self.size: #Bottom of Screen

self.y = 2*(screen_h – self.size) – self.y

self.angle = –self.angle

elif self.y < self.size: #Left side of Screen

self.y = 2*self.size – self.y

self.angle = –self.angle