Multi-room Platformer Game Tutorial with JavaScript and HTML Canvas

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] foreign [Music] platformer we're going to start by creating a basic physics simulation that uses classic Concepts like acceleration and gravity then we'll restrict our player to a certain area using Collision blocks derived from a third-party map editor will completely transform our player by adding in Sprites and animation and code the functionality required to move our player from one room over to the next giving us the ability to create a complete World in which our users can travel and explore this course was made possible by today's sponsor and to the am into the am is a clothing company that makes premium high quality apparel and over the past month they decided shipping out a few t-shirts now I'm not just saying this as a sponsored party but these are honestly pretty much all I've been wearing over the past month they fit me near perfectly and whatever material they're made out of is just way softer than anything else I have in my dresser so they're currently running a bundle deal for teas which is three for 50. so if you're interested in grabbing some super soft well thinning t-shirts then click the link down below and on top of this bundle deal you'll get an additional 10 off now let's hop right on into things and start coding so the first thing we need to do to set up our multi-room game is while set up a project so how do we go about that well the way I like doing it is opening up a finder window whatever it might be in Mac or Windows doesn't really matter but I like opening up a window and then finding a directory in which I like to store all my games for me that is personally within a web directory once I'm within the web directory I can right click hit new folder and then determine what do I want this game to be called well the r word for this game is called Kings and pigs so I think that is a perfect name for our game we're going to call this Kings Dash and dash pigs so our game is going to exist within here and now what do I do well I like opening up this folder within my text editor of choice which for me is Sublime Text so to open this up over there I like grabbing this and then drag it onto Sublime Text and what that's going to do is automatically open up our project within Sublime Text should work for vs code as well but if you're a Windows user it might not work all you need to do is open up your text editor go to open and then find out wherever your folder is right here for me it's Kings of pigs hit open it's going to open it up simple enough right so we have this opened I'll go ahead and full screen this and that's just going to be step one so it's going to open up this blank file for us I want this to be the place in which we store our canvas our index.html file so I'll hit command s to begin saving this and I want to save this within our new directory Kings and pigs and I'll save this as index.html now we have a place in which we can write out our code so the code we want to write in here is going to be just simple canvas element all of our game code all of our rendering is going to be rendered out onto this one element right here this is all we need to get started so let's save this and then open up index.html in a browser so to open this up open up my finder double click index.html and this is what our game looks like a blank screen well we did add a canvas element but we can't see it if we right click hit inspect element use the inspector tool right here and hover over this you'll see our canvas element does indeed exist the thing is it doesn't have anything rendered out on top of it we haven't changed its color we haven't changed our background color or anything like that that is why we don't see it but we will be changing this shortly so let's go ahead and make our background black just to get this really harsh white screen off of us because we might be coding at night to get this background color black all I'm going to do is within index.html add a style tag and to select our body element so I'll select body like so and declare I want our body's background to be black the I can save that refresh and now our body's background is black if I inspect this go over to our code over here our body element just takes out the whole screen so when we give this a background of black while the whole screen no it's background of black several enough but we do want our canvas to start rendering out code so how do we use our canvas to begin rendering out artwork well we're going to need some JavaScript if we want some JavaScript we can add in some script tags and begin writing in our code so I want to start by selecting our canvas element and putting it within these script tags within JavaScript land to do that I'll write a const called canvas this is going to be equal to our document dot query selector with a capital S and what element do I want to select from our options up here well just our canvas element that's pretty much all I can grab besides body and our HTML tag which I rendered out automatically in the browser but we do know we want the canvas element so I'll specify it here let's grab our canvas element and now that I have this canvas element I can create a new const called C and set the sequel to Canvas dot get context to D so we're taking our canvas element in JavaScript world and then we're calling a git context method on top of it which specifies we want our context to be in the 2D realm this just means we're going to be using 2D methods to draw on top of this canvas so with those 2D methods available to us now within the C const and C just stands for context by the way this is the one instance in which I'll use a very short variable name because I know I'm going to be using this so much within our actual code I want to grab C and call fill rect with a capital R now this takes four arguments we're basically just drawing a rectangle with this the first argument is going to be the X position of this rectangle or our canvas over here we can't see it yet that's okay let's start off with an X position of zero the second argument indicated by a comma is going to be our y position I want this to start off at a y position of zero our third argument is going to be the width of the rectangle so from these coordinates how wide should we draw the rectangle I want this to be let's just say 200 pixels a start and then our last argument is going to be the height of this rectangle which I'll also say is 200. so we're basically drawing a square with this we can save this and refresh and nothing's going to show because we need to specify what color we should be drawing this out as so if I want to specify a color I'll write to C dot fill Style and set that equal to a color of white with just this I can save refresh and now we're drawing on top of our canvas so great what would I do next well I want our canvas to be the right aspect ratio and I want the aspect ratio to be something along the lines of 16 to 9 because most computer screens are the aspect ratio most TVs it makes a lot of sense to put our game in the aspect ratio as well so to get a 16 by 9 aspect ratio I want to change the width and height of a can of settlement which you can see over there is basically the size of that blue rectangle we want to enlarge this to a 16 by 9 ratio to do that right beneath our C here I'll select our canvas and then select this dot width so we're getting the canvas width what do we want to set this equal to well I already know the value it's going to be 10 24. for a height I'll grab our canvas dot tight and set that equal to 576. so what are these values well if we were to compare these together this is a 16 by 9 ratio in which we want to use for our game and we can even test this out because I know that our game is going to be using 64 pixels by 64 pixel tiles what I can do here is just multiply 64 by 9 for our height and then multiply 64 for a width by 16 and we're going to get to those exact same values we had out there so this will be equal to 10 24 and this will be equal to 576. so that's how we're going to set our canvas width and height we'd save this refresh we don't see too much changing but over here we can see width and height added onto our canvas and if I scroll over this now our blue rectangle is taking up that full aspect ratio of 16x9 1024 by 576 but we do want to fill up our full canvas element with our drawing right here to do that instead of using 200 for a canvas width now we can just use our canvas with property instead by grabbing canvas with and inserting it into fill wrecked same thing for a height let's say we want to use our canvas height fill up the entire thing right there we'll save refresh and I'll exit out of our console right here and now you can see this is going to be the exact location in which we create our game now we're going to begin creating a player very shortly but what else would I do here for project setup the very last thing I think I'm going to do is just move all of our script code over to a separate file that way we can get a little more organized with things so if I want to put all my script code in a separate file I'll create a script tag up above a separate one at least and then add in a source attribute the source attribute is going to reference the file in which I want all of our JavaScript code loaded from so I want it loaded from index.js but you might notice index.js doesn't actually exist within our project we need to make sure that we create this file and then put all of our code inside of it so to create a new file I'll go up to file new file and then I'm going to save this new file as index.js there's our new file and all I want to do now is make sure that I grab all of our script code that we just wrote out cut this on out of the current script tags this means that I can get rid of the script tags that are on their own now so I'll delete those make sure that I have index.html saved go back to index.js and paste in all that code so if we reference things correctly and we save both of these files we can go back over here refresh and everything still looks the same that's exactly what we want it's just the same look but now our code is a little more organized because all of our JavaScript code is within its own separate file so that's all we need to do for project setup let's head back to to do and check off well project setup now that we have our project set up I want to create a player someone that we can move around on our screen and to begin creating a player I want to go over to our canvas and I just want to create the most simple object possible and that's pretty much always going to be some sort of square or rectangle so I'm going to create a rectangle place them on the screen and then I want to begin animating our player downwards and have them stop until they hit the bottom we're going to start adding in some really basic physics and collision detection so to get started creating this effect we want to go back to our code and we're going to reuse the C dot fillrect method but we're going to give it a different fill style so right beneath this let's add in C dot fill style and assign this equal to the color red so our player is going to be red to start now I want to draw out our player this is easy enough I want to use C dot fill rect and then assign it some coordinates so let's say I want my player 100 pixels from the left side of the screen 100 pixels from the top I want my player to be 100 pixels wide 100 pixels tall with just this code I can save refresh and now we have a player on the screen it's that easy but now if I want our player to begin animating downwards well I need to create what is known as an animation Loop so to create an animation loop we're going to beneath this code we just wrote I'll add in a function called animate the function looks a little something like this and within this I'm going to call Window dot request animation frame animation has a capital A by the way and frame has a capital f and this takes one argument another function the function I want to call is going to be the very function we just created so we call animate as our argument right here and then finally if we want to actually activate this code we need to call our anime function down below now that code should be running so how does this actually work right here how are we creating an animation loop with this we're calling animate down here which in return calls all of our code within animate that is simple enough what code are we calling within animate request animation frame which takes an animate function so we're calling this line right here and once we call it we're going back to the very beginning saying we want to call anime again we call anime again well what do we call request animation frame with animate therefore we go back to the beginning and this is just going to keep running unless we tell it to stop so if you want to ensure that your animation Loop is running and pretty much always just console log out syntax it can be anything and as long as you're calling animate refresh and then inspect an element and open up your console you're going to see that goes just being logged out really quickly that's how we can tell that our animation Loop is running so what we're going to do with this animation Loop is start increasing this y value for a player over time and as long as we keep increasing this within our animation loop it's going to look like as if our player is moving downwards it's pretty much how animation works is we have all these different frames and we start altering small little values within them to create the illusion of movement so all this code up here is only called once when this file is initially loaded now I know I want my player right here which is defined by these two lines to be called for every frame of our animation Loop so I'll delete this const log paste in those two lines now for every frame of Animation we're going to be drawing a red square on top of itself over and over again in this location it's not going to look much different we refresh and it looks exactly the same but once we start adding on to this value right here we're going to start seeing that movement so how do we start increasing this value well we need to create a variable a let so let's create a let up above this is going to be called our Y and by default it's equal to 100 because that is the value we're using right here so we can replace our y right here within Phil rect with the actual let of Y save refresh looks the same that's totally fine I'll exit out of my console but I do want to begin increasing this value for each frame of animate so after we go and draw out this rectangle right here I can grab Y and call plus plus to start adding on one to this value so for each frame we just keep adding one onto that initial value we'll go to 101 we'll go to 102 and we'll just keep drawing unless we tell it to stop so let's save refresh and now you can see we have animation in place but it looks like a rectangle or square per se is just getting larger and larger rather than actually falling downwards why is that well for every frame we call our player code right here we want to make sure that we are clearing our canvas by clearing our canvas we're giving ourselves a new slate to draw new artwork on top of and if we don't do that we're going to get this effect over here that kind of looks like a paint Trail so we want to make sure that we're always clearing it to clear it we can call C dot clear react and this just takes the same arguments as fillrect we can just grab the same r arguments up here that we use to initially clear our canvas and plop them within clear rect we save that refresh and now we are clearing our canvas for every frame of our animation but you'll notice that our white background is gone when we call clear rect is actually getting rid of everything we're not drawing on a color so if we want to define a color well we can just grab this code up above with these two lines get rid of the clear rect and then add in fill style and fill rect so we're going to make sure that this fill rect right here this rectangle we're drawing out has a background of white we're not actually just clearing everything completely we're using that white background to make it look like as if we're clearing things hope that makes sense let's save refresh and now things are looking quite great so we're looking good but how do we get our player to stop at the bottom of a canvas you'll see it just keeps on going even when it hits the bottom well essentially we need to write out some code that says only increases y value under a certain condition what condition is that going to be well let's illustrate this well we know that our player is falling downwards and we want them to stop at the very bottom what condition can we write to right here to stop our player well let's look at our variables we have at the bottom the bottom of our player this is going to be the bottom and how do we get the bottom of our player based on our current variables that are actually within our code well we have a y value which is the top of our player this is our y value but if we were to add on to this our player height which is this right here we would get the bottom of our player so to give the bottom of our player we need to take Y and then add on to that our player height which right now is equal to 100. now we know the bottom is one variable we need to track what other variable might we need to track well simply enough the bottom of our entire canvas right here how do we get the bottom of our entire canvas well this is going to be known as our canvas height because when it comes to Canvas elements our coordinate system starts at the very top left hand corner so this would have coordinates of zero zero the further we go to the right the larger our x value is going to be and the further that we go down 1 the larger or Y coordinates going to be so really the two variables we want to focus in on are going to be our canvas height this down here and the bottom of our player and we're going to say once the bottom of our player touches our canvas height we're no longer going to be adding one onto Y and that's going to prevent our player from moving past the bottom of the screen so let's write this code out we need to get the bottom of our player how do we get that well I'm going to write out a Lut right beneath y we could call this bottom we'll set this Eagle to our current y-coordinate which is the top of the player plus our player's height which right now is defined by the fourth argument within fill rect it's going to be 100. so this will give us the bottom of our player but if we want to be more specific with our variable naming we need to create another let can even be a concept we don't want this to change to say our height is going to be equal to 100 and now we know that this fourth argument right here is our height it makes it a little more descriptive within our code of what we're actually referencing so we're always adding 1 onto y below we can write a conditional that says if the bottom of our player is less than or canvas dot height that is the other variable we want to reference only then do we want to call Y plus plus as long as the bottom of our player is above our canvas height we're going to keep adding 1 onto that y position else we are no longer going to do that we're just never going to call this code at all now this code looks great but we do need to make sure that we are updating bottom for every frame of our animation because Y is always going to be increasing so I'll take bottom equal to Y plus 100 whenever we add 1 onto y right beneath that I'm going to make sure that we're updating bottom as well so let's save this and see how it looks go back to our game and eventually our player will fall downwards but are they going to stop let's find out and Moment of Truth we do stop at the very bottom because this condition is being called this is a great start to our game but if we look over here our code is already getting pretty hard to read if I were to come back to this at another point in time I might not know what any of this does and this is a good sign in which you want to start refactoring your code into something that makes a little more sense and the best way to do this in my opinion is to change what we have right here into a class object so this class object is going to encapsulate all this code and it's basically going to allow us to create one individual player or many in this case which has its own individual properties which we can edit and it makes things a lot more readable you'll see exactly what I mean by this but to create a class right beneath canvas height I'll add in a class identifier and specify my class name I want this to be a player class and class names typically have a capital letters start so that's why that is capitalized and now within my player class I want to call a Constructor function so this Constructor function is going to set properties associated with the player that we create each player we create is going to have individual properties which are specified within Constructor what properties might a player have while we can figure this out just by looking at our fill rect code down below we have an X position a y position a width and then we have a height those are great properties to begin adding in to our player class so let's start off by declaring our first property will be this dot position this is going to be equal to an object with an X property and also a y property what should X be equal to by default well right now we have it set equal to 100 so we'll add that there make sure we add in a comma and then we'll say our Y is also going to be equal to 100 because that's what we're defining right here so a player has an X and Y position the player is also going to have a width our current width is equal to 100 so we'll make sure that we're setting that and then our height is also going to be equal to 100. now within my player class I want to Define what a player should look like directly within the class and to do that right beneath Constructor I can add in a new function I'm going to call this function draw looks a little something like this this is actually a method if we want to be exact but now within draw I want to specify what a player should look like right now a player is defined by these two lines of code so I can grab these cut them out of place and then paste them within draw so now whenever I create a new player and call its draw method we're going to call this code right here but since we're within a player class we no longer have y available to us and we no longer have height available to us at least because they are defined down below instead of at the top of our file but nevertheless we want this based on our player properties rather than these variables that we just wrote out so if we want to make sure that we're drawing this rectangle right here based on our properties instead of referencing 100 we can reference this dot position dot X for x coordinate this dot position dot y for y and then this dot width for a width and then finally we're not going to use the height variable but rather this dot height the height associated with our player so if we create a player and college raw we're going to draw it out we're not going to move anything just yet but let's replace our current code with our new player class so we no longer need y because we replaced it with this dot position.y let's get rid of this we no longer need height we could use bottom if we want let's comment this out for now we're going to keep our clear code and we can comment out this update code down below but if we want to actually draw out a player first we need to create one and to create one we create a const called player with a lowercase p to indicate that this is an object instantiation we're going to create a player from a new player class that's why we just created up above so if we create this player object now we'll have access to this draw method in this draw method calls this code right here so we want to call that let's grab our player and within our animation Loop we'll call player dot draw let's save refresh and now our player is drawn out on the screen but its properties are not currently being edited and that's okay we're going to do that right now so to edit these properties update them over time I'm going to add into our player class and update method looks a little something like this and within this update method I wanted to Define what variables what properties within our player class should be altered over time and I know down below the created some sort of update code with these lines right here so I'm going to cut these out of place and paste them within our new update method uncomment these out and then run this following code and now this code isn't going to work because bomb is no longer available to us but we do want a bottom associated with our player class right here so let's create this dot bottom and actually I'm not going to do this dot bottom but rather this dot decides and this will allow us to use a left top right and bottom side within the size object I'll create a bottom property now what is the bottom of our player what's going to be this dot position dot y plus this dot height that'll give us the bottom coordinate of our player and now that we have that available to us right here we can replace bottom with this dot decides dot bottom we're going to get the same effect so this conditional will run true but this code inside of it will not because Y no longer exists now we're using this dot position.y instead that's what actually controls this new player's coordinate so I'll replace y with this not to position dot y that's going to be added onto for each frame and now I don't want to set our bottom to this new value I want to set this dot sides dot bonded that value instead which is going to be used on the next iteration of this update Loop right here within this conditional but we do want to make sure that we're replacing y right here with this dot position dot Y and I already forgot what 100 is that is why it's useful to always name your values so instead of adding on 100 I'm going to add on this dot height because that is what our bottom is actually equal to our y position plus our height that is much more descriptive as well so now what we can do is right after we call player.draw we can call player dot update instead so we're going to draw out our player and then we're going to add one onto our y position and also alter the value of our bottom side now we're going to go through the next iteration of our animation loop we're just going to draw out our player in its new position and then update those coordinates and it's just going to keep happening over and over again until we stop at the very bottom of our canvas so let's save refresh and now that code works exactly the same and once we hit the bottom which we should we stopped completely so great now obviously this is a lot more readable than what we had earlier we're calling player.draw player.update with animation Loop we don't have any floating variables around we pretty much replace all of our values with things that are much more descriptive such as position width and height but our class code up above is longer than the code we had previously even if it is easier to read it is still cluttering up our file here so we always want to make sure that we're refactoring as her code file gets more and more complex and we definitely just made it a little more complex by adding in this new class so to make this a little less complex and easier to read we can take that new class and cut it out of this file so now this is a lot nicer to look at than what we just had but we do need a place in which we can store that code that we just cut out so in this case it makes sense to create a new file and I'm going to paste that code in here click command s to save it and where do I want to save this well I'm going to organize a little bit in advance which I don't usually do but it'll make sense in this case because we're going to be adding in more classes for the rest of our game within King and pigs I'll add a new folder called JS all of our JavaScript files are going to go inside of here and I know I'm going to have quite a few so with energized folder I'll create one more new folder called classes and I want to store this class as player with a capital P within our classes folder let's save that and now we have this nice little directory structure over here but we do need to make sure we're pulling in player.js for the rest of our code to read so to do that we'll go into index.html duplicate our script tag here and then I want to make sure that I'm referencing this file right here of player.js to do that I need to go inside of our JS directory slash go inside of our classes directory hit slash and then reference player.js with a capital P so as long as I've done this correctly our code should still function exactly as it did before we save refresh and indeed it does and our player will even stop once it hits the bottom of the canvas and there we go so our code is much cleaner here we have our own player class we have all of our implementation code within index.js this is a great start we're trying to keep our game code as clean as possible but that's all it's going to take to begin creating our player we're going to be adding on a bit more right now but let's go ahead and check off the task of create a player so now we're going to add gravity on our player and you might be asking me Chris well isn't gravity already added on our player well the answer is kinda if we go look at our player over here yes our player is moving downwards but this isn't truly gravity gravity is a constant acceleration on the downward velocity of whatever object you're dealing with so yes we do have a y velocity associated with our player here but there is no acceleration associated with that we're not actually getting faster as we fall down towards the bottom of our canvas and that gravitational acceleration is going to give off a really realistic falling effect which is going to really take our gain to the next level so we want to make sure that we add it and it's also going to be helpful for when we jump with our player that we get pulled back down so a quick overview for you on gravity we have our player right here and we're always going to be moving downwards right well currently we have a velocity of one pixel per frame we want to make sure that we're increasing this value for each frame so let's say our gravity is a value of one we're going to render out our player right here with a Y velocity of one pixel for the next frame the next iteration we're going to add on one and this will give us a velocity of two pixels so instead of moving downwards by one pixel now we're going to move down by two so we just moved a little bit further for the next frame in our operation so now we add gravity onto this current value right here Gravity value is one so we add one onto two we're going to get three pixels for our next frame we're going to move even further and as we continue to move further for each frame it's going to look like we're dropping really quickly at the end to really give off a realistic effect of gravity this is exactly how gravity works in the real world it's going to be how gravity Works within our game right here so to begin coding this we want to create some sort of velocity property for our player class let's go ahead and do that now to create a velocity property we'll head into player.js and then within our Constructor we want to add in a property called velocity we can do that with this dot velocity and set it equal to an object because the velocity can have either an X or a y Dimension so our x velocity is going to be equal to zero and this is what's going to determine whether or not we move left or right we're not going to use this for now but we do need a y velocity for gravity and we're also going to set this equal to zero because our y velocity is going to be set from our actual gravity value but this is a good start so let's save that and head on down to update so for each frame we want to call this Dot position.y and we want to add on to the current y position with plus equals our velocity value on the y-axis so by default since our y velocity is equal to zero nothing is going to happen with just this code but if we begin adding on to this.velocity.y for every frame in which we are above our canvas we're going to start pulling our player down and we're going to give off that gravity effect so we know right here this is when we're above the bottom of our canvas we can write that out with a comment above bottom of canvas and if we are above the bottom of our canvas we want to start adding on to this dot velocity.y I'll grab that with this dot velocity that's why what do we want to add on to it well a value of gravity we'll see we're adding on to this for each frame a new value of one one is going to be our gravity value if we're adding 1 onto y we know that's going to be added on to this dot position right here which is also used down below so we need to make sure that we're taking velocity.y into account for our conditional we can add on to this dot sides.bottom this dot velocity dot Y and say as long as the bottom of our Canvas Plus this new velocity right here is less than our canvas height then we wanted to keep adding 1 on y this is going to make us go really fast and even through the bottom of our canvas I'll explain why in a second but let's save this refresh now you can see that we're falling but with a much more realistic movement because we're adding on to our velocity on the y-axis with a greater and greater value what's going to look like as if we're actually falling in real life but why aren't we stopping at the bottom well yes we're saying we only want to apply gravity if this is true but the thing is even when we stop applying gravity this dot velocity.y will still have some sort of value associated with it so let's say that over here that when our player reaches the bottom of our canvas it has a pretty high velocity we'll say the velocity down here is equal to 5 pixels per frame yes we're no longer adding on to this velocity right here with gravity but if we keep adding onto our y position right here with 5 pixels well we're going to go through the bottom of our canvas we're just going to keep going no matter what so really what we wanted to do is when we stop adding on to our y velocity right here we want to set our y velocity equal to zero and as long as we do that there's nothing else to add on to our y position we're just going to stop as soon as we hit the canvas bottom which is exactly what we want so we know this conditional right here is where we keep adding gravity on to rewind velocity we need an else statement that says what happens if we are no longer adding on to that what happens if the conditional is no longer true well in this case we want to grab this dot velocity dot Y and set it equal to zero so we save that refresh now we stop when we hit the bottom now we can be a little more declarative with our code over here one is our gravity and we know that right now but if we come back to this in a later point in time well we might not know what one means so I'm going to replace one with a property called this dot gravity I'm going to assign this up above within our Constructor so that I know our player's gravity is associated with this property right here I'll set that equal to one say that are fresh and now we fall down quite nicely but with this let's head back on over to do and check off gravity so now I want to move our player around using some keys on the keyboard and the very first movement we're going to do is a simple jump now that we have gravity as long as we're adding on to our y velocity we're going to have our player get pulled back down it's going to be really cool so let's just start off with the y-axis and add in a jump effect so to make sure that we're listening for keyboard events we need to add in what's known as an event listener and it looks a little something like this I'm going to go over to index.js and at the bottom of our file I'll type in window dot add event listener and then for the first argument it's going to be a string I can declare what event do I want to listen for I can listen for a click event a mouse down event a touch event if you're using a phone but in this case I want to listen for what's known as a key down event whenever I press down on one of my keys I'm going to respond with the following code and that following code is going to be declared by adding a comma and then an arrow function looks a little something like this so whenever we press down on our keyboard we're going to call what's ever inside of this Arrow function now this Arrow function right here takes an argument and the argument is an event object this event object contains all the properties associated with the event that just occurred so let's say I were to click on the screen with a click event this event object would contain coordinates for where I just clicked on the screen in this case we're using a key down event object so this event object is going to list out what key do we currently press down we can test this out let's add in a console log into our Arrow function that console logs out our event object we want to save this go back over to our browser and make sure that we refresh and then right click inspect element go over to our console Tab and now with our Windows selected if we start keying down I'll go ahead and press a you're going to see this is the event object associated with that key down event I can open this up and we can see all the details associated with that but we really only want to focus on one property here and that is going to be our key property you can see I pressed down on my a key so we can use this to determine how we want to react to certain keys that are pressed if I press my a key well I want to push our player to the left if I press my D key I want to push our player to the right if I press my w key I want to send our player upwards this is how we're going to react to events is by listening for this event object specifically what key we press down so we know right here this event object contains the key we pressed and we can use a switch case statement which takes a value in this case we want to switch out the event.key the key that we're currently pressing down create some curly brackets and then list out a case if this case is equal to W for me I want to add a colon to the end of this and then call break so I'm going to consulate out some text that says I pressed W I'll delete this console log right there so what this is saying is take the key that we're currently pressing and if the key we're pressing down is a case of w meaning we press down W well we're going to log out to text I pressed W save this refresh and I'm going to hit a first I'm going to hit s and then also D and you'll see I'm not logging out anything but once I hit just the W key now we're logging out that text so now that we can respond to a particular key we can declare how we want our player to react I'll get rid of the console log and then select our player velocity on the y-axis and from this I'm going to set this Eagle to a value of negative 10 because if we are moving upwards we want to make sure our y velocity is negative because remember our coordinate system starts at the very top of the canvas meaning the lower our numbers are the higher we go so if we set our y velocity equal to a negative number it should mean that we're jumping upwards let's save this refresh and then hit W you can see we are definitely jumping upwards we can even hit W multiple times go way up and you might notice right there well we just got stuck in the bottom even though we wrote some conditional code that was supposed to prevent us from doing that well let's go ahead and take a look within player.js and look at our condition right here to see what is going on so we know if the bottom of our player plus our y velocity is less than Cam's height then only then do we want to call this code which adds onto our velocity otherwise we should be setting our velocity y equal to zero which has a stop so why aren't we stopping when we hit the bottom of our canvas well the issue is right here we are setting this dot science dot bottom within this conditional when in reality we should always be doing this right after we're adding on to this dot position dot y because we know when we're using this dot signs dot bottom it is dependent on to stop position wise new value so we're using this with an unconditional down below right here we need to make sure that we're using the updated value based on position.y in which we set up above right here otherwise we're not going to get accurate results so let's let's make sure that we move this dot side step bottom right after we call this.position.y give it a quick save before I start jumping up and now we're never going to go past the bottom we always eventually stop which is exactly what we want now let's say we only want our player to be able to jump once this is a really easy fix we can go over an index.js where we wrote out this event listener and say when we hit down the W key we only want to set our player velocity y equal to negative 10. if our current player velocity is equal to zero meaning that we are on the ground we are not moving at all so we write out if our player got to Velocity on the y-axis is equal to zero then we're going to call player velocity y equal to negative 10. save refresh and now when I try hitting W in succession it doesn't really work but if I do it really fast we might be able to get one that works because once we hit the very peak of our jump which is going to be right about here while velocity on the y-axis could be equal to zero at this point in time which means that if we were to hit w at that exact point we could jump again but the odds for that are very low and it's a little more complex to make sure that does not happen but I think for our game right here this is totally okay we still have it good enough we're preventing players from jumping multiple times so we have our jump with W let's go ahead and make sure that we jump a little higher because I want a Little More Bounce to this I'll set our player velocity on the y-axis equal to negative 20 instead refresh and I do like the jump for that so great now it should be noted when listening for keys I'm currently using an American keyboard so I'm going to be using wasd to move my player around now if you're International you're going to have different Keys associated with your keyboard of course so just make sure you're using whatever keys are comfortable for you for moving around and if you ever don't know what key to listen for just make sure that you console log out event.key when you press down and open up your console you're going to be able to see that exact key value let's start moving our player to left and also to the right if I want my player to move towards the left I'm going to listen for an a key so let's add in a case of a a colon and then a break this is going to move player to the left and then I want to also listen for when we're moving to the right so add in a case of d add a colon and then a break and inside of the say this is when we move a player to the right so how would I actually move a player to the left or to the right well we need to set the player's x velocity so if I were to try moving let's start off with the right I would go grab our player get their velocity on the x-axis this time and set it equal to a value like five so when we press down D we should be moving to the right four pixels per frame but if we try this after saving nothing is going to work simply because we haven't implemented how our player should be moving in reaction to this x velocity so over in player.js we need to alter a player blueprint a little bit more so yes we are adding on to our y velocity right here but even before that I want to add on to our player's position on the x-axis and I'm going to add on to this our current player velocity but on the x-axis and that should be all we need to get started so we save both our files we refresh we hit D and now we are moving to the right but if I hit a while we're not moving to the left simply because we haven't implemented that within index.js so what happens when we hit a key of a well we want to change our player velocity on the x-axis but in the opposite direction so all we need to do is add a negative sign right here save refresh now when I hit D we go to the right but now when I hit a we go to the left and we can switch between the two but we're not really stopping how do we actually stop our player well here's one way to do it we can add an event listener that listens for when a key is up so when we release a key we can say hey was that key a was that key D if it was we want to stop our players velocity on the x-axis let's add in that new event listener to add that in I'm simply going to copy this whole event listener right here paste it down below and then replace key down with key up so I don't care what happens when we key up on W I'm just going to delete that case but when we key up on a or D I don't want our velocity on the x axis equal to negative four or four I just want it equal to zero I want to stop all together so save this refresh hit D And now when I release our D key we stop hit a when I release the a key we stop but there is an issue with this method can you guess what it is well watch what happens when I hold down ID hit a and then I release on a I'm still holding down D but I'm not going to the right even though I never released it so if we're to use this method whenever we pull up on another key even if we try going to the other direction it's going to stop our movement all together so rather than just determining our movement within this event listener right here I want to determine our player's movement within our actual animate function for each frame that we Loop through we're going to be listening for what key is currently pressed down and if any keys were pressed even if we lift up another we're still going to be activating the code for that one key that is currently down so if I want to listen for with inner animation Loop a particular key here's how I like doing it I'm going to delete this comment right here and create a const called keys this is going to be equal to an object and within this object I'm going to list out all the keys I want to listen for so I have our W key this will be equal to an object with a pressed property set to false so is the W key pressed by default no it's not same for a this will be equal to an object with a pressed property by default it is not pressed and same for d by default this pressed property will not be true so now based on these properties right here within animate I could say if keys dot d is pressed so if our D key is pressed I want to set our player velocity on the x-axis equal to one which means we should be moving to the right else if our keys dot a is pressed I want our player velocity dot x equal to negative one meaning we are going to move to the left and it looks like I messed up this also if a little bit let me fix that up real quick but if we're going to be listening for whether or not D or a is pressed well we need to make sure that we're changing these values whenever we press one of these Keys down right now we're just directly setting our velocities so let's change that we're going to get rid of this right here and replace it with keys dot a DOT pressed is equal to True when we press down our a key and then when we press down our D key we want to make sure that we're sending keys.d dot press equal to true and now we can set these properties equal to false within key up so we'll get rid of this right here for D when we key up on D we're setting qs.d dot pressed equal to false and when we key up on a we're sending Keys dot a DOT pressed equal to false So based on these conditions when we go through our animation loop we're either going to move our player to the right or to the left we do need to make sure that we're setting our player velocity on the x-axis to zero before we actually set it equal to one so before we call any of this we're going to always set our player velocity on the x-axis to go to zero then when one of those is pressed that's when we set it to begin moving our player either left or to the right so let's save this refresh and now when I hold down D we are moving to the right when I hold down a we're moving to the left and when I key up between the two we no longer have any Jitter which is great that's exactly why we're doing this in the first place I can hit w we still move up our game is looking great but I will say this is quite slow so let's go back to a faster rate our velocity on the x-axis will be equal to five so we'll change that in both locations and we can clean our code up even further so since we only have one statement right here within our if statement we do not need curly brackets we can get rid of those and this is a lot cleaner because now we just have one line instead of three and we can do the same thing for our lsif statement get rid of the curly brackets because we only have one statement right here and now we know exactly what is happening when we press down either a d or an a key the next thing I would do is move our event listers to a separate file just to make sure that index.js is our main code implementation so let's grab our event Lister starting down here on light 65 and on line 35 I'll cut all this out save index.js and then I'm going to go to file new file and then paste in that code hit command s and then save this within my Js folder as event listeners dot Js save that and now that I save that within its own file I want to make sure that I pull it into our game so that it's actually usable and to do that I'll go to nx.html and then right above index.js I'll add in JS slash event listeners.js so I'm referencing the correct location right here I want to save refresh and we have a great start to our physics implementation so this is exactly what we want to begin adding in player movement and gravity we go back to to do and check off player movement next up we're going to focus on a background Sprite so a Sprite is basically just a fancy word for an image I want to get a background image in the back of our game right here how do we begin doing that well I'm going to start over in index.js and I'm going to create a class directly in here we'll start refactoring as we go but to create that class I'm going to go right above player my class is going to be called Sprite with a capital S so this is going to be basically a generic image class we're going to have lots of Sprites within our games for things such as our player things such as our doors that we enter new levels and so forth so I want to create one generic object which I can use for all these different things we're about to load into our game so we have the Sprite class now what properties does a Sprite have people I can think of one immediately it's going to be a position where do we want the Sprite placed on the screen the image placed on the screen that is so let's create a Constructor so we can add in that property I'm going to create a Constructor and then I want to assign a this dot position equal to a position we're going to pass through the Constructor so whenever I pass through properties within a Constructor I like doing it with an object as the only argument and this way I can easily Define what I'm passing through here when I actually create the object it's going to make more sense as we go through this but just bear with me so we're creating a position assigning it to a position property because all of our Sprites are going to have that separate position but the most important property here is going to be this dot image so a Sprite it's like I said basically just an image to create an image within JavaScript we want to use a native image object that looks a little like this we're assigning a new image over to this dot image now to load in an image from some sort of source file we want to declare that this dot images dot SRC the source of this image is equal to wherever that file exists within our project so right now we don't actually have any images and that's a problem because what are we going to put in for our background and if we don't have an image well I created an image using tiled a map editor and the image is going to be available to us over on Google Drive so check the course description make sure you're on Google Drive Right Here we want to go and download this image folder this is going to contain all the images that we need for our game so I'm going to right click IMG and then hit download and you can see down here that's preparing the download and once it's ready it's going to download to my finder so I'm going to call this Kings and pigs assets make sure I'd save and that's going to download So once that downloads you can open up your finder open up that zip file and there is our image folder so I want to grab all these images and then while I'm holding down shift I'm going to click the very last thing with that I'll hit command C to copy these and then find our Kings and pigs folder it's going to be right here within this I want to create a new folder this is within our project called IMG this is where all of our images are going to go so I can hit enter and with this selected I can hit command V or control V if you're on Windows and all those are going to be put directly within this folder which means they're available to us within our project and we can see Sublime Text update over here now we have access to all these different images now what image do we want to select well background level one is going to be it if I click on this this is what it looks like this is going to be the background for a game at least the very first level so inside of index.js I want to make sure when I'm setting dot Source right here that I'm setting it equal to wherever that image is located so let's go from an x.js into our image folder and then we want to select background level one it has a capital l and then one dot PNG so now when we create this image it's going to be equal to background level one now that is great but we actually want to draw this image out right now we're just storing it inside of this dot image.src we want to make sure that we're rendering this out so to do that we're going to add a draw method and within this we can call our canvas context with c and then call draw image so the very first argument for draw image is going to be the image we want to draw out and has to use this JavaScript image object in which we already set its SRC so let's grab that and put it within our first argument with this dot image now the second and third items are going to be positioned on the X and the y axis we're already setting that up above so let's reference it with this dot position dot X and then the third argument will be this dot position dot y that is going to be our y position now with this as soon as we create a Sprite we can call draw and write render it out on the screen let's do that next so down below right above player I'm going to create a new const called background level one and this is going to be equal to a new Sprite object everything is going to be set automatically besides position we do need to make sure that we're setting that manually so let's pass through in argument it's just going to be an object and then I need to grab the position property so I'll grab that and assign it to equal to an object like so so by using this object syntax right here instead of not knowing what we're passing through as the first argument we'd pass through an object right here with an X and A Y and that would define our position but we don't know what this means without that position label so when we add position right here inside is object syntax it requires us to add a label like so and now we know exactly what this object is equal to it's going to be equal to a position it makes our lives easier because our code becomes more descriptive so we have a position and it's going to take an X which we use right here and next by default I'm going to set equal to zero and then y I'm also going to set equal to zero because we want our background drawn on the very top left hand corner of our current canvas so now we have a Sprite object assigned to background level one with this we can call its draw method so let's grab this and then go inside of animate and where relative to everything else would we want to draw this out well I think it makes sense to draw this out as the very first thing we might not even need this fill style fill rectal code anymore because our background should take up the full canvas width and height so let's draw this out by selecting our background level one calling draw saving and then heading back to our game give it a refresh and there is our background image it's going to be that easy so this looks great but there are a few things that I would do before moving on to the next lesson and the first thing I would do is just get rid of C dot fill style white and C dot fill wrecked these are two lines that we no longer need because our background is going to be drawn basically clearing everything else from the canvas so let's save that refresh and you can see we're getting the same effect we didn't need those two lines of code what else would I do here well when we're passing through a position it also makes sense to pass through an image SRC stands for image source so now whenever we create a new Sprite we can assign that a different image and that way we don't have to be stuck with always rendering out our Sprite with background level one we want to make sure that this is scalable and that we have a variety of images in which we can put in our game so I'm going to cut the string right here that has our background level 1 PNG with command X and then I'm going to set image.src equal to image SRC but now I need to make sure when we create a new Sprite that we're creating the image SRC property and set that equal to the string in which I just cut out so given that we did this correctly we can save refresh and everything still works but now only this one Sprite right here is going to have the background image of background level one that's perfect another property I would add in here is going to be this dot loaded set it equal to false this is going to determine whether or not our image has been loaded fully whenever we call draw right here I only want to call c.draw Image if this dot image is completely set and I don't know if this is actually set until our image is loaded and we want to make sure that when this image is loaded we set this dot loaded Eagle to true because if this image has not loaded well this method right here just won't work so right before I call c.draw Image I want to write a conditional that says if this dot loaded is false which we can check for with a bang operator then I want to return completely meaning I'm not calling any code that follows the statement right here it's basically just another way to say if this image is loaded and we're going to contain everything within these curly brackets but it's a way to do away with those curly brackets and make our code a little more readable because we don't have to add any indentation here but if we want to use the syntax right here we always need to make sure that we add in the bang operator to do the inverse of this condition so now we need a way to set this not loaded equal to True which we can do by selecting this dot image Dot onload and set that equal to an arrow function so whenever our image loads we're going to call whatever is inside of this function right here what do we want to call well simply enough this dot load is equal to true we know that our image is loaded we're going to use this to determine whether or not we actually render it out so we save this and then refresh over here and it looks like we're still good to go now the very last thing I would do is simply refactor this into its own separate file so we just created the spread class let's select it cut it out of place and then I'm going to add this into a new file within our classes folder so I'll save index.js go to file new file paste in that Sprite class hit command s go inside of JS go inside of classes and then create a new file called sprite.js so whenever you create a new Javascript file you need to make sure that you pull it into index.html otherwise it's not going to work and I do want this available to us before we load our player clouds because our player class might start inheriting properties from our Sprite Clause when we want to add in images so let's copy the script tag paste it up above and then I'm going to pull in our Sprite class which can now be used across all these different files so we just want to make sure that this works let's save and make sure that index.js is saved as well refresh and we are good to go looking in great shape with that new Sprite class so if we go back to to do we're going to be able to check off background Sprite so the next thing we're going to do is add in Collision blocks now what is a collision Block in the first place well if we go back to our game over here a collision block is basically going to be one specific area that looks like this a small little square in which if our player touches this they cannot go past this boundary and we use Collision blocks to basically determine the area in which our player can and cannot travel so if I wanted to basically make sure that our player cannot travel past this inner rectangle that we have right here for a map I would create Collision blocks all along its boundaries even going upwards here and once I create Collision blocks all around the boundaries while we write Collision detection that says hey if my player runs into one of these right here they cannot go past that point now we could create Collision blocks manually directly within our code but we know that we want to have multiple levels in this case so it makes sense to generate these Collision blocks using a map editor and that map editor in which we're going to use is called no other than tiled so this is a free map editor in which you can download I have tutorials on how to go through this whole entire thing maybe I'll explain more in a premium tutorial with this direct course but I really recommend checking out the Pokemon course if you want to learn how to use tiled in depth but otherwise just make sure you download tiled and open it on up once you have tiled open it's going to look a little something like this we want to open up a new tiled map and if you check out the Google Drive Link you're going to notice inside of it we have a tiled folder and here we have a Maps folder which contains all the maps for the map we're going to use for this specific game we want to open up level 1. TMX so let's double click on this scroll back on over to tiled and you should have this map open automatically for you if any errors show up just make sure that you click OK it should load all the assets because they're relative to where the map was placed within finder so this is what our map is going to look like and you'll see that I have a few layers over here on the top right we can turn things off like our tiles our decorations and I intentionally place these within their own individual layers so that I can separately export my collisions layer right here the collisions layer consists of just these red blocks that surround where our player should and should not be able to move so once our player is spawned in here we don't want them to leave this area and we don't want them to be able to run through these blocks right here that is why I drew collisions in those locations and again if you want to learn more about tile then draw out your own map really check out that Pokemon video but otherwise the main thing we want to do right here is export the data associated with these Collision blocks on this collisions layer so to export this data within tiled all we need to do is go to file export as then we want to go over to downloads this is going to be a temporary file and I'm going to save this as collisions so let's save that and then head back on over to finder so once we're in finder we want to go to downloads where we save this and then we're going to open up collisions.js so let's double click that and this is what this file looks like so this contains all the data associated with all of our layers that were created within tiled this layer right here is our background layer down below we have our tiles layer we're just going to keep scrolling until we find our collisions layer so what we want is this array right here this array consists of every location in which we want to place a collision block but to do this we need to parse this data out within our own game and then make sure that we're rendering Collision blocks in the exact locations wherever we see a symbol of 292 because that is the representation within tiled of why a collision block is relative to all the other tiles within there so let's start by going to our collisions layer and grabbing the data right above it I'm going to get the whole array hit command C to copy that get rid of that file for now and then head back on over to our project so I want to create a new file to store this array I'll go up to file new file paste that on in and then hit command s and then where do I want to save this while within JS and I'm actually going to create a new folder called Data and then within data I'm going to save this as collisions dot JS so let's create a new const called collisions level one set it equal to the array and there we go we're off to a great start so what's next well basically we need to parse our array right here into a 2d array why and what does that even mean well let's visualize this each zero right here represents one cell within our tiled grid and if we look back within tiled over here this grid is 16 blocks wide and nine blocks high each of these cells right here is 64 pixels wide by 64 pixels tall and this is the exact same size in which we're using for actual canvas this is 10 24 pixels wide by 576 pixels tall so referencing that array I was just showing you if we're just focusing on collisions right here we know the start of that array was something like zero zero zero zero repeating so that first zero is going to represent this cell right here we're just going to keep going and filling this in with zero until we reach the very end of this row so all of our zeros go to the very end and what's next we move to the following column and we keep adding n zeros we're going to keep adding in zeros until what well until we hit a collision block so zero zero zero zero zero and now we have a collision block right here so what symbol are we going to put here instead well something like 2 92. that is the symbol that tiled automatically assigned our Collision blocks every red Collision block that we have right here is going to have 2 92. we're just going to keep going until we go over here that's going to be zero this is going to be zero and then this will be 292. so this kind of shows you how that array was laid out we can go back and view that with this in mind to see that we have a ton of zeros in the beginning until we hit 292 and then all of our 292s fill out that entire row of where our Collision blocks were until we go on to the next row we have 0 to 92 and so forth we want to parse all this into a two-dimensional array so right now everything is just within one giant array until we hit to the very end and then for each row we're going to put all these cells within a subarray so we looked through all of our objects and we say we want the first row put into this array right here the subarray once we're looped in those objects we're going to go on to the next objects and put all those within their own subarray basically we're going to go through every single row within this grid right here and keep putting all these symbols within their own individual sub arrays and what this is going to allow us to do is precisely place these blocks in the exact location based on the indices of our rows which is going to be 0 1 2 3 4 and so forth and based on the indices of our columns so 0 1 2 3 4 and 5. and really the only way to get these indices is to put everything within a 2d array so we have our rows which are going to be represented by our sub arrays and then we have our columns which are the actual symbols inside of the sub arrays so if this doesn't make too much sense for it to know it will make more sense as we begin writing out the code but that should give you a general idea of the logic going on here so I'll start by parsing our data into a 2d array how do we go about that so what I can do is run this through a function called parse 2D and then pass through our data it'll look a little something like this and there's a way in which we can make this function a bit cleaner I know a lot of people might have some Flack with this because they're going to say you should never alter the default objects that come with JavaScript but honestly this does make our code more enjoyable to use in my eyes so I really don't care about that advice so instead I'm going to get rid of this function I'm going to reference our main array prototype so this array prototype basically contains all the methods that we can put within an array object so we have an array right here and we could call methods on top of this such as filter we can call things such as slice and so forth if we want to add our own method on top of this we basically need to assign to our array dot prototype a new method which I'm going to call parse 2D and then assign to this new method a new function and I'm not going to pass anything through this because I'm going to have access to the data which we call parse 2D on and to access that data all I need to do is call this but that's not what I want to do to start what I'm going to do is create a new array within this function I'm going to call this our rows because this is going to contain all the sub arrays that make up our main rows object so the next thing I want to do is start looping through these values right here how do we Loop through these well I can Loop through them with a for Loop and to start a for Loop we need to declare and let I'm going to set I equal to zero to start this is a traditional for Loop where we start from the beginning and say I want this to Loop for as long as I is less than this dot length so the length of the array in which we're going to use parse 2D on which is going to be this right here once we call the method and then I need to add a semicolon and state how do I want to start looping through this array well for every iteration I want to take I and I'm going to add on to I 16 values because I know each row within this data right here is going to be representative of 16 cells so then I want to add some opening and closing curly brackets and now I can select a rows array that we created up above and push into this some sub arrays so how would we create a sub array where we grab the first 16 symbols within collisions level one well we can do this by slight selecting our data with this and then calling a slice method the first argument of a slice method is what index do we want to begin slicing elements from well we want to start at the very beginning which is going to be zero but eventually we want to start over on 16 which might be something like this right here to begin the new row so we need to make sure that this value right here which we're slicing at changes for each iteration of our Loop so I actually want to say the very first index in which we want to begin slicing from is going to be I that'll give us an index of 0 to start and then we need to determine as our second argument where do we want to slice to what index well we want to slice two wherever the 16th element is within this array and we can say that we want to do that by grabbing I plus 16. so to start we're selecting 0 and then we're selecting 16 which will give us the first row of 16 elements once we go through the next iteration of this loop we're adding 16 onto I so this would be 16 and then what happens while we slice out from 16 to 32. we're going to keep going until I is greater than this Dot length which means there are no more elements to select we reached the end of our array right here but this is how we're going to parse everything into their own Row in which we can then return and use to start creating those Collision blocks so just this right here is actually going to create a full 2D array for us so now we want to return the value of rows and then we can assign that to some new constant or some new let so I'm going to save this and then right beneath it I'm going to create a const called parsed collisions and parsed collisions is going to be equal to collisions level 1 dot parse to D and make sure that D is uppercase because that's how I declared it right here but now we're going to run all this code on this array in which we selected and store it within parsed collisions so we want to make sure this works let's console log this out let's log out parse collisions and to make sure this file is even red in the first place we need to make sure we're pulling it in within index.html so I'll copy a script tag paste it up above and then make sure I'm referencing the correct file so with inner JS folder I want to go inside of data because that's where we store this and then reference collisions dot JS and that is indeed what it is so let's save this go back to our code and to view that data I want to right click go to inspect element open up our console and now I can open this on up and notice we have an array with nine rows inside of this that's exactly what we wanted each of these rows is exactly representative of what we were drawing out over here in tiled where these first two rows have a symbol of zero zero just means we don't draw anything out as we Loop over those but once we go into row which actually has an index of two you can see we're starting to list out the symbols of 292 which are going to represent where we place a collision block once we go on to row number four you can see we only have basically two of those within this row it's a one to one representation of what we actually draw over here and it'll allow us to draw Collision blocks and their exact location on our actual game app so to draw our collisions on our map we're going to start looping through these if we hit the first row we go to the very end and then we proceed on the next row go to the very end and finally we hit a symbol of something like 292 we want to say a draw some sort of collision block at that exact object in that exact location based off the indices of our row and the column we're currently looping over so how do we begin looping through these within code well back within collisions.js now that we have our collisions parsed out within a 2d array I want to start looping through these and I can start looping through these by grabbing the array of parsed collisions and calling for each on top of it so what I'm saying here is for each row within this array I want to console log out each row simple enough let's save this refresh and see what it looks like so now we're console logging out each row for each iteration which We're looping through parsed collisions so we have the row now we want to grab the individual data piece to grab that within this we're going to select that row and call for each so for each what inside of this row well for each symbol inside of this row I want to const log out that symbol save that refresh and now we're console logging out each symbol individually and we can grab this symbol to say we want to draw an object only when we hit a symbol of 292. we're going to do exactly that within row.4h I'm going to say if our symbol is equal to 292 then I want to draw out a new Collision block but we don't actually have a collision block object just yet but to start we can comment out here we're going to push a new Collision and two Collision blocks array so let's begin by creating a new Collision object and we can do that right here within collisions.js and start refactoring things as needed later on so I'm going to create a new class called Collision block with a capital B this is going to take a Constructor and what do I want to pass through for each individual Collision block well definitely one object with a position property because each Collision block is going to be moved around at different locations independent from one another so whenever I pass through a position I want to make sure I'm assigning it to if this dot position property like so and what else might a collision block have well it might have a width which I can assign with this dot width and I want to set that eagle to the width over actual blocks as they are over in tiled those are going to be 64 pixels wide and then for a height it's going to be 64 as well 64 pixels tall so I believe those are the only properties we need to get started but we do need to add in a method called Draw so we can actually see these and what does a collision block look like well it's simply just a square so we can create this with C dot fill rect and then we can put inside of this the properties in which we just created within our Constructor so our x coordinate is going to be this dot position.x our y coordinate is going to be this dot position dot y of course our third argument is going to be our width so we can reference that with this dot width and then finally our fourth argument will be this dot height now I do want to make sure that these are red so they represent the exact color in which we're using over in tiled and I can declare that with C dot fill style is equal to red and that should be all we need to get started with some Collision blocks so now we have this Collision block class we can begin pushing these into a collision blocks array let's create that array const Collision locks set that equal to an array and now whenever we hit a symbol of 292 we want to select that new array and push in a new Collision block so how do we determine where we should be placing this new Collision block well we want to pass through our position property like so the position is going to have an X which I'll set to zero to start and a y which I'll also set to zero remember how as referencing the indices of what row we're on and what column we're currently on we want to use those to automatically generate the position in which this block should go so we want to get those indices as a second argument for the function within four each right here we can add in next to row and index argument and I'm actually going to call this y instead because this is going to be our y index in which we're currently looping over so this y right here is going to be equal to something like 0 1 2 3 4 5 6 7 and 8. and with that index we can use it to set our y property when we create a new Collision block so instead of referencing 0 I'm going to reference the Y the current index in which We're looping over and multiply that by the size of our block which is going to be 64. so to really Hammer this in let's say better index is going to be one this right here if we multiply 1 by 64 we're going to get a value of 64. we're saying place our block at a position y of 64. where is that it's going to be right here but we don't actually have a block in this position because there is no symbol of 292. so only when we hit an index of 2 are we going to place a block 2 times 64 is going to be 128 128 pixels from the top of our canister right here is going to be in the exact location in which we should be placing one of these collisions blocks this is just going to keep looping through our rows over here and making sure that our y-coordinate is perfect for every single one of these blocks that we have within our map so we have y setup how do we get X set up as well well when we Loop through each row we also want the index of the column we're currently looping over and I'm going to assign that index a name of X this is going to be our X index and now that I have this x index I can assign that X position equal to x times the width of her block which is 64. it's going to make sure that we're pushing our block over to the right by the perfect amount so that we're getting a one-to-one representation of our Collision blocks as we got them over and tiled so let's make sure that we save collisions.js and then I want to grab our Collision blocks array in which we just populated we're going to go over to index.js make sure that I call this within animate so right after we call Background level one draw I'll reference Collision blocks call Four each on top of this we're going to Loop over every closing block within this Collision blocks array so I can say for each Collision block within this array I want to call the following code Collision block dot draw so when we call this draw method right here we're actually calling the draw method that we created the inclusion block which just creates a simple Red Square so let's make sure that we save index.js as well as collisions.js likes it out of our console refresh and now all of our Collision blocks are drawn and their exact perfect locations relative to what we had over here entitled now you might not want these to be the full capacity as we see right here especially for development purposes it's kind of useful to see what's behind these blogs and if that's the case we just need to change our fill style for the Collision block we can do that by assigning this Eagle to rgba instead of red so on a value from 0 to 255 on how strong our red is going to be I want this equal to 255. I want our green value to be equal to zero I want our blue value equal to zero this is basically red right here but this last argument Alpha is going to be how transparent this color is I want it about halfway transparent so assign it equal to a value of 0.5 this ranges from 0 to 1.5 is 50 and if we change that now we can see everything behind these Collision blocks and eventually we're going to get rid of these all together this is going to be invisible running in the background making sure that our Collision is in place but before we move on to adding in Collision I want to make sure that I'm refactoring this so that our code is as clean as possible so really what would I do here well I don't think it makes sense to keep our Collision block class within collisions.js even if they are related because I might want to use it somewhere else within our game so take the class cut it out with command X save collisions JS and then I want to go to file new file paste that in and I want to save this within our classes folder so I'll save this as Collision block like so and whenever I create a new class I need to make sure that I pull it in to index.html so I'll save this right above sprite.js reference a collision block file like so but this won't work right off the bat because we're trying to use this Collision block class within collisions JS as we can see right here so we want to make sure that this Collision block generation code right here is actually referenced within index.js so I'll cut it out of collisions.js go over to index.js and where do I want to put this I think I'll put this as the very first thing after we set our canvas width and height this is an okay location I like where this is and let's save and refresh and everything still works with that but we can clean this up even further within collisions.js I want to put this purse 3D prototype within some sort of utils file because this is more like a utility function if I ever want to reference this later on it might not be apparent to me that this is within collisions.js so let's get it out of here I'll cut this out and then I'll go to new file paste it in hit command s and I'm going to save this in our JS folder as utils.js whenever you create a new Javascript file you need to make sure you pull it in so I'm going to pull this in as the very first thing even before collisions.js make sure I get rid of data right here and reference utils JS instead so we save refresh everything still works looking great collisions.js now just contains our Collision data and utils.js contains our parse 2D function so over in index.js one more thing I would do very last thing for this lesson is I would refactor this into something that is a little more readable because this is a lot to take in on first glance if I were to come back to this in a later point in time I might not have any idea what this does right here so it's kind of an indicator that I want to refactor this into its own function I really like using this dot object notation on my method screw the haters so I'm going to grab this dot 4H right here and go inside of utils.js and create a new array prototype so referencer array prototype and then I'm going to call this create objects from 2D and assign that equal to a new function like so so inside of this I'll paste in that for each in which I just cut out and where we had parsed collisions I'm going to replace this with this this is going to reference the array in which we're currently calling this codon now looking at this code it doesn't really make sense because we don't have a collision blocks array in which we can push in New Collision blocks at least not anymore so we want to make sure that we create that whenever we call this function I'm going to create a const I'm just going to call this objects because we might use this for other things instead of disclosion blocks and I'll set objects equal to an empty array now whenever I Loop through a symbol of 292 I want to push into this object's array a new Collision block this is totally fine to start and now when I get to the end of this function I want to return the populated objects array so now all I need to do is grab dot create objects from 2D go back to index.js and on top of parsed collisions I can now call create objects from 2D which will parse everything out and return to us a closing block filled array so instead of assigning Collision blocks to an empty array up here I'm going to get rid of that create a new const down below called Collision blocks and assign that equal to parsecollisions that create objects from 2D as long as we did this correctly we can save refresh and everything is still going to work exactly as expected but our code within our implementation is much cleaner because we're calling array methods instead of trying to understand all this code right here on first glance so I think that's all I would do to make sure that our Collision blocks are rendered out on the screen let's head back to to do and check off Collision blocks next we're going to add an inclusion detection so how do we start detecting whether or not our player has hit one of these blocks and what do we do in response well I think it makes sense to start illustrating this out to really help you grasp the concept so I'm going to zoom in here let's say that this Blue Block right here is going to be our player this is equal to this and say that we are focusing on frame number one before we have even applied gravity so before we apply gravity which is going to push our player down we hit an arrow key to the left which means our player's position is going to go over one to the left now we can see that we have some overlap here between our player and one of our Collision blocks okay so we're going to Loop through each of these Collision blocks and then if one of these Collision blocks has some sort of collision with our player right here we're going to run some code that pushes our Player's Edge right here to The Far Side of whatever Collision block we're currently colliding with which is going to be this one so we're first going to detect four collisions on the x-axis so that's going to be step number one step check for horror santal collisions only after have we checked for horizontal collisions do we want to apply gravity because if we apply gravity before we check for horizontal collisions we might be in this location right here where we are colliding with three Collision blocks instead of just one and then we need to determine which Collision blocks should push our player back to this location and it's just not going to happen if we do things that way so we check for the X Collision first push our player back to this location and then we push our player down with gravity so we might be over here so that's going to be the second thing we do is apply gravity after we've applied gravity we want to check for vertical collisions which obviously we have one and based off of this one block down here in which we're colliding with we're going to push our player back up so for step number three we check for vertical collisions and this is going to be the end of our Loop so as long as we go through these three steps we're going to go back to the very beginning called Draw update whatever it might be and do the exact same thing and as long as we keep doing this for every frame we're going to make sure that our player cannot move past these blocks and that we always run into them without any weird bugs or stutter effects like that so how would we begin coding this well in order for a player to interact with these Collision blocks we need to pass those Collision blocks through into our player class that's a great way to begin looping through these blocks while referencing our players properties so let's start with that to pass these blocks into our player class we're going to go inside of player.js and inside of Constructor I'm going to add in an empty object and I know I want to pass through this object a collision blocks property and by default I can say this is going to be equal to an array just to give me some further detail in regards to what a collision blocks property is it's going to be an array so once I pass through Collision blocks I want to make sure that I assign a new property called this dot Collision blocks equal to the Collision blocks argument we're passing through and now within our implementation I just need to make sure that these Collision blocks are available to us so let's head on over to index.js and where are we creating our player it's going to be right here on line 18 for me now I know I could pass through an object with a property of collision blocks and what do we want to pass through here to the Collision blocks property well no other then the Collision blocks in which we parsed out up above now the cool thing is if this name right here this cons name is the exact same name as the property name we're trying to pass through to our player class we do not need to add Collision blocks to the end of this since these have the same name we can just get rid of the colon Collision logs and this right here is the exact same thing as this just a cool little JavaScript shortcut for you so let's use the shortcut version and to make sure this works I want to consulate out this dot collection blocks which should be set when our player is created so let's right click inspect element go to console refresh and there are all of our Collision blocks so great we know that works now we can begin looping through these directly within our player class now where do I want to begin looping through these well within our update function right here update is basically going to contain the steps that we wrote over here so the first thing we want to do is check for horizontal collisions it would check for horizontal collisions right after we add on to our X position so we pressed a or D on the keyboard and our player moved left or right right here we check we're horizontal collisions so as I mentioned we wanted to Loop through our Collision blocks we can do this in a few ways such as using for each but we want to break out of this loop as soon as we realize our player is colliding with one of these blocks so if we ever want to break out of a loop it makes sense to use a traditional for Loop in this case so I'm going to create one with four declare a let I set it equal to zero and say I want to Loop through this as long as I it's less than this dot Collision blocks dot length for our third statement right here I'm going to say increase I by 1 for every iteration so this right here is the exact same thing as this dot collisionblocks.4 each but the difference is with this traditional for Loop we can use a break statement to break out of the loop completely and with DOT for each we cannot use that that is not available to us so that's why we're using this traditional for Loop but we do need a way to reference each individual Collision block we're currently looping over but we can get that by declaring a const called Collision block just one so singular this is going to be equal to this dot collisionblocks the array we're currently looping through and we can grab one item from this array by referencing the index in which we're currently looping over so we're going to put I inside of here and now this truly is the same thing as dot for each we can reference Collision block right here and start using this to check for collision between this one block We're looping over and our player's position so I want to begin by creating an if statement this is going to say if a collision exists how do we determine if a collision exists well let's go back to our game over here we just moved our player over to the left and visually we can see that a collision does indeed exist but how do we determine this through code well we can determine this by saying if the left side of our player right here so obviously the left side of this blue rectangle is less than or equal to the right side of our Collision block which is this right here the two are definitely colliding from the left side of our player let's start by writing that out in code so I need to get the left side of our player which I can get with this dot position dot X position.x is the same thing as the left side of our player now if the left side of our player is less than or equal to the right side of the block we're currently looping over and we know these are colliding from the player's left side how do we get the right side of the block We're looping over we can get that with the Collision block which we're currently grabbing dot position dot X this will give us the left side of our Collision block so it's going to give us this right here but if we add on the width of this Collision block we're going to get the right side of it so let's add on to collisionblock.position.x Collision block dot width and with this we are detecting for Collision on the left side of our player and the right side of our Collision block but we need to make sure that we're detecting for collusion on all sides of this Collision block so let's say hypothetically that our player was over here for whatever reason and we're colliding with that same Collision block but from the right side of our player how do we determine within code that the two are indeed lighting well we need to get to the right side of our player and then also the left side of that Collision block if the right side of our player right here is greater than the left side of our Collision block we know they're colliding from that side as well so we're going to add in an and statement to this conditional looks like this I can hit enter and right if the right side of my player which I can get with this dot position dot X plus our player's width which is going to be this dot width is greater than or equal to the left side of our Collision block which I can get with Collision block dot position dot X then we know we are indeed colliding with less out of collection Block in the right side of our player so we're taking into account both sides on the x-axis that is exactly what we want to start so to further detect for Collision we also need to take into account the tops of these Collision blocks so in this case I'm going to say that our player is up here and we are falling downwards and now we are colliding with the top side of our Collision Block in order to get this we need to get the bottom side of our player and the top side of our Collision look so we already know the gist of this we can add an and statement and say we want to get the bottom of our player with this dot position dot y plus this dot height if this value is greater than or equal to the top side of our Collision block which we can get with Collision block dot position dot X we know they're colliding from the bottom of our player and the top side of the block now finally we need to take into account collisions on the top side of our player so if we jumped really high we might be colliding with the ceiling up here so we need the top of our player and the bottom of a collision block so we'll add an and statement that gets the top of our player with this stop position dot y if this is less than or equal to the bottom side of our Collision block which is going to be collisionblock dot position dot y plus collisionblock dot height we know they are indeed colliding from the player's top side so once we take all sides into account this is going to provide us very accurate Collision detection we know we're colliding with that in some way no matter which side we're coming in from so the Collision check we did just did checks for all sides of the rectangle but we want to start with horizontal collisions first so if we end up in this position right here we're going to push our player over on the x-axis how do we detect within this closure check now we're in a position like this well simple enough within this if statement I'm going to also check if this dot velocity on the x-axis is greater than or less than one so if it's less than one I know I'm moving over to the left we are indeed colliding on the x-axis we can comment that out say Collision on x-axis going to the left and if there is indeed a collision on this x-axis how do we want to respond to this event well we want to take our player's position on the left side and move that left side to the Collision blocks right side if we do that we're going to put our player back over here and we're not going to be able to move past this point so let's do that so if our velocity on the x-axis is less than one I'm going to take the left side of our player which is this that position.x and set it equal to the Collision block dot position dot X Plus collisionblock dot width which will give us the right side of our player but that might put us directly on the very edge of our Collision block so what I like doing is adding on a buffer right here just something really small like point zero one to make sure that we're not still on top of that Collision block but that'll move our player back over to the right side of the block now I also want to do the same thing if we are moving to the right so I'll add an if statement that says if this dot velocity.x is greater than one I basically want to do the same thing that we did up here but I'm going to put our players position in a different location so our player's position on the left side is going to be equal to what well let's visualize this if we're coming in from the right side over here and we start colliding with a collision block we want to move the player's left side so that it's equal to the left side of our Collision block minus our player's width if we do that we're going to push our player over to the left to the correct position so this.position.x will be equal to the left side of the Collision block which we'll get to a collision block dot position dot X and then we want to subtract from this this dot width or player width and I'm also going to subtract a small buffer so we're not always colliding with that block right there and whenever we detect some sort of collision with a block I immediately want to break out of this for Loop because it's inefficient to have to go through the whole thing we already know we're colliding with one thing let's run this once and then go on to the next statement after this for Loop so we're going to break out right here if we're colliding with the left side of our player we're also going to break out right here if we're colliding with the right side but this should give us Collision detection on the x-axis given everything thing was rented correctly so let's save this refresh and see if we can get this work so I'm going to jump in from the left hand side and when I hit one of these blocks we should not be able to go past it so I jump and you can see right there no matter how hard I try to get past that block I am just not able to I can even jump past these but when I try moving to the right it's just going to push me all the way to one of the sides because we have all these Collision blocks in the middle and if we go test from the right hand side jump up hit the left well it looks like it is not working if it is not working for one of the sides it just means we have some sort of bug probably some sort of syntax error so let's Analyze This I have no doubt it is within our Collision statement we want to be very precise with this to make sure our Collision is always working and if we look very closely when we're referencing position.y the top of our player over here we are referencing our X position on the Collision block while we don't want to detect from the bottom side of our player and the left side of our Collision block for a collision we want to detect from the bottom of our player and the top of our Collision block which in this case we need to replace x with Y so we want to make sure that we're always referencing y within the same statement and X within the same statement and I think with that we should be okay so let's refresh after saving that and go over to the right hand side jump towards the left and there we go just that simple bug fixed everything so now we have Collision on the horizontal axis which is absolutely great what do we want to do now after this well remember our checklist the next thing we wanted to do is apply gravity which we are doing with this down here this is when we apply gravity to our formula so we already have that taken care of which is absolutely great but the next thing we want to do down here is check for vertical collisions because as gravity is applied while we might be colliding with one of these bottom blocks down here and of reclining we want to push our player back up so it looks like they're standing on top of one of these blocks instead so to check for vertical collisions what we can do is copy this code we just wrote In which we're checking for horizontal collisions I'm going to copy that whole thing paste it down beneath our comment where we're checking for vertical collisions I can get rid of this comment right here we're going to do the exact same thing for the beginning this Collision detection code checks for all sides of our player so we know that's great but if we want to check for whether or not we're climbing on the y-axis all we need to do is change this dot velocity dot X over to Y in both locations and then determine how we should react if we're colliding with the top or the bottom of our player so if our player is going up meaning our velocity on the y-axis is less than one we want to change our y position what do we want to change our y position to well let's visualize this if we're colliding with the top of one of these Collision blocks we want to change it equal to our Collision block position on the y-axis it'll be that right here plus our Collision block height if we add on our height it's going to give us this location in which we can push our player down to so let's get our Collision block position on the y-axis plus our Collision block height plus our little buffer right here of 0.01 and that should take into account collisions whenever the top of our player hits a collision block let's do this same thing for when the bottom of our player hits a block we're going to change our player's position on the y-axis equal to the Collision Block's position on the y-axis of course minus our player's height instead we also provide the buffer and that should put us in the exact position we want so let's save refresh and now you can see as soon as our player spawns respond on the very top of this so to get our player spawning within our boundaries let's change our player's position and also the width and height so that it's a lot smaller we're going to scroll up to where we're setting within height and change our player to have a width and a height of 25 instead and then for our position let's go ahead and say 200 by around 200 should be okay I want to say refresh and now you can see our player is pretty much in place but what just happened right there why do we pass through our Collision well remember we're always going to be adding gravity onto our player's y position and as we apply gravity we're going to be checking for a collision further and further down so for one frame we might be right here yes we do have a collision so we push ourselves back up but for the next frame our y velocity will be even greater because we just added more gravity onto that y velocity so we might be all the way down here and push our player up and eventually we're going to get to the point where we're pushed all the way down here and if we're pushed all the way down here checking for a vertical Collision there is no collision and to hit the very bottom of our screen and hit that other conditional in which we're detecting for collision at the very bottom of our canvas so whenever we have a collision especially on the y-axis we want to make sure that we're resetting our y velocity equal to zero that way we're not just adding a greater and greater value onto it until our player goes past one of our Collision blocks so let's go ahead and do that now we're going to go back to our Collision code specifically on the y-axis and I know this is dealing with the y-axis so I can get rid of this comma referring to the x-axis there but whenever we have a collision and our velocity is less than one meaning we're going up we want the set this that's velocity dot y equal to zero same thing and for velocity.y it's greater than one we're going to reset that back to zero and that should solve the issue with our player going past one of our Collision blocks so let's save and see what this looks like we refresh and we fall and the Collision detection is working but we have this jittery effect where players just bouncing up and down so we just have to inspect our code further make sure we didn't do anything wrong if we look closely well I'm a big dummy and of course our velocity.y can be less than zero to a negative one so it could be like a value like 0.5 and we're not checking for that so if we're going up we also need to make sure that we're checking for those values by saying if our velocity Y is less than zero so something like negative 0.5 then we respond in this particular way so we don't want to check whether or not Y is greater than one here either and also in the horizontal Collision we want to change the one to zero sorry about that is a small mistake on my part but it happens so let's save that refresh and see how things look so looking really good we can move to left and right and our Collision detection works on that axis perfect but if I hit W still we're having an issue we're not jumping up or down so the issue here is we're running through our vertical Collision detection but we have this old code detecting for a collision at the bottom of our canvas and really if we look at this this is actually where we're applying gravity to our velocity so we want to take this line right here cut it out go up to where we're applying gravity and paste this as the very first thing before we apply our velocity to our player's y position we no longer need this.science.bottom unless we really want to detect for the bottom of our canvas but it doesn't really make sense because we're always going to be putting our player in the center of these blocks and we can get rid of this entire if statement and also the comment right here so as long as we're moving our gravity to where we're actually applying the gravity in this exact location save and refresh once we hit w we should be able to jump up and with this our Collision detection is working on the top of our player and we can even increase this jump velocity by going inside of event listeners and making sure we're decreasing this to something lower so like 25 can save that and now we're definitely hitting the top and responding in the correct Manner and this is going to work for every single closure block we have on here on every single axis in which our player moves so that is how we're going to add closing detection between our player and all the blocks on the screen but we're not done just yet I want to make sure that I'm refactoring our code over in player.js to make sure that this is as readable as possible so to make this as readable as possible basically all this code in which we just wrote I want to put them within their own separate functions so I know exactly what is happening with an update rather than trying to determine What's Happening by looking at all this code right here so let's start with checking for horizontal collisions I'll take our entire for Loop which does that and say instead I'm going to call this dot check for horizontal collisions like so and if I want to use this mode method I need to create it so where does update end it's going to be right here now I can go ahead and call check for horizontal collisions and inside of this I'm going to paste all that code which we just wrote we always want to make sure that we're saving and refreshing to make sure everything still works and indeed it does but now this is a little cleaner with an update we don't even need this comment now let's do the same thing for applying gravity I'll take these two lines right here and then instead call this dot apply gravity so now I need to create that method which I can do down below by calling apply gravity and then putting in those two lines so now this is available to us I can call it above I no longer need this comment we'll do the same thing for checking for vertical collisions so I'll go to the very end of this for Loop right here and then replace that with this dot check for vertical collisions and now I just need to create this method doesn't matter really where I put it but to keep things consistent with the order we should be calling this in I'll do it right after apply gravity and check for vertical collisions is that on n and now I can get rid of this comment this is a lot more legible to me in regards to what update does compared to just putting everything directly in there so let's save give it a refresh jump around a bit and everything still works as expected so now we're going to be able to go back to to do successfully check off Collision detection next we're going to add sprite animation so we're going to change our player which is currently a red square into an actual image that has animation associated with it so to start if we look within our image directory we're going to have a directory called King and within this are going to be all the different versions of our main player this is one where we enter a door this is one when our player is standing idle and right here is where we're running to either left or to the right so we're going to be swapping in between these but we want to start off by creating our player with this Sprite sheet right here so we know this is within our project because we already added all of our images but for our player to use an image I no longer want them to call Justina fill style and c.fill rect I actually want to use the Sprite draw method instead so we're going to extend our player class right here and we can do that by adding on after player extends and then Sprite so we're going to inherit from our Sprite class that is going to be the parent and if we want to make use of the Sprite classes draw method we just need to get rid of our own draw method down below and it's as simple as that now when we call draw we're going to be calling the draw method associated with Sprite instead but if we look within sprite.js in order for draw to work well what properties do we need here we need to make sure that we have image source because we want to pass that through into the image that is actually used within c.draw image so over player.js we also need to make sure that when we create a new player that we're passing through an image source and then to pass this on through to the Sprite Constructor up above we can call Super which is just going to call sprite's Constructor and within this object right here I'll pass through our image source so basically when we create a player we're going to pass through an image source we're going to pass through the image source into our Sprites Constructor and that in return is going to set all the properties that we have within sprite.js including this dot image which will allow us in return to use it within this draw method right here so for adding image source to our player class we need to make sure that we're actually passing this through whenever we create a player so we'll go to index.js we know we're creating a player right here on line 18. so we're not only going to pass through Collision blocks but also an image source what is the source of the image we want to use to create our player image well we know we need to go inside of our image folder so we'll go inside of IMG slash King because all of our player image Sprites are within there and then within King we want to reference idle.png so slash idle dot PNG so let's save refresh and see what this looks like so on refresh we now have a our player being rendered out with some images but as you can see we are using the full Sprite sheet here from the very beginning to the very end we want to crop this Sprite sheet so that we're only using one of these images at a time this is how animation is going to work if we crop this entire spreadsheet so we only show this one image right here we can then begin to move this crop Mark to the very next iteration of the Sprite sheet and if we begin moving this crop Mark really quickly to where we're only showing each version of the image at a particular point in time we're going to give off the illusion as if our character right here is actually moving so this is the exact logic we're about to code is we're going to crop our image and then we're going to basically begin shifting this crop box to each other image within the Sprite sheet by doing so we're going to create animation now before I begin creating that animation why is our image right here going past our closure blocks but stopping near the bottom well to figure this out we're going to actually render out where our player Collision block is at this point in time so we can see where exactly we're stopping to do this we're going to go on over to player.js and within update I'm going to call C dot fill Style set to SQL 2 let's just say blue and then I want to call C dot fill rect and I'm just going to draw a rectangle at this dot position.x this dot position dot y using the width and height associated with our player class so this dot height for the fourth argument so let's save this refresh and see what happens so right now really we're detecting for Collision based on the width and height of this rectangle right here this is actually our player but we're just rendering this image next to where a player is actually located instead what we want to do is extend the width and height of our player right here to take up the full width and height of just one frame of this actual Sprite sheet image so since player inherits from Sprite we're no longer going to use some set width and height values like we're doing right here we can get rid of these two and go over to sprite.js and inside of here is where we're going to set those width and height properties so those are going to be dependent on the image we're currently using so if we want the width of our player to be the full width of our image we're going to say that this dot width should be equal to this dot image dot with only when the image fully loads if the image does not fully load this will not be available to us therefore width will not be set so we need to make sure that we're doing this right here and then we want to set our height equal to this dot image dot height so now that we removed within height from our player class over here it's going to inherit this width and height property from the Sprite class instead so let's save that refresh and now you can see that we are drawing in the full width and height of our spreadsheet but it is so large that our player by default is just standing on top of our entire map remember what I said we only want the width of our Collision to be one frame of the Sprite sheet not the full width so to determine the width in which a Sprite should actually be we need to look at how many frames it consists of so I'm going to click on idle.png that's what we're using and count out the frames so it's one two three four five six seven eight nine ten eleven frames long so we're going to remember that and within sprite.js whenever our image loads we're going to divide this dot image.whip by that frame count which in this case is going to be 11. so let's keep that in the back of our minds for now we're going to make this Dynamic layer but 11 in this case is our frame count let's define that save and refresh and now you can see our Collision block is only taking up one frame this is still a little too large we're going to want to use a hitbox that only takes up the exact area of our player but we'll do that later in one of the following lessons but now you can see at least we fit within the bounds we can jump around and this new Collision block works as expected which is really cool but with this new Collision block we're going to want to start animating our spreadsheet so that this guy right here begins moving over to this location as long as we do that correctly we're going to give off the illusion of Animation so I'm going to give our blue rectangle over here some opacity so we can keep it in there but still see everything going on in the background we declare that within player.js and right here within c.fill style I'll replace blue with rgba the clear I want red to be zero we're going to be zero and blue to be 255 the full value and I want this to be 0.5 for the alpha value which is going to give it some transparency so save refresh and now we can see our player so we want to animate this guy to this location how do we do it well the first thing we're going to do is crop our spray Write Sheet so that we're only showing our first frame so this guy right here let's go over to sprite.js and to crop our Sprite sheet we're going to use basically an enhanced version of c.draw image instead of using just three arguments right here we're going to have to use nine not the best function design it's kind of old but this is the way we do it within canvas so the first argument is going to remain the same it's going to be the image we want to use but the next four arguments arguments two through five are going to be the dimensions for the crop box in which we want to crop our image to so right above this I'm going to create a const called crop box that can be a capital b or lowercase b whichever you'd like to use and a crop box is going to have a position which has an X and A Y so X I'm going to start at 0 why I'm going to start at 0 and then we're also going to have a width and a height so our crop box width what should that be by default well I'm going to make it this dot width because we know this dot width is our image width divided by the frame count which is going to be the exact width in which we actually want to crop our crop box too so width will be equal to this dot width and then our height will be equal to this dot height that's actually going to remain the same we don't need to divide that or anything and just make sure you don't use a period like me and you can say colon and we should be good to go so now that we have this crop bot const we can begin using it within C dot draw image so as I mentioned arguments two through five are going to be the crop location so argument 2 will be the X position which we can get with crop box dot position dot X the third argument is going to be the Y position which we can get with crop box dot position dot y the next one is going to be the width of the crop box so cropbox dot width and then finally it's going to be cropbox dot height and then add in a comma right there so this is what C dot draw image is going to look like to start the next two arguments are indeed going to be the stop position X and this stop position now y this is the position of where we actually want the image rendered out and then finally we want to declare the actual width and height of the image we can just use the ones that we already assigned to this dot width and height so put in this dot width and then this dot height so as you can see we have nine arguments a big function but this is what we need to begin cropping our image so let's save this refresh and you can see well we definitely cropped our image but what else did we crop we cropped our whole entire background image as well we do not want to crop that but why is it being cropped in the first place well remember our image also uses this Sprite class we need to make sure that we're taking that into account and that we're not dividing our image width for our Background by 11. because our background image only has one frame which should not be defining it by 11 or elsewhere only get 1 11th of the actual background so this number right here 11 needs to be dynamic and to make it Dynamic we're going to add in a property called this dot frame rate it's equal to the amount of frames within an actual Sprite sheet and since this is dynamic we need to make sure that we're passing it through as an argument within our Constructor so I'm going to add it right here copy this and then add it as an argument and now I know that I can use this within dot onload so I'll add in this dot frame rate right here and one more thing I want to do is assign frame rate a default so if no frame rate is passed through I want to set frame rate equal to 1 meaning there's only one frame in which we can render out such as our background image and this should take care of things at least for the background image but we do need to pass through a frame rate for our new player image Sprite so let's find out where we're creating our player it's going to be in index.js and when we create a player we want to pass through a frame rate with a capital R like so and we know that's going to be equal to 11 because they're 11 frames within idle.png but if we save this refresh things just don't work and a big reason for that is within player.js we never actually passed through that new frame rate property so we're creating a new player we need to pass through a frame rate and then we need to pass frame rate through our parent classes Constructor so we'll pass it through right here at the second property let's save refresh and now our player is back and that's honestly a great start but where's our background image yet well let's check within sprite.js it looks like up here on my tab I have an indicator that I have not saved this file when I set frame rate equal to one so let me save that refresh and there is our background image back in place so we just want to make sure if we're creating a Sprite and where we're not passing through a frame rate property that we at least have this set equal to that default one value and it should render out that image without us having to do any extra work so you can jump around move around as needed but we do want to create some sort of idle animation associated with this crop box so we completed step one where we created the crop box but now we want to move this crop box periodically to wherever the next frame is and as long as we're only moving the crop box and we're keeping the image position in place it's going to give off the illusion of an animation so how do we begin moving that crop box well we want to change this right here our crop box position on the x-axis so we know this right here needs to be dynamic and it needs to be dependent on the cropped width which we have right here assigned equal to this dot width so I'm going to grab this dot with and then I want to multiply this by this dot current frame so what is the current frame we're on within our Sprite sheet by default this is always going to be equal to zero actually so this dot current frame is equal to zero if we save this refresh we're going to see the exact same thing which is great actually but now we can begin iterating current frame upwards until we hit a frame of 11. once we hit a frame of 11 we're going to go back to the zero value it's basically going to allow us to keep shifting through our Sprite sheet because we're increasing our crop box position on the x-axis by the crop width times that new current frame so this is just going to keep increasing until we tell it to go back to the beginning and as long as we're telling it to go back to the beginning we're going to create an animation Loop so to start increasing this value we need to increase the stock current frame and I want to do this within some sort of update function but something different from a name of actual update because I know I'm already using that within player and I know that it will overwrite the parent update if we were to write it out like this so instead of just calling this update I'm going to call this update frames that's more descriptive anyways and within update frames I'm going to take this dot current frame and add one onto it for each frame we Loop through but in order for this to activate I need to make sure that I'm adding in to our draw method right here so we're going to load up the first frame and then once we go through this whole thing we're going to call this dot update frames which will launch us into the next frame for animation if I save this refresh you're going to see a very slight animation but it's way too fast for us to even really comprehend so we're reaching the end of our Sprite sheet and once we reach the end we're just going to keep pushing that crawl mark off to the side and if that's pushed so far off to the side we're not rendering anything in the first place which is why we don't see anything for our player anymore so we want to say if this dot current frame is less than this dot frame rate the max amount of frames associated with the Sprite sheet minus one because we're starting current frame at zero only then do we want to start adding one on the current frame else we know that we've reached the max frame rate so we should set this dot current frame back equal to zero we're going to go back to the very beginning so we save this and refresh you can see we have an animation in place this is what our Sprite sheet animation looks like although it is quite fast way faster than it needs to be so we need to reduce the frames per second in which this animation is running and to do that I'm going to add in two more properties within our Sprite Constructor the first one is going to be this dot elapsed frames and it's going to be equal to zero and then I'm going to add in another called this dot frame buffer and this is going to be equal to let's just start off with two so here's what we're going to do is we're going to keep increasing elapsed frames over time and if last frames is divisible by our frame buffer only then are we going to increase our current frame which puts us into the next version of our animation so let's write that out if this dot elapsed frames is divisible by this dot frame buffer and to say that this is truly divisible we need to set this equal to zero this is the modulo right here which gets the remainder of this division so if that remainder is equal to zero we know it's divisible then we can call this if statement which actually increases our current frame now we can definitely get rid of this up here we don't want to be increasing current frame for every version of update frames should really only happen in this if statement anyways and instead of increasing that we're going to increase this dot elapsed frames instead we're always going to be adding one out of that to make sure we're always checking for whether or not a last frames is divisible by this dot-frame buffer so let's save that refresh and now you can see that is much much smoother for animation so let's comment out this blue box for now just so we can see the full thing go to player.js comment out the blue box I'll actually add a comment that says this is the blue box for later reference save and refresh and that is looking really really cool for our animation so that's what it takes to start animating stuff within canvas and using a Sprite sheet it's going to allow us to go back to to do and check off sprite animation so next up we're going to add in a hitbox implementation so what is a hitbox well right here our player is obviously not touching the ground I want to make sure that our player falls down and their feet are touching these Collision blocks so how do we go about that well right now our players rendered out like this we just have one large frame and we have some space around it so that we can add in things like attacks later on and still show them in the visible area but if we want to have changed the position of our actual player we need to add in a hitbox which is just going to be a little box around the exact area in which we want our player to start colliding with Collision blocks so we need to add this in and then we need to alter our Collision detection and make sure that we're monitoring for just this right here instead of our outer box when we do that we're going to allow our player to fall down move around and then be controlled by just this box right here so how do we go about doing that well let's head on over to player.js we're going to go inside of our update method right here now I'm going to start off with monitoring for collision detections with this new hitbox so right before that I'm going to create something called this Dot hitbox and set that equal to an object now where should our hitbox be located I want it to be located relative to wherever a player is currently positioned so I could say I want a position property on this hitbox and set an x equal to this dot position dot X wherever a player is on the screen I want to do the same thing for y to say the Y position should be this not position dot Y and this is obviously going to have a width and height that's what we're going to use to help determine these collisions so we want to add a width and I only want this to cover the width of our actual player Sprite so about 50 pixels I believe would be a good start and then same thing for height let's just start off with a box and say our height is going to be 50 pixels as well so if I were to save this refresh we're not going to see anything because we're not rendering anything out if we want to render out this hitbox so we can get a visual indicator of what this looks like we want to call a c dot fill rect method it's going to take an X position which we can get with this dot hitbox.position.x same thing for y we want to reference this dot hitbox dot position dot y and then also we're going to grab this dot hitbox dot with and then finally we need to add in the height as well so this dot hitbox dot height and with this we should be able to see this hitbox being rendered out on top of our player so let's save and refresh and there is our hitbox we're starting off where our main player Sprite is being rendered and like I said it's going to be contained within this larger box up here so it really starts from right about there but we want to move this hitbox over by this offset and make sure that it covers our player where this other blue box is that's going to determine where we start colliding with stuff so we just need to add in some offset to our hitbox and I'm going to do that by adding on a value of let's just say 50 to start to our x-axis I'll say something like 30 or a y-axis and let's just see what that looks like saving her fresh and that's pretty close looks like we want about five more pixels maybe 10 on the X and we just kind of have to eye this to make sure that we get it right over our player and I would say maybe about three more so let's go to 58 and I like how that looks so I do want to push things down on our y-axis because this is a little high up and our feet are still showing down there so let's push this down by adding on to Y about four pixels that's looking good and then we want about three pixels on the bottom to cover the feet so I'll add on to height around three and I think that is a really good start for where our Collision box should be so now that we have this Collision box object we need to use this to monitor for Collision instead of that main large outer box and to do that we're going to start by looking at check for vertical collisions so let's scroll on down there and here is so this is where we are detecting for where a collision exists and we're currently using that main large box we want to use our hitbox now instead so any place where we have this stop position X this dot position y this dot width is the height and so forth we want to replace that with this dot hitbox instead so let's do that I'm going to select all six of these using Sublime texts command D and then I'm going to change this with this dot hitbox dot position X position y width and height and with this if we give this a save and refresh you're going to see we're monitoring for collision with our hitbox but the issue is when our hitbox hits one of these Collision blocks while we're moving our player too far up now because prior we're moving our player up based on the height of our main larger box now we have to move our player up based on the height of the Collision box but also the large box it's a little confusing to think about but we're going to go ahead and visualize it so let's go over here and I'm actually going to revert that code to the skies and jumping up and down and annoying us when we try to focus on something we're just going to stay right there and then I'll go back to where we were without saving and refreshing remember this box right here is dependent on the position of this larger box so our larger box is going to be moving down and this is going to be moving down as well So eventually this box right here or hitbox is going to start colliding with one of these Collision boxes and once that happens we're saying well move this up by the full height of our larger box right here if we move this up by the full height while we go up to this position which means that we have this little Gap at the bottom which we can still fall down with our main hitbox and that's why we're getting that up and down jump effect right there so what we wanted to do instead is when our main box goes down here and then our hitbox collides with one of these Collision blocks we only want to move our main box up by the distance between the bottom of our hitbox and the top of our main large outer box so in our climbing if we only move up by that amount it should be right about here since we're only detecting for a collision with our hitbox we're going to be placed right on top of the ground and that's exactly what we want we can ignore the position of our outer box because now we're only detecting for a collision with the bottom of our inner box so how do we get this distance right here how do we say move our player up by this green line distance instead of the distance of our entire outer box well really we're going to need the top of our hitbox so this right here and if we subtract from the top of our hitbox the top of our main outer box we're going to get this length that's going to be a start but if we add on to this also the height of our hitbox well we're going to get the exact length of the screen line which we need to move things up by so that's how we're going to do is get the Y position of our hitbox subtract from at the Y position of our outer box and then add on to that the height of our hitbox so let's do that right here this is going to be on line 103 when our velocity Y is greater than zero meaning we're falling down I'm going to create constant side of this called offset an offset is going to represent the length of this green line right here so how do we get the length of that green line well like I mentioned we want to get this dot hitbox.position dot y then we want to subtract from this this dot position dot y with this now we have the top blue line right here now all we need to do is add on this dot hitbox dot height and we're going to get the full length of this green line perfect so now that we have the full length of the green line we're going to take our closure box position dot y that is going to be the bottom of one of the Collision blocks and subtract from it not the full height of our blue outer box but rather we're just going to subtract the offset instead the exact amount of height we want to go up by the green line so let's save refresh and you can see that is immediately fixed great so we want to do the same thing but for when we hit the top of this you can see there's a little Jitter right there we want to make sure that we're pushing our player down by the exact amount required rather than having to calculate those collisions based on the main outer blue box so how do we go about that well in this case we only need the distance between the top of our hitbox and the top of our outer box and we already know how to get that we just take the top for a hitbox and subtract from at the top of the outer box so let's go inside where we're going upwards right here I'm going to create a const called offset and then this is going to be equal to this dot hitbox.position dot Y and subtract from this this dot position dot y that's going to give us the amount in which we need to shift our player down by so we're going to take our Collision block dot position.y plus our Collision block dot height that is the bottom of the Collision block and then subtract from this or offset so that little amount that was on the top between our inner box and our outer box so we save that jump and you can see that is just much better we're not getting pushed around as much and once we get rid of this red box it's going to be even more apparent but now you'll notice if I try hitting a or D we're just kind of shifted around why is that well to understand this we need to look up above within check for horizontal collisions and you can see within here we're still detecting for a collision based on the X and Y coordinate of our main outer box we want this to be focused and on our new hitbox the inner box so where we're detecting for a collision here we also want to reference this Dot hitbox.position.x and Y width and height instead of the main outer box and when we do that save and refresh well things seem even more broken now why would that be well we're using this dot hitbox right here but if we scroll up above we're only defining this dot hitbox right before we check for vertical collisions so one thing we need to do is we need to make sure that we're assigning this dot hitbox before we check for horizontal collisions as well we need to do this right here and also right before we check for horizontal collisions because after we check for horizontal and vertical collisions we are altering the position of both our x and y coordinate and if this dot hitbox uses this dot position X in this dot position y we need to make sure that we're updating this not hitbox after each calculation so it's very important that we call this in two locations now we could call it right here and right before this dot check for horizontal collisions but this is a little messy and we can clean this up up using a method so let's create a method called update hitbox and inside of this we're just going to paste in this dot hitbox this Eagle says object that is dependent on this.position.x and this dot position dot y so once we do that we can get rid of this dot hitbox in these two locations which we'll do and then replace this with this dot update hitbox instead so I'll grab this and then also replace that up here and now that we're updating our hitbox before we check for both horizontal and vertical collisions we should be in better shape let's save and refresh and yeah that seems to be a lot better and we can even move around and everything is still working as expected but now we're focusing on just this hitbox for Collision rather than that main large outer box but Watch What Happens we still need to alter things for when we're checking for X collisions if I move to the left and run into this Collision block right here you're going to see that we're just moved over by the wrong amount and same thing is going to go if I go over here we're just moved over by the wrong Mount so let's focus on check for horizontal collisions and we know when we're going to the left that we need to move our player over by a certain amount and it's not going to be completely dependent on just the Collision block the precision.x and collisionblock Dot width we kind of need to do the same thing that we did for the y-axis so let's get that little amount of space on the x-axis between our large outer box and our players hitbox we can get that by creating a const called offset and then we're going to grab this Dot hitbox.position.x and subtract from this dot position dot X and as long as we have this we can subtract from the right side of our Collision block which is calculated with these two right here a subtract from this our offset it's going to make sure that we're placed in the correct position on the x-axis when we're moving over to the left so now when we try moving to the left we no longer get transported back over to the right and there's no jittery effect but that still will happen if we go to the right we need to take that into account as well so if we want to speed this up a bit we can go down where we check for vertical collisions and we can find the code in which we wrote to get the correct amount of spacing when we are going downwards and it's going to be right here where we're assigning offset equal to these three so I'm going to copy this scroll on up and now when our velocity on the x-axis is greater than zero I'm going to reference an offset right here and instead of referencing my position on the y-axis I'm going to replace this with X right here right here and then I want to reference our hitbox width instead of height and as long as I do that offset should be calculated correctly so now I know when I'm going to the right I want to take our collisionblock DOT position.x which is the left side of our closure block and subtract from it not this dot width but rather our offset that's going to give us the correct amount of spacing in which we need so that we're not jumping back and forth so we can save refresh and now when we go to the right that is no longer happening where we're teleporting over back to the left so this is perfect Collision detection but using this new hitbox feature and I can't really get a bug using this I haven't experienced it yet so I think this is a pretty good transition over into the next lesson so let's comment out the visual hitbox and we can do that by heading on up to update right here where we're filling interact I'll comment this out save refresh and now we have some really good Collision detection going on between our hitbox Sprite and all the Collision blocks around us so cool let's head on over to to do and check off hitbox implementation next up we're going to work on Sprite swapping so making sure that when we're running over to the right we add in a running animation rather than just keeping this idle animation once we add this in it's going to make our game look much more realistic so it's very important that we actually put this in there so how do we even begin this well I think what I'm going to do is go over to index.js and then start within where we're creating a new player what I'm going to do is add in an animation's property this is going to be equal to an object within here I'm going to Define all the animations I want to add in to our actual player Sprite so let's start off with what we have we have an idle animation in which our player is currently facing the right so I'll add that in by saying idle right it's going to be equal to an object and we can even look up above for reference in regards to what data properties should be going in this idle right animation so we need a frame rate of 11 we already know that exists and then I believe our frame buffer was equal to 12 and I think we also have Loop in there set to true that kind of defines what our animation is currently now this animations object is going to act as our library of Sprites that we can switch between for this one individual Sprite we're working with so our player Sprite is going to have a library of multiple animations let's go ahead and copy this paste one down below and then Place idle right with idle left this is going to have the exact same data down below but if we look within our Kink folder we have run left and run right as well we want to add these in here too so all I need to do is copy these two objects paste them down below and then replace idle with run so we have run right and run left but we do need to change the frame rate and possibly the buffer for these as well we'll experiment to see what the buffer is going to be but we can get the frame rate right now let's look at run left and see how many frames this is It's one two three four five six seven eight so that's how many frames we need to go through before we go back to the beginning so we'll declare within index.js for run right and run left then we have a frame rate of eight in both of these locations that's really all we need to get started so we're passing through this animations property right here we need to declare that this is something we know we're going to pass through with both our Sprite class and also our player class because I want to make sure this is available to us in case we want to use it in another generic Sprite so we need to make sure we do it for both so over in sprite.js I can declare at the top within our Constructor I want to pass through an animations property and down here I'll create that property with this die animations and assign it to the animations argument so all we need to do is start but we need to do the same thing for player as well so I'll scroll up so we want to pass through an animations argument possibly and then I already know that's being assigned within our parent so I can add into Super animations we're going to get the exact same effect for our player Class 2 which is great but let's go on over to sprite.js and review what's going to happen so whenever I press down on one of these keys right here I want to switch on over to a new Sprite and to switch on over to a new Sprite I need to change whatever this dot image is equal to I need to set it equal to a completely new image object that's associated with whatever animation we want to show on the screen so for each of the animations in which we just passed through in index.js these four right here I need to create a new image object associated with each of these now how do we do this in a way where we don't have to keep typing out new image image.source is equal to this well the way I do it is right after I sign this dot animation SQL to animations I can say if this dot animations exist so we know that we're going to have multiple within this one object then I want to run a for Loop through all the keys available to us within this object so I can do that with four let key in this dot animations and what this is going to do is Loop through all the keys associated with the objects within this dot animations so we're going to reference I don't write then we're going to go to idle left we're going to go to run right and then we're going to get to run left but we're only going to get the keys which means we're not going to get any of this data inside of these actual objects we're just going to get the name of the object so things like idle right things like idle left things like run right and so forth that's basically how this for Loop is working so as we Loop through each key I'm going to create a const called image and set this equal to a new image object now that I have this new image I can say for this Loop assign the image.src the image source equal to image source available to us within the current object We're looping over which we can get by referencing this the animations this is going to make all the objects available to us and if we wanted to grab just one individual object particularly the one We're looping over we would add in some brackets like this and then use the key in which we want to reference the object so for the first iteration of this loop we're basic grabbing idle right and all the properties inside of it so what property do we want to reference we want to reference dot image SRC because that is what we wanted to assign well to an image.source but you may have noticed over at nix.js we never actually passed that through that's the property that we missed when assigning these originally so what is the image associated with idle right well it's going to be the same image in which we're using right here for our default we can just grab this and paste it in within idle right now let's go to idle left paste in same thing but we want to reference a different image for when we're looking to the left and idling we have the image right here it's going to be idleft.png so we can just reference that by going inside of image King and then idle left now we want to do the same thing for run right and run left so let's reference those images here for run right we're going to reference run right.png which is right there and then same thing for run left we're going to reference run left.png which is also right there so now all these are available to us and we can use them within sprite.js to assign our image object and actual source so that's the first thing we want to do and now we just want to make sure within each animation object in which we have that we're assigning the actual image we're creating equal to a property called dot image so we're going to take that one object and assign to an image property the image in which we created so really what this is doing is it's automatically creating a image property like so new image with Source already assigned to us but we need two lines to do this and so we're just running it through a loop and assigning this image to each of our objects automatically just a quick little way to make things go A bit quicker so let's get rid of this and then at the end of the swirl Loop I'm just going to console log out this dot animations to make sure that this was populated correctly so let's save refresh everything's still working we go over to inspect element I'm going to extend this out over to console and open up this object so you can see we have idle left and if I look in there we have an image object which is exactly what we wanted an image source should be assigned correctly to that image and this is going to work for very much every animation that we have inside of here so run left has image run right has image and so forth so now we can begin assigning our main render image right here to those new images we just created based on which keys we're pressing so I'll get rid of this console log and then I'm going to go to index.js and I want to go down to our anime Loop this is where I'm going to start switching our Sprite so if our D key is pressed we're going to be moving to the right but I want to add more code in here so I have to add these curly brackets and when we move to the right I also want your player to switch they're Sprite now what Sprite do I want to switch to well simple enough when I'm running to the right I want to switch to the run right to Sprite now this method is not currently available to us which just means we need to to create it so let's save right here and go over to player.js and create a new method I'm going to do this below update called switch Sprite now we know switch Sprite takes an argument it's going to be the name of the Sprite we want to switch to but how do we actually assign this new animation image to the image that our spray is currently using we can get the image or spray it's currently using with this dot image simple enough and then we just need to assign it to this dot animations add some brackets and then get the name of the actual image which we're passing through right here and we want to make sure that we're grabbing the image property associated with this animation object which we can get with DOT image so now we want to make sure that we're getting all the other properties as well things such as our frame rate frame buffer each of these animations might have a different version of those so we need to make sure that we're reassigning it right here let's do that now so I want to say this dot frame rate we'll select the animation which we want to switch on over to with this that animations name and then make sure that we're grabbing the frame rate associated with that one animation let's do the same thing for frame buffer and to expedite this process we can hit command C command V and then in both these locations swap out frame rate with frame buffer instead now whenever I switch on over to a new animation I also want to make sure that I'm setting this dot current frame equal to zero so that we start at the very beginning of this animation because our idle animation only has 11 frames while our Running Animation has eight what if we're on frame 10 with our idle animation and we decide to switch on over to our Running Animation well then we'll be rendering out frame 10 frame 10 doesn't exist on the Running Animation so before we do any of this we want to assign this dot current frame equal to zero and with this we should be good with switching on over to our running Sprite so let's save this refresh and now when we hit D we should see some sort of running animation and there's something going on there's not really animating until we stop moving which is weird why is that happening in the first place well when we hit D what are we doing we're setting current frame equal to zero for every time I call switch Sprite whenever D is pressed well we're calling switch Sprite we want to make sure we're only switching on over to the Sprite if the current Sprite were on has not already been set and we can do that by calling it conditional with if this dot image is equal to the current image in which we're trying to switch on over to then we want to return we don't want to call any of this code because we know these two are the same there's no point of trying to switch to the same image and resetting our current frame equal to zero saving her fresh and start moving to the right and now we have a nice Running Animation in place now this might be a little too fast for you and if you want to slow this down a bit over in index.js we just need to find where we declared run right and then add on to our frame buffer so let's just add on four instead of two for both run right and run left save and refresh and now that's a bit slower but also I think that matches a bit better it's kind of fast before I like the way this looks so you might notice when we're running to the right and we stop we still have that Running Animation in place we need to switch back on over to our idle animation so down here within our animation Loop if our D key is pressed we're running to the right if our a key is pressed we're going to run to the left else I want to switch our Sprite on our player over to idle right because if I'm not doing one of these I should just be standing around so save and refresh run to the right and stop and now we go back to our idle animation we're starting to switch between the two but we do need to add in animations for when we're moving to the left so let's start off when we're pressing down our a key we're going to add in more lines here so we'll add in two curly brackets all I need to do is copy player.switch Sprite to run right paste it into this else if and then reference run left instead it's going to be that easy so let's save refresh run to the right and then run to the left now we have a running animation for when we go to the left and we stop well we turn back to the right it's really the last thing we need to fix is when we run a light and let go we need to make sure we're facing to the left because that makes more sense of course so we're going to reference this L statement and add more lines inside of here basically if we're standing around I wanted to check for our last Direction so if our players last Direction was equal to the left then I wanted to call player that switch Sprite idle left instead so idle left else then we can call idle right we know that the only other direction there is is going to be red we should be facing the right but we don't have player.last Direction set so what we can do is grab this and then whenever we press a we can set player.last Direction equal to left and then when we hit D we'll set our last Direction equal to right and that's really all we need to do so let's save refresh we run to the right stop things look good we run to the left stop and then we're facing the left and now we have some really nice animations going on here with our player and all these different directions that we can go through so this is all we're going to do for sprite switching but you can really add in so much more with jump animations attack animations and so forth maybe we'll cover that in a future video but this is a great start for idling and running in both directions so let's head on over to to do and we're going to check off Sprite swapping so now to go to another level we need to enter a door and then activate the necessary steps to change your level but the first thing we need to do is actually populate our map with doors so that we can enter them we're going to have to animate these as well so where would I start with this well I know I want a door somewhere over here so that we're forced to kind of Traverse this map get to the end and enter a new portion of our actual map so if we look over in our game in our image folder we have something called door open.png this is the animation we're going to use to open and then enter a door so we want to pull this into our game first let's do that now in index.js we're going to scroll down and right beneath our player instantiation I'm going to create a doors array like so this is going to store all the doors associated with one of our levels because we might have multiple but in this case we're only going to have one so inside of this I'll put a new Sprite with a capital S and what does a new Sprite take well it definitely takes a position where do we want this door placed well I want it placed at an exposition of zero and Y position of zero just to start and then we need to reference the door image so image SRC image source is going to be equal to what I'm going to go inside of my image folder and then find door open with a capital O DOT PNG that should be good enough to create a doors right but we want to render the Sprite out which means we need to go into our animation Loop and kind of follow the same pattern we're doing right here for our Collision blocks so I'm going to copy those three lines paste them down below and then instead of looping through our Collision blocks I'm going to Loop through our new doors array and then for each door within this array I want to call the door dot draw function that comes from our Sprite class so if we save this go to our game and refresh we're going to see our doors rendered out in the top left hand corner but this is an animation so we want to make sure that this is animating and we can do that simply by going up to our door instantiation here and then adding in a property called frame rate we already set this up how many frames does our door have it has one two three four five so we just say five right here we can save refresh and now we have a door animation now this is kind of fast for my liking so I want to add in a frame buffer property to slower animation down and I'm going to put a frame buffer about five right here to start see what that looks like I save and refresh and that is actually exactly the same so we have an issue right here where frame buffer is not affecting our actual sprite animation let's go inside of our Sprite clause and if we look up above we're not actually passing through a frame buffer property you want to make sure that we're passing that through frame buffer is by default going to be equal to what well two because that's what we're assigning down here so let's say our default will be equal to two but for our door it's going to be equal to five as we're passing it through which means for actual dis.frame buffer property we're going to assign that equal to the frame but for argument we're passing through so let's save that refresh and that is definitely slowed down so looking great now I don't want to keep looping this animation I only want this to happen once it doesn't make sense for this to be opening and closing unless it's like a ghost door or something like that so if I want to prevent this from looping I'm going to go to index.js and within our new Sprite right here for our door I'm going to declare our Loop should be equal to false we should not be looping through this but kind of the same deal as what we had for frame buffer we can save this refresh and we're still looping through our door just means we need to add some Loop property changes over to sprite.js so when we're creating our original Sprite we're not actually passing through anything that says should we Loop or not so I'm going to add in a loop argument right here within our Constructor and then down below I need to make sure that for our default Sprite that we're declaring this dot Loop is equal to the loop we're passing through as this argument we just added in so now Loop will either be true or false based on what we've passed through when we create a Sprite but down below within update frames we need to determine how our looping should be affected based off this new Loop property so we know right here with this else statement we are resetting our frame back to zero which means we go back to the beginning of the animation what we can do is change this to an else if and say if this dot Loop is equal to true then we want to go back to the beginning so if this download is equal to false we're never going to reset that frame and we're never going to be able to keep adding on a frame to the current position we're just going to stop the animation altogether if this dot Loop is equal to false so let's save this refresh and now you can see that animation definitely only happened once for our door now the issue is our player is no longer looping so we need to fix this to take into account our new changes so the first thing I do is go over an nx.js and look at our player instantiation right here we're not declaring whether or not we want this to Loop so I think it makes sense in this case to give a default of loop equal to true for each of our Sprites so I'll go up into clear Loop it should be equal to True by default let's see if that fixes things refresh and now we are definitely looping through everything which is great all we had to do is add in that default so now we need to detect for a collision between our player and the door but the door is up there we can't even reach it because of our Collision blocks we need to change our door's position to be somewhere over here on the right hand side of our level now we could go ahead and just guess things and place it in the right position and within our code but that's a little slow for my liking so what we can do is head on over to tiled the map editor and select our miscellaneous objects layer right here with this selected we can open on up our object tile set and select our door and now with the door selected we can hit this little image stamp tool and then we can draw a door wherever we want on our map so if I want this door drawn right here within our miscellaneous layer I can click and now our door is drawn and it doesn't really help that much to just kind of click this there but what we do want is to grab the X and Y coordinates associated with this door so our x coordinate is going to be 767. let's go back to our code find where we are creating our door it's going to be right here on line 50 for me and then I want to change or X position equal to 767. save refresh and you can see that's almost in the perfect position for x coordinate now what is our y coordinate it says 381 but one issue here is the y coordinate is the bottom of the image we're currently referencing if I use the select tool right here to drag our image upwards and I drag it to the very top on the y axis you're going to see that we still have a y coordinate of 112 because that is the bottom of this image when in reality our canvas draws from the top down so what we want to do is get the y coordinate let's subtract from this y coordinate the height of this axle object which is also listed right here so about 381 382 minus 112 that is going to be 270 pixels so we'll head back to our code and say we want this door placed 270 pixels from the top of our map to refresh and now that it's within the perfect position right now one thing you might have noticed is the store just opens by default we only want to open this door if we activate some event so we don't want to run this animation as soon as we create the door and therefore we want to add in an auto play property so within our door I'm going to declare that our autoplay should be equal to false by default specifically for our door once we add this property in we need to go on over to our Sprite class and begin integrating it here so autoplay by default I'm going to set Eagle to true because I do want most of my stuff to autoplay and I'm only setting autoplay equal to files for our door instantiation anyways so I think this is okay we're going to create a property down below called this dot auto play set it equal to the argument we're passing through and this is how we're going to use this we're going to go on down to update frames and we're going to say if this dot autoplay is set equal to false meaning we do not want this to start right off the bat we're just going to return all together and we're not going to play anything else if we save this refresh you can see that our door is closed but our player is still going because we never actually said that our autoplay property for our player should be equal to false now going back here I want to make sure that we have the ability to play our door animation when we're ready so preemptively I'm going to add in a method called play and whenever we call play on a Sprite I'm going to set this dot autoplay equal to true that means that this is no longer going to run we can run through our actual frame animation so let's give this a save and refresh make sure everything is still working now what we want to do is have our player walk over here and we're going to detect for a collision between our player and our door if the two are indeed colliding we're going to activate that play animation and we're going to switch our players Sprite to an animation where they actually go through the door so let's start by detecting four Collision how do we go about that well I know I want to activate this code within eventlisteners.js specifically when I press W on my keyboard because that is where I'm supposed to jump up I want this to kind of double as going through doors so what I want to do is grab the door whenever I press W so I can start detecting for a collision and to grab the door I need to Loop through our doors array because we might have multiple we want to detect which door are we currently looping through so to Loop through our doors I'm going to use a traditional for Loop and say 4 let I equal to zero and then for our next statement I'll say as long as I is less than Doris that length I want to increase I for every iteration of this for Loop and I want to select the door we're currently on with const or is equal to doors I and now that I have this door available to us I can run an if statement that compares the location between our player and the current door we're selecting right here now that's going to be quite lengthy to write out and we have actually already done this over within player.js so if we look when we're checking for either horizontal or vertical collisions we'll start with this right here we have Collision detection code it's all within this if statement so to save some time we can simply copy this go back to event listers.js and paste it within our newest statement and just make sure that we're adding some opening closing curly brackets so the code for this is pretty much going to be exactly the same we want to select our players hitbox which already referencing right here but we can't reference this because this is more class syntax we need to reference the actual player object in which we created that's going to give us the hitbox details and then we don't want to reference a collision block but rather the current door We're looping through so we're going to change Collision Block in these six locations with door instead and with just this we're monitoring for collision between our player and our door and to prove this to you we can come select out we are colliding whenever we press W and we're intersecting with the door so it's refresh and then open up our console so we can actually see that log and move that to the bottom so we can see it better we move on over to the right and now when I press W on my keyboard we're definitely colliding with that door but once I go off of it we are no longer logging out that text now one thing we want to do is make sure that if we are colliding that we don't actually jump up so right here if we Are Climbing we're just going to return all together which just means we don't call any of the following code within our actual switch case to save refresh go over to the right and now when we press W we're no longer jumping but we can still jump as long as we're not colliding with the door now before we go to a switch sprite animation you're going to notice that we're saying that we are colliding when it looks like we're kind of off with the door so we want to change our Collision detection code just a little bit to make sure that we only activate this Collision if we're in the middle of the door rather than just touching it so here's how this is going to work we're going to have the boundaries for our main door right here and then of course we're going to have the boundaries for our player we need to monitor for whether or not the left side of our player right here is greater than or equal to the left side of our bound box we need to do the same thing for the right side is the right side of our player over here less than or equal to the right side of our bounding box it's just a small little change up to our equation to make sure that we're colliding fully on the inside rather than just touching this box a little bit from the outside so to write that we'll start with the right side of our player which we can get by adding on to our position.x our player dot width that'll give us the right side of the player so now we're saying if the right side of our player right here is less than or equal to the right side of our door then we are indeed colliding that's exactly what we want let's do the left side of our players we have the left side of our player with position.x we no longer need to track our player hitbox.with we just want that full left side of the player we're saying if the left side of the player is greater than the left side of our door we are colliding but looking at this real quick we always want to make sure that we're correcting the correct thing we don't want our player with but rather a player hitbox.width because our hitbox is much smaller and that's actually where our player is moving around on the map so let's save that refresh and see if things work so if I go over to the right and start jumping looks like we're good to go we're not fully in the middle of our door same thing with the right side but if I go near the middle hit W we're saying we are colliding because we're in the middle that is perfect that is exactly what we want and we can move on to the next step so what do I want to do next well when we Collide here we don't need to consolag anymore but rather what I want to do is Select our player and add on a a prevent input property I'm going to set this equal to true so as long as we're colliding with this door I no longer want the player to be able to move around so at the very top of our event listener I can say if our player dot prevent input is equal to true meaning we cannot move we're going to return and we cannot call any of the following code down below that's simple enough but now I also want to make sure that I set our player velocity.x equal to zero so we're not sliding around or anything like that I'll do the same thing for y just in case player velocity.y is equal to zero and then we prevent movement altogether and now we want to switch on over to a different Sprite so we're going to call switch Sprite and what Sprite do we want to switch on over to well we have an enter door Sprite right here we look at that it's one two three four five six seven eight frames long so we're going to switch on over to enter door and now we need to make sure that the Sprite is imported within index.js so right now we only have these four animations I'm going to add in one more by copying run left and I'm going to replace run left with enter door our frame rate is going to be the same a frame buffer let's just go ahead and keep it at four for now that seems totally fine bar image source is going to be enter door.png instead of run left and we don't want to Loop this we actually want to set the sequel to false because it doesn't really make sense to enter a door kind of teleport backwards and then try entering the door again now if we save this refresh you might think that entering the door will switch on over to the Sprite completely and I'm pressing W right now so we should be switching over to that Sprite but we're not why is that well we need to look within our animation Loop to find out although we are switching over to that Sprite by default we're always switching back to either idle left or idle right so basically what we wanted to do is say if we're preventing our player input we do not want to call any of this code it would kind of be like adding in an if statement that says if or player dot prevent input is equal to true then we're going to return all together but in this case we want to be calling player.draw or player.update which we definitely still need to actually render a player out and animate them on our level so instead of calling return right here directly within animate what I'm going to do is cut all this code out from line 93 down to 106 hit command X to cut that out I'm going to put this within its own method within player.js so right beneath the update a call handle and put then paste in all that code and if I'm pasting this in here I don't want to reference a player object I just want to reference this is going to be basically the same thing since we're calling this from the player class so now if I call return I'm only returning from this function I'm not going to cause any other code to be skipped over within our animation Loop but in order to make sure that handle input is being called well we need to either call this within our player's update function up above or you can just call it within index.js so right before I call it draw I'm going to call player dot handle input and that's going to match up with what we have over here and if I really want to be pretty good with my code quality I can pass through our keys as an argument save and then make sure that I'm passing through our keys value over here within handle input and now we know exactly where this Keys object is coming from it's coming through an argument which we're calling right here and a signing up above so let's save this refresh start walking around and now when we hit W in front of her door we're going to activate that new animation so you can see right now our player is looping through his animation even though I believe we have Loop set equal to false for it so let's look up above for enter door and yes Loop is equal to false so something is going on here let's check player.js and go up to our Constructor we can see within our arguments we're not actually passing through a loop property which is coming through our player class and that should go up to our Sprite class so we're going to pass through a loop here and then within super we're also going to pass through Loop now this is good for determining whether or not our initial animation should be looping or not but the thing is when we switch to another animation we're not actually setting our Loop property equal to the new value of this new animations Loop so in order to do that we need to make sure within switch Sprite we're saying that this dot Loop associated with our player is equal to the loop value of the current animation we want to switch to so I'm going to copy this line get the current animation which is this right here and then instead of referencing frame buffer I'm going to say get the new Loop property with that we should not Loop whenever we press W in front of our door hit W and yeah we only call that once that's exactly what we want what else is left really well we need to open our door and we already set ourselves up for success with this by adding in that play property specifically for sprint.js right here where we set autoplay equal to true so all we have to do is call door dot play whenever we hit W and we can do that with an event listeners.js so after we switch our Sprite we're also going to call door dot play to actually play that animation we should be good to go let's refresh after I save and then in front of her door hit W that opens and now everything is in the exact position we need it to be to begin changing to a different level so with this we can head back on over to to do and check off entering doors so now finally as soon as we enter a door we want to go on to the next level to present a new challenge to our player so how would we go about doing that well essentially what I want to do is when we walk inside of here I want to run some sort of on complete function that Fades our screen to Black so whenever this animation where we walk through the door completes we're going to fade in a black screen activate the code that brings up a completely new level and then spawn our player in a new position to begin the new level so first thing first though let's add in an oncomplete property for when we complete this animation and then fade our screen to Black so to add in an oncomplete property I'm going to go to nx.js and I want to focus on our player animations we know the animation when we enter a door is going to be right here so I'm going to add in a property called on complete and this is going to be equal to a function so whenever this animation completes we want to console log out completed animation but now we need to integrate the functionality in which we can actually call on complete once this animation ends so here is a way to do it we can go over to spread.js and within our Constructor we can add in a property called this dot current animation and this is going to be equal to undefined start we're not actually going to assign anything to it within our Sprite class but over into player.js when we're calling switch Sprite the first thing I wanted to do is assign this new property which we now have access to because player inherits from sprite this.current animation is going to be equal to the animation we just switched to so in this case we can get the animation with this the animations name now that's going to be stored within this.current animation great now that we have access to this property over in sprite.js what we can do is call the stock current animation dot on complete but we only want to call this under certain condition such as does this on complete property actually exist on the current animation and other conditions such as have we reached the end of our animation we need to make sure that we're checking for those conditions and we can do that within update frames so at the very bottom the first thing I want to check for is if we have this dot current animation set so we're checking for that but if we also want to check if this has an oncomplete property we can use optional syntax with a question mark which first says does this dot current animation exist if it does continue on with the dot and check if on complete exists so it's basically a shorthand way of writing a double conditional with and but we're just doing it a lot cleaner using this some tags so if our current animation exists and it has an oncomplete property what do we want to do we'll call this dot current animation not the frame dot on complete and activate that function but even if it exists we only want to call this at a certain time specifically when we are at the end of our animation so how do we check whether or not we're at the end of one of these animations well we can use an if statement that says if this dot current frame is equal to the end frame over animation which we can get with this that frame rate minus one then we're going to call oncomplete but another issue is we might be at the very end of our animation and since we're at the end we're just going to call the statement right here repeatedly we only want to ever call this once so we just need to add on an extra conditional with an and statement that says if it's not current animation dot is active and we actually want to add a bang operator to this so if the current animation has not been activated then that is when we want to call Dot on complete and to make sure this doesn't run again we need to set this current animation dot is active equal to true as soon as we activate the animation so this is what things should look like and what do we save and refresh and open up our console now when we enter the door we should see some text being logged out we're activating that on complete function so we enter and there is our completed animation text as soon as we reach the very last frame right here perfect that is exactly what we want so now we can call at the end of our animation some code which fades in a black background so how would we get started with that well we need to create a black background first and the best place to do this is going to be within our animation Loop in index.js so after everything has been called I also want to create a black rectangle which I can do with C dot fill correct and I want this to cover the whole canvas so I can do that with 0 0 canvas width and then also canvas height and right before this I'm going to assign our C dot fill Style equal to black with just this we shouldn't see anything at all that's why we want to start saving our fresh and yes our whole game is gone because it's been covered by this black rectangle that's totally okay though so what we're going to do is fade this out and to fade this out with canvas we need to do something called C dot save and then after this call C dot Global Alpha set this equal to a value such as 0 or 1. anywhere from zero to one this is basically going to determine the transparency of this rectangle right here now at the end of C dot fill rect I'm going to call C dot restore and basically what save and restore do is it says only apply This Global Alpha to whatever code is inside of save and restore so right now I'm saying only make this transparency zero for these two lines right here I don't want our player to be invisible I don't want our doors to be invisible only what is within save and restore so let's save and refresh and now we see everything and you can see if I change this equal to like 0.5 or something like that we have a nice black transparent background we're going to basically fade this Alpha value in and then fade it out so if we want to fade this in and out we need to make sure that this is dynamic and I'm going to assign this Eagle to Overlay dot opacity but in order to make sure that I can actually assign it to this I need to create that object top above will declare that our constant of overlay is equal to an object with an opacity property and this by default is going to be equal to zero of course because we don't want to see it as long as we have that should not see that black background perfect but what we're going to do is when we complete our enter door animation yes we're going to console like this out but we want to fade in that new value we just created so what is that value it's going to be overlay dot opacity how do we get this from 0 over to one well I think the easiest way to do it is going to be using an animation library and there's one that we can pull in really easily it is called gsap I pretty much use it for every game that I do so let's just do a quick search for gsap CDN go to the very first result at cdnjs.com and we're going to be grabbing version 3.11.1 we can describe the very first result click copy script tag go over to index.html and at the very top of our script tags paste that on in and now we have access to the GSAT Library which we can do to animate things such as that opacity value so let's do exactly that in index.js if I want to change overlay.opacity from 0 to 1 I'm going to call gsap.2 this basically says go from this value to the next one now what object do we want to change a property of simply our overlay object now I'll add in a comma and add an object right here and declare what property I want to change I want to animate our opacity property to the value 1 and this is all we need to fade in this value right here so let's save go back to our game refresh and try entering our door and on complete we should see that faded in Black Background so I go in and yes we are on the right path so now that we have this black background what do we want to happen well essentially we want to re-initialize all of our values associated with our game but we're going to assign new things such as New Collision blocks a new background and so forth so right now we're assigning all these on load we're going to want to assign them when we call a function instead so it's time to start setting up our separate levels rip beneath where we're assigning canvas height I'll create a Lut called level set it equal to one because that's going to be the first level we start on and then beneath this I'll create a levels let this is going to be equal to an object that contains all the data related to our levels so level one will be equal to an object and inside of this I'm going to have in the knit property set equal to a function so when I select levels 1 and knit we're going to call all the code that we need to populate level 1 with the level one data so why is the level one data well pretty much everything that we already have written out here so what I want to do is move some of these right above where we're declaring level and levels and I'm going to change our const to let select parse collisions let Collision blocks and let level background one I want all these to be lights because I want to assign them within this init function instead of assigning them directly when we load our file so I'm also going to copy this from here and put them within a net but when they're within a niche we can get rid of the left because they're already declared up above we can also get rid of the Declarations right here because we're going to assign these only when we call a knit for these levels so these are more like Global objects in which we're assigning whenever we call it knit and we want to do this for basically every object we know is going to change so we know where Collision blocks are going to change which is great we're putting that within init we know our background is going to change but we really shouldn't be calling this background level one anymore this is more going to be a generic background instead so I'm going to rename back on level 1 to background in any location in which it exists do a quick search for background level one change it right here as well and we can leave this image right here because in this case we do want to assign background level one to whatever background we're rendering out but let's scroll on down what else is going to change on a level by level basis it looks like our doors will for sure change so let's grab this go to the top paste this in change cause to let and now doors will be assigned whenever we call a knit for level one so inside of a knit I'll say Doris is equal to that array in which I cut out and now this door will only be available when we call level one init is there anything else we need to change on a level by level basis I'm scrolling down and no it doesn't really look like it we might change some stuff with our player though so let's move player up to the top right beneath doors I think we can keep this as a const and we might just change some properties on the fly now the first thing I want to do is actually call a knit on level 1 right here because all this in Nick code is being called whenever the file is loaded Instead at the very bottom yes we're going to call animate but before that I'm going to select our levels object get the current level we're on which we're starting off on level 1 and then call it's a knit function and everything should still work the same as long as we've done this right so let's save and refresh and it looks like we're definitely having an issue there with our player falling off the Collision blocks so if we scroll enough to our code where we're actually assigning our Collision blocks it's going to be within a knit but if you can recall from a previous lesson right here we're trying to reference Collision blocks but it's just not assigned when we're actually instantiating a player so we don't want to add in Collision blocks right here when we're instantiating a player instead we're going to assign that dynamically whenever we call a network level so we'll grab our player object and then assign Collision blocks equal to the Collision blocks in which we're parsing out up above as long as we save that and refresh now our collisions work again we should be able to go through the store and get the same result but with cleaner code so we know we're going to fade in that overlay but when this animation completes we want to increase our level so GSAT provides its own oncomplete property and this will be equal to an arrow function and now within this we can say we want to increase level by one that's going to push us to level two and then we want to call level two's init function so grab levels get the current level we're on which in this case would be 2 initially and then call a knit on top of that and that should send us on over to level 2 as long as level 2 exists which currently it does not so if we want to go to level two I'll grab everything within one paste it down below change this one to two and now whatever we call it in a net is going to activate for our second level so we're going to keep our closures the same just to start the only thing I want to change right now is going to be the background image in which we're using so rather than assigning background equal to background level one we're going to change this to two because we have that available to us right here this is what it's going to look like so as long as we reassign our background we should see it when we fade our overlay back out to an opacity of zero so let's go back to that gsap code and on complete we're going to init our new level and then we can call gsap.2 grab our overlay and then fade its opacity out back to zero so let's see what this looks like let's save refresh and go inside our door I'm going to fade out to Black and now we can see our new level we see all the Collision blocks from level one we're going to change that really quickly but we did change our background image that is a great start now if we look at things our player is still in the same position in which they were and we're still rendering out our door so we want to make sure that we change our player to a position somewhere up here and we want to get rid of this door completely whenever we activate level two so let's see what level two looks like we have this door but we want to put this door in a new position relative to our level 2 map so how do we go about doing that we want to go over to tile and do the same thing we did before with placing our door we can select an object layer which is indicated by these purple boxes click the stamp tool and then place our door wherever we'd like and I know I want to place it down here so I'll click and get the coordinates for this new door so the x is going to be 782 go back on over to our code and assign this x coordinate equal to that and then we just need our Y which remember is going to be the Y minus the height of the door so 448 about minus 112 is going to be 446. 4 3 36 I believe if my math on the Fly is correct so I think I said 336 refresh and yeah we're still at level one it's kind of annoying having to walk over there to see where everything is placed so you just want to start out at level two all you need to do is scroll on up to where you're actually assigning levels and here it is on line 61 for me I'm going to assign our current level equal to 2 saving her fresh and now that looks a lot better so I actually got that right on the y-axis that is great and now our door is over here but it kind of looks like we have two doors and I think that's just because when I export a background level two I included the door so all we really need to do in this case is make sure that our new door in which we actually wanted to interact with is overlaid directly on top of the background door or you can just export the whole background image without the background door but uh let's just do the quick way let's move our door over to the left a little bit I'm going to say this should be around 760 776 a little closer let's subtract around four more pixels 772 and that seems to be about perfect I like how that looks now when we activate level two our player should be somewhere up here so something we can do is head on over to tiled grab a small object like this and place it in the position we want to spawn our player I'll click right here and then grab the coordinates associated with this so it is 96 for x and let's just say this is going to be around 140 for y so 96 and 140. let's change our player's position on those two coordinates so player position dot X it's going to be equal to 96 and then player dot position dot y will be equal to 140. we save this refresh and now our players spawn around that position this is good enough for me and you can kind of find two things as you'd like but this is a totally good start so obviously we have the issue where a player is on top of these Collision blocks we want completely New Collision blocks for our new map how do we actually get those well we need to do the same thing that we did for level one we need to export this whole file and then grab the data associated with our collisions so I'll go to file and then export as and then I can save this wherever I like I pretty much say this as a temporary file within downloads I'll call this level two and go back to my finder so this is going to be within downloads and right here level 2.js I want to open that and then I can scroll down until I find our collisions or I can do command F and search for collisions instead and this is all of our Collision data so I want to copy this array and go back to our code and I'm going to go inside of our data folder where we assigned our original collisions level 1 equal to the collisions array which we exported from level one in this case I'm going to create a new const called collisions level 2 and assigned to this the new array which I just copied so these are all the collisions related to level two and now that we have this available to us when we activate level 2 within nx.js we can make sure that we're referencing collisions level 2 parsing them to a 2d array and then creating objects from that 2D array and populating collision box from all that data that we just parsed so let's see how this works let's save refresh and all this Collision blocks are immediately in the correct spot and now our player reacts accordingly which is really freaking cool so if we go ahead and press W on this door yes we're going to enter but we don't currently have another level to go to we want to go on to level three and level three is available to us within Finder right here so I want you to open this up export your Collision blocks and then try to get level 3 up and running on your own so pause the video and see if you can do it otherwise let's get right on into it I'm going to open up level three click on that and that should be open and tiled for me which it is and you'll see I have my collisions up here so the first thing I'm going to do is actually export these collisions I'll go to file export as and let's save this as level three that's totally fine within downloads that saves and now I can go over to my finder once more click downloads open up level 3.js here it is I'll do a command f for collisions and this is all the data I want associated with our level 3 collisions I'm going to copy this array go back to our code go within collisions.js create a new const called collisions level three set it equal to the array I just copied and now within index.js I want to State what happens as soon as we go to level three so let's create level three I'm going to copy level two paste it down below and change the two to A3 and now I don't want to select collisions from level two I want to select collisions from level three so to test that this is working I'm going to find my level let change level to three by default so after changing that save and refresh and you're going to notice no Collision blocks are being spawned so why might this occur and you might have even come across as trying to do it yourself well in order to figure this out we need to look at our data for level three so we're going to go inside of collisions JS and if we look at this well oh that is new we are using a different symbol right here for closures level 3 than where you're using for two and one and if that's the case we need to tell our parser how to react when we hit a symbol of 250 rather than 292. so all of our parsing code was within utils.js and whenever we hit a symbol of 292 we're creating a new Collision block we also want to do this if our symbol is equal to now I believe it was 250 exactly 250. so as long as our symbol is equal to 250 we'll push in Collision blocks and this should work for this level as well so after a save and refresh now we have those Collision blocks in place that is solved we need to change the location of our door though so we'll do that next in level three I want to change the position of our door Sprite over to where it was on the left and I am lazy so I'm just going to do this directly with entitled select our layer right here grab the door make sure that our little image stamp is selected just place this directly on top of where it is on the map I click and I have those coordinates available to me so X is going to be about 175 and then Y is going to be the same as it was for level 2. so I'll change X to 175 saving our fresh and now that's pretty much in the same location just a little bit off so we'll just subtract a pixel or add on a pixel to X and subtract one from y and that seems to be pretty good that doesn't really make sense if our player starts all the way over here let's start a player in the top right and I'll do the same thing that we did with the Box just click on the location which I want our player to spawn and that's going to be 817 by around 180 ish so let's add that in we're going to change our player position on the x-axis to 817 lose as 140 for now and our player is too high up I want this to be a y of about 180. let's push our player down a bit by changing 140 to 180 and it looks like we're just spawning on top of the occlusion blocks so we probably need to subtract from our player position on the x-axis save refresh and it looks like we just need to keep doing this until we get it right I'm going to subtract about 50 pixels from X and I'll add on around 50 for y save and refresh and now we're in a good spot when we spawn perfect so that puts level 3 in really good shape but now I just need to make sure that our transitions between doors work so let's go back to level one I'm going to find our level let change this back to one instead of three it'll start us off here we go inside of our door we should call on complete activate level two and yeah we definitely have an issue up here where we can no longer see our player we need to switch our Sprite back to the idle right position we also need to make sure that prevent default is turned off so let's do that whenever oncomplete is basically Midway meaning that our black overlay has faded in we've changed our level and the new level has been initialized we can call player dot switch Sprite and then what do I want to switch to well idle right now Chicago is facing to the right as soon as we go through one of these doors let's try it out we go through now we're facing towards the right but I can't move because prevent input is still set to True after we call player.switch Sprite I also want to call player dot prevent input and set this equal to false and that way we can move around again and navigate our level so we go inside of the door after that we're animated and now we can move around in level two we have all of our Collision blocks in place so let's try going to level three see how that looks we try going inside and uh oh you might have noticed well we are not going fully in the door and proceeding to the next level so why is that well let's investigate we need to go on over to sprite.js and look within update frames so right now we're only able to call on complete if is active is equal to false and this is what's making sure oncomplete is only ever called want we call it once we set is active vehicle true we can no longer call this code so what we need to do is make sure that we're setting this back equal to false whenever we load a new level and that will allow us to call this again once we enter a new door so over in index.js let's find level 2 and what I want to say is if a player.current animation exists then I want to call our player dot current animation is set is active back equal false and that should make sure we can call on complete again when ready we want to make sure that we're putting this on a knit for each level so I'll put it within level three as well and also level one so let's save with this fresh looking good we go through the door on complete is called everything's still activated and now I'm going to go through this because we set our current animation is active Eagle Falls we should be able to call on complete again which indeed we are so looking great if I try going through our final door you're going to notice that we just Fade to Black and if I open on my console there should be a bug within there and indeed there is so we're trying to call a net on a level that does not exist so what you can do is either add level four or you can just loop back to the very beginning I'm just going to loop back to the very beginning for the time being so I'll say if level is equal to 4 which does not currently exist then I'm going to set the level back equal to level one and I'll just make sure that I knit on level one once I hit to level three and I can test this real quick by changing a level one to three to start I'll start us off over here and now when I go inside the door I should go back to level one and indeed I do and now the loop is complete we can go between all these rooms with all the different Collision blocks and so forth and it's just going to allow us to keep doing this until we add in levels we'll start adding in multiple doors and new features but this is the general gist of how you're going to create a multi-level platformer I really suggest creating multiple doors multiple locations in which you can go and really start experimenting with things once you start adding some enemies in here and a little bit of functionality it's going to create a really really cool game so the last thing I do here is just comment out our Collision blocks so we can see the whole thing and really enjoy our creation comment these out I'll scroll down to our animation Loop and I know I'm rendering out our Collision blocks right here comment that out refresh and now we have this full map in which we can do reverse [Music] so with this functionality in place we can head back to to do and check off change levels now you might not want your platform to be restricted to just the confines of one screen and if that's the case well I recommend checking out this video right here we're just going to show you how to extend your level through the creation of a Mario based side scroller game
Info
Channel: Chris Courses
Views: 136,223
Rating: undefined out of 5
Keywords:
Id: Lcdc2v-9PjA
Channel Id: undefined
Length: 183min 24sec (11004 seconds)
Published: Wed Sep 28 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.