You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/2024/11/24-making-particle-systems-for-fun-and-robotics/24-making-particle-systems-for-fun-and-robotics.md
+32-34Lines changed: 32 additions & 34 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ I have a lifelong fascination with Particle systems, complementing my robotics.
8
8
9
9
Today I am going to express my love of particle systems in Python. This might be a long ride, with a few programs in a series of posts. I hope you'll join me, with some demonstrations in how much fun these can be. It would be helpful if you've done a little Python before, but this aims to be a beginner-friendly course.
10
10
11
-
This series will focus on programming with lots of visuals. We'll write it using PyGame letting us get a lot on the screen. Beyond being handy in robotics, this is fun for some simple visual effects, games and simulations.
11
+
This series will focus on programming with lots of visuals. You'll write it using PyGame letting us get a lot on the screen. Beyond being handy in robotics, this is fun for some simple visual effects, games and simulations.
12
12
13
13
## Getting prepared
14
14
@@ -24,7 +24,7 @@ pip install pygame
24
24
25
25
## One dot
26
26
27
-
The simplest particle system is one dot. We'll use this to get up and running. This is the least interesting particle system, but we can build on it to something more fun.
27
+
The simplest particle system is one dot. You'll use this to get up and running. This is the least interesting particle system, but you can build on it to something more fun.
28
28
29
29
```python
30
30
import pygame
@@ -63,27 +63,25 @@ Run it and you should see this:
63
63
64
64

65
65
66
-
We start with importing [PyGame](https://www.pygame.org/), a Python gaming library for drawing 2D games.
66
+
The code starts with importing [PyGame](https://www.pygame.org/), a Python gaming library for drawing 2D games. It then sets up some parameters for your program. It defines the display size with `WIDTH` and `HEIGHT`, and uses `FRAME_RATE` so the program runs at a consistent speed.
67
67
68
-
We then set up some parameters for our program. We define the display size with `WIDTH` and `HEIGHT`. We use FRAME_RATE so the program runs at a consistent speed.
68
+
You then set up some colours. A background colour, and a colour for your dot, followed by a dot size. putting these things in parameters makes them easy to change later.
69
69
70
-
We then set up some colours. A background colour, and a colour for our dot, followed by a dot size. putting these things in parameters makes them easy to change later.
71
-
72
-
We then define a list with two numbers, the x and y position of the dot. This is our particle, followed by a function to draw our particle, a circle on the screen. In PyGame, the top left corner is 0,0, so the bottom of the screen is HEIGHT.
70
+
Your code then defines a list with two numbers, the x and y position of the dot. This is your particle, followed by a function to draw our particle, a circle on the screen. In PyGame, the top left corner is 0,0, so the bottom of the screen is HEIGHT.
After this we initialise pygame, with a screen and a clock and enter a main loop. The main loop starts with a running variable, so the system can be told when to exit. The code looks for a QUIT event, triggered when you close the window to ensure it shuts down. This is a common pattern in PyGame.
74
+
After this you initialise pygame, with a screen and a clock and enter a main loop. The main loop starts with a running variable, so the system can be told when to exit. The code looks for a QUIT event, triggered when you close the window to ensure it shuts down. This is a common pattern in PyGame.
77
75
78
-
The next part of the loop fills the screen with background colour. We then use the `draw` function to draw the dot. We must call `pygame.display.flip` as pygame draws everything on a hidden buffer, which we swap with the visible screen.
76
+
The next part of the loop fills the screen with background colour. You then use the `draw` function to draw the dot. You must call `pygame.display.flip` as pygame draws everything on a hidden buffer, which you swap with the visible screen.
79
77
80
-
Finally we tick the clock to keep the framerate the same. The last line of the program is `pygame.quit` to ensure everything is cleaned up.
78
+
Finally you tick the clock to keep the framerate the same. The last line of the program is `pygame.quit` to ensure everything is cleaned up.
81
79
82
80
This is drawn at 400, 400 which is the middle of the screen. I suggest you try a few values between 0 and the WIDTH to see how it changes. I guarantee you won't like my colour choices, so you can also try different colour names, or even RGB values (like `(255, 0, 0)` for red).
83
81
84
82
## Making it a bit random
85
83
86
-
A key concept in a particle system is randomness. We can make the one dot less boring by making it random.
84
+
A key concept in a particle system is randomness. You can make the one dot less boring by making it random.
87
85
88
86
At the top of the file, lets import the random module above pygame:
89
87
@@ -92,29 +90,29 @@ import random
92
90
import pygame
93
91
```
94
92
95
-
Now we can make it show the dot at a random place every time we run it. Update the one_dot line to be:
93
+
Now you can make it show the dot at a random place every time you run it. Update the one_dot line to be:
We have a particle, but particles have a lifecycle:
101
+
You have a particle, but it's not doing much. You can add a little movement to our particle.
102
+
103
+
Particles have a lifecycle:
104
104
105
105
- They are created
106
106
- They update and change over time
107
107
- They may also die
108
108
109
-
We can add a little movement to our particle. Let's introduce a speed constant and update our particle with it.
110
-
111
-
In the constants add the following:
109
+
Let's introduce a speed constant and update our particle with it. In the constants add the following:
112
110
113
111
```python
114
112
SPEED=2
115
113
```
116
114
117
-
We can add an update function, which can be called in the main loop:
115
+
You then add an `update` function, which can be called in the main loop:
118
116
119
117
```python
120
118
defupdate():
@@ -123,9 +121,9 @@ def update():
123
121
one_dot[1] =0
124
122
```
125
123
126
-
This will add the speed to the second element (the Y coordinate) of the one_dot list. If the dot reaches the bottom of the screen, we reset it to the top.
124
+
This will add the speed to the second element (the Y coordinate) of the one_dot list. If the dot reaches the bottom of the screen, you reset it to the top.
127
125
128
-
We then call this in the main loop before we start drawing things:
126
+
You then call `update` in the main loop before you start drawing things:
129
127
130
128
```python
131
129
running =True
@@ -141,17 +139,19 @@ while running:
141
139
clock.tick(FRAME_RATE)
142
140
```
143
141
144
-
Run this. You can adjust the speed by changing the SPEED constant, or increasing the FRAME_RATE, however, note that above a certain frame rate value we may be being slowed by the speed of the program. With high SPEED values, you may see the dot jump on the screen.
142
+
Run this. You can adjust the speed by changing the SPEED constant, or increasing the FRAME_RATE, however, note that above a certain frame rate value your frames may be being slowed by the speed of the program. With high SPEED values, you may see the dot jump on the screen.
145
143
146
144
This dot has a lifecycle:
147
145
148
146
- It is created at a random position
149
147
- It moves down the screen
150
148
- When it reaches the bottom, it is moved back to the top
151
149
150
+
What happens if you make the SPEED constant negative?
151
+
152
152
## Multiple dots
153
153
154
-
We can make this more interesting again by having multiple dots, like a rain storm. We can do this by having a list of dots.
154
+
You can make this more interesting again by having multiple dots, like a rain storm. You can do this by having a list of dots.
155
155
156
156
Swap our one dot for this:
157
157
@@ -170,7 +170,7 @@ def populate():
170
170
)
171
171
```
172
172
173
-
We then need to update the draw function to draw all the dots:
173
+
You then need to update the draw function to draw all the dots:
174
174
175
175
```python
176
176
defdraw(surface):
@@ -188,7 +188,7 @@ def update():
188
188
raindrop[1] =0
189
189
```
190
190
191
-
Finally, we need to call the populate function to create the dots, while we initialise the program:
191
+
Finally, you need to call the populate function to create the dots while you initialise the program:
192
192
193
193
```python
194
194
pygame.init()
@@ -209,11 +209,9 @@ These dot's all have the same lifecycle as our one dot!
209
209
210
210
## Adjusting the lifecycle
211
211
212
-
We can change this particle system in a few interesting ways. You might have noticed the raindrops loop around in a repeating pattern.
213
-
214
-
We can fix this by changing the lifecycle. Instead of just wrapping the raindrop, we can pretend this raindrop has reached the end of the lifecycle and that we are creating a new one. However, we can do something sneaky and reset the x to a random value when we do this.
212
+
You can change this particle system in a few interesting ways. You might have noticed the raindrops loop around in a repeating pattern.
215
213
216
-
We only need to modify the `update` function:
214
+
You can fix this by changing the lifecycle. Instead of just wrapping the raindrop, you can pretend this raindrop has reached the end of the lifecycle and that your are creating a new one. However, you can do something sneaky and reset the x to a random value when you do this. You only need to modify the `update` function:
217
215
218
216
```python
219
217
defupdate():
@@ -228,16 +226,16 @@ You shouldn't be able to see a repeating pattern any more.
228
226
229
227
## Random speeds
230
228
231
-
We can add a little depth by adding a further parameter to our raindrops. For this we will change two parts of the lifecycle - the add function and the update function.
232
-
We'll also adjust the parameters above.
229
+
You can add a little depth by adding a further parameter to our raindrops. For this you will change two parts of the lifecycle - the add function and the update function.
230
+
You'll also adjust the parameters above. Extend the constants after the POPULATION_SIZE:
233
231
234
232
```python
235
233
POPULATION_SIZE=200
236
234
MIN_SPEED=2
237
235
MAX_SPEED=6
238
236
```
239
237
240
-
In the populate function, lets make a random speed:
238
+
You can then modify the populate function to generate a random speed:
241
239
242
240
```python
243
241
defpopulate():
@@ -251,7 +249,7 @@ def populate():
251
249
)
252
250
```
253
251
254
-
We can then update using this stored speed:
252
+
You can then update using this stored speed:
255
253
256
254
```python
257
255
defupdate():
@@ -262,7 +260,7 @@ def update():
262
260
raindrop[0] = random.randint(0, WIDTH)
263
261
```
264
262
265
-
However, we made an assumption in draw that the raindrop was only 2 numbers - the coordinates of the drop. With 3, we need to filter them:
263
+
However, the code made an assumption in draw that the raindrop was only 2 numbers - the coordinates of the drop. With 3, you need to filter them:
266
264
267
265
```python
268
266
defdraw(surface):
@@ -274,7 +272,7 @@ If you run this, you can now see raindrops falling at different speeds.
274
272
275
273
## Checkpoint - raindrops
276
274
277
-
We've built a small particle system, transforming a single static dot into a rainstorm with raindrops at different speeds. Here's the full code:
275
+
You've built a small particle system, transforming a single static dot into a rainstorm with raindrops at different speeds. Here's the full code:
278
276
279
277
```python
280
278
import random
@@ -345,6 +343,6 @@ You've built a simple particle system, raindrops, using Python and PyGame. You'v
345
343
346
344
You've also seen how particles have a lifecycle.
347
345
348
-
Over the coming for posts, we can explore what other ways we can use particle systems, some variations on this theme, and some quite different.
346
+
Over the coming for posts, we can explore what other ways you can use particle systems, some variations on this theme, and some quite different.
349
347
350
348
I've built this inspired by the Kingston University Coder Dojo where I mentor Python, and will have other particle systems inspired by research I've done for my books.
0 commit comments