Hello fellow Scratchers, have your levels been feeling rather bereft of life? Well it’s time to
liven things up as we add adorable, yet temptingly squishable enemies into our platformer!
I’m griffpatch, and welcome back to part 8 of our series
on “creating a tiled scrolling platformer in Scratch”.
Before diving in to the code, for those at the cutting edge, following the tutorial
as it is shared, you may not have the Enemy sprite & costumes in your project.
Well, do not fear, I have updated my starter project on my griffpatch_tutor account
with the new sprite, and there is of course a link to it under this video. If I just jump there now,
you can see the new “Enemy” sprite here contains a whole raft of exciting Mario enemy costumes,
so drag the whole sprite into your backpack and then we are ready to begin!
So, open your project from where we left off in episode 7, and drag the Enemy sprite out of
the backpack into the sprite panel. I’m going to re-order it to be the 3rd sprite. Now if you are
creating the sprite yourself then that’s fine too, it only contains costumes after all.
In this episode we are going to create the classic Mario enemy, Goomba.
He’ll need to be able to fall, and move around, colliding with our tiles level. Click into the
Mario sprite. We put a lot of time into making these scripts, and we certainly don’t want to have
to do that all over that for Goomba. Luckily many of our scripts are perfectly reusable!
For those lucky enough to have my scratch bowser extension installed you can use the find bar
to locate the scripts (there’s a link under the video), but otherwise let’s find them by hand.
Firstly, we want the “define get tile at xy” script.
This is key to detecting collisions, so drag it carefully until your mouse cursor is directly
over the Enemy sprite and drop it there. Next find the “define fix collision at point”
script. We’ll drag that over too, again being careful to let go directly over the enemy sprite
(it can be tricky to see behind these huge scripts)
Then we want the “define fix collision in direction” script.
Man I’m glad we can reuse all of these! Lastly we want the “define move sprite x” script,
and the “define more sprite y” scripts. Awesome, that covers
a lot of the required sprite movement. So, let’s click back into the Enemy sprite
and observe the dogs dinner scratch has made of laying out our copied scripts… Not the best,
so right click the scripting area and Clean up our blocks – There, at least they are now readable.
I’ll just check they are all here, we have the get tile at xy, fix collision at point,
fix collision in direction, move sprite x & move sprite y – that’s all of them,
great. And look, it’s worth noting Scratch has kindly recreated all the variables that
were used by these scripts specific to Mario, that’s going to be very hand.
So, we can get right down to business – We intend to have many enemies on a level
all at the same time, so we of course will be using clones. We therefore have to set things
up with that in mind. When Green Flag clicked,
set size to 200 (as we have been doing throughout), and then hide this sprite.
This original sprite will be a dummy sprite from which all other clones will be made.
Now to identify this dummy sprite, and what sort of enemy each other clone is,
Make a new variable named “type” for this sprite only, and set it to the empty value.
That indicates that this is the dummy enemy. We’ll also set both speed x, & speed y to 0.
Now looking ahead, to position Goomba on the screen we’ll need a new custom block
named “paint sprite” run without screen refresh. We code this in the usual way
by first switching the costume to “BIG” to allow it to move offscreen,
position the sprite using go to xy of x – CAMERA X and y - CAMERA Y. Then we’ll switch the costume
to the correct costume, which… we don’t yet know. So, make a new variable named “costume”
to hold the costume name or number. Then we can switch costume to that variable.
To trigger this paint sprite, use a “when I receive position tiles”. But to rule out
the dummy sprite check IF type > the empty value, only then do we “paint the sprite”.
Oh man, this is exciting – I really want to test things, but we haven’t yet cloned any Goombas!
Now obviously we are going to want to work towards adding Goombas through the level editor,
but we are better off starting simple. We’ll add a “When G key pressed” – G is for
Goomba of course, and then if Type = the empty value, then create clone of myself. This is an
important IF condition, because we only want the dummy Enemy sprite to spawn new clones…
This G keypress will always trigger for each clone of the Enemy sprite too,
and they would be quite happy to create their own clones, this leads to the common bug where clone
create new clones and wow do they quickly multiply out of control! This IF will stop all that.
So, When I start as clone, set this clone’s type to “Goomba”.
Also set costume to 2, this is Goomba first costume number. Then set width & height to 14
so the collision scripts we copied over from Mario know how large Goomba should be.
For now, we’ll position the new Goomba right at the same location as
Mario. Simply set x to the x OF Mario (The “of” block is from the sensing category – Do
make sure not to use x position of Mario, but just the plain x of Mario instead).
We do the same for the y variable, and bring in a “point in Direction (direction of Mario) so that
Goomba faces the same way as us too. Finish the clone off by using the
“paint sprite” to set its position and costume, and then use a show block.
Oh thank goodness, the moment has arrived – We can run the project. Without waiting,
let’s smash that G key to clone a Goomba! And yay! There he is, right on cue. Let’s
drop a few more! :). This is fun. Notice how the Goombas can be happily scrolled off screen
and when we return they are awaiting us exactly where we left them, that’s neat…
At least it’s neat if you like legions of floating Goombas, personally I favour my Goombas to be a
little more lively, perhaps we should proceed to get them to obey the law of gravity.
Before we can bring movement to our Enemies, our main Mario game loop
in in need of a minor upgrade. Click into the Mario sprite and find the “define
game loop” script. Now you’re going to like this – A number of people have asked how come my Scratch
has some extra features that you don’t see in regular Scratch – Well, that’s because I have
Scratch Add-ons and my Scratch Dev Tools extension installed. Here’s an option I added just two days
ago that lets me add extra space around a script that I’m about to work on. If you want to know
more then there’s a link under the video. Just to be clear though, you do not need these tools
to follow or complete any of my tutorials. Ok, so we are going to create two new broadcast
events. The first we’ll name “move enemy”, and the second “move player after enemy”.
Drop these in after the “broadcast move player” and before “position tiles”.
The order of these broadcasts is critical for our program to run
correctly. The first broadcast will run in all sprites before the second one begins running in
any other sprite. Similarly no sprite will begin to run the 3rd broadcast until both the 1st and
2nd have been run across all sprites. This way, as long as our events are running in one frame,
we can queue up many events to fire in the exact order we want them to run this frame. This lets us
move the player, then move all the enemies, and then perform more player movements and checks
all in the same frame of the gameplay, but across multiple sprites. This was a real gamechanger
when I learnt this trick. We will use it now to split off the camera movement and final sprite
positioning of the player and place it under the new “when I receive move player after enemy”,
like this. Enemies can now safely run their scripts before the level is scrolled, just as the
player already does. This will help no end when we want to do sprite touching collisions later on.
I’ll just test that things are still working after those game loop changes… Good.
Let’s switch back to the Enemy sprite now, and we’ll look at making Goomba fall to the ground.
Find some free space, and then drop in a new “When I receive Move Enemy” event
receiver. This sprite may or may not be a Goomba, so let’s check. IF type = Goomba.
Now make a new custom block naming it “tick goomba” run without screen refresh,
and drop the new block in the IF, followed by a stop this script.
So, gravity? We know what to do there, change speed y by -1. And then drop in
our very own “move sprite y” block – Wait, we can do that? You bet-cha we can!
Run the project, and press G – Oh wow, did you see what I saw? I think you might have missed it,
hold on let me get more height! Oh yeah, these Goombas are hugging the floor like little floor
hugging… floor huggers! – That is most satisfying to see, and a testament to reusable code!
So, can Goomba walking be as simple? We want these little critters to have a bit
of acceleration to their walk. We’ll assume they are facing the direction they want to walm in, so
using an IF ELSE, check IF direction > 0 (facing right). If Goomba’s speed x < 1 (1 will be his top
speed, yeah Goomba’s move dog slow, but they’re cool – don’t worry), then we change speed x by
0.1. Otherwise they must be facing left. So IF speed x > -1, then change speed x by -0.1. Nice.
Now bring in our “move sprite x” block to handle the movement
and tile collisions for us – Oh yes…. We can run the project again – Pressing G
to drop a Goomba, and off he goes! Told you he was fast :) – And if I drop another while facing left,
he goes off that way too. So what if I drop one by a wall? Well… he stops… That’s not quite right,
but… he does look good falling off a cliff 😊 - that I like! Hold on a sec,
I just noticed my Mario sprite is behind the Goomba sprite, we can fix that at any
time by going back into the project editor, and dragging Mario on the stage. Good.
So, let’s ensure that Goomba does not get stuck when walking into walls! Instead we want him
to change direction. Click back into the Enemy sprite, and locate the “define move sprite x”.
We are going to have to make a minor change to this copied script specific to the Enemy sprite.
This is where we have detected a collision, where solid > 0. We can simply add a set a turn
clockwise by 180 after setting the speed x to 0. This will turn Goomba right around.
Testing that simple change. I’ll run over here and spawn a Goomba expecting
them to now turn around at the wall – Yay, Perfect… and look all his friends
want to join in the fun! I’m not surprised. Next up we will work on Goomba walking animation.
Find the “define Tick Goomba” script, and make a new variable named “frame” for this sprite
only. After our Goomba moving code, we change frame by 0.25 (that will mean it takes 4 frames
to change costume – Goomba only has 2 frames in his walk cycle). Set the “costume” variable
to 2 +. Goomba first costume is number 2, and then add the floor of (“frame” mod 2). The mod 2
keeps us within Goombas 2 frames of animation, and the floor rounds down to a whole number.
Run the project and we can confirm that it’s all looking good. Yeah,
Goomba is doing the Goomba shuffle, excellent! But you know, one better than the Goomba shuffle
is the Goomba squish – yes it’s time to get Mario some exercise and jump on a few heads!
Switch to the Mario sprite and find the “when I receive move player” script. Before we move Mario,
right at the start of a game frame, we want to check whether Mario is primed to squish enemies.
In general this is when we is moving downwards. Add in an IF/ELSE block and check if falling >
2 (this occurs as soon as we leave the ground), and also that speed y < -1 (trigger on downward
movements only). Make a new variable named “bop y”, for this sprite only, and we “set bop y to y”
otherwise, if we are not falling downwards, we set “bop y” it to the empty value.
A quick test show how bop y is set only when we are travelling downwards.
So, why do we set this at the start of the game frame before Mario moves? The reason is that after
Mario falls down, it’s possible that we will actually impact the ground before we check for
collisions with Goomba. In that case we will have set Mario to no longer be falling, and as such
Goomba would not be squished, and worse, Mario would trigger as being hurt instead – We really
don’t want that! So, with that set up,
switch back into the Enemy sprite, and scroll to the bottom of the “define tick Goomba” script.
Now we check IF Goomba is “touching Mario”. We must then decide if it is Mario or Goomba who
is to lose a life. IF / ELSE and check if (bop y of Mario) > the empty value. This will be a Mario
Win, so Goomba should be squished. Start by Pointing in direction 90,
set frame to 0 and I’ll set type to “squish”. All squished enemies will be identified as such.
Now set the costume variable to the words “Goomba Squish”. We can look in the costumes and copy
the exact name or consume number from here. Right, we are not going to handle Mario losing
a life in this episode, so let’s just leave the else empty for now.
We’ll test the script as they are – Drop a Goomba, and jump! Squish!
Excellent… And now a few more to squish… squish squish squish! Working great… I’m leaving rather
a trail of destruction behind me… These Goomba remains should not be left to linger this long.
Move over to the “when I receive move enemy” script, and IF type = “squish”
then we change frame by 1, and then once frame > 10 then delete this clone.
We can test this, and when we despatch a Goomba,
he now only hangs around for a very short period before he leaves this world for a better place.
To finish off this episode we should get Mario to bounce off Goomba’s head – that
gives the player nice feedback that they pulled off a successful move.
Back in the “define Tick Goomba” script, we can create a new variable named “BOUNCE PLAYER” for
all sprites, and when we squish Goomba, we also set BOUNCE PLAYER to 5. We are going
to use this to automatically simulate the player jumping for 5 frames after hitting the Goomba.
Click into the Mario sprite, and under the “when I receive move player after enemy”, we insert an
IF before the move camera block. Check IF PLAYER BOUNCE > 0. If it is then we change bounce by -1,
and jump by firstly setting Speed y to 13. Also we set falling to 2
so we are off the ground, and then lastly set jumping to 1. Keeping jumping low will allow us
to continue jumping up higher if we hold the jump key down after bouncing on the Goomba’s head.
Right – that’s it, we’re ready to test. Run the project, drop a Goomba and jump on their
head – Yes, did you see us bounce?! Again…? Cool… How about jumping high off a Goomba – woohoo
that was higher! Hold on let me find somewhere I can test this extra height…
Yeah, this platform is too high for a standard jump, but now if I spawn a Goomba, then jumping
on his head now brings the platform in reach! That’s great, it opens up exciting level design
especially for reaching secret passages. Outro - old
Well!!! Things are looking great, we’ve managed to spawn many simple enemies in our game,
but we still have some work ahead of us. In the next exciting episodes we will work on bringing
the enemies into the level editor, and hopefully how to also add them to our level save codes. We
also really need balance things out for poor Goomba and allow Mario to lose a life too!
So, please do keep me updated with how your projects are coming along,
and what features you are most looking forward to covering in future episodes. If you’ve enjoyed
this tutorial, then please smash the like button, and don’t forget to subscribe to the
channel to avoid missing my next exciting video! - Thanks for watching, and Scratch on guys!