[MUSIC PLAYING]
SPEAKER: Welcome back, everyone, to an introduction
to Programming with Scratch.
And at this point, we've seen many of the major features of Scratch,
how we can use loops and variables and conditions
to put together some interesting projects.
So today, let's take a step back, think about how we might use these blocks
inside of our projects, and how we might be able to improve upon the way
that we've designed the blocks inside of our Scratch projects.
So let's start with a sample application or project
that we might want to create.
Let's open up Scratch.
And let's say I want to make a game that involves the dinosaur
and moving the dinosaur around, for example.
So to do that, I'll start by getting rid of the cat and adding a new sprite.
I'll go ahead and find the dinosaur.
And we'll bring the dinosaur into our Scratch project.
And I'd like to be able to control the dinosaur by moving the arrow keys.
And so to do that, I'll need to respond to various different events.
I can use the when Up Arrow key is pressed, for example.
And then have the dinosaur respond by changing its y-value--
the up and down value-- by 10, for example.
And then I'll do similar things for the other arrow keys.
I'll add one for the Down Arrow key.
And when the Down Arrow key is pressed, let's
go ahead and change the y-value by negative 10 to move the dinosaur down.
Let's add one event for the Right Arrow key.
When the Right Arrow key is pressed, instead of changing y,
we'll instead change x, which is the left or right value for the dinosaur.
And then finally, we'll also allow the dinosaur
to respond to when the Left Arrow key is pressed.
At which point, we'll also change x.
But instead of positive 10, it's going to be negative 10.
And we've seen blocks like this before.
And what they allow the dinosaur to do is respond
to me pressing keys on the keyboard.
If I press the Right Arrow, the dinosaur moves right.
If I press the Left Arrow, the dinosaur moves left.
If I press Up, the dinosaur moves up.
And if I press Down, the dinosaur moves down.
But let's not give this game away to win,
some way that we can-- goal that we can try to accomplish.
And I'll add a new sprite.
And let's look through the sprites and see what might make sense here.
I'm going to go with the star.
So here's the star sprite.
And I would like the dinosaur to try to chase after the star
as by moving around using the arrow keys.
And maybe once the dinosaur is touching the star,
well, then we'll say that we've won the game.
And there are multiple ways that I could go about doing this.
But here's one way.
I could say that every time I move--
every time I change y by some amount or change x by some amount, let's go ahead
and check to see if we're touching the star.
So for example, when the Up Arrow is pressed, we change the y by 10.
But we've now moved the dinosaur, so we better now
check to see if the dinosaur is touching the star.
So what can I do?
I could go into control here and ask a question with IF.
And I'll move these other scripts out of the way for now
just by dragging them around.
And what I'd like to check for is if the dinosaur is touching the star.
Touching, that's under Sensing.
And here is a touching block that I'll drag out and change
mouse pointer to star.
So now, when I press the Up Arrow, y will change by 10,
and then the dinosaur will check to see if it's touching the star.
And if it is, let's go ahead and let the dinosaur report
how long it took to find the star.
So maybe it's going to say something.
And it's going to say the timer.
The timer under Sensing [INAUDIBLE] is just how many
seconds has it been since we started this program.
So we'll go ahead and start my project.
And I'll press the green flag.
I'll move the dinosaur to the right.
And then move the dinosaur up.
And notice that as soon as it's touching the star, it reports.
It's been 4.82 seconds.
And that's how long it took the dinosaur to find the star.
Now, this doesn't work perfectly all the time.
I can try this again, for example.
Press the flag.
This time if I move up first-- move all the way up, and now
start moving to the right, well, I'm touching the star,
but no time was reported.
Why not?
Well, if you notice, we can take a look at the blocks
that I have inside of this project.
My condition-- this condition here, if we're touching the star,
then say the timer for two seconds--
it appears here when the Up Arrow key is pressed.
But really, I should be checking this all the time, whenever I move.
Whether I'm moving to the right or to the left or moving down.
Every time the dinosaur moves, I would like
for the dinosaur to check to see if the dinosaur is touching the star.
So what I'm going to need to do to make this project work is
take this same condition, if we're touching the star,
say the time say the timer.
And I'll have to include that in each of the other scripts in my project
as well.
That way it's going to check regardless of what key on the keyboard
the person playing the game is actually pressing.
And so I could add this to the Down Arrow, for example.
And the way that I would do that is by adding a condition and saying,
if we are touching the star, then go ahead
and say the timer for two seconds.
And that took a fair bit of time.
So you might also know that you can duplicate some of the blocks instead.
Since these are really just the same blocks, I can just copy them again.
To get them to work for Left Arrow, I'll go ahead
and Control or Right Click on the IF block and just say Duplicate.
I want to copy this whole section.
And I'll drag it underneath the Left Arrow.
And I'll do that one more time for the Right Arrow.
Duplicate, drag it underneath Right Arrow.
And now, regardless of which Arrow key is pressed,
whether it's Up or Down or Left or Right,
we're still going to be able to check if we're touching the star.
And just to make things a little more interesting,
let's add some code to the star too.
Let's say when I press the green flag to start the program,
let's have the star go to a random position.
Just so that it chooses somewhere on the stage to go to
so that the game is a little bit different every time.
Now I press the flag.
The program started.
You see the star moved a little bit.
And now I can use the arrows to try and make my way to the star.
And once I get to the star, you'll notice that the dinosaur reported
to me how long it took.
In this case, it was 9.70 seconds.
And 9.70, that's very precise.
Maybe I decide a little bit later, I'd like
to improve upon this program a little bit.
And what I'd really like to do is I would like to not say 9.70,
just rounded to 10 seconds.
Round to the nearest number of seconds.
And we've seen before, there's a block under Operators
called Round that can round a number to the nearest whole number.
And so that might be what I would want to do here.
And what would I have to change in this project to get that to work?
Well, I'd have to add Round to this say block and to this say block
and to this say block, and the one down below too.
I'd have to add it to all four directions.
Because effectively, I've copied myself again and again and again and again.
And whenever you find yourself copying a lot of code in your project
multiple times, oftentimes, that's an indication
that there might be a better way to try to solve that problem.
And in this case, there is.
And what we can do is create an entirely new block of our own.
Instead of repeat all of these--
this combination of multiple blocks, the IF and the touching
and the say and the timer and repeating that set of blocks multiple times,
I'm going to write the set of blocks once.
And then just refer back to that collection of blocks by a name
that I choose.
And I'll show you exactly what I mean by that right now.
We're going to look at a new section of the Scratch interface,
which is here called My Blocks.
And this is a place where you can create blocks of your own.
Scratch has blocks that say something, that change the y-value of the x-value
by something.
But we can create a new block, if we would like to.
And I can click Make a Block to make a new block.
And I have to give the block a name.
And I'll call the block Check If Won, because that's
what I want the block to do.
I would like the block to just take care of checking
if the dinosaur has won the game.
Meaning checking if we're touching the star.
And if so, go ahead and report how long it took.
So I've defined this Check If Won block.
And what you'll notice here, up at the top of my screen,
I now have a block that says, define check if one.
Everything beneath this block now are going
to be the blocks that run every time I want
to check if won-- every time I want to check if the dinosaur has won the game.
So what should I do?
Well, I'll take this same condition, if touching star,
then say the timer for two seconds.
And I'm going to put that underneath this definition for check if won.
What does it mean to check if the dinosaurs won the game?
Well, it means check if the dinosaur is touching the star then
say the timer for two seconds.
And now, underneath this event here, when the Up Arrow key
is pressed, rather than change y by 10 and then
this complicated condition with multiple blocks that I had to put together,
I can just change y by 10.
And then drag out this new block that I created and I
picked a name for called check if won.
So the logic for that script now, when the upper deck is pressed,
is much simpler.
It's only two blocks.
Change y by 10.
And then check if won.
And what does it mean to check if won?
Well, I defined what that means up here.
The definition of the check if one block-- what
should happen when I run that block, is we
want to check if we're touching the star then say the timer for two seconds.
And now, I can do the same thing for all of the other scripts as well.
Replace this complicated condition with four different blocks
that I've put together.
And instead, just use a single block, the Check If Won block.
So I'm going to delete this condition and just replace it with this one Check
If Won block.
And I'll do the same for the Left Arrow, getting rid of the condition,
adding back Check If Won.
And the same for the Right Arrow, getting rid of the condition,
cutting back Check If Won.
And now the logic for these arrow keys is much simpler to read
and it's organized more nicely into just a single block, Check If Won.
And the program will behave the same way.
I can try again.
I can still move the arrow keys around.
And the dinosaur will still report to me when it's touching the star.
But I'm not repeating myself as much.
So I'm using fewer blocks and being more efficient about my use of blocks.
And it's also now easier for me to modify the behavior of this program
too.
If instead of saying the timer, I would now like around the timer--
as I talked about wanting to do--
instead of needing to add round to four different places for four
different arrow keys, I can just change it in one place.
I can say, OK, let's go to Operators.
Let's take this Round operator and let's around the timer for two seconds.
And since I've modified what it means to check if won,
now all of these other arrow keys that use the Check If Won block
will be taking advantage of this updated definition of what it
means to check if we've won the game.
Press the green flag.
We'll start the game.
I'll move the dinosaur around.
And once I'm touching the star, you'll see that it now reports a number.
But it's been rounded to the nearest integer.
We're now just say six seconds instead of like 6.28 seconds or something
like that, for example.
So the ability to create your own block opens up a lot of doors
for trying to improve the overall design and the overall readability
of your project as well.
And I'll give you another example of that.
Let's delete the dinosaur and the star and bring back our familiar balloon
that we've been inflating and deflating a couple of times
throughout this course.
And so let's try now to inflate and then deflate the balloon.
I'll say, when the flag is clicked, what should the balloon do?
Well, let's start by giving the balloon a size of 50%.
Start it at half size.
And then what I would like for the balloon
to do in order to inflate itself is to repeatedly change its size.
Increase the size by 10, increase the size by 10 again.
And repeat that a couple of times.
So here is change size by 10.
But if I wanted to repeat that process a number of times,
then I would go under Control and say, repeat 10 times.
That seems reasonable.
Let's repeat 10 times and change size by 10.
So now, when I press the green flag, you'll
see the balloon starts at 50% size, and then it grows--
it inflates very quickly up to full size.
And now just for fun, let's go backwards.
Let's deflate the balloon.
We'll have our balloon wait one second.
And then I want to deflate it-- decrease its size, which I can
do by changing its size by negative 10.
And I'll have to repeat that as well.
I'll repeat that 10 times by going into Control, repeat 10 times,
change the size by negative 10.
So now, watch what happens when I run this balloon.
It inflates, waits a second, and then it deflates.
It goes back down to 50% size.
I'll run it again.
It inflates, it waits a second, and it deflates.
And this works.
This certainly achieves the effect that I
want of increasing the size of the balloon,
waiting, and then deflating it.
But it might be a little bit hard for someone to read.
If I just showed this code to someone and ask them, what does it do,
you'd have to pay very careful attention.
We're starting to size at 50%.
We're repeating 10 times, changing the size by 10 each time.
So that's 10 times 10.
We're increasing the size by 100, waiting a second,
and then doing it in reverse.
You'd have to do a lot of processing, thinking
about what are the numbers, what are the loops doing,
how many times is everything happening, just to get
a sense for what the project is doing.
It's not necessarily wrong, but we might be
able to make it a little bit easier to read as by creating some new blocks.
These blocks right here, ultimately, the changing size by 10 over and over
again, what they're doing is they're inflating the balloon.
But of course, Scratch doesn't have a block
called inflate to increase the size of the balloon 10 times.
But we could create it.
We could add a new block called Inflate that does exactly that.
So let's try it.
I'll go into my blocks.
I'll create a new block.
And I'll call it Inflate.
And the definition of inflation will be this loop right here, repeat 10 times
and change the size by 10.
And let me create another new block called Deflate.
And the definition of deflate will be the opposite, repeat 10 times,
change the size by negative 10.
And now, instead of using these repeat and change
size by blocks inside of this script here,
I'll just drag out my new blocks-- my Inflate block and my Deflate block.
And now, first, notice that this program does exactly the same thing.
The balloon increases in size, waits a second, and then decreases.
But look how much easier to read this code now it
is, especially right underneath this when flag clicked.
I've simplified the logic by making it easier
to read by taking advantage of these custom blocks, which we can now
call abstractions.
Abstraction is all about taking things that look very different or that are
in different parts of your program-- like I had that IF condition in four
different places in my program--
and realizing that they're all just the same idea that I could give a name to.
And here, I can give a name to inflate and deflate.
And now just refer to those actions by their name.
So when the flag is clicked, we're going to set the size to 50%.
We're going to inflate the balloon, wait one second, and deflate the balloon.
You can just read exactly what it is that this project should do.
And if in other places inside of my project
I later wanted to inflate or deflate the balloon, I could do that too.
I could add other blocks and other scripts
and just use inflate and deflate multiple times,
rather than need to repeat myself by saying repeat 10 times,
change size by 10 every time that I wanted to inflate the balloon.
So these blocks really helped to organize your code,
help to reduce repetition and help make it clearer to someone
reading the code what it is the code is doing.
Now one thing is true, that these blocks are always
going to do the same thing every time.
They're always going to repeat 10 times and change the size
by 10, which will have the effect of increasing
the overall size of the balloon by 100, 10 times 10.
But maybe I'd like a little bit more control.
Maybe sometimes I just want to inflate the balloon a little bit,
and other times I would like to inflate the balloon a little bit more
or a little bit less.
So how could I do that?
Well, let's go ahead and Control Click or Right Click on the Inflate block
and now edit it.
You'll notice that I've named the block.
And I could change the name of the block now if I wanted to.
But when you make a block or when you edit the block,
you also have the ability to add input to that block as well.
This block is now a function.
And we've discussed before that functions
can accept inputs, information that tells that function how to behave.
And so here, for example, I could add an input that would just be some number.
I'll call that number n, for example, which
is just a convention for some number and for number.
And let's add a label.
We're going to inflate n times.
This is just words that will describe what
it is the block is now going to do.
And now I'll press, OK.
And what you'll notice now is that the Inflate block is now changed.
It's now Inflate and then a blank value times.
And that blank volume looks much like the blink value and change size
by or move some number of steps, for example.
This is now a place where I can provide input into this function
to tell it how to behave.
And you'll notice now that under Define Inflate,
it doesn't just say Define Inflate, but Define Inflate n times,
where I have access to this block here called n.
So what I'm going to do is take n and drag it inside of this repeat.
Instead of repeating 10 times every time, let's repeat n times every time.
Whatever n is, where n is going to be the input to this function.
And I'll do the same thing with Deflate.
I'll edit it.
And it will be deflate n and then add a label times.
And I'll say, OK to that.
And now instead of repeating 10 times and deflate,
let's repeat n times as well.
Now these functions have the ability to take some input.
And you'll notice down below under the Inflate block,
I need to type a number into this space.
So I can say inflate 10 times and then deflate 10 times.
And now, if I run the project, it works the same way.
It inflates and then it deflates.
But if I just change these inputs, inflate 20 times and deflate 20 times,
well, now the project's going to behave differently.
Inflate and deflate.
It gets much bigger and then much smaller,
because I'm inflating and deflating it more often.
And then I'll change these back to 10 for now
so we go back to the usual behavior.
Inflate and then deflate.
But I could use these blocks in other places too.
I could say, for example, that any time I
click on the balloon, when this sprite clicked, well, let's
like clicking inflate the balloon two times.
So not 10, a little bit fewer.
So I press the flag and it inflates a lot.
Inflates by 10 and then deflates.
But every time I click on the balloon, it's just going to inflate by a little.
It's going to inflate two times.
And we were able to achieve all of that just
by giving our functions some inputs.
We defined and inflate block, gave it an input n,
and then use that n inside of the definition of the block.
When we run the block, we're going to look at what is the value of n.
And that's going to tell us how many times to repeat, such
that now when we use that block, I can decide how much to inflate
the balloon by just by saying, well, in this case,
I want to inflate it 10 times.
But down here, I only want to inflate it two times for example.
So you can make your blocks very customizable, very flexible as well.
And these blocks don't just need to take one input.
They could also take multiple inputs as well.
So let's see an example of that.
Let's go back to our bear, which we've had around before.
And you might recall that before, we've had a walk
in a couple of different costumes.
If you go to Costumes, you see that we have this costume where
the bear is on four legs.
And I'll go ahead and call that costume 4.
And here, the bear is on two legs.
And I'll rename that costume--
up in the name section, I'll call it 2.
So I have a costume called 4 and a costume called 2.
I just renamed those two default costumes.
But now let me make a new block.
And here's what we'll call this block.
The block will be Walk.
Then I'll add an input, which will be a number.
And I'm going to call it m for now.
You can call this whatever you want.
This is just a name of an input.
And it's going to be a Walk m, and then I'll add some next, steps.
And then I'm going to say, on, and then I'm going to add a second input--
a second input that I'll call n.
And then I'll add some text, feet.
So I added two inputs and two additional labels.
But this block is now called Walk m Steps on n Feet.
So what this is going to do is it's going
to control how far the bear is going to walk on a certain number of feet.
So what do I do about the number of feet?
Well, that's a costume.
There's a costume for four feet and a costume for two feet.
So let's switch the costume to m or n.
Well, n is the number of feet, and that's the costume.
So n is going to go here.
We're going to switch to the costume to n, representing how many feet should
the bear now be walking on.
And now let's walk m steps.
Well, I can walk one step just by saying, move one step.
And if I want to do that multiple times, I can put that in a repeat block.
So let's go under Control and repeat the process of moving one step.
But instead of repeating 10 times every time, let's instead repeat m times.
So this then is our definition of what does it mean
for the bear to walk m steps on n feet.
We first switched the costume to n, where is the number of feet.
n is either going to be four or two to determine
which costume we should switch to.
And then we're walking m steps.
So let's repeat m times this move one step block.
We've organized the logic for what it means for the bear
to walk on a certain number of feet.
And now I can use that block inside of my project.
I can say that whenever the flag is clicked, what should the bear do?
Well, let's first have the block--
or have the bear walk 30 steps on four feet
and then walk 30 more steps on two feet.
So it's going to start on four feet, walk for 30 steps, then go to two feet,
walk 30 steps.
And we can watch what happens.
I'll press the flag.
It walks on four feet, and then on two.
I'll try it again and it does the same thing.
And this code right underneath the When Flag Clicked is now very easy to read.
I can very easily see exactly what the bear is going to do.
And it might have been harder to see that if I
was using all of these every single time,
switch costume and repeat this movement process.
And I can use this block now multiple times,
as I have here, to avoid repeating myself as well.
So Scratch offers a number of different blocks
that you can use to achieve a variety of different things inside
of your project.
But we now have the ability to add our own blocks.
If there's additional behavior that we want our sprites
to have inside of our Scratch projects, we
can create our own blocks to define some custom behaviors that we can use inside
of our project to make them more complex,
more interesting, and ultimately, better organized and more exciting as well.
That's it for an introduction to Programming with Scratch for today.
We'll see you next time.