1
00:00:05,412 --> 00:00:09,363
Hi, welcome to this new video.

2
00:00:09,363 --> 00:00:14,213
So, we're going to start MOOC
three with our first project,

3
00:00:14,213 --> 00:00:18,098
project 1,
it's going to be a particle system.

4
00:00:18,098 --> 00:00:20,711
So we're going to be
talking about systems,

5
00:00:20,711 --> 00:00:24,202
like how certain many objects
interact with each other.

6
00:00:24,202 --> 00:00:28,604
And as we discussed initially, all these
projects are really going to start putting

7
00:00:28,604 --> 00:00:33,024
together the material from the course one
and the course two that we developed.

8
00:00:33,024 --> 00:00:37,308
So if you haven't really covered that,
make sure that you start there,

9
00:00:37,308 --> 00:00:40,611
because we really will assume
a lot of the principles and

10
00:00:40,611 --> 00:00:44,421
knowledge that we covered over
those courses already present.

11
00:00:44,421 --> 00:00:48,491
So let's talk a little bit
about the particle systems.

12
00:00:48,491 --> 00:00:53,086
So, a particle system is a technique for
creating graphics and

13
00:00:53,086 --> 00:00:56,641
creating a simulation,
where we can have a large

14
00:00:56,641 --> 00:01:01,609
number of small graphical objects,
in this case, the particles.

15
00:01:01,609 --> 00:01:05,239
We call it a system because there's a
series of objects that interact with each

16
00:01:05,239 --> 00:01:06,512
other in particular ways.

17
00:01:06,512 --> 00:01:08,073
So we have an emitter,

18
00:01:08,073 --> 00:01:12,937
that would represent the point from
which we are emitting particles.

19
00:01:12,937 --> 00:01:14,877
We'll have the particles themselves,

20
00:01:14,877 --> 00:01:17,166
which is what we're going to
write in this video.

21
00:01:17,166 --> 00:01:20,148
And we will eventually introduce forces.

22
00:01:20,148 --> 00:01:22,820
The way this project is going to work,

23
00:01:22,820 --> 00:01:28,803
we're going to spend the whole week 1 of
this course developing this project 1.

24
00:01:28,803 --> 00:01:34,507
It's going to take us around eight videos
or so to really cover several details and

25
00:01:34,507 --> 00:01:40,210
really open different dimensions that
allow us to design with these systems and

26
00:01:40,210 --> 00:01:43,716
really offer potential for
expansion, right?

27
00:01:43,716 --> 00:01:48,635
Not only understanding how these elements
interact with each other, but also,

28
00:01:48,635 --> 00:01:53,283
where would you adapt it and where would
you make it yours in different ways?

29
00:01:53,283 --> 00:01:56,455
So, as we have these
three elements in mind,

30
00:01:56,455 --> 00:02:00,549
let's just go deeper into what
we're going to write today.

31
00:02:00,549 --> 00:02:02,515
We're going to write a particle class.

32
00:02:02,515 --> 00:02:07,841
The most central attribute of
a particle will be its position,

33
00:02:07,841 --> 00:02:10,755
its velocity, and potentially,

34
00:02:10,755 --> 00:02:15,591
some other information like lifespan,
acceleration.

35
00:02:15,591 --> 00:02:20,179
Then some functions, like,
does it display itself to the screen, and

36
00:02:20,179 --> 00:02:23,014
how it would interact with forces, right?

37
00:02:23,014 --> 00:02:26,912
Many software packages have
these particles already inbuilt.

38
00:02:26,912 --> 00:02:30,545
So you might be wondering, well, why do
I need to write my own particle system?

39
00:02:30,545 --> 00:02:35,359
Well, we're going to just be learning from
a particle system to continue learning

40
00:02:35,359 --> 00:02:36,646
python principles.

41
00:02:36,646 --> 00:02:41,705
And also, the way in which we would adapt
it and not necessarily make it exactly

42
00:02:41,705 --> 00:02:46,935
the same, that something that would be
featured in a software package, right?

