Transcripts
1. Skillshare Introduction: This course, we're
going to go ahead and create a classic that still gets remake to this day, even especially on
the mobile platform. And this game is
called breakout. Now, the objective
from here is you have a ball that's bouncing around
on the sides of the walls. You bounce it off your paddle, and your objective is to break all of the bricks that
you see on screen. Different bricks give you
or different color bricks, gives you different
amounts of points. Alright. This is exciting. Let's go ahead and start
recreating this classic game that maybe you or even your parents have played
or still play to this day.
2. What is Breakout: Next up in this
section, we're going to do a slight alteration to Pong, and that is going to be
a game called breakout. This one is from 1976, and an interesting factoid about this is the screen
was only black and white, yet we had color like this, and we had color like this, like you can see on
the screen here, because they actually put
some colored celophane in the screen or on the screen. But that's how they were put color on there because
the screen itself, as I said, was only
black and white. Now, what is breakout? Well, I'm gonna play a bit, but be warned that there is a
little bit of flashing. You can see my mouse here in the top left of your
screen at the moment. And if we were to play that, we can see what we basically
have here is a ball bouncing off of the sides and hitting a paddle and
getting bounced back up. And I'm doing this doing breakout right after Pong
here because, as you can see, just base off of
those specifically, we already have a similar system kind
of set up with Pong. So we're going to be building off of what we just
did in the previous project. Now, we don't really need
this one here at the top. This is I believe just showing
that this is player one. Technically, it's a
two player thing, but each person just
takes turns anyway, so we're just going to
leave it as one player. Plus the two player system had a big machine with
it anyway, yeah. This next one here to the right of that still
remaining at the top. If I move forward, we should
see numbers. There we go. So that's keeping track
of what ball you're on. So you're on ball one,
ball two, ball three. Once you hit ball four,
then that's a game over. And the number up here in the
corner that was flashing, that is the points that you get. Yellow bricks give
you one point, green bricks give
you three points, orange bricks give
you five points, and red bricks gives
you seven points. Now, your objective is to completely clear the
board of all the bricks. The ball speeds up,
it gets harder. And as you see here, in comparison to Pong, you got a pretty small paddle
here. To get this going. Now, when you beat the
game, I'm pretty sure that the game just resets just as it would if you got
a game over anyway. So we can use the
same logic with that, whether we win or lose, just doing a reset.
But that's breakout. If you did not know
what that was, and I'm sure there's some modern versions of the game
that are out there. But if you did not
know what that was, then now you do. And let's go ahead and jump
into setting our project up.
3. Setting Up the Project: So for breakout here, I think I'm just going to leave the same project resolution
that we used with Pong. If you wanted to change it,
of course, feel free to. Again, that's in the project
settings display and Window. But I'm just going to
stick with what I had from the last one
we did at Pong. I've gotten into my project I created a breakout
folder, of course. If you're going to set yours
as a separate project, you're probably going to call it breakout because
that's what it is. And once you're ready
to get started, and then we can create
our main scene, which obviously isn't going to be a whole lot in here
when we think about it. I guess we could put
the waltz in for this. Do we want to do that?
Yeah, let's do that. So I'm going to create a two D. I'm just going
to sect two D here. That'll give me a root. I have a no two D, which
is perfectly fine. For this, I'm going to go ahead and do
what I usually do and rename it to say Mine. I'm going to save it inside
of my breakout folder. And like I was
saying Glick Pong, I'm just going to
save mine as a SCN, but you can leave yours
as a TSCN if you prefer. All right? So I have my project here. Now, what do we need? Do we need? Well, we're going to eventually
have a paddle, but that'll be in
the players section. We need the ball. The ball
will have its own section. We can put up the
labels for UI, right? So we're going to need
a spot for score, and we're going to need
a spot to keep track of the lives or what ball
the player is on. And we're going to need walls around the entire thing.
So I'm going to go up. We're going to do
a canvas layer, just like we always
do for our Gooeys. So I'm going to go ahead
and rename it GUI. Inside of that is
where I'll make my label we want
to stay accurate, we can set that as a one. That's fine. We can call it player. That's
honestly perfectly fine. We don't really need to do
anything outside of that. Next up, instead of player, this would be, I guess,
our lives, right? Lives or ball count.
Current ball. Yeah, I'm going to
go current ball, and that'll start out as a
one by default, as well. Now notice, I'm going to
change the anchors of this one of our ball counter
to be in the top right. And I'm going to leave the
alignment to be on the left, just so it's pulled
away from the edge. And on the player, I'm going to change
the alignment to be the horizontal
alignment to be on the right to again, pull
it away from the edge. This is just a personal
preference here. And we're going to
need two more labels. So I'm just going to duplicate player here and pull it down. And I'm just going to
call this one score. I guess I should
technically call it score label because
that's what it is. And I'll rename current
ball to current ball label. Because we don't need to
have variables to have the exact same name as
other notes in the scene, and it'll make things a little confusing as we go about it. Score label obviously
is going to be three zeros for us here. All right. So we're going to need
walls set up for us. So these walls, I'm going to click back onto my main node. We're going to add and
walls do not move. So I'm going to use a static
body two D. Remember, these do not move whatsoever, no matter what hits them. Now, these these the
only reason I'm doing this is because they were
visible in the original game. So I'm going to add a sprite
two D to my static body. And remember, it's
a physics body, and it's got the yellow
triangle to tell us, Hey, it needs a collision. So let's add to it
a collision shape. And we can go ahead
and give that shape, give it a rectangle. That's fine. Sprite two D. Texture, go do exactly
like we did before. New gradient
texture, open it up, open our gradient, select the black, change it to a white. And now I'm just going to
change the size of it. Brink it down. I'm going to
pull the whole thing down. And we're going to
extend it all the way. Okay. So I have one wall here. I'll rename my static
body, say wall. I'm going to with that selected. Oh, I got to change my
collision shape as well. Then now, I'm going to hit Control D on my wall here
to make a duplicate, but there is something that
you do need to keep in mind. If you're doing this in how can I not just grab a
hold in that arrow. Here we go. Just drag it over. Roughly centered. There we go. If you're duplicating,
sometimes there are things that you do
need to make unique here. For example, if I
go ahead and grab the collision shape here on
my first one and I change it, you see it affects both of them. So what we actually
need to do is go into our wall, our second wall, and we need to go
into things like our collision shape on the
shape and our inspector, go to the drop down and
select Make Unique. And now, if we were
to change this, it's not going to
affect both of them. It's only going to affect
the one because now they are classified as separate
objects, separate shapes. So they're not
sharing the same one. All right. And we
need one more wall to go across the top. So we're going to need to
somewhere around the center, and we need to resize
these objects. Sprint that down. And I'm just going to compare
a size over here. That's roughly about
the same thickness. Alright. And I'll
pull my sprite out. Adjustments. Here we go. That's fine. Now I got to do the same
thing with the shape. But remember, I duplicated it, so I need to come in and make it unique before I change it. And now I can come in and manipulate it in
whichever way I want. Line that up. Excellent. So now we have our three walls set up, and
they have their collision. So if the ball hits it, we just have to set up the bouncing,
and it should be fine. The bottom is wide open. Our paddle, we can
just slap in there. When we do our player, the ball, we'll set that up later, and the bricks, I believe, we'll do later as
well, which means I think we're done
with our setup here. So go ahead and I'll see
you guys in the next one where we will continue and start by
setting up our paddle.
4. Creating the Paddle: Let's go ahead and create
the battle for breakout. So this is going to
be similar to Pong, only instead of
moving up and down, we're going to be
moving left and right. So, in our main scene. And if you haven't already,
you should probably save since you've already
got yourself set up. We can go ahead and add into it a character body two D because that's going
to be our player. We can add a sprite two D so
we can display our paddle. And of course,
we're going to need a collision shape on that
character body as well. So I'm going to rename
my character body to be called player. Sprite two D, I'm going
to go into the texture, new gradient texture two D, select it, open the gradient, paint the black,
change it to white. I can see it's not changing over there automatically for us, so I'm going to just take use
HDR and then turn it off. Now, we have a small
paddle with this, so I'm just going to go
ahead and bring that down. Yeah, maybe something
like that would be good. And I'll add a collision shape. I'm going to change the
color of this to make it stand out. We're
gonna go with red. And I'm going to
make it a rectangle. Brink it in to be the side
of our paddle. Perfect. Now grab our player
and move it down on the screen to where we want a nice starting
position to be. I'm going to have a
space underneath of my player underneath
of my paddle. I'm going to go ahead
and run this scene and take a look at it,
see how I like it. Yeah, I think that's
a fair space to put. All right. So I'm
going to go now up to my project
project settings. I'm going to create my mappings that I'm going to
use for this game. Now, in this case, I already have some of these
that I had previously, but I think I'm going to
continue with the theme, and I'm just going to break
out left and break out right. No, left of course,
is going to be A. Right, it's going
to be D. Of course, for you, they might be arrow
keys if you prefer that. And now our player needs a
script, so we can get moving. Let's see. Res, breakout player.
Yep, that's fine. Extending a character
body two D, written GD script.
All right, create. And all we need here
is our movement. So if you remember from before, we had a speed That was
an int of some number. I'm going to go ahead
and set it at 30. And let's see. We can
go into our function, the physics process because we are dealing with
movement here, and we can go ahead and
use move and slide, although maybe we would want move and collide
this time around. We can try it. See what happens. Move and collide
and we'll just pass in the velocity ourselves. And our velocity dot X. We need to actually
get our inputs first. So I input dot is action, Pressed, break out left. So this one we're going to
be going negative on the X. So let's say velocity X equals negative one times speed. L if input is action pressed. Break out, right. We're
going to do the opposite. We're going to do velocity dot X equals one times our speed, and we can take a look at that. I'm just going to go
ahead and run the scene. And I just realized I didn't
put an else in there. So if I hit it once,
we're going to move, and that is really fast. So I'm probably going to
turn that down a lot. We'll go down to five,
and we could try that. And I'm going to go ahead and put our else block in there. So else Velocity dot X equals. Actually, you know what I can
just overall say velocity equals a vector 20, and that's what's
going to give us a zero on the X and
zero for the Y, which is fine because the Y is not affected in
this game for us. And this is just easier to read than doing velocity
dot X equals zero. When we would just
say velocity is zero. Alright, so let's try that
again with our new speed. Alright? I like that, but it might be a little too
fast for what I'm going for. So I'm going to go
ahead and change that maybe I try three. And I believe that updated, but just to be safe,
I'll restart it. Yeah, I think that'll
be good for my speed. So if you want to
go slower, you can. If you want to go faster,
that's up to you. I'm trying to keep in
mind that the ball is going to speed up at porches, just like it does with Pong. Alright. Great. So I
have my player set up, and if I stop pressing buttons, we'll just stop moving together. So there's my player. And next up, we can go ahead
and get our ball created and get the ball
spawning into it. And maybe we'll get the
bouncing going in here as well. Maybe we'll do all that in one
video for the ball. Right. So I'll see you guys in the next one when you
got your paddle set up, and we'll start creating
our ball for the game. And once we got the ball,
we'll set up our bricks.
5. Player Tweak: So you might notice if I
come in here. There we go. My paddle is still moving
roughly about the same, but I have made some changes, and I just want to show you
that just in case you get a little confused from
seeing it later. So if I go to my script,
my speed is now at 200. And what I'm doing different is I'm doing velocity times Delta, and that's what you should do when we have objects
with motion here. Now, we only have to do
this with move and collide. We don't have to use this with move and slide because
move and slide, to my understanding is actually calculating this on
within itself, right? But if we're using Moving Cloud like we're doing
in this project, we need to multiply our velocity times Delta
ourselves. All right. So I just wanted to pair that up real quick before we move on
and see this get confused. And then maybe I'll
get a bunch of questions about it for
not mentioning it.
6. Creating the Ball: Go ahead and create our ball
for our game now, right? So I'm going to go in into
my main here, hit plus, and I'm going to use
a character body two D. I'm going to go ahead and
rename it to being ball. Of course, it's going to need
a collision shape, right? That makes sense, and
it's going to need a sprite so that we can see it. Just like our player, Alright, so our texture, you know where we're going
with this at this point, spray two D, inspector, texture, new gradient, two D, open the gradient, select the
black, change it to white. There we go. That's obviously too big. So let's
shrink it down. Se. How big do we want
to go for the gol? Bring that whole
thing over here. Let's not run the
game here real quick. Take a look. Um, I
think that's fine. Probably don't want to
go any bigger than that. Though. You want to go
smaller, we certainly could. Drop in one more on each side
and go something like that. And I'm going to have to
reset the transform this. So with my ball inspector,
transform position. I'm going to click
the reset button just so I can put
it back up here in the corner where
it should be. Collision. I'm going to give it a new color, go with a green, shape, a rectangle and
shrink that bad boy in. And now we have a
ball. Now, I'm going to take that ball and I'm
going to reposition it here. All the way down here. Because the ball does
spawn not on the player, but just above the player, and then it gets launched off. So the way I'm going to do it, before now, I think we'll
leave it like this. This for the current time. And let's see. I'll
go ahead and add a script onto my
ball, check my path, break out ball, character body, two D, GD, script,
right, create. And what we're going to need is an initial direction that it's running in
that it's going in. So we can go ahead and go into our physics process because we are a physics body,
and we are moving. We can do move and collide. Although I think I'm just
going to use MoveN ide, maybe with this one. We need our velocity dot X. Yes. And our velocity Y. We need to set both of those, and I'm going to Oh, we
don't need a constant. I'm going to go ahead and
create a variable called speed. This is not going
to be a constant because remember our
speed doesn't need to change over time
as it's bouncing. And I'll set this equal to 30 initially, and
we'll take a look at it. So for the time being, let's go ahead and
just set it to one just one times
speed for now. And we'll do the
same thing with Y, only we'll make it negative, obviously, to make
it go up for now. And I just want to
see the speed at which it's going to
go. So there's 30. That seems like a perfectly
fine starting speed for us. I think we're going to do a similar thing that
we did with Pong, and we'll see how that works
out, how far we can go with that before we have to make
any potential changes. So I'm going to have an H
direction and a V direction, so we can pass those
in for our ones here, and I'll start our
vertical with a minus one. And this is where our
changes come in, right? So based on whether we hit hit a floor, hit a
ceiling, and so on. So let's go ahead and
say if is on Whoops. Sealing in B direction times equals negative one,
so that's going to flip it. But we don't want to
just do it on ceiling. We want to do it if we
hit the floor as well, because the floor is going to be when it hits our pattern. Or is Whoops, is on floor. Now, this might work. This might not work. We're going to have to
take a look and see how this works because
we've worked with Pong. We know how to do these bounces, so we're going to
take a look at it. Right? All right. So let's go with LF. We're going to work with
what we know is on Wall. H direction times
equals negative one. All right, so let's
play that and let's take a look and
see how that goes. So the ball goes. It should
bounce here. It does. Should bounce off
the top. It does. It's coming down.
It might hit us. It might hit the wall. We'll see. It's going to hit us. Alright, so it looks like
we have our bouncing. It looks like just like Pong. This is working perfectly,
at least for the time being. So as far as we
can be concerned, we have our bounce coded.
We have our player set up. Now the difference is we
do want to speed this up. And we're going
to speed this up, no matter what it
bounces on, right? So we're going to
go ahead and say, we're going to go ahead and
do speed plus equals five. We'll do that if we
hit a wall as well. So we should be
seeing this speeding up every time it bounces, just like we did with Pong. So let's just be patient
and take a look. There's one bounce, two
bounces, we're at plus ten. We're going to hit
down here somewhere. Boom, 15, 20, so we should
be at a speed of 50, 55, 60, and I bounced it down below,
so now it's out of bounds. That would have
lost the sour ball. But we do want to make
sure that we have a maximum speed set. Now, what this maximum is, I don't know. We'd
have to test it. We did see there that we got up to about 55. It wasn't too bad. So maybe we can do a max speed of maybe 100. Now, how do we
keep this in line? Well, we would have
to set our speed. It's equal to, and we
want to get the minimum. So we're going to
say min between what this does is it's
going to return us the minimum value of the
arguments we pass in. So if we say speed plus five, max speed, it's going to give us either speed plus five or it's going to give
us maximum speed, whichever is the smaller number, and that's what speed
is going to equal. So by doing this, speed
will continuously increase, but it will never
exceed max speed here. Right? And we can
do that down below. The next one. There we go. And I'll just go ahead
and save that seen. And for now, like I said, it looks like everything is working perfectly fine for us. We do want to set the
spawn of the ball, though, when we start because there is typically a small
pause when this happens, and then it spawns
above the player, so let's go ahead and
put that in real quick. That's going to be inside
of our ready function here for the ball. And what I'm going to do Ah, yeah. You know
what? That's fine. Alright, so let's go with we're going to use something
called await. And I think I mentioned
this during Pong, when we had the game over
section or the game win screen, whatever you wanted
to call it, await, get underscore
tree, create timer. We can pass in a numbers
three and dot timeout. And then with this after the predefined
amount of time here, then then we do
whatever's after that, which in our case is going
to be spawning the position. Alright, so let's go ahead
and we can do Let's see. So instead of having a
predefined 3 seconds here, let's go ahead and do a Rd
is it Randi or Rand range? I believe it's randi. Who, it's not quite
doesn't go in there. It'll be percent three plus one. Now, this is exclusive, and that means that this is going to give us a random
integer up to the number three. However, since this is code, this is going to
give us 01 and two. And obviously, zero isn't going to be acceptable here because we need
some kind of bonus. So I'm doing plus one. So whatever number we get,
we're going to add one to it. So if we get to zero,
we'll do plus one. So that gives our
minimum number to be a one And then if we actually got a one,
that would become a two. If we got a two, that
would become a three. So now we're getting 1-3, this. All right. So we're going to wait a random amount of time. And then we'll set
our position to be wherever the player is
at the current time. So we'll say global position equals the player's position, which we do not have
a reference to. I'll go ahead and do that here. I'll do an export for this our player as a
character body two D that I can set and our position will be set
to player Global position. Only we're going to change Y because we want it to
be above the player. So we have to go
global position, dot Y minus equals.
Let's say five. We'll see how that goes.
But remember I got to go to my ball script here and
set the player variable, hit the assigned button,
select our actual player. And we'll see how that works. Initially, we're going to set speed to zero because we don't want
the ball to move yet. I'm actually going to go
into the scene hierarchy and click the little
eyeball to hide it. So if we were to take
a look and I click it, the ball disappears, back in the ball script after we've set the position, right?
So we've waited. We set it equal to
the player position. We raised the ball
above the player. Then we're actually going to
set the ball's visibility, so we're just going
to say visible. Equals true to show it. And then we're going to
set the speed equal to 30. And we can even set
this with a const, just to make things ven clearer. We'll call this starting speed. Now we can just say speed
equals starting speed. All right, so if we play this, we'll see the ball. There we go. It just spawned on us
and wash itself off. And if we do that
again, we can see it. There it goes. Alright, so we have
our ball spawning. It spawns just about the player. I think I'm want to
actually set this to ten instead of five
because that five was looking a little close. That might have just been
me with us moving around. But I'm going to
change that to ten, right, we have our ball
working. It's bouncing around. Now, once we get some
bricks in there, we'll see if our
bounces are still good or if we need to tweak. As well as, I guess, start working on
destroying the bricks, doing our score, counting up the balls when we lose
them or our lives. I suppose, at that point, we'll be pretty well done, aside from anything
el we want to tweak. Alright, so we got the
basics of our ball working. And next, we'll take
a look at our bricks.
7. Creating the Bricks: All right, so we're going
to go ahead and create the bricks for us
for our game here, and the bricks are going
to be about the same size as the player is. So what I'm going
to do is copy that. I'm going to go to my main ad, and we could do a static body. Yeah, because we don't
need them to move at all. And I'm going to call
this one yellow brick. That yellow brick
is going to need a collision shape and a sprite. So what I'm going to do
to cheat this little bit is I'm going to
go to my player. I'm going to click
on the Sprite two D, hold Shift, click on collision
shape, do Control C. Go to my yellow brick, hit Control V to kind
of add those in. Now, remember what
I said before. We're going to come
in and we're going to make them unique. And make unique recursive. That we can do the
gradient as well. Collision shape, grab that, make unique and for the color. Sure, let's go with
a yellow for now. But now we have a yellow
brick and we can take that brick and we can put
it anywhere in our game. For example, I could put one right here and
just line that up. Now I can just do Control
D, Spide the next one out. So I think I'm going to put that little space in between them. Control D, direct next one out. And I'm just going
to try and keep this as consistent as I can. And I'm going to go ahead and pull this all the way across. Real quick. Alright,
so I've gone ahead, and I have all of these yellow
bricks all set up here, and there are a lot of them. And I have two rows. I don't
see off the top of my head. I can't remember
if they had two or three rows in the game, but for now, I've got two rows. And there are a lot
of ones to collapse here. I just collapsed them all. Unfortunately, I don't No, that's just for the one branch. Well, that's unfortunately.
Maybe there's a shortcut key that
I'm missing somewhere. But for now, that's
not important. You can see we have all these
bricks here all set up. And I want to show
you how we're going to determine what it
is that we're hitting. Because all we have to do is just create this
same setup again, do it for the orange blocks, red blocks, and
the green blocks. But to show you how this works, I'm going to go into my ball, go into my ball script, and
inside a physics process, we're going to do an
if statement here. So we're basically
going to say, if we are colliding with anything, then we're going to print out the name of the thing we
collided with, right? So if Yet, is a glide
collision count. So if this is anything but zero, this is going to
return true to us, and this is basically going
to be basically just saying, if we're colliding
with anything, and if we are, then
we're going to print. And what we're going to print
is slider slide collision. And we're going to
pass in an index of zero because we want to get the first item that
we're colliding with, which in reality, we should only ever be colliding
with one object at a time. So if we go ahead
and print not print, but play this we
should take a look, we should see down in our output the yellow brick being printed. Yeah, those are
all of our There's my confusion in
there in the print. We're printing the collision
of the first side, but what we need to do is
actually get the collider, so get the actual thing
we're colliding with. And then we'll print name. So get slide collision, pass in a zero, get
collider, dot name. And if we do that, we should see the name of our
bricks get printed out as it hits objects down
here in the inspector. Go yellow brick 12. Player, wall two,
Yellow brick 16, Player, wall, Yellow
brick three, player. Yellow brick 20, wall, player. Yellow brick eight,
Wall, player. Yellow brick 11, so
you get the idea here. Right. So that's how we're
going to go ahead and set things up for actually destroying our bricks and determining our
points in that. And well, just in general, that's how we're
going to determine if we're hitting a
brick to begin with. But right, so I'm going to
go ahead and take my bricks, turn them into or set up the
other colors for my bricks, and I'll be right back. There's no need to really
show you how to do that. I've already shown you how to do one brick and just copying it, sliding it across until
I made two layers. I'm going to do the same thing, but with different colors. And with those colors as well, I can go into my gradient here and just change these two colors so we can actually have
the color end game. This is going to
be a yellow that. I'm going to copy
my code down there. Select the other
white, paste that in. And if I play it,
you'll see that we now have one Oh, no, we
have all of them. That's right because
we copied them over. So we now have all
of my yellow bricks. So now I can just go ahead and create my orange bricks now. Alright. So just give me 1 second, and I'll go ahead
and create that. You can go ahead and,
of course, pause and create and set
up all your bricks. All right, I've gone
through and I've created all my bricks, and I double checked
with the video. There is only two layers of
yellow, green, orange, red. So with our bricks, what do we need left
for our bricks? We need the actual destruction
of them when they get hit. So if we jump over to our code, we should easily be
able to detect this. So instead of printing
here, I'm going to go ahead and create a variable of ops a variable
called object name. This big string. That's going to be equal to what we
were printing out. So get slide collision zero. Get collider dot name. And then from here, we can
go ahead and check if Wow. If brick in object name, which obviously it should be, at least with the way my
naming is set up, right? Yellow brick, green
brick, orange brick, red brick. Sorry about that. What if brick is in the name and the object name Then we're going to need to get that
object and cue free it. And to do that, we
should actually be storing the
collider, as well. So as well with the name, they're also going to
get a var collider. Now with this, I'm going to narrow it down
as best as I can, because I can't just call it a static body like the bricks are because they're not always going
to be bricks, right? Could be the wall.
The wall is also a static body, static body. Okay, so it looks like
we use static body. But remember, our player
is a character body. So we got to take that
into consideration. So the lowest form
that we can go on here is just classifying it as a physics body
two D. And that is, of course, going to be equal to t slide collision zero
dot Yet collider. The collider is going
to be our object. Object name is going to
be the name of the thing. If brick is in the name, then we're going to take
that collider and free. All right. Let's see how that works if our bricks
start getting destroyed. Go, little yellow go. I did. Our yellow brick got
destroyed, and let's see. All these bricks
should work as well. Since the yellow works, since we're all working
off on the same logic, I don't know why I
moved over to the left. That's completely
ruined all of that. We're gonna have to get the respawn in here
at some point, so we don't have to keep
restarting the game anytime we missed the ball
for testing like this. A boom. He goes. Yes, sir. We've almost got a good
amount of that first layer, and I bounced it off the side, but I think we can
probably safely assume that all the bricks are
working off of this since, again, they're all working
on the same thing. They off brick in their name. We know that we
can confirm that. Fantastic. Alright. So we
now have all of our bricks, our red, orange,
green and yellow. They're all set up.
We can destroy them. The ball bounces off them, perfectly fine.
Proper detections. So next we'll go ahead
and we'll take a look at updating our points
for the next section, which means we're
going to be getting points for every
brick we destroy.
8. The Scoring System: Well, in order for
us to start keeping track of things like score, we actually need to have
a score to keep track of. So we're going to go all
the way up to our Guy here and add a
nice little script onto it. We'll create one. We'll create a
variable called score. There'll be an int, of course, zero. Here we go. And in the ready function, we're going to set
some stuff up, such as the score
as a good example. But I also want to go ahead
and inside of my Due, have the score label and current ball
label set up as well. So I'm going to use
those with the exports. So export Oops, not
storage, export, arc label. That's a label. And same thing. Export VR current
ball label has, of course, a label. Now I can select
those in the GUI. Inspector, click assign. Score label will be
the score label. Current ball will be
the current ball. Okay. Now I'm ready, we can now set. Score label dot text equals GORE we need to pad it
and convert it to a string, so STR at the beginning,
open parentheses. Put score inside, close the
parentheses and do pad zeros, and we're going to pad it with three because we
can definitely get up into three digits with
this game. Easy enough. And we're going to need
another variable here for the current ball current ball and start at one as
it does in the game. And we'll make sure to set that for our current ball label. So current Ball label
dot text equals a string of current ball. Now when you run it,
it's not going to look any different than
what it did before. And, of course, we're still
not getting any points, but like you said at least see that nothing is broken,
which is great. Let's see. So what
do we need now? We need to actually
update our score. And when we do that, we need to update the
text here. All right. So let's go to our ball script. And when we hit a brick, before we collide with
it or before we free, we need to check or at
least we're going to check I yellow in object name, do this, and we'll just
continue this down a few times and we can
change this into actually, we only need one if because only one of these
should be able to trigger. I got that backwards. I started the first time. Elsif. That's what I was
putting. And all we're going to check is yellow, green, orange and red. And all we're going to do in
here is update the score. And to do that, I think
we can either grab the GUI or we can create a
signal to send up to it. Now, since I don't think we've learned a ton of
new concepts here, I'm going to show you how
to create your own signal, just like if you look
at the inspector and the node tab and you
have these signals, I'm going to show you how we
can create our own signal. So just like the variables, you just type the word signal, right, because we want
to create a signal, just like you type in VR when you want
to create a variable, and then you put
in a signal name. So this signal is going
to be increase score. And I'm going to have to pass in a num as an inch like that. So the signal is increase score. Is it passes in an argument and that
argument is an integer. Now if we were to
take a look at that inside the inspector,
click on Ball, click on the No tab and
we can actually see our custom signal
here all set up. Now, we can double click that
and connect it to the GUI, and I think that's what
I'm going to do here. Double click, GI, Make
sure it's connected. Sorry, click, hit Connect. Now here on GI we'll be
able to update our score. To do that, we can do SCOR
plus equals NUM Great. And just like we
did on the ready, we can just update
the score label text and, of course, pad it out. All right. Now, this isn't going to work yet because we
have to go back to our ball because we're never sending this signal
at any point. So we need to think about
where do we need to send this? Well, we need to send it here and here and here
and here, right? Anytime we got these bricks
to pass in the score. So we go to increase
score dot emit, then we got to pass
in our argument with the yellow brick,
it was one point. With the green brick, I was three points
with the orange brick. Oops, I copied the
wrong thing now. With the orange brick,
it was five points, and with the red brick,
it was seven points. So if we do this now
and we hit play, we should now see our
score right up here, updating every time
we break a brick. So let's go. We should
get one point here from the yellow bricks. There we go. So we are now getting points. That ball was moving so
slow that eye lost at an embarrassingly slow speed as it lazily drifted to the left. So one point, boom,
bounce it up. We'll get one more
point. Bounce, bounce. And you notice we
are only getting these points when we hit the
bricks just like we should. So that is great. Boom, boom. As the paddle was
a little longer. Alright. So we got our points working. We're sending out our
signal is working, sending out the right numbers. We can easily assume that these numbers are going to
work perfectly fine, as well. And do we need to do anything
else in the point section? I do not believe so. No, next, let's go
ahead and we'll set up our ball count and
ball respawn for us.
9. Bug Fix after scoring: Alright, so I was
playing around here, just kind of make sure things are working
and all that fine, and we actually ran
into an issue here. I'm not 100% sure what happened, but I think the ball hit two bricks either at
the same time or very, very close to each other. Enough for us to get
inside if statement, but not enough for Clider to actually equal
give us anything. So what we're going to do is first clean up object name here. We just set this to
collider dot name. What I'm actually
going to put in another check here
and say, I collider. So this should give us a check to make sure that collider is actually
something and it's not null. And that means I'm
just going to grab everything from line 25 here. Down to collider dot quarter, and I'm just going to hit
tab with it all highlighted, and that should prevent
that issue from happening. Seeing as the issue was, we got into this If statement, somehow, we can put another check in here
as well if we want. We can say greater than zero, even though we shouldn't
get in if it's not already. And then we get the collider, and if somehow the
collider is null, then we're just going
to stop out of there. We're not going to continue. Alright, so I just wanted to throw that in there
just in case you guys came across that as well while you were
playing, just like I did. And, right, so next, we'll go ahead and we'll jump into setting up the
respawn of the ball.
10. The Ball Count: Let's go ahead and get our
response happening here. So the essence of
what we need here is when the ball
goes off screen, then we need to do
what we do when ready and respond it up here with its default speed
and default direction of going up and everything. So there is actually a node
that we can use for this. Now, if we go to our ball, I'm just going to turn it
on so we can see it here. Now, this blue line here is the bottom of our screen,
which you should know by now. And on this ball, I'm
going to go ahead and add a special node called
visible on screen Notifier. Now, what this is going
to do is this has given us a little box space here, and that's the area that
is going to be checking. And once this box is no
longer on the screen, then it's able to
send out a signal to us what'll be up here, the screen entered or
screen exited, in our case, exit signal, and that will
allow us to reset our ball. All right, so I'm going to
double click the screen exited signal from our visible
on screen notifier. I'm going to scroll
down to my ball, select it, and
connect my script. And what we're going to do here is exactly what you
would already expect. We're going to grab
everything out of our ready, scroll down, and we can
paste it all in there. But we do have to do
more than just this because speed at the moment, that ball is still
heading straight down. So before we wait, we're going to go ahead and
set that speed to zero, so the ball just
stops where it's at. Because no matter
what our velocity is, it's being set to zero, right? Because anything times zero, then we wait that random amount
of time, up to 3 seconds. We reset the position, set the visibility to true. But the thing is, we
never set it to fals, so we need to do that, as well. We need to do visible
equals false. And if there anything
else we need to reset, yes, because remember
we're going down, which means our V direction must be at negative
one at this point. So before we actually
set the speed, we can go ahead and
do V direction times equals negative one to
flip it back to going up and our speed gets
reset to starting speed. That should be all we have to do nor to get this
respond working. All right. So there's our ball. It goes. It's going to
disappear, and it's going to respond for
us. Boop, there we go. Though our respawn is
working just fine. We just need to keep track
of the ball count now. Boop. There it goes again. Alright, so we have to update
that ball count label. And with that, you can
probably guess it. We're going to go
ahead and create our own signal for this
from our ball. Signal increase ball count. And just like before, we're
going to have a num in there, and it's going to be an int
or we're going to cast it as. And just like before,
select our ball, go to Dno tab with our signals. Double click increase ball
count, connect it to our Gui. And just like before, we're going to do or just like
you would imagine rather, current ball plus SQLs Num, which, in theory,
should always be one. And I think I can
actually set that up as default doubly but here's the label for us to
update that as well. Current ball label dot text equals a string of current ball. I just double checked, and we cannot pass a default
value into there, so that's little unfortunate. But if we just move down, take a look for when
we go off screen here, we can go ahead and
send out this signal. So we'll say increase ball count dot Emit and pass in one to increase the
ball ball count by one. All right. So now when
our ball goes off screen, you've got to reset that
to be off by default. I'll do that. No off,
but not visible. Click the eyeball, hit play. That ball's going to spawn. Goes. It's going to hit a brick. We're going to get a point.
It's going to update. Fantastic. As the ball goes, it bounces off a few
things, speeds up slowly. We get more points
as it keeps going. It's going to go off screen, increase the ball
count 1-2, respond. Speed is all reset. All right, so all we
have to take a look at now is setting up the I guess both of the win and loss
conditions for this game. Which shouldn't be
too crazy difficult. Because for our loss condition, we pretty much just got to
check if we're on ball four, which should be our last ball in this situation because we
only have three balls. So when it goes
down, we hit four. That would be our game
over. And that game over would be a reset
of the whole scene. Alright, so we have
our signals going. We have our ball reset going, and we have our
ball counter going. Alright. Next, we'll take a look at the win
and loss aspect.
11. Game Over and Win: Right, so the first
thing I'm going to set up here is going to be the easiest
one and quickest one for us to be
able to test here. And that's going to
be our ball count. Once that equals four, then we're going to reset the game. So the easiest way to do that is since we
already have all of this setup for our ball is
just going into our Guy. Current ball plus equals num. We update the text,
all we have to do is check if current
ball equals four, and we're going to
get Tree dot, reload. G just reload current scene. And we can test that
in two quick seconds. Just let the ball fly off. I'll just sit over here in the
corner and we'll just rack up some of these ball counts. That's one. Let's get
that second ball. Off it goes. Down. That takes us to three. And
once we lose this ball, it should be a game over
once it goes down below, and the whole scene
should be reset. So we see those
yellow bricks fill in again. Oh, I did not. Why is this? A, yes, because
we can't actually create a timer because the tree is being
reset at this time. So we have this small
bug to work out. How can we fix this? Well,
the easiest way to fix this, most likely, is just changing our order of operation here. And we could just grab a ball
count and move it down one. And that will probably
fix that issue. But will we have any issues with the rest of
our code down here? Let's test and find out.
Let's see what happens. Sometimes that's all that
you need to look at is that order that everything is being called in.
Sometimes that's it. It's as simple as
that, other times you got to find other workarounds or perform other checks to
see if things still exist. Here we go. Run our third ball, and this is where we
should hit our game over. So let's see if we still run into an error or
if that's fixed. Alright, it's fixed.
So in this case, it was as simple
as just updating the order of operation that
everything gets called. All right. So our reset works. Now we just have to check if we have any bricks
left in the screen. And if so, obviously,
the games not over yet, because what we're
going to be looking for is that there are
no bricks left. So how can we easily check that the simplest way possible? Well, the simplest
way would be take all of our bricks here,
all in my case, 176 of them, and we
can just tuck them under a default node for this. So if I just grab this and I'm just going to grab my guy just so I can get my
node up top here. I'm going to add
just a regular node because I'm just using
it for organizing. I'm going to drag it out
of my guy into the main. And the reason I did
that is because if I selected Min and
created the node, it would have been added
all the way down here. Then that would have
been annoying to be able to pull it
all the way back up. So I'm just going to
move the node down, then I'm going to click
on my first brick, scroll all the way
down, hold shift, click on my last brick. That should select
all my bricks here. I'm just going to drag it
up inside of that node. I'm going to rename this
node to being called bricks. And that should
have no effect on our gameplay, but
I'll take a look. Just on the off chance
something somehow broke. Take a look. Bricks still destroy,
score still update. Ball still gets counted,
still response. Fantastic. So we
have broken nothing. And the reason why we
did this is because the easiest way is we're just going to say, Hey, bricks no. Do you have any bricks left?
Do you have any children? Right? Do any of these
176 bricks exist still? So when that happens, we can actually do that on our We can do it on the ball or we
can do it on the Gooey. I was going to say
we could do it either when we're emitting the signal to increase the score or when we do
increase the school. I think we'll do it when we
actually increase the score. Right? Yeah, so right here,
we'll emit it or sorry, we'll update our score, and then we'll perform
our check here. So to do that, I'm going
to go ahead and do an export of our bricks. I'll call it bricks container, and this is just a node. And I click my Guy. Make sure I go to
the Inspector tab, hit the assigned button. Elect bricks. Now when I update my score, I can say I bricks container, Do have a has children? Probably not. Now. So get children or get child count. That
would work as well? And just for my own sanity, I'm going to go
ahead and print it. So when we destoe
our first brick, we should have 175 printed out to us down
here in the console. 176 now. Okay, so may either my math is
somehow off or that counted before the
brick was destroyed. Right. So that would not work for us then because the brick has already been destroyed or sorry, the bricks not destroyed
at this point. So that's a shame. Not going to be able
to do it there. Though I'll delete
that variable. And that means I'll head over to the ball. And we'll come down. This is where we're going to cue free based on the collider. And the collider, the parent
should be our bricks. So I'll go ahead and
we can store that. Actually, we just
store that up top, like we did normally,
there's no reason to keep grabbing it every time
we collide with something. So export var brick
container as just a node, select our ball, hit a sign, select the bricks container. And after we call
collider dot free, we can go ahead and paste in our I statement that
we were using before. What did I rename it? I said brick container
said it bricks. There we go. Have to reset
that now. There we go. So now, it's just a typo
from copying it over. So if it has
children after we've deleted a brick, then we're
going to print it out. So our first one
is destroyed here, we should have 175 for
the correct number. That is curious, and
that has make me want to double
check the math now. Yeah, I have 22, 22, 44. So it's 44 per color. So that's 88 on the bottom half, 88 on the top half, there
should be 176 in total. I must be a little crazy. Let me check that right when
the game starts. Yeah, 176. So it's counting
it before it gets free is the issue. Got it. So if you're curious
why this happens, this is because Q free
here it's not freeing it. It doesn't free the node, right? It's not getting
rid of the brick. That second it's deleting
it at the end of the frame. Though since we are still
getting this information, our frame has not
been completed. We're still getting the
incorrect information. So what we need to do
here is we need to use that awake keyword and
we can get our tree. Only instead of
creating a timer, we're actually going
to look at no, not idle that was
renamed process frame. I guess, in our case,
we could just look for I think they have
a physics, right? Yeah, a physics frame. So that'll wait until the
next frame where this gets called. And then
we'll get the number. So this should now give
us the correct number of 175 when that
brick gets destroyed, and if so, then excellent. There we go. 175. So we now have our bricks
being counted correctly. Man, fantastic. Look at that. Look
at that brick, go. Go, little ball, go. You're
getting up some good speed. Yeah, look at you go. I need to stop before I
just get into this, and I just sit here
playing for a while. We lost the ball. But you can see this can definitely get fun
once you get into it. All right. So keep that in
mind, we do have to wait for the next frame
and then get the count. So now that we have the count, we need to check
what we specifically need to know if
there is zero left. So if count equals zero, Go. Then this is where
we need a game over. Alright. So we can do we want to do want to
wait for a few seconds, or do we just want to reload it? Let's just go for the reload. Tree reload current scene. And so we don't have to sit here all day just to test this. I'm going to go ahead and we'll remove the majority of
these just for this test. Don't worry. I've done that, but I can hit Control Z
and put them all back. As you can see, I'm
just doing this temporarily and just give
us two yellow bricks. So if we store both of those, we should get a brand new game with everything
getting reloaded. And if this ball could speed up a little bit,
that would be great. It appears I deleted the wall. I was wondering where that went. Because, of course, I did. I dragged that tolo, and maybe we can just go even easier and just give
ourselves one brick. Because we saw when we
still had a brick left, obviously, it was
still counting. We were still playing. So if we could skip that ball over there
to that one yellow brick, that would be great. I think I threw that into
the right spot, boom, and our game reset
with our well, new game having only
the one brick here. But yeah, there we
go. That works. And I think what I want here, I'm going to put
these bricks back. But I think what I
want personally before reloading is I think I
want to wait a moment. So I'm going to say I'll
wait Ge tree, create Tr. And I think I want to have
a two second pause here. Or even a 1 second
pause would be nice, just so that we can see that the brick has actually
been cleared. And you could go even further if you wanted
to expand on all of this, there are modern
versions of this game. There are some that
add power ups, multiple balls, and so on. So if you wanted,
you could always go through and add all
those kind of things. It's as simple as the things
that we've already done, its detecting if
we hit something, we bumped it, if so,
do this. Do XYZ. And I noticed a little
bug down there, so I'm just going to stop
the ball speed as well. Speed of the set
speed equals zero, and that should be fine for us. But even if it didn't fix that, it's not going to affect
anything in our game here, but it is something
that we should probably address and strive for to have no deep buggers down
there. All right. So we've got our score working. We've got our game over.
Should be working. Yeah, 'cause we went down, we hit four balls and
the whole game reset. We had the win reset for us. We're keeping track of score. Yeah, I think that's everything. We don't really need
to add anything else. We have the classic
game recreated here, and if you want to add any
more of your own features, you could always come
back and add onto it. Go with that. That's breakout, the classic game from 1976.