Hello.
Are you just sitting at home wondering,
when could I possibly watch another video about bubbles?
Well today's your lucky day.
This is another video about bubbles.
And in this video, what I want to look at specifically
is, how can I-- if I have a bubble object like this, bubble
one, and I have another bubble object like this, bubble two,
how can these objects talk to each other?
Communicate to each other?
How can they ask each other questions,
like, am I intersecting you or am I overlapping you?
How close are you from me?
These types of things.
And you can imagine all of the implications and possibilities
of this.
Now, on the one hand, to do this, all we need to do
is figure out some math, right?
And that math is, what is the math
of two circles that are overlapping versus two circles
that aren't overlapping.
That math is quite simple in some ways.
I just want to look at the distance
between the centers of both of those circles, right?
And you can see here that that distance
is going to tell us whether they're
overlapping or not, right?
So one way that I could think about it, look at this.
If this is r1 and this is r2--
this is the radius of this circle,
this is the radius of this circle.
If this distance-- that's also, this is r2 right here
and this is r1 right here.
If that distance is greater than r1 plus r2, then certainly,
the circles are not overlapping.
However, if that distance is less
than the sum of the radii of these two circles,
then they are overlapping.
So on the one hand, this is all I need to do.
I need to be able to say, give me the distance--
can you see that?
Just barely on the top.
Of between x1, y1, x2, y2, and then
I need some sort of if statement to see,
is this distance less than r1 plus r2?
Then they are intersecting.
So let's actually go and start to implement
that math in the code first, but what I want you to think about,
is there a way for the objects themselves
to handle the computation of that math rather than that math
just be fiddling about in the code somewhere,
perhaps less convenient.
So come back over here with me and let's go over here.
And so I'm continuing from where I left off.
This is essentially the same Bubble class that's
been in my previous videos.
And I'm just going to make two objects.
I'm going to say bubble1 and bubble2.
The E key on my keyboard doesn't work.
It only works about 40% of the time,
if you notice me pressing it a bunch of times.
So then what I'm going to do is I'm going to say,
bubble1 equals a new bubble at 200--
I'm going to put one on the left side of the screen--
and one on the 300.
200 on the right side of the screen.
And then I'm going to say bubble1.show and bubble2.show.
And that's bubble1 and bubble2.
So now, when I go to my sketch, I should hit Refresh.
I don't see any bubbles.
Let's look here.
Bubble1.
Oh, look at this.
I forgot.
The bubble has a r property for its radius
and I did not define that.
Here's an interesting thing, as if I'm just
coming up with this right now.
One of the features of ES6, which
is the version of JavaScript that we're
using that allows us to write classes to make objects from,
allows us to give a default value to a particular argument
if we forget to pass it in.
So this parameter here, r, which is
going to be assigned to the bubble object's r property,
I can actually say r equals 50 right up here,
and then if I refresh it, look.
I have two bubble objects.
They seem to be sort of a weird--
oh, I meant for this one to be at 400, not that that really
matters.
So you can see those are two bubble objects.
And I could optionally give one of them--
if I don't want to use that default value for r,
I could give it a value.
So this is actually incredibly convenient.
Little piece of syntax here that if you're
going to have a parameter to a function-- and this
is not just for the constructor.
You can do this for any function,
although it's quite convenient to do it
with constructor functions.
And I want to give it a default value.
So that's a little tidbit there for you
inside this video, which is about the objects intersecting.
OK, so now, let's move them around.
Bubble1.move, bubble2.move.
Let's move them around just to see.
OK.
So what I want-- come on.
Come on, bubbles.
So we're going to have to do some work here
to get those bubbles to get a little closer to each other.
All right, so what I want to do now is I want to go back
and let's-- oh, you can't really.
I did end up going above, but this is fine.
You can see that.
I'll be better about this in the future.
So I want to try to implement this math.
For example, what if I want to say, right here in draw,
I can say, all right, I need to find the distance
between bubble1.x, bubble1.y.
These are the properties-- the x and y of that bubble.
And bubble2.x and bubble2.y.
Oh, and this should say d.
And then I want to say, if d is less than what?
If it's less than bubble1.r plus bubble2.r, then--
and let's put all--
I'm going to do something silly here.
Let's put all of this over here and I can say, bubble1.--
no, no, I'm just going to say, like, background 200, 0, 100.
OK?
So this is the idea of, like, ah,
now I have the math for intersection.
I know I need to find the distance between those two
bubble objects.
What's the distance between these two bubble objects?
If it's less than the sum of their two radii,
then it's intersecting.
OK, so let's run this.
You can do it, bubble.
Be together, bubbles.
Be together.
OK, I'm just going to have to force it.
Let's bring them a little bit closer.
[DRUMROLL]
Ah, there you go.
Now move apart, bubbles.
So one thing I could do is I could just assign--
that was a terrible idea.
I could just assign the bubble location to the mouse
or something, and then I could move it
and you would be able to see-- but the bubbles,
they're going to move apart eventually.
Come on, move apart.
Move apart.
Oh, it's close.
I think you saw the background flick.
OK.
So you get that this works.
And there we go.
I've got to be a little bit more thoughtful about the sort
of intersection thing.
Now here's the thing.
I don't like this at all.
I don't like this one bit because the idea here
is, eventually, what if I have three bubbles or four bubbles
or 10 bubbles or 100 bubbles?
I need some way that I really just want to say,
if any given bubble, let's say b1.intersects b2.
I want to be able to write code like this.
I want to be able to encapsulate all the idea of this math
into a function in the bubble object.
So bubbles know how to communicate with each other
and how to test one bubble's location
versus another bubble's location.
So if I come back over here, what I mean is,
I want to say something like, if bubble1.intersects bubble2,
then do this.
OK?
So this is the idea because then I
could start having a raise of things and loops
and check every bubble and it's just
going to be more convenient than having this math sort of out
here where it doesn't really need to be.
So let's take a look at how we might do this.
So what this means to me is, I need
to write a new function that's part of the Bubble class called
intersects.
So that's pretty easy.
I could just do that.
Done.
That function, by the way, because of the way that I wrote
it here inside this if statement,
the idea is that function is going
to return true or return false.
So right now, just to have this do something,
I could just say return true right here.
And the idea here is that, OK, well the intersects function
is a function that's called on one bubble
and receives as an argument another bubble.
So I need to give it an argument here,
and I can call that other, for example.
So now, if I comment out this math and I run this,
it looks like it's working.
But of course, if I move their locations away,
it's always drawing that pinkish background
because my function always returns true.
So one thing you can kind of see from this
is, it's often worth kind of writing
the skeleton of your code and then just,
like, hard-coding in true or false
and see if it's working as, ah, false, I don't see it.
True, I do see it.
Now I could actually go and fill in the math in that part.
So what I'm going to do is I'm going
to grab this math that I had before
and I'm going to bring it down here
and things are going to get a little bit easier.
I still want to calculate the distance,
but what do I want to calculate it between?
I want to calculate it between the bubble that I am right now.
What is the bubble that I am right now?
This.
This bubble with what?
The other bubble.
The other bubble that you have so
generously passed in as an argument to my parameter
named other.
Other, other.
And then, if that distance is less
than my radius and the other radius, then and only then
would I return true.
And don't worry, I'm going to show
you something that's going to make this nicer in a minute
because many of you are complaining right now,
the way I'm writing this.
And we can see, now, this bubble class has a function called
intersects which can receive any other bubble
and always check if the current bubble is intersecting
the other bubble.
So here we go, I'm going to do this.
They're not intersecting.
Let's hack something to make our lives a little easier.
Instead of moving bubble2, I'm just going to say,
bubble2.x equals mouseX and bubble2.y equals mouseY.
OK?
Now of course I could write a function
to have it follow the mouse or set the mouse or whatever,
but I'm just going to throw this in there
really quickly so that I can do this
and I can do-- woo, intersects, doesn't intersect.
OK.
So now, let's take a look at one thing which
I want to change here, which is that I
am a weird, strange person and I really
like the way I wrote this.
It just says it all.
I know I have an if statement, and I know when it's true,
I want to return true, and when it's false,
I want to return false.
And I've said all that and I said it
in like five lines of code here.
But the truth of the matter is, this is a statement,
distance is less than this.r plus other.r.
That whole statement evaluates to true or false.
When it evaluates to true, I want it to return true.
When it evaluates to false, I want it to return false.
So this can actually be condensed into just--
whoops.
Oh, autofill.
Return the result of this Boolean.
Right?
I could just say, does that return
the truth of this statement, true or false,
and this will in fact be the same exact result. Yay.
Oh, this is the end of this video.
So what have I done here?
What might you want to do?
Now here's the thing.
Ah, let me show you one other thing.
Let's ask a question.
I'm going to ask a very important question here.
If I were to say, if bubble2 intersects bubble1, have I
changed anything?
Program still works.
This is exactly the same program.
So in this case, I am writing sort of a function.
You could maybe make the argument that you want, like,
a BubbleManager class and the BubbleManager class
has an intersects function that takes two bubbles.
So the point is, there's always other ways
to organize your code, and you have to watch out for, like,
over-engineering your system, but this
is one way of doing it.
It's the way that I kind of like to do it.
Later, you might see in other videos or tutorials
that I make where I have--
instead of just all bubbles, I have frogs and turtles and fish
and kitty cats, and maybe the frogs
have to check their location relative to the kitty cats
but the kitty cats have to check their location
relative to the turtles.
So having the different objects act
on different kinds of objects is also something that comes up.
But what I'm going to do in the next video
is, how do I go from this idea to suddenly have
a system of like 100 bubbles?
And I'm checking if every single one
is intersecting any other one.
And what happens when we do that?
So I am going to do that in the next video.
You might actually just give that a try yourself
and then see how it goes and watch the next video.
OK, thanks for watching.
[MUSIC PLAYING]