43
00:02:46,935 --> 00:02:52,793
So with that in mind,
let's just jump into processing and

44
00:02:52,793 --> 00:02:55,553
start writing this class.

45
00:02:55,553 --> 00:03:00,243
So here we are, we have our template,

46
00:03:00,243 --> 00:03:04,503
basically, our setup function.

47
00:03:04,503 --> 00:03:09,212
We have imported random, and
it's something that we probably will work

48
00:03:09,212 --> 00:03:14,162
with canvas size, as we have been doing
in the past, and also a background.

49
00:03:14,162 --> 00:03:20,689
Let's just open up here and
let's create a new tab called particle.

50
00:03:24,219 --> 00:03:27,897
Right, and the particle tab,

51
00:03:27,897 --> 00:03:33,141
remember that a tab will
be a separate file.

52
00:03:33,141 --> 00:03:38,083
We're going to also import random here,
and

53
00:03:38,083 --> 00:03:43,581
let's just write our class particle,
right?

54
00:03:43,581 --> 00:03:48,701
We're going to define the constructor
method for this class

55
00:03:53,640 --> 00:03:55,797
With only the position.

56
00:03:55,797 --> 00:03:58,471
Position is going to be a vector, right?

57
00:03:58,471 --> 00:04:03,362
So if you want to use a variable that
specifies more clearly that it's a vector,

58
00:04:03,362 --> 00:04:04,389
you could do so.

59
00:04:04,389 --> 00:04:09,361
But in general, we're going to be using
a lot of vectors for the math and

60
00:04:09,361 --> 00:04:12,377
the calculations of positions in space.

61
00:04:12,377 --> 00:04:18,246
So we're going to get used to using
position as a vector often and

62
00:04:18,246 --> 00:04:21,954
velocity and acceleration as vectors.

63
00:04:21,954 --> 00:04:28,263
So let's define our self.pos = pos.

64
00:04:28,263 --> 00:04:32,065
So at this point,
we can just leave it here.

65
00:04:32,065 --> 00:04:36,001
What I want to do is just create the
simplest form of a particle that we could

66
00:04:36,001 --> 00:04:37,496
see in the screen, right?

67
00:04:37,496 --> 00:04:41,014
So, we could say def display.

68
00:04:45,750 --> 00:04:49,830
So how can we actually draw
the particle in the screen?

69
00:04:49,830 --> 00:04:55,342
So, stroke(255) fill(0,

70
00:04:55,342 --> 00:05:00,675
0, 255), let's do a blue.

71
00:05:00,675 --> 00:05:05,051
Again, here's where you
can use your own style.

72
00:05:05,051 --> 00:05:11,187
And then the ellipse itself is
going to use the position vector,

73
00:05:11,187 --> 00:05:15,317
the x coordinate of the position vector,

74
00:05:15,317 --> 00:05:19,459
the y coordinate of the position vector.

75
00:05:19,459 --> 00:05:20,879
And it's just for now,

76
00:05:20,879 --> 00:05:25,080
it could have a variable called size
that would define this size here.

77
00:05:25,080 --> 00:05:30,048
But I'm going to just hard code
a number 5 just because I want to keep

78
00:05:30,048 --> 00:05:32,726
this class fairly short, right?

79
00:05:32,726 --> 00:05:37,874
So, at this level, this class is actually

80
00:05:37,874 --> 00:05:42,168
more of a point if you want, right?

81
00:05:42,168 --> 00:05:47,598
A point or kind of ellipse that is just
has some location in space, right?

82
00:05:47,598 --> 00:05:52,979
To make sure that we have
things hooked up correctly,

83
00:05:52,979 --> 00:05:59,199
let's go back to our setup and
see how we can actually invoke or

84
00:05:59,199 --> 00:06:02,922
create instances of this particle.

85
00:06:02,922 --> 00:06:07,155
So in our setup, I'm going to create a for

86
00:06:07,155 --> 00:06:11,784
loop, right, for i in range(100).

87
00:06:11,784 --> 00:06:16,283
And here I could create a new particle.

