[Intro] Hello Fellow Scratchers! – I’m
Griffpatch, and today we are beginning a new miniseries, perhaps just 2 episodes,
on the exciting world of Scratch Raycasting! So “Raycasting”, what’s it all about? Well
it’s about firing a ray from one point in our game outwards across a level until it hits something,
be that a wall, or some other object. This simple idea has many exciting applications,
from tracing projectiles, to creating real time laser pointers, flashlights, and even can help
us draw 3d first person worlds like this one. Wow, are you as excited by this as me?
Now, every project needs a beginning, and before we get on to raycasting or even 3d rendering,
we first need a level, and a robust script for controlling the player.
After all we want to be able to move around the maze using a first person control scheme,
and we need to safely handle collisions and any snagging on walls. So let’s see how far we
can get! Are you ready? Let’s get Scratching!!! [Part 1 – Level & Navigation – Drawing the Level]
We begin with a brand new Scratch project, and before we do any coding,
we need to draw our level. It wants to represent some kind of arena or maze.
Now as such I think these projects look good in the dark, so head over to the stage backdrop,
and after converting the costume to bitmap, fill the entire backdrop black. Ooh,
spooky – Love it! Next up, make a new sprite,
and name it “Level”. No prizes for what this is going to be used for 😊.
The level we are drawing is top down. I’m going to draw it using simple grey rectangles as
raycasters tend to work best with flat walls. We start by ensuring we draw a full wall
around the entire level. Don’t leave any gaps at the corners otherwise your project will bug out
later on. Now just have fun making corridors and interesting rooms to walk around in.
Now while I do this I just want to let you know that for this tutorial,
none of the scripts or costumes in this episode have to be followed exactly as I
do them for episode 2 to work. You can recreate the level, and the player in anyway you like,
and the raycasting part should work just fine. Either way, watch the video and you may pick up
some useful tips and we can ensure you finish with something that will be very successful.
Ok, my level is done. As you can see it’s fully surrounded by walls. This looks good,
but… I bet yours will look better than mine ha!, can’t wait to see them in the
scratch studio when you are done – As always there’s a link to the studio under the video.
Now, it would be a good idea to ensure the level is kept centred on the stage
when the project starts running, so in the code tab: “When green flag clicked”,
simply “go to 0, 0”. [The Player]
Splendid, we can now concentrate on the Player who is to be walking around our maze.
We’ll reuse this first sprite since it’s here, so rename it as “Player”.
I’m afraid to say we won’t be keeping these Scratch Cat costumes, so delete them
and we’ll paint a new costume, sorry Scratchy, maybe next time.
Now I’m going to draw a beautiful lemon yellow triangle to represent the player.
Recentre the view, and zoom right in. To create a perfect triangle,
we draw a square (holding the shift key while drawing keeps it square).
Then select and delete one corner using the shape tool. Now, again while holding shift,
we can rotate the shape to point right. Lastly size it as you want,
this time holding “alt” allows the shape to stay centred. But, if you are not sure it is centred,
double check by dragging and snapping the shape to the centre of the canvas afterwards.
Finally, give the costume the name “Player”. [Coding the Player - Setup]
Now, for some code! We’ll start the player centred on the level.
“When Flag Clicked”, use a “go to xy of 0 0”. We want this player to be able to rotate around
to face different directions, so “set rotation style to all around”.
To prove the point, why not “point in direction 45”.
If we run that, you can see the player is facing diagonally up to the right.
Great. Now, since my level has a nice empty space in the middle, this was a good place to start, but
if your player is touching a walls right now, then just drag them to a new position on the stage,
and update your “go to xy” to that new position. You really don’t want to start in a wall.
Last thing we’ll do to set things up is to ensure we “switch to the Player costume”.
[Player - Movement] Now we’ll concentrate on player movement – Oh,
there are so many ways we could tackle this. I’ll lead you through one possible way,
but you are free to do this any way you want, it really won’t affect the raycasting later on.
We need a game loop, and this will simply run “forever”.
Next we’ll check IF the player is holding down the “Left arrow” key. If they are we
want to turn the player counter-clockwise, that is to the left. I’m going to turn by
just 3 degrees… This may feel a little slow, and you are free to increase this if you’d like.
To turn right we do likewise, duplicate the first IF, and change it to check for the “right
arrow key” press. Then just switch the turn for a turn clockwise, (that is to the right)
by again 3 degrees. If you test that now,
we should find the left and right arrows make our player rotate nicely on the spot.
So how about some real movement, forward and back.
We need two more IF statements, I duplicate these first two,
but we can discard the turning scripts. The first IF needs to check for an “up
arrow” key press, and the second one a “down arrow” key press.
So, when we press the up arrow, we simply move 2 steps forward.
To move back, we do the same, but move -2 steps, as a negative move will indeed move us backwards.
Yay, it’s testing time – And this is now much more fun. We can scoot around this level, walking
forward and backwards and turning as we go. This is a great start to creating all sorts of games,
but until we fix the fact we can walk through walls, it’s not really much use!
[Player to wall collisions] We’ll begin by adding the most basic
collision scripts, and then work from there. So, basically we just want to stop the player
walking forwards, or backwards into a wall. To stop us having to code the same thing
twice for forward and back, we’ll make a new custom block to handle this.
Name it “move”, and add a numeric input named “steps”. Click to run without screen refresh.
So, this is going to replace these two move blocks in our game loop,
so drag the move 2 steps block into the new define move script, and where it came from,
drop in our home made move block, like so. We set is as before to move by 2 steps.
Now looking back at the define move script, drag the steps input variable into move 2
steps block below to link it all up. Right, now we can use this new custom
block to replace the backwards movement too. But this time again move by -2 steps.
At this point, our code does exactly the same as it did a before,
but we can now add in the collision detection. So check whether we have moved into a wall.
“IF touching Level then”. So if we have, then the simplest way to get back out is to move back
to where we came from. So again we move, and to get a negative value of steps, we use 0 –
steps. There, I think we can give that a try! Let’s walk into a wall… Boink! That looks
promising right? Testing from different angles, and each time the player stops
and everything looks good. But, don’t let that fool you,
for there be dragons! Not literally obviously,
but how many of you already know what might be wrong with this simple approach to collisions?
Shall I show you? So, if I turn so I can walk closer to this wall
over here. I collide and stop, and now that I’m real close, what happens when I turn the player?
Oh no, this can’t be good, can you see how I can turn the player to overlap the wall. Yeah, and
now – I’m stuck, my player can’t move forward or backwards as they are already colliding with the
wall either way! I think you’ll see this problem time and time again in many a Scratch project. We
really don’t want the players rotation to affect the collision detection, so to get around this
problem, we will switch to using a simple square hitbox instead. This way, no matter how we rotate,
the collisions will not change. Perfect! [Player Hitbox]
Ok, no problem. Enter the costume editor, and make a new costume.
Name it “Hitbox”. You may find it useful
to “convert to bitmap” before we begin as this helps to draw an accurate hitbox shape.
Now, zooming in, draw a 4 by 4 filled square. It should perfectly fill
one of the shaded grid squares of the canvas. Then once done, drag it until it snaps into the
centre of the canvas. Coolio, and that’s our simple hitbox.
Back to the code, and we’ll update the “define move” script.
Simply, switch to the hitbox costume before we do anything else.
Also, we’ll ensure the hitbox never rotates by setting the
sprites rotation mode to don’t rotate. Ok, so now this “touching Level” check
will be using the hitbox costume for collisions as we wanted.
But, once the checks are done, we should switch back to the original player costume.
Duplicate the top two blocks we just added, and pop them at the end of this custom block.
We switch the costume back to the Player costume. And reset the rotation style to All around.
And that should do it, shall we give it a test. Just as before, I run into a wall at a shallow
angle, and then rotate until I overlap. But this time, we find we are not getting stuck,
as although we are overlapping the level wall, we can safely back out and continue moving around the
level – Phew. Thank goodness for hitboxes! [Sticky Walls / Wall Snagging]
Right, so we are really getting somewhere, but let me show you one thing about this classic collision
code that really bugs me! If while running down a passageway we snag up against a wall,
we’d not expect to pass though the wall, but we would expect to continue down the corridor…
however, that does not happen. Nope, instead we instantly stop, dead as a dodo!
This is because our collision code crudely undoes our last movement, pushing us right back to where
we came from. So how can we handle this better? The best solution is to break the directional
movement apart into its x & y components, and then even if one direction is blocked,
the movement in the other direction can still be completed and the movement continues.
But to do this is not straight forward as currently we use a “move 2 steps”
to move forwards. How do we split that into a change x & change y?
Luckily we have some maths that does the job, and here it is. Move 2 steps actually
does the same job as, are you ready for it: “change x by 2 * sin(direction)”,
and “change y by 2 * cos(direction)”. Yep, that’s how the move block actually works.
So we can make use of this, but before we do we have some coding to do. We’ll start by making a
new custom block that tries to move the player by a value of x & y. Name it “try move”, and add two
numeric inputs, “dx” and “dy”. These indicate just how far to move in the x & y directions.
In here, we first do the movement. Bring in a change x & change y block.
We then simply use the dx & dy input variables as the amounts to move.
Next we check for collisions, IF touching Level then.
And of course if we collide, as before, we simply reverse the previous movements with
a change x & y by 0 – dx, and 0 – dy. Ok, so that may seem like it’s not going
to help us much, but just hold on and you’ll see what we are up to.
Separate off the old “move steps” block and its level touching check.
In its place stuff a nice new try move block. And this is where we need that cool maths,
to translate this move steps block into a try move x & y.
No problem. Try move, steps * sin
of direction. And for the y axis, we can duplicate that,
only switch the sin for a cos operator. Excellent!
That’s the maths! So in theory, this will end up moving us exactly the same as before…
We should just test that to be sure… Yep, just the same, and therefore we still have the problem
of getting snagged on the walls… But… now we can fix this by first moving the x, and then the y.
Duplicate the try move block like so. Then we can remove the second input parameter
from the first “try move”. That will now only move in the x direction.
And then, remove the first input from the second “try move” block.
That will only try and move in the y direction. Stick a zero in the empty inputs if you like. I’m
feeling good about this, shall we test it out! And here we go… And yeah! Can you see how I
didn’t snag on the wall, and instead just slipped across the surface, that’s perfect.
Great work everyone. [Player Strafing]
So we are nearly there, the last little thing I want to add before calling these movement
scripts complete it to include player strafing. What’s that? It’s the common movement in first
person games where the player can sidestep. Very useful for looking around corners.
It’s common convention to use the WASD keys for strafing and generally walking about.
The cursor keys are then used for rotations. Come back to the green flag game loop script.
Find the “if key up arrow pressed?”. This now needs to also support the W key for moving
forward. We need an “or” for that, so if key up arrow OR key W pressed then we move forward.
Do the same for the Down Arrow key. With an or, add a check for the S key.
Ok, now for sidestepping with the A & D keys. If, A key pressed? Then.
To sidestep to our left, we simply “turn left by 90 degrees”
first, before “moving by 2”. Then after that “turn back right by 90 degrees”
returns us to facing forward again. To sidestep right, check “if the d key
is pressed”, “turn right by 90 degrees”. “Move 2”, and then finally “turn left by 90 degrees again”.
Sorted! And here we go… Strafe away! Woo-hoo, look at me sliding about,
that’s cool… and you just wait. This will make the next raycasting part of the tutorial series
ever-so-much more enjoyable to play with. [Outro]
But… oh my gosh, I’m afraid that this is where this episode ends. Man, the next episode though,
oh, it’s going to be simply epic, I just can’t tell you just how cool it’s going to be. But
thank goodness we now have these episode 1 scripts in place as it gives us the solid foundations that
we needed to build upon. So, have fun designing your levels, and getting your player movement just
right. Just make sure you then keep a copy of this project safe, all ready to continue next time.
So, if you enjoyed this episode and can’t wait for part 2, then smash that like button and make sure
you’ve not forgotten to subscribe to the channel – You don’t want to miss out on that notification
when the next episode becomes public! Of course, if you can’t wait, then there’s also the early
access channel membership where members get to see the videos as soon as they are made before
everyone else! How cool is that. Well, that’s it from me today,
thank you for watching. Have a great week ahead, and Scratch on guys!