(train whistle sound) - Hello, welcome to a coding
challenge, Angry Birds. Although, my birds won't be angry, they're going to be loving loving birds. But maybe they won't even be birds, they'll be like cute little Coding Train characters, but
that's not the point. I am going to program a version, a much simpler simplified version of an Angry Bird style clone. I'm going to use p5.js,
I'm going to use a physics library called matter.js, and I'm going to get started in one moment. But first (laughs) let me
diagram out what I need. So, I'm going to use an
object-oriented programing approach. I'm going to need something
called like a box. So, this will be a box class. I'm going to need something like a bird, we'll just call it a bird for right now. And I also need, the ground. So, I'm going to start my
simplified Angry Birds, it's going to have a
single box, a single bird. The box is sitting on the ground. I'm going to want to
toss the bird at the box and knock it over. And from there, the glorious games throughout the universe that you will make maybe will follow. This is the p5 web editor,
I'm going to use p5 for all of the drawing stuff, and I'm going to use the
physics library matter.js for handling all of the physics. Now, matter.js does have
rendering built into it but I'm going to do things my sort of way of combining both libraries so that I can do all the
rendering custom in p5, and maybe by the end of this video, have some of my Coding Train characters inside of this little game that we make. Alright, so, first I want to take an object-oriented approach and I'm going to do Add
File, and I want to add, I need a bird.js, and I'm going to make something called a box.js. And I think I'm going to be able to use the box for both. I'm going to use the box class for both this thing that can
actually get knocked over, and the ground, which needs to be something immobile, static. So, what does a box need to have? It needs to have an x,
it needs to have a y, it needs to have a width, and
it needs to have a height. And I'm going to require
that all of those arguments are passed in, via the constructor. Then I'm going to, oh, and so I need to put the arguments in here, x, y, w, h, and I need to, what do I need to do? I'm going to write a show function, and in here, I'm just going to say, I'm going to use fill to make it white and I'm going to say rectangle this.x, this.y, this.w, this.h. Okay, so, this is the
basic idea of a box class, with no physics, this is just the data about a box and this is me drawing it. So, now, in the main
sketch, I'm going to say, let ground, I'm going to have a
global variable called ground. I'm going to say ground equals a new Box, and it's going to be, the
x is going to be at zero, the y is going to be at
like height minus 20, and the width will be the
full width of the window, and the height will be 20. And then I'm going to say ground.show. Now, it's giving me all sorts of errors like it has no idea what a box is, and the reason why it has
no idea what a box is, is because even though I
added a new JavaScript file, I didn't add it to my index.html. So, let me go and add it
to index.html, box.js. And there we go look. (bell ringing) Step one is done. I have the ground. The ground is there. Now, the next thing I'm going to do, is I'm going to have a box. I'm going to just call it a box. A box is another new Box, and let's put it over to the side in some arbitrary place. And say box.show, there it is. I want it to be tall. I don't know what I'm doing exactly yet, but something like this, there we go. Okay, so that's the thing that
I need to throw my bird at. Now, I need another class. I'm going to do Add File, and
I'm going to call this bird, oh, look when did I? It like knows what I'm
going to do in advance, isn't that crazy? I think I've written other things in the p5 editor with a bird.js. bird.js, class Bird,
and I'm just, you know, I probably could maybe
use inheritance here, where I made some videos about recently, but I'm just going to do like a sort of horrible copy paste job. But I'm going to change this to an r, to indicate radius, because my bird is going to be a circle, and this dot r. And now I can say let
bird, bird equals new Bird, and it'll be at like 50
pixels over, 300 pixels down, and with a radius of
25, and oh, doesn't know what bird is yet again because I now also need to add
bird.js to my index.html file. So, I've got the bird, I've got the box, these are all the elements. So, I have all the elements
that I want in my scene. Ultimately, I'm going to want
to have like a stack of boxes and use images to make
this have more personality. But the next thing that I need to do, is add physics. Now, I could use, you
know, I could start doing, adding some functions to
do all the physics myself, but I would like to use a physics engine. The matter.js library
is released through NPM, node package manager. So, I can go, and everything NPM, it's already like appearing in my, 'cause I looked for it
before I started this. But if I just go to unpkg, unpackage which is the content delivery network for NPM packages, and do matter.js, and hit Enter, we can see this is the URL for the matter.js library. I want to get the minified version of it. So, I'm going to also add .min.js. So, now I have this particular URL. I can go back to the p5
web editor, index and html and I can, I'm just going
to like paste it here for a second. I'm going to grab one of these. These are the script tags
for the p5 library, right. And so, instead of, I've
got p5, p5 dom, p5 sound and now I want to add
matter.js as a library. So, these are now all of my libraries, and all of my custom JavaScript code. And if I go back to sketch.js. Let's make sure the matter
dot library has loaded. If I just say console log Matter. We can see yes, stuff is coming out here. The library is loading. That would obviously say if
I hadn't loaded that library, I don't know what you're talking about. So, I have a whole bunch of tutorials about the matter.js library. So, I don't need to spend. I can refer you to those if
you want more background. But basically, I need to establish this idea of an engine object, and a world object. The world is talking
about the environment, and then, each one of these things will be a body. This will be a rectangular body, this will be a rectangular body, and this will be a circular body. So, my classes, box and bird, I'm going to make them wrappers to have inside of them, a piece of data which refers to the actual matter.js body. So, the first thing that I need to do, I think is let's have
a world and an engine. And then I think I say
engine equals Matter. Well, I think I better do this first. engine equals Matter.Engine.create, I don't know, I'm guessing. I think that's right,
having done this before. And then I think the world is actually created when I create the engine, I can just grab it from the world. So, now I have the matter engine, and the matter world. Then inside of my objects,
what I want to do, let's just do the box first. So, here instead of having an x, a y and a width, and a height. Although, I think I might keep the width and the height just to store it. I now want to add this.body
equals Matter.Bodies.rectangle. This is a function that
in the matter library, will create a rectangular
body object for me. And I can give it, I'm going to do this first. Like, I don't, this box
object no longer is going to have its own x and y, it's just going to give the matter body, the x and the y. So, I'm going to say x, y, I think this is actually what it gets. And then I need to say Matter.World.add to the world, this.body. So, I need to actually
put it in the world. So, what happened to the box? Oh, oh, oh, I took out this.x.y, so now, the whole point of this is in show, I want to ask, I want to say hey, Matter. (laughs) I want to say give me a position which is this.body's position. And now, I'm going to draw the
rectangle at pos.x, and pos.y. Now, there may be a way in fact, that I could dig into the body and get its width and height
but I'm just going to store those out of convenience for myself. The size of these rectangles
is never going to change, so I can keep that. There is a big issue here though. Which is that, one, is that
once I start adding the physics, the box could wobble,
meaning it could rotate, so, I'm also wanting, I'm also
going to want to get an angle. And I am going to want to
then draw it with rotation. So, I'm going to say push,
I'm going to say pop. I'm going to say, translate pos.x, pos.y. And then the rectangle's at zero, zero. And I'm going to rotate by that angle. There's another little weird nuance here. So, I like for myself,
I like to think about placing the rectangle with
the x, y in the corner, and then the width and the height, and that's the default behavior of p5. But matter.js, when you make a rectangular or circular object, the x, y position for that object is always in the center. So, this actually have told matter.js where the object is and drawn it in a different place. So, I need to reconcile those two things. So, to reconcile those two things. There's a few different
ways I could do it. One, is first, I should
say rectMode CENTER. So, that I'm drawing. But now you can see everything's
off in a weird place, which is maybe fine, maybe
I just need to rethink where I'm placing the stuff. For example, the ground would be now at, width divided by two, height minus 10. So, that's the same thing. So, that's fine. (hands clapping) (laughs) That's one way of doing it. And my rectangle is in a weird place. But I'm not going to worry
about that right now, I'm going to position
stuff and I obviously could use some math to get it to rest perfectly on the ground. But I'm not going to worry about that. Still, there's no physics happening. Why is there no physics happening? I created the body, I
added it to the world. It's because I'm not running the engine. So, what I need to do, draw is my loop. So, basically I need to say every time through draw step forward in time. So, I think I can just say engine.run, no. (bell ringing) I looked it up. I probably could have
shown you me looking it up, but it's not, how do
you look this stuff up? Let me show you, looking it up. So, if I go here and I go under engine, and I scroll through here. I could be like, oh, where's
that engine.run function. Oh, it is there, how interesting. But that's not, oh I forgot
to say Matter.engine, but that's actually not
what I want. (laughs) I want to use update. I think there's two different
ways of doing things. Engine.run will just
set the engine running. But I want to lock step
my p5 animation loop with my matter physics engine, so I'm going to use update. So, and what I'm going to do then is in here, I'm going
to say Engine.update, but I need to say Matter.Engine.update and there we go, oh, did you see that. The physics is happening. (sighing) But the ground fell out below
us, we're sinking. (laughs) It's okay everybody, we can
violate the laws of physics and create an object with
infinite mass that never moves. The ground can be known as a static, it can be a static object. So, objects that you create in matter.js, the physics engines can
be static or dynamic, by default they're dynamic. So, the tricky thing here is I'm using the same box class to describe both the ground, and that rectangle. So, I could separate them if they really are different, or use inheritance, but maybe, why not? Let's use inheritance. This will be fun. I've been talking about
inheritance, let's use it. So, I'm going to add another file. I don't know if this
is the best technique. I'm going to call it ground. And I'm going to say class Ground, oh there's a problem with
this idea but it's fine, extends Box (laughs) and then
I'm going to say constructor. It's going to get a x,
y, width, and a height. I'm going to say super
x, y, width, and height. So, now, the ground is a class that inherits everything from box. If you don't know about inheritance, I'll refer you to my video about that. And I can go into sketch, and I can now say ground
equals new Ground, and it's not defined because I have to add it to my index.html, there it is, hello. Alright, now, what still? Still. (bell ringing) Wow, something really crazy happened. I kind of forgot that the order, it usually doesn't matter for me because I don't have
anything really happen until the setup function in
draw, and everything has loaded. But I can't reference the
Ground.js JavaScript file before box.js 'cause it's extending box, and as it's loading the DOM, it's got to look at the box file first. So, this actually is one
of the rare instances where I've got to put this script tag before that one, no. (laughs) Oh no, that's the bird. Yes, this is going to work any second now. Yes. Okay, oh, it still goes away. So, now I need to figure out how do I just change one thing to make this static? Can I do this? this.body is static equals true. Yay. Okay, so, this is the idea of I have a whole other kind of
body that extends box, it does everything the same way, but I can set an additional
variable isStatic to true. And so, now, when this runs, we've got our Angry Bird box thing over there, and now we're ready to
start working with our bird. Oh, okay. So, let's work with our bird now. So, we need to get rid of the x and the y. I'm going to say this.body equals Matter.Bodies.circle, x, y, r. I'm going to do the same thing. I'll actually worry about rotation. So, I'm going to sort
of cheat a little bit, by just copying this over, 'cause I don't feel like typing right now, and then just change this
to circle, and this dot r, and there we go. And then I also should
say Matter.World.add this.body to the world, or this.body to the world. There we go. Ah, it's rolling away. Alright, excellent. So, I want to be able to toss this bird over here to this rectangle, how do I do that? Well okay, maybe I do an if statement to see if I click the mouse
inside it, then I grab it. Well, one of the nice things
that matter.js provides is this very general thing
called a MouseConstraint. So, I can add, I'm going to add,
and this is a little tricky. I'm definitely going to
have to look this up. I'm going to call this
mConstraint for mouse constraint, and then I'm going to say
mConstraint equals matter dot, alright we're going to
have to look this up. I want a MouseConstraint. Create engine options, okay. So, this is what I want,
matter.MouseConstraint.create. So, I'm going to say,
Matter.MouseConstraint, was capital, MouseConstraint.create, and give it the engine. Okay, so, look at this,
options.mouse was undefined, options.element was undefined. May not function as expected. So, matter.js is giving
me a nice warning here, explaining that well you
made this mouse constraint, but you need tell me
where you're going to be clicking the mouse, I need to know where you're clicking the mouse. And where I am clicking
the mouse is in the canvas. So, I could like if the
canvas is a DOM element, does it have an ID. Well, one of the nice
things about using p5 is I can just store in a variable, the result of createCanvas
which is this canvas object. And I should be able to now say, I should be able to give it some options. And then so I can add
a second argument here, which is options, and I think I need to
just give it mouse null. I'm just going to put things as null, and then element null. (bell ringing) Alright I'm back, after
looking up what I need to do. So, what I forgot is
that I need this mouse. So, I need a separate mouse object that I can use to create and manipulate those mouse inputs. One of the interesting
things, there's a live chat going on right now as I'm recording this. And Alka wrote a nice
suggestion for aliasing all these matter dot things, you'll notice how I'm driving to write matter dot, matter dot, matter dot everywhere. So, I'm going to actually
just go over here and take. I forget what this is called, but this is kind of a new fangled JavaScript thing, where I can basically
just make a nice list of all these objects I want. I'm at Engine, World, MouseConstraint and I'm maybe going to use Constraint, and I can just set that
all equal to Matter. So, basically, this is me aliasing everything that's matter.Engine, matter.World, matter.Bodies. So, in theory, I should be able
to just say Engine now here, this makes things a little bit easier, just MouseConstraint here. So, my code is a little bit more succinct and I'll go back and fix that in other places, as necessary. But, what I need here is a Mouse, and I need to say constant Matter mouse, I'll just call it mouse equals
Mouse.create canvas.elt. So, I need to make a mouse
object with the DOM element associated with the canvas. And then I believe, I can just
put this here, under options. And now, here we go, let me
bring this all the way back. Dare I say, oh no, oh, so close. Oh, what did I forget? I probably have to add it to the world. World.add world, mConstraint. Yay, look. Now, I can pick this stuff up and I can toss it, oh look come on. I can do better. Yay, oh, goodbye. What's left to do? I want to add a few more boxes. I want to put images instead of these, just these boxes and circles, and I think I should try to add a slingshot,
even though right now, I could kind of just toss it. Okay, the first thing would
be just adding more boxes. So, I'm going to change box to boxes, and I am going to now
have a little for loop, i is zero, i is less
than three, i plus plus. And then I'm going to say
instead of a single box, I'm going to say boxes
index i equals a new Box, and then here I am going to then say for let box of boxes,
little for loop, draw them all. So, now you can see, look at that, What's so crazy, is when I start
them all at the same point, the two objects cannot appear, cannot occupy the same
space in a world of physics. So, they like burst off from each other. But let's do something like
say, 300 minus i times 75, which will stack them. So, now I have little stack of boxes, and then I can toss it, and there we go, I didn't knock them over. Oh, whoa, I threw it over. So there's some nuance here
to how physics engines work and how I'm going to need to
create some balance in the system. And you know, one of the things there is I probably need to increase
the number of iterations per update in order for
it not to be able to move so fast, just to jump over the stuff. But let me just run this again. I want to really see if I
can knock those things over. Yay, I knocked them over. I could also play around
with the properties like restitution and friction, which are physics attributes of
each of these objects, restitution being
elasticity or bouncyness. So, maybe towards the end of this video, I'll try adding that. But now we're in pretty good shape. So, let me add the slingshot. So, what I did right now, is I created this idea of a MouseConstraint, and a MouseConstraint is
this very generic constraint that just like, any time
I click on something it'll make a little spring like connection between where I click the
mouse, and the object, so I can move it around. But what I want, is actually to introduce, a constraint maybe right here,
that's fixed to this point, and only attached to this particular bird. And I think it's probably
smart for me to wrap this into a class. Because I'm really going all in on this object-orientated
programming approach. So, let me make another JavaScript
file called slingshot.js, and let me just right out the outset, remember that I need to
refer to slingshot.js, then class SlingShot. So, what does a slingshot need? So, I think it needs an x and a y, like where is the point from which this object will be attached? And then it needs. Oh, no no,
that's not where these go. It needs an x and a y,
and then it needs a body. So, now, I'm going to create,
let's call this this.sling, equals Constraint.create and then options. I think this is how that works. And this should be Constraint. (laughs) Constraint. So, I'm going to make up some options now. So, I need to configure that Constraint. The two things I want to be connected, with this constraint are a point, which I'll call pointA,
this is in the matter.js documentation specs,
pointA, which is an object with an x, which will be what I pass in, and a y, which will be what I pass in, and then also it needs to be connected to something else, bodyB. I think it could be bodyA and bodyB, or pointA and bodyB. There's different ways
you can configure it, but I want a point and a body. I could make another body
that's static body I guess, but a point is the equivalent to that. So, then the body is going to be, oh, I don't think I need an object here, just this particular body. Then I want to say
World.add, this to the world, this.sling. And the other things that
are part of a constraint, I believe, I forget the actual stiffness, like, it's like a spring connection, how stiff is it? So, I think that's actually
just called stiffness. A value of one means the constraint should be very stiff, a value of 0.2, means the constraint
acts like a soft spring. So, let's just try, just to
start with, let's try 0.5. And then, a length is very important. What is the rest length of that spring? Let's make it like 20 pixels. So, now, I've created this slingshot. I also think it would make
sense for me to draw it. So, I'm going to do a show, I'm
going to make show function, and I'm going to say stroke 255,
and I'm going to draw a line, well, let's make posA
equal this.sling.pointA. And posB equals this.sling.body.position. These are the two things that the sling, the string, the spring, the connection, the constraint is attached to. So, draw a line from posA.x,
posA.y, posB.x, posB.y. Oh, so, I think, by the
way I'm writing this class, I didn't even make the slingshot. So, now, I need to go into sketch.js and I'm going to make a
variable called slingshot. I'm going to say slingshot
equals a new SlingShot. And I need to give it a x and a y, which where did I make the bird 5300? Let's just put it in the same place. And then, I need to connect
it to the bird's body. You can see already, look, this is kind of like
stuck somewhere, right. This is great. But let me draw it, 'cause I think that'll make it more obvious. slingshot slash show, and what did I call it? slingshot show, ah PosB. Oh, bodyB, it's pointA and bodyB. So, if I do this. Right, you can see there it is. Now, okay, this was some goofiness here. So, one thing that's really weird is that if I drag the mouse off, the mouse constraint gets confused, and thinks it's stuck. So, that's just an
interaction design problem, that I have to iron out at some point. Let's change a few things like let's make the bird much smaller. Let's move everything over a little bit. Just to give me little space here. So, now, we can see and maybe
I should make that rest length a little bit longer, there we go. And maybe the stiffness should be a little bit less, there we go. So, I'm pulling this back. The idea is that I'm going to pull it back and let go, and I want it to fly. So, we're getting there. I have this slingshot now. Now, how do I release it? I have to come up with
a way of releasing this. I need a way somehow, to launch this bird off of the slingshot. Like the slingshot should be broken, and the constraint should be broken, and it should go flying. So, first let me least
create a mechanism for that. So, let me write a function here. I'm going to call it fly. And I think if I just say
this.sling.bodyB equals null. Like if I just detach the body then the thing that's attached
to it, will go flying. So, let's just try in, let's
just add, just as a test, a keyPressed function. If key equals space, then slingshot.fly. So, again, I need to figure
out when it should be flying. But if I just hit the space bar, cannot read property position
of null, slingshot line 24. So, okay, so only if
there is a body attached, then should I bother to draw the line. Okay, so, I need to also not draw the line if there's no body. So, let me run it, there we go. We can see (laughs) now
could I possibly time it? Like now my interaction
is, I have to do this. Yeah, but I shouldn't have
to hit the space bar, right. I shouldn't have to hit the space bar. So, how can I determine a time where I should have it fly? What if I were to get
the body's speed right. So, a suggestion came in the chat to just look at when
the mouse is released. I think this isn't going
to work, timing wise. But let's try it. What if I just write
function mouseReleased which is a global p5 event
for when I release the mouse. And there I could just say, slingshot fly. So now, I'm pulling this
back and release the mouse. See, it didn't have a chance to move, before it could start pulling it. So, I could use like setTimeout,
this is kind of ridiculous. I could and then, like do it
in like 50 milliseconds later. Is that right? Maybe it should be more like
a 100 milliseconds later. Oh, that's actually kind of great. That worked. Weirdly, just giving
it a little time later. I was going to go through this whole thing of testing its speed. You know what? This is good enough. I think you could probably, those of you watching, you might want to come up with a different solution. But I'm surprised that
this actually worked, just the little setTimeout, just give it a 100 milliseconds later, thank you to Betatester704, who maybe was the one who suggested that. So, this is great. We have Angry Birds. Now, one thing I should
say, is like, at some point I want to be able to like have a new bird, and so, there's a variety
of ways I could do that. Let's use keyPressed. We'll just use a key press right now. And I could say, remake the bird, and then I could say, slingshot.attach this bird.body, and then in bird, I mean
sorry, in slingshot, I could say, attach, get a body, and I could say this.sling.bodyB
equals that new body. So here, now, what I
should be able to do is I should be able to let it
fly, knock the stuff over, and then, oh sure I
want to probably detect when it should do this. I can hit space, oh no sorry, oops. Space and then, oh there
is, there's a big flaw here in my system, I'm not
going to worry about it, this is good enough because
I could like, first of all, I can use the MouseConstraint (laughs) the MouseConstraint
will let me do anything. And then I can also release, when I release the box,
also the bird gets released. But you, the viewer, these
things can be cleaned up. These are interaction design problems. There are better solutions. This is kind of exciting. I've got the basics of Angry Birds here. Alma writes, you should utilize
the concept of potential and kinetic energy for it, it's just a pure projectile thing. So, I would love to see somebody
make a variation on this, and submit it to thecodingtrain.com. There's a way that you can submit your versions and doing that. But I just got one more
thing I want to do. I want to add some images to this. Before I add the images, there
is kind of a big bug here that I really should
fix, which is that when I put the new bird in, there's actually another bird, that old bird is still here, I'm just not drawing it anymore. Maybe I want it there, or
maybe I should remove it. But probably right now, I should just say World.remove bird.body world. And its always the other way around. So, I believe this. Right, let me see if I
can show you what I mean. Right, I'm going to shoot this over there. Now, notice this is here, I'm
not going to see it anymore, but I'm going to try to shoot
it right over there again. (laughs) See how it hit
the invisible thing. So, let me remove it. And that should fix that. So, if I do this. And it's there, and then
I do this again. (laughs) I do this again. Anyway, you can see it's
gone, it's removing it. So, there are different ways
that I could approach this. A Simon in the chat is pointing out that instead of just making the bodyB of the slingshot null, I could actually remove the slingshot, I could reuse the same bird by just
resetting its position. So, again, you might make, have a different take on this, refactor this in a different way. But I've got the basic idea down. Now, I want to start adding images. Alright, so, I have all these
Coding Train character images designed by Jason Hegland,
thank you for that. I'm going to use the dot for
the bird, a little smiley dot, and the angry equals sign for the block. Now, this block is square
I think, not rectangular, so I'll probably have to
adjust the dimensions. But the first thing I need to do, is upload these images to the web editor. So, the way that I will do that, is by just going over
here, doing Add File, and then I can just drag
these two images in. You know, I could put them
in a folder or something, and we can see they're there. So, now I have dot png and equals png. And you know, there's
probably a thoughtful way, that I could think about what if I want different blocks
to show different images, but I'm just going to
in a very simple way, use the preload function of p5. I'm going to have a
variable called dotImage, and a variable called boxImage. And I'm going to say dot image
equals loadImage dot.png, and boxImage equals loadImage, what is it called? equals.png. And let's first just
change the bird to show, instead of a circle, instead of fill, I'm just going to say image and
then I'm, what was the name? dotImg. Oh, and then I want to
say, imageMode CENTER, and then I'm going to have to say this.r. And this should be
this.r times two really. If I'm thinking about that as a radius. So, there we go. So, we can see now I've got
the little dot, it's so tiny. I should make it bigger. And I think what I
would prefer to do also, is draw the slingshot behind the bird. Okay. So, now, I have my dot. There it goes. Now, I just need to replace those blocks. So, the boxes. When I make the box, I am in sketch.js. When I make the box, I'm
giving them an x and a y, and a width, and a height. Let's just make them square right now. I could have an image that's not square. So, they're much larger
now, but that's fine. And then, what I'm going to do is in box, let's change I to image. image, what did I call it? boxImage, there we go. Oh, we've got a problem. (laughs) So, the ground is messed up now 'cause the ground is also the equals. So, and we also have to say
imageMode CENTER, (laughs) the ground is this like
smooshed equals, but guess what? Not to worry, I used inheritance. Oh, I'm so happy I used inheritance. Then I could just override
the show function, and there's probably a more
thoughtful way I could do this, but I am just going to
put this all in here, and I'm just going to
put this back TO rect, and back to this. And now, there we go. So, I now, here we go. (drum beating) I have my Angry Birds
clone with p5 and matter.js and I'm going to pull
this back, release and, oh wait why did it make
it so small? (laughs) So, one thing I really need to do a lot of
(energetic rock music) refactoring of this, because I did something very silly here, where I remake the bird,
but I use a different size. Which having a hard coded
value here is pretty bad. Right, let's try this one more time. (drum beating) Right. Wait, wait, wait, wait. I have an idea, I have an idea. Let's add restitution. So, I'm going to go to the
bird, and when I make the body, I could also add some options. For example, one option
might be restitution, which is like elasticity. Let's give that a value of one. (laughs) Let's look it up in the documentation. Always positive and in
the range, zero to one. A value of zero means the collision would be perfectly
inelastic and no bouncing would may occur. A value of 0.8 means
the body may bounce back with approximately 80 percent
of its kinetic energy. So, let's try giving it a value of 0.8. Oh, guess what? I can make up this variable called options till the cows come home, but if I don't actually put
it in creating the body, it's not going to make any difference. So, now, let's see how
that changes things. There we go. (laughs) It's kind of like Jenga, where it just like slid out a little bit. Oh, wait a sec, it's even bigger. Whoa, okay, oh, things have
gone really off the rails here. This is supposed to be 25. And let's be a little bit more kind, let's give it 0.5 and
let's also go to the box, and let's give that also a restitution. Okay, here we go. (drum beating) This is my angry birds game, made with p5 and matter.js, and Coding Train characters. (laughs) Oh, fall, fall, fall. Yes. (triumphant classical music) Thank you for watching
this coding challenge. Sorry to interrupt, I'm
about to wrap this video up, but I want to show you two quick
improvements before I finish. The first one is, when
I loaded my Coding Train equals character, it was a square image, and there's actually a lot
of additional extra space on the width, and so there
is some funny physics happening that looked a little bit off. So, I'm now actually cropped
and re-uploaded that image. So, that it's 84 pixels by 100. The other thing that,
thanks to a suggestion, I increased the mass of the bird's body. So, the matter.js will give elements a sort of default mass,
probably based on their size and their geometry, and
I just take the bodies and set its mass to its
own mass times four. And so, now, if I were to play my game. (drum beating) One more time. Let's zoom in on this. And go. Boom. Yeah. I am so angry dot Shiffman coding. Oops sorry bonk. So, this is my version,
there are so many flaws to what I've done here, in terms of how I've organized the code,
there's some like weirdness in the physics, I haven't really been sort of thoughtful about the design. The whole slingshot
mechanic is kind of off. So, there's a couple things
you could do for me here. Number one, go to
thecodingtrain.com, find the page for this challenge, the
source code will be there, as well as any other supplementary links, and you can submit your own version. Maybe you just want to improve
the way I wrote the code, to make it better organized. So, that people could see that. Maybe you want to make your own delightful design of a scene. Maybe you have a totally
other game mechanic and idea for how the physics
of this world should work. Maybe you actually want
to build this out to be, you have more features,
and levels, and score. There's so many possibilities. So, make your own version of this, you don't need to use p5, you
don't even need to use matter. These kind of concepts will extend to other drawing libraries
and game engines. Phaser might be one that
you should take a look at. Even perhaps, you can check out the video from Catt Small, about using Phaser and
codependents on this channel. And I will see you in a
future coding challenge. Thank you. Mwah, goodbye. (energetic electronic music) (bell ringing)