88
00:06:16,283 --> 00:06:20,365
Let's just create a position for
the particle.

89
00:06:20,365 --> 00:06:27,832
So we're going to create an x =

90
00:06:27,832 --> 00:06:38,733
random.randrange(0,1200).

91
00:06:38,733 --> 00:06:40,924
That would be the size of our screen.

92
00:06:40,924 --> 00:06:45,327
This is a placeholder, but for
now let's just create a random position so

93
00:06:45,327 --> 00:06:49,601
that we have 100 particles in
different random positions, right?

94
00:06:49,601 --> 00:06:53,085
Random.randrange(0, 600).

95
00:06:59,649 --> 00:07:06,072
So the new particle,
the new_particle would be equal to,

96
00:07:06,072 --> 00:07:10,705
and here we want to use
the particle class.

97
00:07:10,705 --> 00:07:15,168
But we don't have access to this
at the moment because we haven't

98
00:07:15,168 --> 00:07:18,912
really imported the particle
class into this script.

99
00:07:18,912 --> 00:07:22,961
So let's,
do from the file particle, I mean,

100
00:07:22,961 --> 00:07:29,056
I named those two files the same,
the particle and the class particle.

101
00:07:29,056 --> 00:07:34,230
So it might be confusing,
but from the file particle,

102
00:07:34,230 --> 00:07:37,949
we could say import particle, right?

103
00:07:37,949 --> 00:07:42,962
So that means from this file here,
which we call particle,

104
00:07:42,962 --> 00:07:46,084
import the particle class, right?

105
00:07:46,084 --> 00:07:50,600
So now we should have access
to this particle class.

106
00:07:50,600 --> 00:07:55,871
And let's just come down here,
let's create a bit of space.

107
00:07:55,871 --> 00:07:58,082
Let's create that particle.

108
00:07:58,082 --> 00:08:01,796
And that particle requires a position,
right?

109
00:08:01,796 --> 00:08:05,576
So we could create the vector here,

110
00:08:05,576 --> 00:08:11,120
we could say position and
create a vector position,

111
00:08:11,120 --> 00:08:15,913
which is equal to pVector(x, y), right?

112
00:08:15,913 --> 00:08:19,591
So those two variables create
a position vector, and

113
00:08:19,591 --> 00:08:22,872
then we pass that vector
into the new particle.

114
00:08:22,872 --> 00:08:27,865
Because we're working with
a collection of particles,

115
00:08:27,865 --> 00:08:33,282
we will have to store all these
created particles into a list.

116
00:08:33,282 --> 00:08:40,088
So let's create an all_particles list,
right?

117
00:08:40,088 --> 00:08:46,778
So we're using a list data
structure to store them.

118
00:08:46,778 --> 00:08:50,057
So all_particles.append,

119
00:08:50,057 --> 00:08:55,986
this is adding the particle
that we created to the list.

120
00:08:55,986 --> 00:08:59,514
The new_particle,
we're going to add it to the list, right?

121
00:08:59,514 --> 00:09:00,849
So at this point,

122
00:09:00,849 --> 00:09:06,649
we should have a collection of particles
that all have been added to our list.

123
00:09:06,649 --> 00:09:14,037
The only final bit here that we need
to do would be to define the draw.

124
00:09:14,037 --> 00:09:17,670
So where we going to make
them appear in the screen.

125
00:09:17,670 --> 00:09:22,796
And let's do a background that is black.

126
00:09:22,796 --> 00:09:26,396
And for P in, sorry,

127
00:09:26,396 --> 00:09:30,801
should be all particles.

128
00:09:30,801 --> 00:09:35,819
We're kind of trying to loop
through the list of particles for

129
00:09:35,819 --> 00:09:41,426
a particle, P in the list of
all_particles, p.display, right?

130
00:09:41,426 --> 00:09:46,556
So we're basically saying,
let's call the function

131
00:09:46,556 --> 00:09:51,029
display of that particle every frame,
right?

132
00:09:51,029 --> 00:09:54,216
So we're looping through those
100 particles we created and

