[BELL RINGING]
Hello, I think at this point until I make some more,
this is the last video in this section
about arrays of objects.
And one of the things that comes up
a lot, especially when you're first learning to code,
is with p5 and doing graphics animations-- everything
I've been doing pretty much in all of these videos
has just been with shapes.
And so, as you can see here, here is one of the examples
arrays of objects where, when I click on them,
they change color.
This was one of my previous videos.
What I want to look at is what would
it take to have each one of these circles--
each one of these objects display
instead of a shape an image--
a JPEG or a PNG that I load-- a file that I load.
And how could I have the same object?
So, how could I make a bubble class
where each bubble displays an image,
but each bubble displays a different image?
So, the first thing I'm going to do
is just change all of these into flowers.
OK?
So, I have a directory of images associated with this project.
I'm going to go over to my code.
And it looks like this.
It has a bunch-- it has one image in it called flower.png.
And it has a bunch of other images called kitten.jpg.
The reason why I'm making this distinction
is PNG is a format for images that
allows for transparent pixels.
And that's something that you're probably
going to find very useful when designing and using
images in your code--
that you can have an image not just
be that sort of like rectangular thing,
but rather have part of the image be transparent.
So, OK.
So let's first-- I'm going to-- one of the things--
if I want to load an image into p5,
there are a variety of ways to do it,
and I'm sure I have other videos in the future--
even though I'm in the future, but I
made in the past that are further ahead
in this playlist--
where I look at this more specifically.
But a quick way to load media--
it seems a little bit silly.
Like, oh, there's a preload function?
Setup is the function where all the code at the beginning runs.
Well, I want to load images at the beginning to use.
I should use those in Setup.
But there's a funny way about JavaScript-- the way
that it loads media files and large data files
is that it can totally take a while for those things to load.
So, the preload function is a way of saying,
I'm going to have a variable--
I'm going to call it flower--
and in preload I'm going to say flower
equals loadImage flower.png.
And this could be double quotes or single quotes.
They mean the same thing.
I'm kind of like--
I like single quotes these days.
So, this right here is saying, hey,
I know you're about to set up a p5 sketch.
Before you do that, I want to have a pre-setup to the setup
where I want to load this image.
So, this will guarantee that the flower
image is ready to be used by the time you get to setup.
Now the rest of our work is really as simple
as if I have this image--
that data from that PNG file stored in this variable flower,
I can just go all the way down to my bubble object--
and look here.
This is where I draw the bubble as a circle.
So, I can just get rid of all of this code,
and I can just change and use this function called image.
So, there's a function in p5 called image which says,
hey, I want to draw an image to the screen.
Just like I want to draw an ellipse at this.x,
this.y, now I want to draw an image at this.x, this.y.
So, now all I've done is load that image in preload
in a global variable and then draw that image here
in the show function.
So, let's refresh.
[LAUGHS] OK.
So, what is this error file not found?
I forgot that I put the images in this directory
called kittens.
So, I need to make sure I reference that directory.
Now note I also need this directory
to be part of the same directory where
my index.html and sketch.js stuff is.
So, there could be some nuance here
into where you store your image files.
But in this case, I just need to make sure I include the folder
name kittens/flower.png.
And now if I do this, you can say look,
there my bubbles are flowers!
Yay!
Now, they aren't different sizes.
And so if I wanted to, I could kind of
go a little farther with this.
And I could use this variable r, and I
could make that the width and height of the image.
Now, one thing to realize here--
I'm looking over there to see if I can use my whiteboard, which
I'm about to.
But I have to go erase it first.
So, when I drew a circle--
when I used the ellipse function,
and I have this variable called this.r,
I actually assigned that-- it's poorly
named because it's assigned to the diameter of the circle.
A rectangle or a square--
which is a rectangle with equal sides--
if I have the xy here, this is its width
and this is its height.
The reason why I'm bringing this up
is because the image function--
I switched from ellipse to image,
but it would be almost a better example
if I were switching from rectangle, which requires an x,
a y, a width, and a height.
If I were switching from rectangle
to image, which also requires an x, a y, a width, and a height,
the only difference is fill that rectangle with the pixels
from some actual image, like flower.
So this is really what's going on.
So I can manipulate the size and that sort of thing.
I'm not going to worry about that too much.
And I'm just going to leave it--
I'm going to just simplify this example.
But let's just show it to you with r in there.
You can see now they're all different sizes.
I'll leave that in there.
Why not?
All right, so now what if what I want to do is click on these
and have them change--
transform from a beautiful flower to a butterfly?
Because we all know butter flowers transform--
OK.
I have kittens-- to a kitten!
All I have are kittens!
So I do have this clicked function.
It changes the brightness.
Let's just first make this work.
Let's back up a second.
And what I want to do now is I want
to instead of having each image be the-- each bubble object
be the same image, I want to pick up an image of a kitten.
So I'm now going to add an array called kittens.
And what I'm going to do is in preload I'm going to say
kittens index 0 equals loadImage kittens/kittens0.jpg.
So you can see here I could do this.
And I have five of them.
So here's the thing, this is pretty horrible.
What I want to be able to do is if I have
a whole bunch of images and they're
named in some consistent way, what I actually want to do is,
could I write a loop to load all of these?
So instead of having three images
loaded into an array 0, 1, and 2, could I write a loop?
And one thing that's interesting is
I can do this very easily with something
called string concatenation.
Nice excuse to bring that up in here.
So as you might know, 2 plus 2 equals 4.
However, A plus B equals the string AB, or cow plus bell
equals cowbell.
So when you use the plus operator with text,
it joins the text rather than the plus operator
with numbers adding the numbers.
And the reason why this is so useful is what I can do here
is I can write a loop for let I equals 0. i is less than--
how many kitten images do I have?
I think I had five.
I can see them here.
0, 1, 2, 3, 4.
I had 5-- 5 i plus plus.
Then I can just take this line of code, put it here,
and I can say kittens index i equals loadImage kitten.
Now I don't want to load the 0 kitten into each one.
Although I could do that now for just testing.
But I'm going to keep moving on.
I want to load this plus-- oh, and there's
a new way to do this.
[LAUGHS] There's a new way to do this ES6.
I'll come back to that at the end of this video
if you're interested.
This is a bold way that I--
I could add the i in between.
I can say take this string, kittens/kitten,
join it with the value of i, which is 0, 1, 2, 3, 4,
and then add .jpg to the end.
And that will load all of those image files into kittens.
Now let's just make sure this works
by going down here and saying something like kittens index 0.
That's kittens0.
Let's take a look at kittens index 3.
That's kittens index 3.
Look at that little kitten.
That little kitten.
OK, so now how do I have each object
have a reference to a different kitten?
Very important.
So one thing that I think that I want to have--
I'm going to get rid of this brightness thing.
This brightness was from a previous example.
What I want to do is have an image associated
with each bubble object.
So why not say this.img equals--
or this.kitten equals what-- img.
So when I make a bubble, I want to say I want a bubble
to be at this x location and this y location with this size,
and I want it to use this particular image.
So what that means is I need to now up here--
I need to pick one of these images.
Now let's say I want to pick a random one.
The nice thing is if you have an array in p5,
I can just say kitten equals random kittens.
This random function-- if I give the random function array,
it will pull out a random element
from that array, which is one of those random kitten images,
and put it in this variable.
And then I can pass that in.
So this is me picking a random image,
then passing it into the object, and then the object
receiving it and putting it in as a property.
And then what's the last step?
I need to make sure I draw that particular kitten image.
All right, let's see what we got here.
Yay, look!
Lots of random-- now it's hard to see them
because they're so small.
So let's make these kittens bigger.
There we go.
So you can see you have a bunch of kitten objects.
And I could-- I do the thing where I click,
and I add new ones or I delete them.
But let's have all of these kittens every time
I click change to a new kitten.
[LAUGHS]
So we already had this whole clicked function.
And I'm saying if d is less than this.r,
why not just say this dot image--
this.kitten is a new random kitten?
So we can see I could always at any moment
pick a new image to store into that bubble object's image
variable.
And so now-- oh, and this is bad though.
This is for checking--
this is math that I had leftover from before is
checking to see if the mouse clicks inside of a circle.
And since the image is actually a rectangle, why don't we
make those back to flowers?
Because the nice thing about the flower is it
was kind of like circular thing inside.
Whatever.
But I could change this code.
I could change this code to say if px is greater than this.x.
And px is less than this.x plus this.r.
And py is greater than this.y.
And py is less than this.y plus this.r.
What is all this crazy mumbo jumbo that I just put in there?
What I'm trying to do is I'm trying to say,
hey, there is a point.
It's clicked.
Is it in between this x?
Well, you can't see that-- this x.
And this location is x plus r, and the y is between this y,
and this location is y plus r.
So I'm checking to see if the x and y of the mouse
is within those boundaries.
And once I've done that, we should--
yay, look!
I can just keep making different kittens.
Yay!
It's not a square.
It is a square.
It's not a square.
I don't know.
So I've done something goofy here where I'm just--
you can clean this up and try it different ways.
And what if I make it a flower?
And is a circle better to check?
Maybe I could just change it when I click to flower.
So these kittens are changing into flowers
when I click on them.
And then if I click on them again,
oh, they still are a flower.
So you can see the range of possibilities.
You can also make the argument here
that maybe this whole picking the random kitten here
and passing it in was kind of unnecessary.
Because what I could have just done is right down in here
I could just picked the random thing in the constructor,
and that's also the same thing.
So there's lots of different ways
of organizing the code depending on what you're trying to do.
And generally speaking, I don't love the fact
that I'm using flower here or kittens here,
because these are variables that exist
outside the scope of the class.
And the class, if it's going to know about things outside
of its scope, should probably receive them
as parameters to a function.
But that's neither here or there.
It's worked.
Wait, there's a bonus here at the end of this video!
I don't know why I'm looking around as
if someone's going to catch me.
I forgot, I should probably make a video just about this.
But while we're here, there's also a new way.
Look at this.
And I was told, by the way--
I was just given some nice advice about I shouldn't really
be using the word join because that's kind of using another--
but this is string concatenation.
kittens/kitten plus concatenate with the value of i plus
the concatenate with .jpg.
But there's a new way to create strings from actual characters
and variables in JavaScript, and it's something
called template literals.
And this is in lots of other languages,
but this is a new way to do it in JavaScript.
And it involves the use of the back-tick.
So if I put back-tick here and back-tick here,
get rid of this, get rid of this--
now I don't want the pluses anymore,
so this is just like a string.
It's a literal string.
Ah, it's literal!
This is a literal string, kittens/kitten.jpg.
But if I want to use a variable in there--
well, we're calling this the template literal,
I can put a variable in there with curly brackets and dollar
sign and then the name of that variable.
Hopefully, I'm getting this right.
So this is a way of saying, hey, I
want to have this string instead of having
to use plus for joining-- and the nice thing about this,
I'm pretty sure it lets you do this over multiple lines
too, which is really, really nice.
Because with regular quotes, you can't have multiple lines--
line breaks.
So this should work exactly the same way--
template literal.
Ahh!
So close!
What did I get wrong?
[SAD TROMBONE SOUND]
I made a mistake.
Because, by the way, I don't actually know what
I'm doing at all.
It looks like this.
The dollar sign-- ah, I knew I should have syntax highlighted
that in some way!
The dollar sign is an indication like, hold on a second,
I'm going to use a template literal.
And so now I'm saying what's inside
of here is the variable name.
And we can see the syntax highlighting
fixed, which is good.
There we go.
Now this is working, and it's the same exact program.
I should mention, well, what if I really wanted to have--
so one thing, if I just had dollar sign in the string,
it's not going to think it's part of this
unless the curly brackets are there.
And so if I really wanted it to be this,
I could probably use an escape sequence or something.
But it's pretty rare that you're actually
going to want to have this sequence of characters
in your string.
OK, so that's a little extra bonus
piece at the end of this video.
Maybe I'll make a special video just
all about the wonder of template literals,
because that's what I'm sure everybody on the internet
wants to watch.
And I'll see you in the future.
[MUSIC PLAYING]
[BELL RINGING]