133
00:09:54,216 --> 00:09:55,878
we are displaying them, right?

134
00:09:55,878 --> 00:09:59,780
So let's see if this is working.

135
00:09:59,780 --> 00:10:05,158
I'm having an error, let's see,
what are we missing?

136
00:10:05,158 --> 00:10:08,112
I think I have a double dot here.

137
00:10:08,112 --> 00:10:10,324
Let's see if that's it.

138
00:10:10,324 --> 00:10:15,223
Okay, so, we have 100 particles

139
00:10:15,223 --> 00:10:20,445
basically created randomly, right?

140
00:10:20,445 --> 00:10:23,703
Notice that we don't really
have an emitter at this point,

141
00:10:23,703 --> 00:10:27,612
the emitter is something kind of
invisible, because we are emitting,

142
00:10:27,612 --> 00:10:31,867
you could imagine that this for loop is
the kind of constructor of particles.

143
00:10:31,867 --> 00:10:34,137
So that could be the role of the emitter.

144
00:10:34,137 --> 00:10:41,190
And we're not going to focus too much on
the emission at the moment, but particles.

145
00:10:41,190 --> 00:10:46,065
As we generate it, we could actually give
this role of creating the particles to

146
00:10:46,065 --> 00:10:50,672
an emission class, or we could give
it to some specific characteristics.

147
00:10:50,672 --> 00:10:54,997
Like for instance, start from a point or
start in a particular direction, right?

148
00:10:54,997 --> 00:10:56,807
Or a cone, right?

149
00:10:56,807 --> 00:11:01,545
But let's just try to kind of
simulate a little bit what

150
00:11:01,545 --> 00:11:05,768
particles actually do,
which is movement, and

151
00:11:05,768 --> 00:11:11,545
the idea of them having some form
of behavior of their own, right?

152
00:11:11,545 --> 00:11:17,987
So, what we will actually do here, we're
not going to offer a new variable for

153
00:11:17,987 --> 00:11:24,945
velocity necessarily yet, because we
don't need to provide that from outside.

154
00:11:24,945 --> 00:11:31,667
So we're going to just say self.velocity,

155
00:11:31,667 --> 00:11:37,835
or .vel, for velocity, = PVector.

156
00:11:37,835 --> 00:11:42,514
And let's just make all the particles
move in a particular direction, right?

157
00:11:42,514 --> 00:11:48,735
So something like,
towards the right, 1, 0, right?

158
00:11:48,735 --> 00:11:50,799
Just a little bit to the right.

159
00:11:50,799 --> 00:11:53,336
But for this velocity to take effect,

160
00:11:53,336 --> 00:11:58,579
we need to actually do the calculation
of updating the particles' position.

161
00:11:58,579 --> 00:12:05,985
So, def.update_particle.

162
00:12:05,985 --> 00:12:11,291
And here we need our self, right?

163
00:12:11,291 --> 00:12:13,744
We would use self.position, so

164
00:12:13,744 --> 00:12:19,263
if you think about what we're doing
here is, adding the velocity vector,

165
00:12:19,263 --> 00:12:24,444
which has some kind of velocity,
to the particles position, right?

166
00:12:24,444 --> 00:12:29,659
So, self.velocity right?

167
00:12:29,659 --> 00:12:31,477
So now we have two functions,

168
00:12:31,477 --> 00:12:35,638
I would like to keep the way we
invoke those functions rather short.

169
00:12:35,638 --> 00:12:40,992
So we're going to create a third function,
which is going to be our index or

170
00:12:40,992 --> 00:12:46,183
a shortcut for the functions that
will simulate our entire system.

171
00:12:46,183 --> 00:12:53,392
So we would say,
this is going to be calling this function.

172
00:13:03,156 --> 00:13:04,155
And this function, right?

173
00:13:04,155 --> 00:13:07,525
So, we basically have a run function
that calls our two other functions.

174
00:13:07,525 --> 00:13:11,168
So now from outside our class,
we can only invoke,

175
00:13:11,168 --> 00:13:16,256
instead of running the display function,
which was rather specific,

176
00:13:16,256 --> 00:13:19,562
let's say we're going to
run the run function,

177
00:13:19,562 --> 00:13:23,154
which contains all the other functions,
right?

178
00:13:23,154 --> 00:13:25,314
So let's see what we have.

179
00:13:25,314 --> 00:13:27,857
We're running into an error.

180
00:13:27,857 --> 00:13:30,046
See what we did wrong?

181
00:13:30,046 --> 00:13:37,345
So, self.position.add,
I was getting ahead of myself here.

182
00:13:37,345 --> 00:13:39,044
We need to add the vector.

183
00:13:39,044 --> 00:13:43,071
So self.position,
add the velocity vector, right?

184
00:13:43,071 --> 00:13:47,369
And as we learned in vector math, if we
update that position constantly a little

185
00:13:47,369 --> 00:13:51,811
bit to the right, we should have our
particles moving towards the right, right?

186
00:13:51,811 --> 00:13:54,553
So that's pretty straightforward,

187
00:13:54,553 --> 00:13:59,872
we've done this independently with
circles and other kind of geometry.

188
00:13:59,872 --> 00:14:05,007
Let's just create a random vector, so

189
00:14:05,007 --> 00:14:11,076
that we actually say
x_vel = random vector,

190
00:14:11,076 --> 00:14:14,343
I'm going to do a uniform,

191
00:14:14,343 --> 00:14:19,963
because I want a value between -1 and 1.

192
00:14:19,963 --> 00:14:21,387
And that's a decimal place.

193
00:14:21,387 --> 00:14:25,630
So I'm going to say that the initial
velocity of all these particles is

194
00:14:25,630 --> 00:14:27,274
going to be random, right?

195
00:14:30,206 --> 00:14:34,690
And it's going to be the variable for
the y.

196
00:14:34,690 --> 00:14:38,895
So we have,
x velocity is going to be here.

197
00:14:38,895 --> 00:14:45,440
So the initial velocity speed,
it's going to be done at random,

198
00:14:45,440 --> 00:14:50,438
so that we could actually
have all these particles

199
00:14:50,438 --> 00:14:54,369
moving in random directions, right?

200
00:14:54,369 --> 00:14:58,570
We might want to write a function to
see how they deal with the environment,

201
00:14:58,570 --> 00:15:02,664
what happens when they reach the border,
right, things of that sort.

202
00:15:02,664 --> 00:15:07,697
For now, this is pretty good,
let's just finalize this video.

203
00:15:07,697 --> 00:15:13,362
And we have a template or
a good starting point for our particles.

204
00:15:13,362 --> 00:15:18,855
What would happen if we make
them all start from zero?

205
00:15:18,855 --> 00:15:22,335
I'm going to comment out
this line like this, so

206
00:15:22,335 --> 00:15:25,021
that I basically keep a reference.

207
00:15:25,021 --> 00:15:28,276
I like doing this when I'm
designing with the system.

208
00:15:28,276 --> 00:15:32,837
Well, let's start from
a particular coordinate,

209
00:15:32,837 --> 00:15:38,340
let's just say 600 in the center
of the screen, by 300.

210
00:15:38,340 --> 00:15:41,094
Or we could start anywhere in the screen.

211
00:15:41,094 --> 00:15:43,969
So those are very different
starting conditions.

212
00:15:43,969 --> 00:15:47,098
And you can see how these particles
really started now, from the center,

213
00:15:47,098 --> 00:15:48,678
which would be more like an emitter.

214
00:15:48,678 --> 00:15:52,110
A point where these
particles spread apart and

215
00:15:52,110 --> 00:15:56,343
they start simulating their
behavior as they go around.

216
00:15:56,343 --> 00:16:02,373
So, that's it for this first video, we're
going to continue working with this setup.

217
00:16:02,373 --> 00:16:07,044
So by all means, just keep this material
where we have it here, and we're going to

218
00:16:07,044 --> 00:16:11,103
keep building up this particle
system in the next following videos.

219
00:16:11,103 --> 00:16:11,634
I'll see you then.