JavaScript Fighting Game Tutorial with HTML Canvas

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
welcome everyone this is another chris chorus with  your host chris and today we're going to be coding your very first fighting game we'll start off  by learning how to code some basic fighting game   mechanics we're going to start off with some  rectangles that know how to fight each other   once we develop these fighting rectangles  then we're going to go ahead and change these   rectangles into sprites with animation we'll learn  how to create sprites for both our background and   our fighters and then we'll touch up our interface  design making this game ready for live on the web   so without further ado let's get started so the  first thing we're going to do is focus on project   setup this just means we're going to set up our  folders our files pretty much everything we need   to get up and running so to do this what i like  doing is within sublime text i like going to file   new file and then i have a new file open all  i need to do now is hit command s to save it   and now i need to go ahead and create a  directory so i'm going to go inside of   a folder that is familiar to me that is a  web directory that i created personally and   inside of here i can go ahead and create a new  folder and i'm going to call this fighting dash   game so with this new folder created now i can go  ahead and save this as index.html and hit save we   have our first file created great so now inside of  index.html what kind of html element do we need to   create a game well no other than a canvas element  so we're going to go ahead and create that now   so once we have a canvas element in place we  can hit command s and we should be good to go   in regards to opening this up within a browser so  to open this within a browser we can go to finder   and then go inside of our web directory  specifically the folder we just created which   is going to be fighting dash game and this is the  file we just created index.html so all i need to   do here is double click it now we have it opened  up within a browser so i go ahead and inspect this   element by right clicking and hitting that inspect  element tab you'll see we have a canvas within our   browser and all the html elements which are pretty  much put in there by default thanks to chrome so   we have our canvas element within our html but  now we need a place in which we can actually write   code so we're going to create a javascript file  to do that back in sublime text we can go to file   new file that's going to create a completely new  file for us once we're here we can hit command s   and then we want to go ahead and create a new file  within our fighting game folder called index dot   js then we're going to go ahead and hit save and  now we pretty much have all the files we need   in order to get started with this game it's that  simple so it's pretty useful to have both index.js   and index.html open at the same time so in order  to do that we're going to go to file open and then   we just want to go ahead and find the folder in  which we want to open rather than one specific   file so once we have just this folder open we  don't need to click either of these we can simply   just hit open right here and then we're going  to see our project opens up we have our folders   on the left hand side going to be a lot easier for  game development if we have this open at all times   so let's go ahead and start by resizing our canvas  so it's the correct size for our game it's going   to be 1024 by 576 i typically find this a good  ratio in size to make sure that our game fits on   most computer screen sizes so in order to do this  we're going to go inside of index.js and we're   going to go ahead and create a const called  canvas this is going to be equal to document   dot query selector we want to go ahead and select  an element from this list over here whether it be   html head body or canvas which element do we want  to select well simply the element that has a name   of canvas so all we're doing is grabbing canvas  from right here and storing it within the const   of canvas simple enough the next thing we want  to do is select our canvas context this is what's   going to be responsible for drawing out shapes  and sprites onto our game so it's important   that we go ahead and pull this in to pull in  our context we'll create a const call it c   set it equal to our canvas const and then we want  to call a method on top of this called get context   and then what kind of context do we want to get a  2d context 3d context those are mainly our options   we want to go ahead and get a 2d context  because we know this is going to be a 2d game   not a 3d game so with 2d inside of here we can go  ahead and save and now we have our two main const   ready to go canvas and c c just stands for context  and the reason we're calling this c is because   we're going to be using this so much it's going  to be really tedious to keep calling something   that's long typically i never recommend creating  variables that are just c or something really   short like this but this is the one exception i'll  make for canvas context it is okay to call this   c so we have our canvas const and our c const our  context but we want to go ahead and resize our   canvas and we're just going to use javascript  to do this i typically find css models things   up a bit when creating canvas games so we're just  going to do it the standard way within javascript   we can do that by selecting our canvas cons and  then we want to go ahead and select the width   property on top of this so once we go ahead and  assign any value to this whether it be a thousand   two thousand we're basically just saying our  canvas width is going to be equal to that amount   of pixels so a good value for width is going to  be 1024 and then beneath this we want to go ahead   and select our canvas height as well and declare  that our height is going to be 576. this is a 16   by 9 ratio and by having a width of 10 24 we're  going to make sure this fits on most screen sizes   so if we save this go back to our browser and  refresh we're not going to see any difference   in our canvas size just yet because after  we go ahead and save index.js with all this   code right here we need to make sure that  this is pulled into index.html so right now   we only have our canvas element but when we're  inside of here we can also create a script tag   that has a source equal to index.js so go ahead  and type in index.js save go back to our browser   refresh and then you can see our width and  height are taking effect i can hover over this   you'll see it's pretty much taking up the width  of 1024 the height to 576. so we're pretty good   to go in regards to the size of our canvas  if we want to go ahead and see the full width   we can always move our dev tools down by clicking  these three icons right here and then clicking   this little tab icon dock to bottom that's going  to move it to the bottom you can hover over our   canvas again and you'll see that's how much  width it actually takes up now in order to see   our canvas background well we need to be hovering  over this canvas element down here to emit that   blue highlight onto our screen let's go ahead  and make it so our canvas has a white background   by default just so we can differentiate it from  our actual browser background so within index.js   we can go ahead and select our canvas context  this is what's used to draw shapes onto the screen   once we have our canvas context we can begin using  the canvas api so what is an api method that we   can call to draw a white background well we can  call c dot fill rect we're going to create a   big rectangle we're going to use it to fill up the  entire width and height of the canvas so fill rect   takes four arguments the first is going to be an  x position so i go ahead and put the x position at   zero and then the second argument is going to be  the y position so i'm going to go ahead and assign   that to zero as well all this means right here  is to draw starting from the very top left of our   canvas this is a coordinate of zero and zero back  over in our code we want to add in a third and   a fourth argument so third argument is going to  be the rectangle's width how large do we want to   draw this well we want to go ahead and draw this  to full width over canvas so go ahead and select   our canvas width and then for our fourth argument  we want to go ahead and put the height in there   so let's say this is going to be a rectangle that  takes up the full width and the full height of our   canvas which is assigned right here on lines four  and five so let's go ahead and save this we'll go   back over here to our browser and refresh and  now we have a black background so that actually   takes care of the need to differentiate our  canvas from the browser background and i'm   actually using a browser called min it's just a  minimal browser that still uses chrome devtools   if i go ahead and close out of this you'll see  our background is white but our canvas is black   that is totally fine to start we know where  our canvas is we know where our background is   we can begin developing our game as needed because  we know our drawing area is going to be this giant   black rectangle so as long as we have a folder  with index.html and index.js we can go back to   our to-do list and we can go ahead and check off  project setup that is all we need to get started   with our project the next thing we're going to do  is create a player and an enemy and we're going to   start off creating these with just pure rectangles  a lot of games are created that way developers   just insert rectangles into the game and they code  the functionality between those rectangles before   inserting sprites we're going to do the same  thing because it's pretty complicated to add some   sprites using just vanilla javascript and canvas  it's more important to learn the functionality   and the basics behind a fighting game before  we go ahead and get to the sprite portion   so in order to create a player and an enemy we  want to make sure that we're within index.js and   although we could create a rectangular player just  using fill rect we don't want to do it that way   we want to use object oriented programming because  we need these rectangles interact with each other   and have their own individual properties that act  independent from one another so in order to create   an object we're going to go ahead and create a  class this acts as the blueprint for the object   before we actually create it so this class is  going to be called sprite because later on when   we begin using images and replacing our rectangles  actually moving things while moving images and   games are basically called sprites we're going  to call it sprite in advance but within this   we're just going to start with the rectangles so  whenever you create a class you need some sort   of constructor method which is basically just  a function within the class and constructor is   fired for every time we create a new object from  the sprite class and so whenever this is fired we   want to define the properties associated with a  sprite so whenever you're doing game development   one of the main properties that you want to put  on pretty much any object is going to be position   and whenever you create a property within a class  and a constructor you need to make sure that it's   prefaced by this dot so each time we create a new  instance of sprite it's going to have a property   of this stop position it's going to have some sort  of position associated with it which we can place   it on the screen but we know our sprites might  have positions independent from one another and if   that's the case we want to go into our constructor  function and we want to pass through an argument   so we want to pass through an argument called  position and each time we instantiate a sprite   while this position is going to be assigned to the  position of the individual sprite we are creating   so now that we have a class of sprite with a  constructor we can go ahead and begin creating our   player and enemy let's start with our player we're  just going to create a const called player and set   this equal to a new sprite this is how we create a  new object from this class right here so now that   we're creating a new sprite we can look inside of  our constructor and see what argument this takes   so it takes a position argument and this is just  a position we want associated with our player now   position can be any data type it could be a number  it could be an object it could be a string but   in our case we want to go ahead and make this an  object so i'll go ahead and put an object in here   and say that the x for our object should be equal  to zero to start and the y of our object is also   going to be equal to zero this just means within  our game we're going to place our sprite at the   top left hand corner of the screen to start and  if we save this and then console log out player   save that head back to our browser open up our  inspector and then hit the console tab and then   finally refresh you're going to see our sprite  object is logged out we successfully created one   instance of our sprite class that is perfect that  is exactly what we want but now we need some sort   of way to define what a player actually looks like  so we also want to do that within our sprite class   inside of here i'm going to go ahead and create a  draw method and this is arbitrarily named we could   call this whatever we want but it makes sense to  call it draw because we know what we call this   we're going to draw out our sprite so whenever  we call draw what should our sprite look like   well our sprite should just be some sort of  rectangle as a result we want to go ahead and   call c dot fill rect to create a new rectangle so  what we can go ahead and do is we can say well i   want the sprite to be drawn at whatever position  is passed through our constructor right here   so basically what we're doing is we're creating  a new sprite we're grabbing this x and y   we're going on up to our argument right  here where positions being passed through   we're passing position through into this  right here and then finally position is   going to be stored in this dot position which  is the individual property we're creating for   our player const right here but now that we  have this object right here being stored in this   stop position we can go ahead and reference this  opposition within other methods within our class   so now that we have this opposition we can use  it within c dot fill rect to say that our x value   should be this dot position dot x so now this  right here is just referencing this x that we   passed through our second argument is going to be  this dot position dot y that's going to reference   this y value right here and then finally we need  some sort of width and height associated with   our player to start we can go ahead and just put  these in as static values i'll go ahead and say   our player is going to be 50 pixels wide and about  let's say 150 pixels tall so now we need some sort   of color associated with this draw method in order  to make sure that it differentiates itself from   the black background of our canvas as a result we  can put in c dot fill style and set this equal to   a string of simply red and if we assign fill  style to red right here right before we call c   dot fill rect it's just going to make sure that  we're filling in a rectangle with a red color   so if we save this nothing's going to happen if  we go back to our browser but what we can do is   we can select our player const and then on top of  this call this draw method that we just created   so now with player.draw below if we save go back  to our browser and refresh you'll see this is   what our player looks like great that is exactly  what we want to start so we have our player there   let's go ahead and create an enemy we'll put our  enemy somewhere over here on the right side of   the screen kind of makes sense for fighting games  put an enemy over there instead of right next to   us so in order to create an enemy we'd simply just  duplicate the code that we created for our player   so we're going to create a const called enemy and  set the sequel to a new sprite so what properties   does a new sprite take well we know it takes a  position the position is stored within a position   property and we're just saying that we're using  an x and a y property within this object we're   passing through so i'm going to say that our  x is going to be equal to something like 400   just an arbitrary number off to the right and then  our y value can either be zero or we can add some   numbers onto this to make sure that our enemy  is pushed down we're going to say our y value   is going to be equal to 100. so now we have an  enemy created in order to draw this enemy out we   just need to call enemy.draw save this go back to  our game over here refresh and there's our enemy   not exactly where we wanted it since it's not  all the way on the far right side of the screen   but this is close enough just to get started this  is all we need so now we know our player and our   enemy are going to be moving objects and whenever  you have moving objects within canvas it's pretty   standard to add a velocity property onto your  sprite class velocity is just going to determine   in which direction should these be moving when  they're inside of an animation loop so let's   go ahead and add some velocity and gravity to make  sure that our player and our enemy right here fall   to the bottom of the screen and they stop once  they hit the bottom of it so in order to get these   moving we need to create some sort of animation  loop to create an animation loop we can go to the   bottom of our file and create a function called  animate totally arbitrarily named by the way   you can call this whatever you want animate just  makes sense because that's what we're about to do   now we can call window dot request animation frame  which just says what function do i want to loop   over and over and over again i need to select one  well we really only have one function created and   that is going to be animate so we can go ahead  and take this name right here and paste it within   request animation frame so now right beneath  our function if i go ahead and call animate   with animate and then some opening and closing  parenthesis what's going to happen is we're   going to call requestanimationframe and then it's  going to say we want to call what will animate   so we're going to go ahead and go right  back to calling this function so we call   this function again what happens while we call  request animation frame we call animate we're   basically just creating an infinite loop that we  want to go on and on forever until we tell it to   stop so you can begin animating your objects frame  by frame so if we really want to test that animate   is working we can just put a const log inside of  it and i'm just going to put any string inside of   here it doesn't really matter what and i can go  ahead and save this and make sure you're calling   animate down below for this to fire and then off  in our browser if we refresh and then right click   hit inspect element and then open up our console  tab right here you'll see we are logging out go   over and over and over again that is how fast  our function over here of animate is being called   just really really quickly so we can begin  moving these objects over time as this loops   through itself so now that we know that's working  we want to go ahead and alter our sprites position   so that both our player and our enemy begin to  move downwards they're going to be affected by   gravity so as i mentioned a little bit earlier we  want to go ahead and add a velocity property onto   our sprite to do this right beneath position  we can add in a new property called this dot   velocity and this is going to be equal to a new  velocity that we're going to pass through as an   argument so if you need another argument within  your constructor you can go ahead and add a comma   at the end of position and then pass through  velocity as the second argument but one issue i   have with this is eventually as we begin adding  more and more properties onto our constructor   well we need to remember the position of our  properties first we need to pass through position   and then velocity we can't pass through velocity  first and we can't pass through position second   and as this gets bigger and bigger it's going  to be hard to remember the order of everything   so what i like doing to fix this is i like  wrapping these two arguments within one singular   object like so so now we're only passing through  one argument but within this object argument we're   going to be passing through a position property  and or a velocity property they're not required   and the order does not matter anymore because  we're passing them through as properties within an   object nice little trick to make your code cleaner  and easier to manage so now that we're passing   through a position and a velocity this way we need  to refactor our sprite instantiation down below   before we were just passing through one singular  object so this right here is just equal to our   position but we need to define that we need to go  ahead and wrap this one object in another object   so i'm going to go ahead and do that wrapping it  in opening and closing curly brackets and then   inside of that first opening curler bracket i  want to hit enter and i'm going to assign the   second object equal to a position property so  your first sprite should look like this and now   this is a lot more legible as well we know that  this object right here is equal to our position   so we need to pass through a second property and  that is going to be equal to velocity so i'm going   to add a comma here and say that our velocity is  also equal to an object with an x and a y property   because we're going to have two dimensional  velocity to make sure that our object can move   left and right and also up and down so by default  our player is going to have an x velocity of zero   and a y velocity of zero as well this just means  that our player is not going to be moving by   default so this is the correct way to instantiate  our player now let's go ahead and do the same   thing for our enemy we know that our enemy has  a different x and y and x a 400 and a y of 100   but if we want to do this as quickly as possible  we can simply just copy our whole cost of player   is equal to new sprite get rid of our const of  enemy and then paste in a duplicate of player   now all we need to do is change the console player  to a const of enemy and then set its position back   equal to 400 and 100 and now this is instantiated  in the correct way but using a lot cleaner syntax   because we added in this object destructuring  within our constructor function right here   so if we save this go back to our game everything  should be the same we refresh it is that is great   it works with all of our new code but now we can  begin using our velocity to move these objects   now when i have things moving around typically  i like creating an additional method within my   class this method is going to be called updates  when i want properties updated to begin moving   my spray across the screen this is where i'm going  to call it is inside of update so whenever i call   update the first thing i want to do is call draw  we're going to go ahead and call these two lines   right here and to call draw we can simply write  this dot draw this just means we're referencing   this right here now if we want our player and  our enemy to fall we need to go ahead and select   their position so we're going to select them with  this not position dot y and then we're going to   add on to this over time with plus equal all plus  equal means is that we're using this dot position   dot y and adding something onto it over time this  is the exact same thing as this dot position dot y   plus equal to 10 it's just shorthand syntax to  make our code a little cleaner so we're going to   use a shorthand syntax get rid of this line right  here save and now what we're saying is over time   our position.y is going to have 10 pixels added  onto it for each frame we loop over but in order   for this to take effect we need to make sure we're  calling update within our animation loop down   here so let's go ahead and get rid of player.draw  because those are only going to be called when our   file first loads we want to make sure that they're  called for every frame within our animation loop   so inside of here we can call player dot update  instead of draw because remember update is still   calling this.draw so we'll call player.update  and then we'll call enemy.update as well   we save this go back to our game over here and  refresh and you're going to see these are now   moving across the screen although it's creating  a paint like effect instead of showing the   individual objects so in order to fix this we need  to make sure that we're always clearing our canvas   for each frame we're looping over otherwise we're  going to get that paint-like effect so before we   update our player and our enemy right before that  we're going to call our canvas context with c   and then we're going to call clear rect on top of  that make sure that second r is uppercase so this   is just going to be the same thing as fillrect  but clearact just means we're not actually   drawing anything when we call this method so how  large of a rectangle do we want to clear well we   have to start at zero zero the top left hand  corner of our canvas and this should take up a   width of our canvas width and a height or canvas  height so we save that and refresh and those are   indeed falling but we lost our black background  because we're calling clear act instead of fill   erect well i guess clear wrecked just make  sure nothing is shown in the background at   all so let's go ahead and change this to fill  rack to my apologies let's just call c dot   right to make sure we get that differentiation  of our canvas and the background and now what   happened while our background is red because the  last thing we set for fill style was red right   here within draw so right before we call c dot  fill rect we want to set c dot fill style equal to   black so that means when we call c dot fill right  right here it's going to be a black rectangle   but then when we call player and enemy dot update  they're going to have a fill style of red to make   sure that those differentiate themselves from  the black background so i save go back over here   refresh things are looking a lot better although  our player and our enemy are going off the screen   now so to get these two to stop at the bottom  right here we're going to want to focus in on   our update function the first thing we want to  do is change his static value of 10 equal to the   velocity we're actually passing through for both  our player and our enemy sprite because if we want   our sprites to stop moving we're going to have  to set our velocity equal to zero at some point   so what we're going to do here is instead  of adding on 10 we're going to add on this   dot velocity dot y so for our position on the y  axis we're adding on our y velocity we save this   and refresh now they stay in place because over  here our y velocity for both our player and our   enemy is equal to zero but if we go ahead and  change our player velocity equal to 10 on the   y axis and refresh now our player is moving down  so you can kind of see the benefit of using object   oriented programming is it allows you to go  ahead and change individual object properties   independent from one another right now only our  player is moving down because we said for its   y velocity that should be equal to 10 while our  enemy's velocity should be equal to zero so that's   a start but now what we want to say with an update  is we want to write an if statement that says   if this dot position dot y that is going to go  ahead and give us the top of one of our sprites   so this right here so if this dot position dot y  plus this dot height now we don't have a height   property yet on our sprites let's go ahead and  add one to add a height property right below   velocity we'll just add on this dot height we go  ahead and set this equal to the static value we're   currently using down here of 150 and now we can  swap out this location with this dot height within   our draw method but now we can also go ahead and  reference this within our update method as well   so this position.y plus this dot height what is  that equal to well that's going to be equal to the   bottom of a rectangle right here so if the bottom  of our rectangle plus our sprite's velocity is   greater than or equal to the bottom of our canvas  right here then we're going to go ahead and set   the velocity of our rectangle right here equal to  zero and that's going to prevent it from falling   down past our canvas so with that in mind over  in our code we have the bottom of our rectangle   we also want to add on this dot velocity on the y  we want to say if this is greater than or equal to   the bottom of our canvas which we can get with  canvas dot height because on canvas y coordinates   at the top start at zero and the further we go  down the greater they get so down here will be   576 pixels which is equal to our canvas height  then what do we want to do well we want to go   ahead and select this.velocity.y and set that  equal to zero we want to stop our player from   moving downwards all together so we go ahead and  save this and refresh and that falls down and then   it stops right before it hits the bottom so you'll  see there's a little gap right here we're going   to go ahead and take care of that using gravity so  what is gravity well it's simply just acceleration   onto our y velocity so that just means over  time as long as our object is up in the air   we're going to keep adding a value onto this  velocity until it hits the ground and if we keep   increasing our velocity over time the faster it's  going to get the longer it falls it's just like   real life gravity so to create gravity right above  our class we can create a global const called   gravity and set the sequel to something like  let's just say 0.2 to start that should make   it fall relatively on the slower side so we'll go  ahead and save that and we want to keep our code   right here the same but right before we affect  our position on the y-axis we can go ahead and say   that this dot velocity dot y is going to have some  sort of value added onto it over time and that is   going to be gravity it's going to be a value of  0.2 so now we don't need to say our velocity on   the y-axis is equal to 10 because this is going  to be affected by gravity over time it's going to   add that downwards acceleration to our objects so  we save this and refresh let's watch what happens   we refresh and that gravity is looking pretty darn  good you'll see that it had that acceleration as   it was pulled downwards but we do have an issue  while our player and our enemy are going off the   screen that is not a very good fighting game so  to fix this what we can do is we can grab this   code we just put in and say we don't want to call  this for every frame otherwise we're just going to   keep forcing our player downwards but rather we  want to call this if this is not equal to true   so if we go ahead and add an l statement right  here and paste in this.velocity.y plus equal   gravity for that else statement now we're only  going to be adding gravity onto our y velocity if   our player and the enemy are actually above this  value right here which is our canvas height so   let's go ahead and save that and refresh and  you'll see both of these are pretty much in   the perfect position there's no gap beneath either  of them because gravity took into effect to make   sure that these are pulled to the very bottom of  the screen over time and that they're not pulled   down any further as long as this is equal to true  so with this we are looking to be in great shape   and that leads us back to our to-do list we can  go ahead and check off create a player and an   enemy so now we're going to go ahead and move our  characters both our player and our enemy using   event listeners we're going to go ahead and make  this a two-player game to start because coding ai   is pretty dang complicated so we're going  to go ahead and just focus on the essentials   at least to start maybe in some premium  tutorials later we'll go ahead and add an ai   let's go ahead and get our characters moving both  our player and our enemy using event listeners   so within our code we want to go ahead and add an  event listener this is just a snippet of code that   listens for some sort of specific event so to add  in an event listener we can call our window object   and then on top of this call add event listener  like so so this is going to take one argument   just a simple string which declares what kind  of event do we want to listen for so there are   things like click there are things like touch  we want to go ahead and listen for an event of   key down this is an event that occurs  whenever we press any key on our keyboard   so here we're going to add in an arrow function  as our second argument this is what's going to   be fired for any time we press down on a key and  within this arrow function we can pass through an   event object like so and then console log out  within our arrow function this event object so   we can see what's inside of this so we're going to  save this right click hit inspect element and then   open up our console and then make sure that we  clicked on our canvas and then we press down on a   key i'm going to go ahead and press k you're going  to see that we just logged out that event object   so this is a keyboard event and if i open this  up we have a bunch of different data properties   associated with that event so here you can see  we pressed a key of k here we press the key of k   a lot of the stuff i don't even know why it's here  but the thing we want to focus in on is what key   are we currently pressing so this property right  here of key is what we want to bring into our code   so right here we can reference event dot key save  that go back over to our game refresh click on our   canvas and then start pressing keys you're going  to see i'm logging out each key that i press down   on a keyboard that's exactly what we want because  we want to determine which keys should move our   player in which direction so if i go ahead and  move this off to the right side by clicking these   right here clicking dock to right now we can keep  our console open while seeing both our player and   our enemy as well so back within our code within  this keydown event listener i want to go ahead   and add in a switch case statement within this  switch i'll go ahead and reference event dot key   and say for a case of what well a case of d then  i want to go ahead and call the following code   and then call break so what i'm saying right  here is i want to go ahead and grab the key   we're currently pressing with event dot key and  if that key is equal to d on the keyboard then   what do i want to call well i'm going to want to  call some code that moves our player so whenever   i press d i want to select our player and then  i can set our player's velocity on the x-axis   equal to about one this means we're going to be  moving one pixel for every frame we loop over   within our animate loop so if i save this and  refresh and then hit d while we're not actually   moving even though i'm clicking the key because we  need to define how our player should be moving on   the x-axis if we look within our update function  right here we only define how our player is moving   on the y-axis we need to do the same thing for  the x so right above this.position.y i'm going   to reference this dot position dot x and over  time we're going to add on this dot velocity dot   x so with this simple line of code if i save that  and refresh now when i go ahead and hit d on the   keyboard we have our player moving on over to the  right simply because i hit d on the keyboard now   this is just going to keep going because i didn't  declare what should happen when i lift up on a key   so back within our code we're going to want to  add in a new event listener right beneath this one   but to add in that event listener i want to copy  this one we just created so go ahead and copy that   paste it down below and i want to listen for an  event of key up rather than key down so whenever   i key up well i want our player velocity  on the x-axis equal to zero so i save that   refresh and then hold down d you're going to see  that's firing we're moving over to the right but   as soon as i lift up you're going to see we  stop because we set our player's velocity on   the x-axis equal to zero so this is a great way  to get our player and our enemy moving to start   let's go ahead and make our player be able to move  to the left as well so to get our player to move   to the left all we need to do is copy this case  statement paste it down below and then say when   should our player move to the left well when we  have a case of a we know when we press down the   a key our player should be moving leftwards  but in order to move our player leftwards   we need to make sure that our player velocity  on the x-axis is a negative value rather than a   positive one so we're going to set our player  velocity on the x-axis equal to negative one   and then when we key up we're going to set that  back equal to zero no matter which key we press   but we need to make sure that we add in that  additional case for when we lift up on the a key   so we go ahead and lift up on the a  key as well our player velocity on   the x-axis is going to be equal to zero so  i save that go back over here and refresh   now when i hold down d we start moving to the  right i let go we stop and then when i start   holding down a we go to the left when i lift up we  stop so that's cool and you might think we're done   but there's something i want to show you if i go  ahead and hold down d well everything looks great   right but now if i keep holding d down and i press  a to go to the left looking great but i have a   lift up on d i'm still holding down a but we're  not moving to the left that is because within   our code even if we're holding one of these down  we're saying whenever we lift up on either d or a   we're setting our player velocity x equal to zero  this occurs after one of these occur so therefore   we're stopping our player from moving just by  lifting up on any key as a result we don't want   to set our velocity within our key down or key up  function we want to go ahead and set it within our   animate loop instead to make sure we have the  most accurate movement possible within our game   so i already have a pretty good method for doing  this this is by creating a const and i'm going   to do this right above function animate a const  called keys this is going to be equal to an object   that declares all the keys we want to use  to control our game so the first key i want   to use is going to be a i'm going to create a  new object assigned to that and then i want to   go ahead and create a pressed property and set it  equal to false to start so this is what our first   property is going to look like and now i also  know i want a d property to move our character to   the right so i'm going to monitor for a d key by  copying this property right here adding in a comma   and then pasting in that second object say  instead of a i want to reference d by default this   is going to have pressed equal to false and now  within animate i can say if keys dot a dot pressed   is equal to true well i want to go ahead and set  her player dot velocity on the x-axis equal to one   and then i can write an else if in here  that says if keys dot d is equal to pressed   what do i want to do well i want to go  ahead and call player dot velocity dot x   is equal to one here actually so if we go and  look at a well a means we should go to the left   this should actually be set equal to negative one  instead of one but let's go ahead and save that   nothing's going to happen on refresh because we  need to set a dot pressed or d dot pressed equal   to true when we actually press down on one of  these keys so to set a dot pressed equal to true   we're going to do that within our q down event  listener and right here when we press down a we're   no longer going to set our player's x velocity  rather we're going to grab keys dot a dot pressed   and we're going to set this equal to true because  we know we just pressed down on our a key but   whenever we lift up on our a key down here we want  to select the same thing so keys dot a dot pressed   but here we're going to set it equal to false  let's go ahead and do the same thing for our d   key i'm just going to copy this line  of code right here within our case of d   i'm going to get rid of player.velocity.x  equal to 1 paste in keys.a.pressed equal to   true but instead of referencing a this should  be our d key which we assigned right about here   and then when we're listening for key up we  want to go ahead and select keys.d.pressed   and instead of setting our  player velocity x equals zero   we're going to set keys.d.press equal to false  whenever we key up on our d key so now for each   loop of our animation we're going to be listening  for whether or not one of our keys is pressed down   and it doesn't matter if we key up now we're  still going to be moving either left or right   because our key up event listener is not  responsible for our player's actual velocity   on the x-axis let's go ahead and save this  and refresh and see what that looks like   so now if i go ahead and hold down d we're moving  to the right but watch what happens if i lift up   we're still moving to the right that's okay but if  i go ahead and press down a now we're going to the   left but we keep on going even though both hands  up i'm not actually pressing down on any of the   keys so right before we actually set our player  velocity equal to either negative one or one   we need to make sure that before this we set  player.velocity.x equal to zero so the default   value for our player's x velocity is going to be  equal to zero but if one of these is equal to true   then we're going to set it equal to one and  move our player in that direction it's going   to make sure that we stop whenever we lift up  on one of our keys save and refresh now if i go   ahead and hold down d we move to the right but  if i lift up both hands up we stop moving great   if i go ahead and hold down a we move to the  left now watch what happens when i hold down d   and then i press a while i'm holding down d  we start moving to the left but if i lift up d   we keep on moving so we fix that issue in which  our player stopped if we lift it up on one of   the keys now you might think we're good to go but  there is one more improvement we want to make here   to give us the most accurate movement possible so  i go ahead and move our player over to the right   and i stop and i hold down a and then i hold down  d well they're both pressed down but we're moving   to the left even though i just pressed down d  why is that happening well if we look within   our code specifically this portion right here  let's analyze this while if a is pressed we're   moving to the left but if a is not pressed then  we're going to go ahead and move to the right   if d is pressed only if d is pressed the  thing is if i go ahead and press down a   first we're going to be calling this code right  here and then when i press down d yes we do want   to call this code but only this first if statement  is going to be called because this value right   here is still pressed down to fix this we want to  go ahead and add in some sort of let some sort of   variable that tracks the last key that we press  down to make sure that we get the most accurate   movement possible and that when we go ahead and  press down on our d key while a is also pressed   the d key overwrites that and we make sure that  our player moves to the right because that was   the last key we pressed down so to do this right  beneath our keys const i can go ahead and create a   lut and this is going to be called last key i'm  not going to assign anything to this to start   but whenever we key down and have a case of d i  want to select our last key and set that equal to   d just a simple d string and then right here for  our case of a i'll go ahead and select our last   key and say the last key we pressed down was a so  now keys dot d dot pressed and keys a dot pressed   those can be equal to true at the same time but  last key is only ever going to be equal to one   value and that is going to be the last key that  was pressed down we don't need to do anything   with in key up we just want to know what was the  last key we pressed down so nothing within key up   now that we are monitoring which key we press  last we can use this within our if and else   if statement so if keys.a.pressed is equal to  true and our last key is equal to a then we're   going to go ahead and move our player to the left  else if keys dot d dot press is equal to true and   our last key is equal to d then we're going  to go ahead and move our player to the right   so that should fix our issue with overriding which  direction our player should be moving so i save   that i go back to our game i refresh and i begin  holding down d looking great i hold down a we're   now moving to left lift up on d and then i start  holding down d that overwrites a even though i'm   still holding down a at the moment so that's how  we're going to add pretty much perfect movement to   our game using event listeners and our animation  loop at the same time now let's also add a jump   effect to our player to add a jump effect while  we want to listen for on key down another case   this is going to be a case of not a but rather  w this is going to be our player on the left   hand side screen whenever we press the w key we're  going to jump upwards so we want to go ahead and   select our keys object specifically a w property  which we haven't created yet but we will and then   our last key is going to be equal to w that's the  last key we press down when we key down on w then   within key up we know we need another case to  listen for whether or not this key is currently   pressed when we have a case of w we know keys.w  dot pressed is equal to false so we just need to   go ahead and create this property right here and  we can do so within our keys object by setting w   equal to an object with pressed equal to false so  to create a jump effect the first thing we want to   do is add in a new case whenever we key down what  case do we want to listen for well simply a case   of not a but w we're actually going to do this a  little differently from moving our player to the   left and to the right we don't have to monitor for  whether or not this key is pressed and we don't   have to use a last key what we want to do is just  go ahead and select our player velocity on the   y-axis and set this equal to something ridiculous  so let's just say something like negative 10.   we're going to set this equal to negative 10  whenever we press down on w we go back to our   game refresh let our player fall and then we go  ahead and hit w on the keyboard you're going to   see that our player just moves upwards and falls  down perfectly because we added gravity into our   sprite class right on up here right here we know  we're always adding on gravity to our y velocity   if the bottom of our player is above the bottom of  our canvas so as long as our player is above this   we're going to keep on pulling our player down by  altering our player's y velocity and since our y   velocity is always being added onto our player's  y position over time when we set our velocity.y   equal to 10 we're just shooting it upwards we're  basically just saying move upwards as quickly   as possible using a velocity of 10. and then over  time we're pulling that back down because we know   we're calling else and when we call else we're  adding gravity back on to our velocity until it   hits a velocity of zero which is going to keep our  player on the ground so that's how that works down   here is we're setting our player velocity y equal  to negative 10. when we press w on the keyboard we   move up and then gravity pulls us back down that's  all we have to do to create that jump effect   so now let's go ahead and move our enemy over  here using our arrow keys so to monitor for our   arrow keys we want to listen for a case but we  might not know what case an actual arrow key is   so if we want to go ahead and monitor that case we  can go ahead and console.log out our event object   specifically the key property if we're going to  save this go back to our browser and refresh and   then we only press down on some of our arrow  keys so i'm going to press the right arrow key   you're going to see that gives us a value of  arrow right i know i also want to press down   on our left arrow key it's going to give us arrow  left and if i press up that'll give us arrow up   so these are the values that we want to listen  for within our case statement so i'm just going   to go ahead and duplicate these three and  then we're going to go ahead and paste in   three new case values so d should actually be  arrow right with the exact same casing that we saw   over here in the browser which that is correct and  whenever we press down on arrow right while keys   dot arrow right dot pressed should be equal to  true now for last key well we don't want set last   key equal to arrow right because this is going to  be our second player essentially we don't want to   overwrite our first player's movement by setting  last key equal to something like arrow right   as a result it makes sense to add in a last key  property onto our sprite class because we know   this property is going to be independent for  both our player and our player 2 enemy objects   so instead of referencing last key like this i'm  actually going to go into our classes sprite and   say that this dot the last key is going to be  a property within our sprite class but it's not   going to be equal to anything by default but  now that i have that declared i can say within   arrowright i want to go ahead and select our  enemy specifically the enemy's last key property   and set that equal to a string of arrow right  and now i can delete this last key right here   so now i just need to make sure i do the same  thing for arrow left so i'll get rid of a   and say whenever we press down arrow left keys  dot arrow left dot press should be equal to true   and not our last key but our enemy last key should  also be equal to arrow left and then finally we   need to say what happens when we press on the up  arrow key so when we have a case of arrow up we   want to go ahead and select our enemy dot velocity  dot y and set that equal to negative 10 instead so   that takes care of our key down event listeners  for our enemy and we need to make sure that we   add in our key up event listeners as well so we'll  go ahead and duplicate the switch case statement   right here for key up for our player we can go  ahead and comment this out to say this is our   enemy keys right here we're going to paste in a  duplicate of that and say whenever a case of error   write is keyed up on then we want to go ahead and  declare keys.arrowright.press is equal to false   whenever a case of arrow left is lifted up  on then we want to go ahead and say keys dot   arrow left dot pressed is equal to false  as well so that'll take care of key up   now we need to go ahead and add this into our  animation loop so this statement is going to   be player movement we can go ahead and duplicate  all this code right here paste it below and say   that this is going to be our enemy movement so to  move our enemy if keys not a is pressed but rather   arrow left is pressed and our enemy last key is  equal to arrow left then we want to go ahead and   select our enemy's velocity on the x-axis and  push it over to the left then within this else   if we want to select our keys dot arrow right if  that is pressed and our enemy last key is equal to   arrow right then we're going to set  our enemy velocity.x equal to 1.   so what do we need to do now well within our keys  up here we need to make sure that we're adding in   arrow right that's going to be equal to an  object with a press property equal to false   we also need to add in arrow left that'll also  be equal to an object with a pressed property   equal to false and we should be good to go with  that so let's go ahead and save refresh over here   and then we're going to test out our arrow keys so  if i go ahead and hold down on the left arrow key   you'll see our enemy over here is moving to the  left i hold down on right well now we're moving   over to the right and you're going to have to  excuse some of this movement right now because i   have this console open just kind of messing things  up a bit when i press down on those but we do have   the same issue in which our enemy continues moving  even though both hands up i'm not pressing down on   any of the keys so back within our game right here  we're setting our player velocity x equal to zero   we also want to make sure we're setting our enemy  velocity x equal to zero as well to make sure that   we stop for every frame we're not holding down  on a key i save that i go back hold down on the   right arrow key lift up we stop hold down the left  arrow key lift up we stop but if i go ahead and   hold down d for our player that moves as well and  now watch what happens when i press on the right   arrow key we can move both of these at the same  time independent from one another it's a pretty   classic game style where you used to have to sit  next to your friend and use different keys on the   keyboard to actually get things moving around so  to finish up this movement with event listeners   i just want to make sure that our enemy and our  player move a bit quicker throughout our scene   and i also just want to go ahead and refactor some  of our player code real quick let's go ahead and   do that first let's refactor that player code what  code do i want to refactor well it's going to be   within our event listener right here we don't  want to listen for last key anymore because we   don't need that independent variable we created  a property for our sprites so instead we can   reference our player last key set that equal to  d right here and any place where last key is by   itself we're going to make sure that we prefix  that with player so these two locations right   here are going to be player dot last key and then  we would listen for last key within our animation   loop we're going to say and player last key for a  and player last key for d and then finally we can   get rid of this line right here because we know  we created that property within our sprite class   so we save that refresh hit down d we move  to the right lift up good to go hold down a   lift up good to go so just a small refactor to get  rid of that lut that we no longer needed now let's   get everything moving around a bit quicker we want  everything to move around quicker we just need to   increase these values right here so i think a good  speed for a fighting game instead of ones is going   to be five this just means we move at five pixels  per frame instead of just one so each location and   which one is currently at within our animation  loop i'm going to change that equal to five   save and refresh over in our browser now if i hit  down d we move a lot quicker for both our enemy   and our player if i jump well that's pretty slow  still to make sure that our enemy and our player   fall down quicker we just need to change the  value of gravity so up above when gravity is   equal to 0.2 we fall down pretty slow but  if we increase this to something like 0.7   save and refresh and then start jumping  you're going to see we fall down pretty quick   although we don't jump as high so how do we go  ahead and fall down at this rate but jump higher   well we do want to go ahead and increase gravity  we'll keep it at 0.7 for now but within our event   listener specifically when we key down on either  w or arrow up we just want to set this equal to a   higher value so i'll go ahead and set it equal  to 30 for both w and arrow up save and refresh   and now when i go ahead and press w you're  going to see well maybe a little too high   right there we're going into outer space it's  going to decrease it to something like 20.   just say that both of these should be equal to  20 save and refresh and then jump i think that's   pretty good for the jump in our game so now we  have some really responsive movement between our   player and our enemy and using a good method to  make sure that our keys over right which one is   supposed to control the direction in which our  character or enemy is moving so with that we are   going to be able to check off move characters with  event listeners so now we're going to go ahead and   create attacks for both our player and our enemy  how's this going to work well over here when we   go ahead and move closer to our enemy on the right  hand side eventually we're going to go ahead and   press something like spacebar what this is going  to do is it's going to activate a rectangle that's   drawn on top of our player this rectangle is going  to represent our attack whether it be a sword   swing or a punch it's going to represent either  one of those so what we want to do is monitor for   collision between this rectangle and our enemy  is this rectangle currently touching our enemy   no it's not so we're going to say the  attack missed we're not going to do anything   but if we go ahead and move our player a little  closer now our rectangle when we go ahead and   press spacebar should indeed be touching our enemy  therefore our enemy has been hit we're going to   go ahead and subtract health from our enemies  health bar so to get this effect we need to go   ahead and create this rectangle on top of both our  player and our enemy for when our enemy wants to   use an attack so to create that rectangle we're  going to go back to our code over here and we're   going to focus in on our class of sprite so that  rectangle i'm going to add it in as a property of   this dot attack box like so now what is an  attack box well it's going to be eagle 2   and object it's basically just a rectangle so  what properties does a rectangle have well they're   going to have a position property and they're also  going to have a width and a height so we'll add in   properties for width height and position right  here now what should position be equal to well i   want our attack boxes position to always follow  our player around therefore i'm going to make   it based on the position of our actual player  it's going to be starting at the top left hand   corner right here to make sure that i always  follows our player around well we can assign   position right here equal to this dot position  by default whenever position changes right here   our tag box position is also going to change as  well that's perfect that's exactly what we want   now for our width i'm just going to go ahead and  give this a value of 100 to start and for height   i'm going to make sure that height is equal to 50.  so now if we want our attack box drawn out we're   going to have to go inside of our draw function  right beneath this code right here i'm going to   create a comment that says this is where attack  box is drawn and i can go ahead and draw this with   c dot fill rect so the first argument is going  to be the position of the attack box so this   dot attack box dot position dot x the second  argument is going to be this dot attack box dot   position dot y so the y position of our attack box  and then we need the attack boxes width and height   which we can get with this dot attack box dot  width and then our fourth argument is going to be   the height of our attack box and we can get that  with this attack box dot height so if we save this   and then refresh our game over here you're going  to see now our attack box is drawn on top of our   player and our enemy so it's kind of hard to  tell right now what is our player what is our   attack box so right before we're drawing out the  c dot fill rect we can add in c dot fill style   set that eagle to a different color such as green  save that refresh now we know what our attack box   is and what our player is so now we need to detect  for a collision between this attack box right here   and our enemy is this attack box touching our  enemy well now it is we need to detect for that   and tell our game what should happen as a result  now to detect for a collision it's going to be a   little hard to tell what is our player and what  is our enemy as we go about doing this so i want   to make sure that our enemy is a different color  from our player just so we can see where things   are relative to each other as we go about coding  this so we want to change the color of just our   enemy what we can do is we can set this fill style  right here equal to an argument we passed through   our constructor so instead of referencing red i  want to go ahead and say that this is going to   be equal to this dot color which means we need to  create a property for this dot color right up here   within our constructor so this dot color is going  to be equal to color which now we're going to pass   through as an argument right here so we're going  to pass through that argument of color by default   i'm going to set this equal to red so we save  that and refresh still going to function exactly   the same but now that we have this as an argument  what we can do is down below where we're actually   creating our player and our enemy when we go ahead  and create an enemy we can say that we want the   enemy color to be equal to a string of blue if  we save this go back over here now we can easily   differentiate between our player and our enemy  because our player is red our enemy is blue this   is going to be really good for when we go ahead  and detect for collision let's go ahead and do   that now to detect for a collision we need to go  inside of our animation loop right beneath where   we're sending our player and our enemy movement  we're going to go ahead and detect our collision   right here so detect for collision we need to  go ahead and write an if statement and what does   this if statement say well we need to go ahead and  say is the right side of our attack box right here   greater than or equal to the left side of our  enemy if this is past this point right here   we know the two are colliding in that case we're  going to start off with that so how do we get the   right side of our tack box we're going to go  ahead and get that with our player attack box   dot position dot x that's actually going to give  us the left side of our attack box so this right   here we need the right side and to get that we  can get it with player dot attack box dot width   that is going to give us the right hand side of  our player's attack box perfect but now we need to   say is this greater than or equal to the left side  of our enemy so we can do that with greater than   or equal to plus side over enemy which we'll get  with enemy dot position dot x now if this is true   we can go ahead and cause log out any text such as  just go it doesn't really matter what we put here   but if we save this go back to our game right  click hit inspect go to console now we're not   actually console logging out to go until the right  side of our attack box is greater than or equal to   the left side of our enemy right here as soon as  i go off of that you'll see that stops logging out   that is perfect that's why we want  to begin detecting for collision   but now watch what happens if our attack box goes  off of our enemy but keep moving even though our   attack box is not touching the enemy while we're  still constantly out go so now we need to add in   an additional conditional what is that conditional  going to be well we need to detect for whether or   not the left side of our attack box right here is  less than or equal to the right side of our enemy   we're basically just going to do the  conditional in reverse that we just wrote   so to get the left side of our attack box we want  to go ahead and add in an and statement that says   is our player dot attack box dot position dot x  that is the left side of the attack box is this   less than or equal to what while the right side of  our enemy we can get the right side of our enemy   with enemy dot position dot x that'll actually  give us the left side but to get the right side   we add on the enemy's width and that's going  to make sure we get the right side of the enemy   but if we're referencing a property of width on  the enemy and we look within our class up above   right up here you'll notice we never actually  assign a with property to our sprite class   we need to make sure we do that in order for  this collision detection to work properly   so right above height i'm going to add in a  property called this dot width and i'm going   to assign that to the 50 we're currently using to  draw out our player so width is going to be equal   to 50 here we can replace 50 with this dot width  and if we save that go back to our game now our   collision detection should work as expected on  the x-axis so we're no longer consolidating out   go which is great now when our attack box touches  our enemy we're logging that out but if i go past   our enemy over here we're no longer logging  out to go until the left side of our attack box   is past the right side of our enemy so eventually  we go to that point now we are touching we know   that our enemy should be hit in this case now  we're also going to want to account for the y-axis   you'll see if i begin jumping and i move into  our enemies area we're still logging out go even   though our attack box isn't necessarily touching  the enemy so we need to make sure that we monitor   for collision on the y-axis we want to say is the  bottom of our attack box right here greater than   or equal to the top of our player in this case  it definitely is so we want to say that these two   are colliding but as soon as we jump up that's  not the case we want to set that equal to false   so let's go ahead and write this conditional we  want to get the bottom side of our player let's   go back to our animation loop this is where we're  detecting for collision we want to add in an and   statement that says get our player dot attack  box dot position dot y we want the bottom of our   attack box though this right here is currently  the top of it to get the bottom we'll add on   our player dot attack box dot height we want to  say if this is greater than or equal to the top   side of our enemy which we can get with enemy dot  position dot y then we know the two are colliding   but we do need to add in one more conditional to  make sure that this is as accurate as possible   we want to get the top side of our player's  attack box which we can get with player   dot attack box dot position dot y if this is less  than or equal to the bottom side of our enemy   which we can get with enemy the position dot  y plus enemy dot height then we know the two   are indeed colliding on the y-axis for sure so  let's go ahead and save this refresh over here   and now when we go ahead and jump up and down when  we're overlapping our enemy with our attack box   that's going to go away that's exactly what we  want we know our collision detection is correct   for when our attack box is overlapping on top of  our enemy so right now we're basically walking   around with our sword out at all times that's not  really a fun fighting game we can't just walk into   an enemy and say hey you got hit we need something  that actually activates our sword to say that this   is the exact moment in which our enemy can be  hit so within this conditional we're actually   going to add in one more and statement that says  if our attack box is colliding with our enemy and   our player is attacking then we know our enemy  did indeed get hit so basically we need to add a   property onto our player that says whether or not  they are currently attacking let's go ahead and   add that property on we'll go on up to our sprite  class and then here we'll add in a property called   this dot is attacking we're not going to assign it  to anything by default it's going to be equal to   false but in order to activate this to true right  beneath update we can add in an attack method   and whenever we call attack on one of these  objects we're going to go ahead and set   this dot is attacking equal to true now we should  only be attacking for a certain period of time   we're going to set this equal to true without  setting it back equal to false well it's going   to say we're always attacking at all times  we only want to activate this for a certain   period of time so we're going to call a function  called set time out it's going to take an arrow   function as the first argument and a time as the  second argument for the time we're going to put in   100 which should be equal to around 100  milliseconds i do believe that is but   basically within the set timeout arrow function  we can set this stun is attacking equal to false   so when we call attack this dot is attacking  is going to be equal to true then after 100   milliseconds this that is attacking is going to  be equal to false so just make sure that we set   this back equal to its original value at some  point in time but we do need a way to activate   this attack method we're actually going to do  that within our event listener down below where   we're listening for key down so if our event key  for our player which are these cases right here   has a case of space we're just going to include an  empty space right here for a case which just means   we press down on the space bar what do we want  to do when we go ahead and press down on space   well we want to go ahead and say that our player  is going to attack whenever we press down on the   space bar so if i go ahead and save this and  go back to our game and i walk into our enemy   you're going to see that we're no longer  console.logging out to go but as soon as i press   space it's going to set is attacking equal to true  which means we're going to activate our collision   detection code which should console.log out go  so let's go ahead and press space and you'll see   for that brief period of time that conditional was  true our attack box was overlapping with the enemy   so we constant logged out go for that period if i  go ahead and move off our enemy and i press space   we're not logging out because our attack box is  not touching the enemy if i go back over here   press space we're logging it out once more because  we know we're currently attacking at that point   in time so you'll see goes being logged out a  couple of times that means our enemy has been hit   but we know our enemy didn't get hit four  or two times in a row they only got hit once   so whenever we go ahead and detect for collision  and we call it log out to go we immediately want   to set player that is attacking back equal to  false and just with this if we go back over   here and refresh and move inside of our enemy and  then hit space you're going to see that now we're   only logging out go once that's exactly what we  want to subtract the accurate amount of health   from our enemy when we hit them now it doesn't  really make sense to show our attack box at all   times it's kind of confusing actually so back up  in our sprite class we can make sure that we're   only showing it when we're actually attacking so  where we're actually drawing out our attack box   we can write above it if this dot is attacking if  this is equal to true then we want to go ahead and   call the draw code inside of it otherwise  we're never going to draw it so if i save   and refresh and hit space you're going to see that  our attack box only shows for that brief period of   time and we're only going to log out that this got  attacked if we're currently overlapping with our   enemy so that is exactly what we want to begin  creating attacks within our game so that's how   we're going to add attacks for our player let's go  ahead and add attacks for player 2 or our enemy as   we've been calling it to make sure that this blue  guy over here can fight back towards the red one   so to get our enemies attack box position in the  correct spot i'm actually going to comment out   this statement we just wrote just so we can see  the attack box at all times so you can refresh   and that's looking good but we do want this attack  facing towards the left so we need to move this   attack box over some to change the position we  need to make sure that our attack boxes position   is not completely dependent on the position of  our actual player or enemy entity so to do this   we're going to go ahead and change position  right here equal to an object with an x   and a y property and then x by default is going  to be equal to fighter's position which we can get   with this.position.x and this stop position dot y  now when i save this and i refresh you're going to   notice that our attack boxes are staying up in  the sky that is because with this change we no   longer have a shallow copy of our parent position  when we don't have a shallow copy what that means   is position.x is no longer going to be directly  linked to this stop position we need to go ahead   and make sure that our attack boxes position  updates manually based off position of the   parent so to do this we just need to  head inside of update and right beneath   this dot draw we'll say this dot attack box dot  position on the x axis is going to be equal to   this dot position dot x and then we'll do the  same thing for attack box position on the y-axis   it's going to be equal to this.position.y so i  save that and refresh now those follow accordingly   which is great but we do need to offset our  enemies attack box so to add in that offset   we're going to want to focus in on where we're  setting our attack boxes position on the x-axis   so we're setting it equal to our current parent  position but we also want to subtract from it some   sort of assay if we go ahead and subtract 50 from  here save and refresh you'll see that moved over   a little bit for our enemies attack box but it  also moved over our player's attack box as well we   don't want that we want this value right here to  be dynamic based on what we're passing through our   constructor so instead we're going to go ahead and  subtract from this this dot attack box dot offset   dot x so we need to create this offset property  and we're going to create it within our attack box   right here so we'll add an offset and this offset  is going to have an x and then also a y what is   x going to be equal to well whatever offset we  pass through within our constructor it's going   to pass through just one offset object we'll add  it within our constructor and offset property   and then we can go ahead and just set offset  equal to that property we're passing through   so offset is going to be equal to the offset we're  currently passing through and if we want to use   shorthand syntax we can actually get rid of this  colon and offset because since these two have the   exact same name we can simply get rid of the colon  offset this right here is the exact same thing   as this right here it's just shorthand syntax to  make our code a little cleaner but now that we're   passing through an offset argument we need to make  sure we're doing that whenever we're creating a   sprite so right here we're going to add in an  offset argument we're just going to have an x   and also a y our x for our player isn't going to  be anything it's going to be zero and same thing   for our y we're just going to keep it where it  is at the moment but if we want to pass through   an offset argument for our enemy right here we  can say that our offset for our attack box on   the x-axis is going to be negative 50. so we  save that now this negative 50 should take effect   by being set to offset right here which means  when we go inside of update we're going to call   attackbox.offset on the x-axis this right here is  going to be equal to negative 50. so we don't want   to subtract the negative 50 but rather add it on  that's going to give us the correct effect that   we want and if we save that and refresh now our  attack box for our player is in the correct spot   and our attack box for enemies in the correct spot  as well just need a little bit of refactoring and   where this rectangle is drawn so now we want to  monitor for a collision between our enemies attack   box and our actual player over here so to do this  we're going to focus in on where we're currently   detecting for a collision between our player's  attack box and our enemy we simply just want to   go ahead and duplicate this code but refactor it  for our enemies attack box and our actual player   but this code is kind of hard to read because  we have so many and statements inside of here   it would make a lot more sense to refactor this  into its own function that detects for collision   as a result i'm going to go ahead and copy  these first four conditionals which are actually   detecting for that collision and right above  animate i'm going to create a new function called   rectangular collision this is going to  detect for a collision between two rectangles   and inside of here i'm going to return some  parentheses and paste in those four conditions   i just copied so now if these four conditions are  true we're going to return true if they're false   we're going to return false but in order for  this to work we need to make sure that we have   a player.attack box to reference and that we have  an enemy.positioner reference as well so whenever   we call rectangular collision we also want to  pass through an argument it's just going to   be a singular object which takes a rectangle one  property and then a rectangle to property as well   so what is the first rectangle we want to detect  for collision with it's going to be our player   rectangle so everywhere we have player i'm going  to go ahead and replace player with rectangle 1   and then every place we have enemy it's going to  be in these couple of locations right here i'm   going to replace that with rectangle 2. so now we  have a reusable rectangular collision function in   which we can use to detect for a collision between  our attack boxes and our fighters but it's also   going to be usable for when we want to use it with  our enemy so down below when we're detecting for a   collision we can get rid of these first four  conditions and then we can call rectangular   collision what does this take it takes one  argument which is going to be an object and inside   of this we have two properties it's going to be  rectangle one what is the first rectangle equal   to what's going to be eagle 2 or player and the  second rectangle is going to be equal to our enemy   so if our player's attack box and our enemy are  colliding and our player is attacking we should   cause log out go let's save this and refresh to  make sure this is working have our console open   move closer and then i hit space that indeed is  still working but we want to make sure that we get   this going for our enemy as well so what we can  do is we can copy this if statement paste it below   and now our rectangle 1 is going to be our enemy  we want to text for our enemies attack box and   what will our actual player this is the case and  our enemy is attacking then we know enemy dot is   attacking is equal to false eventually because  we know we hit them but we should cause lock out   enemy attack successful so the last thing we need  to do is determine what button we want to press   down in order to set enemy dot is attacking equal  to true we're going to do that within our key down   event listener and say we're going to add in a new  case let's just go ahead and say our down arrow is   when our enemy attacks so for arrow down i want to  go ahead and select our enemy and say is attacking   is equal to true so now whenever we press down  on the down arrow key our enemy is going to be   attacking so i save that and then i refresh moves  off the side just a little bit and i move closer   towards our player as long as our attack box  right here for our enemy is inside of our player   and i hit down you're going to see our enemy  attack was indeed successful we're just getting   a bunch of console logs over here at the moment  because we're constantly hanging out our event   keys we no longer need these console logs let's  just go ahead and get rid of them in both key down   and also key up and refresh and do that  one more time move over towards our player   hit down to attack enemy attack was successful  and now since our player is also overlapping   their attack box on our enemy if i hit space we're  consolidating that out as well we know that these   two methods are now working for attack so to  finish this off we can go back up to our class   and we can uncomment this code where we actually  draw out the rectangle for when we're attacking   save that and refresh now when i go closer towards  our player you can see that our enemy attack box   is showing enemy attack was successful when i hit  space for our player now we're consoling out to go   that means our player attack was successful so  with that we can go ahead and check off attacks   next we're going to add in a health bar interface  so what we're going to do is we're going to create   some html elements that look like this essentially  this bar on the left is going to indicate our   player's health and this bar on the right is  going to indicate our enemy's health we're   going to have a timer in the middle but it's most  important that we just lay this out correctly so   that when we start hitting something like our  enemy while their health decreases over time   so how would we recreate this effect that we  have going on at the top here well to create   that interface we're actually going to want to  head inside of index.html and we're going to start   laying this out like a real html document so i'm  going to wrap our canvas tag and also our script   tag inside of a body tag so we know that these  are our body elements and basically what we want   to do is we want to wrap our canvas tag in one  large div this is going to be our container div   so this div that we just created is going to  represent the full width and height of our canvas   all the way from up here to down here and we want  to go ahead and place all of our elements inside   of this one large div because all these elements  need to be relative to the div we just created   we don't want our elements relative to something  like our browser window otherwise they might be   placed somewhere like down here outside of our  canvas we want to make sure they're always placed   within our canvas width and height which is why  we're wrapping everything in that one div now   within this div we also want to place one more div  inside of it and this is going to take up the full   width of the parent div but it's also going to be  the location in which we want to put our health   bar and the timer right here so we're going to add  one more div inside of that div we just created   and this div right here is equivalent to this  red rectangle that sends a full width that we   just created so what's within this one smaller red  rectangle while we have one rectangle here we have   one rectangle here and we have one rectangle here  so essentially we're going to be creating three   more rectangles inside of that div we just created  so over here inside of this div we'll add three   more one two three this first one is going to be  player health last one is going to be enemy health   and the third one is going to be the timer so to  start styling these divs let's go ahead and add   a style attribute onto these and here we're just  going to write inline styles to do this because   it is the easiest method so our styler right here  is going to be equal to background dash color this   changes the background color of whatever div we're  currently on we're going to assign this to yellow   to make sure that we get this yellowish color  for the background this is what we're creating   by the way there's just this one rectangle  right here with the red inside of it with our   background color equal to yellow we can go ahead  and give this a height of something like 30 pixels   and if we give this a width of something like 100  pixels let's go ahead and see what this looks like   let's save go back over here and refresh you're  going to see we just created the beginning of   our health bar perfect we're going to notice  that the health bar right here is pushing our   canvas down but we don't want that we want that  overlaid on top of our canvas what this means is   we need to select the main container div right  here that's going to be the largest red rectangle   and we need to add a position of relative on top  of that that's going to be the first requirement   you're going to see why i'm doing this soon enough  so this is going to be the red container dip we   can even comment this out red container div to  help us out in our code a little bit and within   this div we're going to add a style attribute  and here we can go ahead and add a position   of relative onto that so if we were to save and  refresh nothing's going to change by default but   we do need this in place to get the effect we're  going for so now we're going to be able to get   this yellow health bar on top of our canvas how  are we going to do that well what we can do is we   can select this child div inside of it this is the  smaller red container div we want to go ahead and   select this add a style attribute on top of it and  give this a position of absolute so if i save that   and refresh now by default this is on top of our  canvas so whenever a child element like this has a   position absolute basically what that means is we  want to take it out of the document flow when it's   taken out of document flow other elements such  as our canvas element right here aren't going to   be affected by the width or height of that one  individual element so we give it a position of   absolute and since it's container div the large  red rectangle that's containing the whole canvas   has a position of relative basically what we're  saying is this element with a position of absolute   should be relative to that main container div  with the position of relative which it is now   because that container contains our entire canvas  it's drawn in the top left-hand corner of where   that container div begins so perfect now before  we make this the correct width let's go ahead   and draw our timer box in there it's going to be  focusing in on this div right here right below   timer we're going to add in a style give this  a background color let's just save red to start   we're going to give it a width of 100 pixels  and then a height of 100 pixels as well   so we save that and refresh this is going  to be the container div for our timer so   obviously this is placed beneath our health  bar right here when it should be next to it   so how do we move these two discs next to each  other rather than placing them on top of each   other well by default if we go ahead and look at  these two elements right here within our inspector   we see we have our health bar div and we have  our timer div if we look down below by default   divs have a display of block what does the display  block mean well it means the elements are laid on   top of each other like blocks they're stacked on  top of each other so by default the div is always   going to be stacked on top of another div but the  thing is if we go ahead and add a display of flex   to the parent div then these disks are going to be  placed next to each other by default rather than   stocked on top of each other a parent div with a  display of flex affects all elements within that   parent div so we're going to go ahead and find  our parent div for these two elements right here   that parent div is going to be this one with  a position of absolute we're going to add a   semicolon to the end of the style and then add  into this display style equal to flex so now that   this parent has a display of flex it's saying  take all the children elements and place them   next to each other by default even if they have a  display of block so we save that refresh over here   you'll see now these elements are next to each  other perfect we're getting closer and closer   finally let's go ahead and add in our enemy health  to do this i'm simply going to copy this div   and paste it right beneath enemy health saving  refresh and we're getting closer and closer to   the style we're going for to match up with what  we should have right here now this display flex   that we just added is pretty magical because there  are a bunch of subclasses that work in tandem with   display flex so by hovering over this div you'll  see that it doesn't take up the full width of our   canvas we definitely want to make sure that  it takes up the full width simply because we   want our health bars to expand so we can see  the exact amount of health either our player   or enemy has left so by selecting this element  within our browser right here we can test this   out temporarily to see what this would look like  with a width of 100 percent so as soon as i give   this a width of 100 we don't see any changes but  if we hover over this you'll see now the div is   taking up the full width of the canvas that is  perfect that is what we want to start because   if the parent has a width of 100 it's going to  allow our children elements to grow based on our   needs so adding a width of 100 right here in the  browser is just temporary if i'm going to refresh   you're going to see that width disappears so  we do want that width on that element that we   just placed it on which is going to be the  one with position absolute and display flex   we want the width of this to be 100 so we'll add  that in right there save and refresh you'll see   that takes effect permanently and now we can begin  affecting the actual widths of our health bars   so we don't want a static width of 100 for our  health bars right now they're equal to 100 pixels   we just want to make sure that they take up the  full remaining space of our actual canvas so right   here where we're using width of 100 pixels we're  no longer going to define this as 100 pixels but   rather 100 percent we save that we refresh and now  you'll see right here this player health is taking   up 100 percent of the remaining space the thing  is we can eagle this out with our enemy health   by changing our width right here of 100 pixels  to 100 as well save and refresh that and now   you'll see these are taking up an equal amount  of space because both of them have a width of 100   and they're also inside of a div that has a  display of flex now by adding that width of   100 you'll see that our timer div right here even  though it has a width and a height of 100 pixels   well now it looks to be at 47 pixels wide rather  than 100 so by default flex elements will shrink   based on their neighboring elements since their  neighboring elements have a width of 100 and this   one has a static width this one element is trying  to shrink to accommodate for all that other space   that is being taken up if you don't want a child  element within a parent that has a display of flex   to shrink here's what you need to do you need  to select the element you don't want to shrink   and then add in a style called flex shrink and  you're going to set this equal to zero so if   you set this equal to zero zero basically means  false it says do not shrink this and save that   and refresh you'll see now that it's correct size  it's no longer shrinking simply because we set   flux shrink equal to zero so now let's go  ahead and get our health bars in the middle   of our timer to represent more of what we have  over here within our initial design so to get   those centered we're also going to be adding on  an additional flex property this one is going   to go right next to display flex on the parent  so the style is going to be called align dash   items so this style right here only works if the  element has a display of flex if we were to get   rid of display flex right here align items would  not work at all you need to make sure that it has   a neighboring display flex in order for this to  work what is something that we could set align   items to well center basically what this says  is we want to take all the items within this div   going to be these three divs right here and  we want to align them vertically in the center   of this parent div right here so by adding  a line item center we're going to center   all the children vertically let's go ahead  and save that and refresh and you'll see   those children elements are centered vertically  we're starting to look even closer to our design   over here so now it's important that we see what  this looks like without the inspector open so   we're going to go ahead and hit the x right here  you're going to see well that definitely looks   wrong so let's go ahead and fix this i'm going to  go back to inspect element but i'm going to move   our inspector to the bottom now i can see exactly  what this looks like and can figure out what is   going wrong so if i hover over this div right here  you'll see it's taking up the full width of our   browser window if i go up one higher this is also  taking up the full width of the browser window   we only want this taking up the full width of  our canvas and the reason this is taking up the   full width of our browser window rather than the  canvas inside of it is because a div by default   has a display of block a display block element  takes up 100 of the parent div which in this   case is going to be body which is also the full  width of our screen right now so we don't want   a display blocked to this div what we want to  use instead is going to be display is equal to   inline block an inline block means that the  element can still stack on top of other elements   but it's only going to take up the full  width of whatever children are inside of it   so this child right here this div that contains  our health bar has a position absolute it doesn't   actually affect the width or height of this  parent div right here but this canvas element   has a display of block so it does affect the width  and height of the parent element as a result when   we put a display of inline block on this parent  element it's saying that it should only be the   full width and height of the canvas that's  inside of it so that's all we have to do with   our code is find our parent div which is going  to be right up here and then add in a display   of inline dash block so if i save that and  refresh now you'll see this is within our   canvas even when i exit out of our inspector it's  in the correct spot it's starting to represent   our health bar even more accurately now before we  start subtracting from our health bars i think it   makes sense to add some padding around this just  to give it a little bit of breathing room from   the edges of our game so we want to go ahead and  add padding into our health bar while we'll grab   our small red container div and here we can add  in a property of padding and here we're going to   set this equal to something like 20 pixels we set  this equal to 20 pixels we're putting 20 pixels of   padding on every side of this one container so  we want to go ahead and make sure we save that   go back over here and refresh now you'll see we  have padding all around this but you'll notice   that adding the padding here is pushing our  box outside of our canvas we just added around   40 pixels of padding onto the overall width  of the container which means it's being pushed   out well something that we need to do in order to  fix this is we need to add in a custom style that   says we don't want our overall width affected by  our padding so to do this we're going to create a   head tag above our body tag and this is where all  your site's metadata typically goes but inside of   here we're going to add in some style tags and  now we can go ahead and begin writing some more   traditional css the css we want to write is going  to start with an asterisk and then an opening and   closing curly bracket this asterisk means we  want to go ahead and apply the following style   to every single element within our web page  what style do we want to apply to everything   well it's going to be box dash sizing and we're  going to set this equal to border dash box so   if i save this and refresh over here now you're  going to see that this is aligned correctly why   well by adding that border box property padding  is no longer going to be taken into effect   when calculating the width of elements you should  pretty much always have this on every site you   create i don't know why it's not on browsers  by default but you pretty much always want   that there to make sure that your padding isn't  messing up the overall width of your elements   so that's all we have to do to make sure that we  have padding in place to give our interface some   breathing room so we can begin subtracting health  from both our player and our enemy so now whenever   our player hits our enemy let's go ahead and start  subtracting from our enemies health bar up above   to start subtracting from this health bar we're  going to want to go ahead and add an id onto it   so right here this is our enemy health we can add  an id onto this div by declaring our id should   be equal to some sort of string what is a good  identifier for our enemy health well other than   enemy health like so this is how we're  going to reference it within our javascript   so now we can head over to index.js and start  on scrolling down to where our enemy gets   hit so this right here is where our player is  attacking this means our enemy is getting hit   instead of cause logging out to go we're going  to go ahead and select our enemy health bar   we can go ahead and grab that health bar with  document dot query selector and then we're going   to select the id we just created it's going to be  indicated by pound sign that's how we select an id   and then the name of the id which is enemy  health and here we want to select the style on   this specifically the width and now when our enemy  gets hit we can set this equal to something like   20 percent and that should shrink the health bar  down from 100 to 20 just to illustrate how this is   working so i save this and refresh move over and  then hit our enemy you're going to see while the   width of this definitely shrunk down to 20 percent  but it kind of just looks like our timer moved   over to the right because of this new change so we  want to take this into account when styling these   health bars right now the positioning of our timer  is dependent on the width of these health bars in   the background let's go ahead and refresh get that  back to its original position what we're going to   need to do is add in a new div that is not part  of this little mini layout we have going on here   this new div is going to have a position  absolute and it's essentially going to cover   the full width and height of one of these health  bars so since this new div is no longer part of   the layout when we change the width of this div  with a position absolute well it's no longer   going to push everything around just this one div  is going to be shrinking as a result so let's go   ahead and add in that position absolute div we're  going to go back on over to index.html and to add   in a position absolute div right beneath enemy  health we'll add in a new div give it a style   of position absolute like so  we'll say the background here   is going to be equal to blue so since we're using  a div with position absolute we want to go ahead   and wrap these two divs right here inside of a  parent div to make sure this position absolute div   can be relative to the parent so for the parent  we're going to add on a style of position relative   and then since this parent div is now going to  be responsible for pushing elements around it's   going to be responsible for our layout we want to  make sure that we declare for the parent div this   is where the width and the height should be 100  so i'm going to copy these two styles right here   well at least cut them out not copy and then i'm  going to paste them in within the parent style tag   so if i save that and refresh we lose our health  bar over here but that's totally okay that's   actually what we want in order to get this working  correctly you'll see if i right click and hit   inspect and hover over that div we just created  this is what it looks like which is perfect it   represents our health bar but if we look inside of  our children elements right here well they don't   take up the full width and height of this parent  div like we want them to so our current enemy   health criteria has a width of 442 that's great  but it doesn't have any height associated with it   so if we want to go ahead and make sure this has a  height associated with it we can just make it the   same height as the parent by adding in height 30  pixels and that should show this div again we save   that and refresh and indeed it is back but now  when we select our enemy health down here that   has a background color of yellow this div right  here if we begin affecting this width instead   set it to something equal to like 90 you're going  to see that decreases over time so let's go ahead   and refresh our game and then we're going to  attack our enemy we hit space you're going to   see that shrinks down to 20 immediately that is  great but one thing is we don't know the full   extent of our health bar because we don't have any  background dave right here saying well how much   health was there to begin with you'll see this a  lot in traditional fighting games there should be   some sort of background div right here indicating  how much health was there originally we actually   set this up by adding in the second div right here  with position absolute and a background of blue   so we want to make sure that this div right here  takes up the full width and height of this parent   div with a position of relative and to do this we  can go ahead and say that the top style is equal   to zero that the right style is equal to zero that  the bottom style is equal to zero and then finally   that the left style is also equal to zero so i  save that and refresh well now we see our blue   element is overlaid on top of our yellow basically  what top right bottom and left indicate are   how far from the parent div should this rectangle  be placed so we're saying that the top of this   rectangle we're creating should be placed zero  pixels from the top of the parent div zero pixels   from the right of the parent div zero pixels from  the bottom of the parent div and zero pixels from   the left at the parent div and by doing that we're  basically just saying for this position absolute   element take out the full width and height of the  parent so if this element is going to be on top   this is actually what we want to subtract to show  our player's health decreasing so what we're going   to do is we're going to move this id right here  from this first div onto the second div which has   a background of blue we're going to paste that on  in save and refresh and then when we hit our enemy   you're going to see the blue div decreases but  the yellow stays in the background yellow is just   going to be the full indicator of how much health  was there while the blue is going to be well how   much health do we have currently that's exactly  what we want but we don't want to be decreasing   this so that this goes directly down to 20 percent  we want to make sure that this decreases over time   based on how many times we hit our enemy so back  within index.js we don't want to go down by 20   but rather by the enemy dot health so we're going  to use a property called health we need to make   sure that we're adding that on to our sprite  class up above so go ahead and say that this   dot health is going to be equal to 100 to start  so our enemy and our player are going to have   100 hit points to start and then back down here  whenever we hit our enemy we need to make sure   that we select our enemy.health and we subtract  from it a value of something like let's just   say 20. so for each time we hit our enemy we're  going to subtract 20 hit points from enemy.health   and we're going to set our health bar equal to  that new percentage but if we want to set this   equal to percentage we need to make sure that we  add on a string of percent and now when we save   and refresh that if we begin hitting our enemy  you're going to see that decreases incrementally   over time so now let's go ahead and do the same  thing so that when our enemy hits our player   the player health bar decreases as well we're  going to go ahead and use the same methodology   that we used before for our enemy all we need  to do here is simply copy our enemy health divs   all the way down here and we're going to  go ahead and replace our player health   with those divs the only thing we really need  to change is the id we're going to change this   to player health but this is going to set us  up for success to use the same technique that   we just had prior so now that we have an id of  player health right here we can go into index.js   and now we want to detect for collision when our  enemy is attacking is going to be right here we   can simply copy this line of code and then paste  it into when our enemy is attacking and say we   want to select not our enemy health but our player  health instead and then set the width equal to not   the enemy health but our player health as they get  hit so we do need to subtract our player health   each time our player gets hit so to do this we  can copy this line right here paste it down below   and then say that each time our player gets hit  we want to subtract our player health by 20.   and with just this let's go ahead  and see what happens let's refresh   and we're going to take our enemy and hit our  player you're going to see that decreases over   time though it is in the wrong direction we want  to make sure that this decreases from the left to   the right rather than from the right to the left  like we did for our enemy so to get this moving   towards the right instead of towards the left  we're going to select the parent div right here   and set its display equal to flex once we do  that we can say for all the children elements   we want them aligned to the right so that's  what we're going to do to get this effect   is we're going to select that parent div over in  index.html that's going to be this div right here   we're going to add in a style of display flex so i  add that in save and refresh still looks the same   and if i go ahead and attack our player still the  same functionality although our yellow health bar   is gone that's totally okay for now we just want  to make sure that this is going in the correct   direction so we want to align this to the right  over here since we have a display of flex on this   parent div we can add on a subflex property called  justify dash content this only works if you have   an element with a display of flex so now we have  this we can say that we want all children elements   to go to the very end of this container by adding  in a property of flex dash end so once we say we   want all of our children elements aligned to the  right all we need to do now is get rid of left   equal to zero because we don't want the left hand  side of this div always touching the left hand   side of the parent div we want this to decrease  over time so we're going to go ahead and get rid   of left and we want to set our width right here  equal to 100 percent by default so if i save this   and refresh over here everything still looks  the same but as soon as i hit our player we're   going to see that starts decreasing in the correct  direction because the parent div has a display of   flex and its justify content is set to flex end  but we are missing that background element now   all we should have to do here is add in a width  100 to the stiff with a background color of yellow   can save that and then hit our player a few more  times you're going to see that stays in place that   looks great for our player when our player fights  back that looks great for enemy so with that we're   going to be able to check off our health bar  interface so let's take care of game timers and   game over functionality so basically in our game  over here we're going to put a timer right in the   middle of this red box it's going to decrease  over time and then eventually when it hits zero   depending on who has the lower amount of health  we're going to go ahead and determine who won   and then display some text in the middle right  here that says either player one or player two   one so to add that functionality the first thing  we need to do is head inside of index.html and we   need to find where our timer is it's going to be  right here as indicated by this timer comment and   inside of this div we can go ahead and insert a  time so we're going to say our game is going to be   10 seconds long to start simply because we want to  go ahead and test this pretty quickly relatively   quickly at least so with 10 seconds inside of here  we'll save we'll go back to our game refresh there   is our timer let's go ahead and make sure that  this is centered right in the middle of this red   square to center this we're going to go ahead  and add a display of flex onto this div right   here and then we want to go ahead and use some of  those properties we were using earlier including   align dash items this is going to be equal  to center that means we're going to center   the text inside of this vertically we can save  this and then refresh to see how that looks and   that is indeed centered vertically now we just  need to center this horizontally so to center   this horizontally in the exact same location all  we need to do is add a justify content style and   we're going to go ahead and say that we want  to justify our content in the center this means   we're going to align our content in the center of  our container on the x-axis so we can save that   go back to our game and now that is in the correct  position so perfect so let's start getting this   timer counting down towards zero to do this we  want to make sure that we can select this div   within javascript and to do that it makes sense to  add an id onto this div this is going to be called   timer simple enough and now that we have an  id on this we can head on over to index.js   we're going to create a function right above  animate that is responsible for decreasing   this timer as time continues so this function  is going to be called decrease timer whenever   we call this function we want to go ahead and  decrease this number by one so to do this we need   to start with a variable we're going to create a  let called timer let's set this equal to 10 that   is the time we currently have over here so now  that we have timer equal to 10 each time we call   decreased timer timer is going to subtract one  from itself but we should only be subtracting one   from itself as long as timer is greater than zero  because we don't want to get into negative values   so right now what we're saying is if timer is  greater than zero we're going to subtract one from   it but we want to make sure that this is occurring  over and over again and to get this call multiple   times we can go ahead and call set timeout inside  of this make sure you have a capital t for the   second t right here and then what function do we  want to call we're going to call the same function   that's right here it's called decrease timer  so basically we're creating an infinite loop   it's basically the same thing as we have down here  within our animate loop with our quest animation   frame we're just living through this set timeout  is going to be the same thing but we can go ahead   and determine what interval do we want set timeout  to be called as the second argument so the second   argument right here is going to be in milliseconds  so this basically just creates a loop right here   for our function and we can go ahead and test this  out simply by calling decrease timer right beneath   it so we call this out save and then refresh  we're not going to see anything actually because   right now this is only programmatic our timer is  decreasing but we can't see it unless we can't log   it out we need to associate this with the label we  actually have inside of our red square right here   so to get that association we'll also say if  timer is greater than zero we're going to add some   brackets right here so we can write multiple lines  of code we're going to subtract one from timer   and then we're going to go ahead and  select our document get our query selector   and then what do we want to select  well let's look within index.html   we just created an id of timer so let's go ahead  and grab that with a pound sign and then we'll   select timer and we could say the enter html  for this element so whatever is inside this   element right now is just a text 10 we want  to go ahead and set this inner html equal to   the timer that we're currently subtracting  so as long as we have this code right here   we save it and then refresh we're going to see  that this decreases over time for every second   until we get down to zero and once we get down  to zero we should see this stop and we should   not proceed into negative values which indeed we  stop at zero we are good to go so looking back at   our code it really only makes sense to continue  calling set timeout if timer is greater than zero   otherwise there's really no point so also i'm  going to go ahead and add this inside of here   and then right beneath this if statement is  where we're going to determine who won is it   going to be player 1 or player 2 that actually  won the game it's going to be dependent on who   has the most amount of health so right beneath  this if statement we can write an additional one   that says if our player health is equal to our  enemy health then what happens while we know   we want to go ahead and say that there is a tie if  they have the same amount of health when the game   ends based on the timer we're going to have a tied  game but it doesn't really make sense to cons log   this out because someone playing our game is not  going to have their developer tools open at least   they probably won't so we need to create some sort  of label that we can change and display onto our   game so within index.html we need to find a good  location to put some sort of display label and i   think a good place to put it is right above our  canvas because i don't want this associated with   our health bar user interface i actually want this  right here in its own separate container so i'm   going to create a div right above canvas and then  inside of this i'm going to go ahead and write out   tie i just want to go ahead and see where that is  so i save that and i refresh and it's going to be   placed up here by default but we can get this on  top of our canvas by making this have a position   of absolute so let's go ahead and do that next all  this div we're going to add on a style tag and say   the position here should be absolute and if we  go ahead and make this absolute if we look at   this text it's currently black and our background  is black for our canvas we need to make sure that   we have some contrast here by changing our text  color equal to white so right after a position   i'm going to add in color and set this equal  to white so i want to go ahead and save that   refresh over here and now tie is overlaid on top  for canvas but we might want it centered directly   in the middle so we need to write a little bit  extra code right here to do this what we're going   to do is we're going to add a display of flex on  this element and can you tell me what comes next   well we want to use aligned items center to get  this centered vertically and then justify content   center to get to centered horizontally so you  might think if i save this and refresh it's going   to be run in center but unfortunately it is not  let's go ahead and inspect this i'm going to go   ahead and right click hit inspect element and  then i want to inspect our tie tag right here   so i look at this this div with a position  absolute is not taking out the full width or   height of the canvas right now it's only taking  up the amount of space of the text inside of it   which is just tie but our canvas is full width  and height right here so we need to make sure   that this div takes out the full width and height  of the canvas as well and in order to do that   since we have a position of absolute we can go  ahead and add on the top right bottom and left   properties to say that we want the top left bottom  and right of this one div to expand the full width   and height of the parent container so to do that  we're going to say top is equal to zero right   is equal to zero bottom is equal to zero and then  finally left is going to be equal to zero as well   so let's save that and refresh over here and now  we're going to see that tie is directly in the   center because now our div starts from zero from  the top zero from the right zero from the bottom   and zero from the left of our actual canvas  this is looking to be in a great spot right now   so we don't want this showed by default you'll  see right here when i'm refreshing we see the text   tie let's go ahead and hide this i'm going to  give this a display of none and if we give this   a display of none we need to make sure that we  delete display flex right here because we don't   want to show this at all right now we'll keep  everything else but as long as this has a display   of none we're going to see that's hidden and that  doesn't get in the way of anything so the next   thing we want to do is head over to index.js and  when our playerhealth is equal to our enemyhealth   when our timer runs out then we want to go ahead  and select that text to select that text we're   going to use document.queryselector and then  we need some sort of id to select that one div   so within index.html we need to add an id right  here we can go ahead and call this id display   text this is what we want to go  ahead and change back within index.js   so we can select this width a pound sign get  display text and we want to change the inner html   equal to tie not only do we want to set this equal  to tie but we also want to select it again so i'll   go ahead and copy this line right here and set its  style specifically its display property back equal   to flex so we're no longer hiding it when this is  true we're going to set it equal to flex it should   indeed display when the time runs out so to make  this a bit quicker let's go ahead and decrease our   timer to five save our code and then refresh over  here we're decreasing downwards and it looks like   we're already showing tie right here that's not  exactly what we want we need to make sure this   if statement only fires if timer is less than zero  so technically what we need to do we need to make   sure that this text right here only shows if timer  is actually equal to zero not for each iteration   of decreased timer so we can go ahead and wrap  all this in an if statement that says if timer   is actually equal to zero then we want to call the  following code so we save that and let's go ahead   and test this i'm actually going to go ahead and  hit the enemy right here you'll see that decreases   and now we're no longer showing that text  because the health bars are no longer equal   this conditional right here is just not true so  we're not going to fire these two lines of code so   now we need to take into account what happens if a  player's health is greater than the enemy's health   we can write an else if right after this that says  if our player health is greater than our enemy dot   health well we want to show some different text  we're going to select these two lines right here   and paste them in below and instead of saying  that our inner html should be equal to tie we're   going to say player one wins now this code right  here is duplicative of the code above when we're   setting style display equal to flex if we see  some duplicate code like this what we can do is we   can simply take it out of the location where it's  being used i'm going to cut it out right here and   paste it in a location where it's only going to be  called once so when timer is equal to zero i know   i want to show our display text but then based on  whether our player health is equal to enemy health   or greater or less than that is when we're going  to change what text is actually inside of this div   so we can also delete that other query selector  with style display equal flex right here and now   we saved ourselves two lines of code made it equal  to one instead so let's test out what happens when   player 1 wins we'll save this refresh and now we  need to hit our enemy and enemies health decreases   and now we're displaying the text player 1  wins simply because player 1 has more health   than our enemy now we want to do the same thing  for when our enemy wins so we'll simply add in   another elsa statement right here and say when  our enemy help is greater than our player health   right here and that is when player 2 wins instead  so save and refresh and then i'll hit our player   with our enemy now our enemy is going to win now  player 2 wins so great that is perfect so we're   looking to be in good shape with the timer  but what happens if our enemy or our player   decreases one of the others health down to  zero before the timer runs out we need to   write some code for that to tell what happens so  we're going to go ahead and increase our timer   to something more standard like 60 seconds that  way this doesn't actually call before we're ready   so we refresh with that and you'll see this starts  decreasing and now we have 60 seconds in order   to end our game based on health rather than time  running out so when we go ahead and get our enemy   down to zero then we want to go ahead and display  that same text that we were showing earlier for   when our timer ran out so to monitor for that  we're going to go inside of our animation loop and   this is going to go beneath where we're detecting  for a collision for both our player and our enemy   because we know these are two places in which we  are decreasing our enemy and our players health   so beneath this second if statement we're going to  go ahead and end the game based on health and we   want to say if our enemy dot health is less than  or equal to zero or our player dot held is less   than or equal to zero then we know our game should  be over and we should show some certain display   text right here so to determine what text we  should display basically what we can do is we can   go ahead and change this conditional into its own  function and then call that function down below   so let's go ahead and refactor this a little bit  we're going to add a new function above decrease   timer that says determine winner this is going to  take well one argument it's going to be an object   with two properties inside of it what are the  two properties well it's going to be your player   and also our enemy and now that we have these two  in place we can go ahead and call this code right   here so i'm going to cut it out of this location  simply paste it in determine winner and now we can   go ahead and use determine winner in that exact  location where we just cut that code out so right   here we're going to call determine winner we know  this takes one argument it's going to be an object   with a player and an enemy property so i'm going  to add player right here an enemy right here and   now based on whether or not our player health is  equal to our enemy health we're going to show tie   or player 1 or player 2 wins it's just a nice  little abstraction to make our life a little   easier when we want to do the exact same thing  down below within our animation loop so if enemy   health is less than zero or player health is less  than zero then we know that we should be calling   determine winner right here this also takes an  argument it's going to be an object with a player   and an enemy and based on all this we're going  to go ahead and display that text that we were   showing prior with our timer now before we  actually go ahead and save and refresh let's   go back up to determine winner and we just want  to make sure that we also put this code inside   of it right here that sets our style display  equal to flex otherwise it's not going to show   so within determine winner we're going to go  ahead paste that in and now when we save and   refresh over here and we'd be up on player two  eventually when we get them down to zero you're   going to see now player one wins we display the  correct text so same deal let's go ahead and beat   up player one now get them down to zero now we  know player two wins before the timer runs out   we still have our timer functionality in place  although i suppose when either player one or   player two wins we need to make sure that we stop  this timer all together so let's do that next   so to stop a timer we need to get the timer id  that's returned from set time out so we're going   to create a lut right beneath timer called timer  id and we don't actually need to assign this to   anything by default but when we're calling set  time out we're going to go ahead and say timer   id is equal to the return value of set timeout  so for each time we call set timeout this is   going to return a number it's going to be either  0 1 2 3. it's just going to keep increasing over   time that's going to be the timer id and since  we associate that with this let of timer id we   can use this to cancel our loop altogether to make  sure that we're no longer calling decreased timer   so within determine winner we're going to add in  an additional argument it's going to be timer id   and then as the very first thing right here we're  going to call a function called cancel time out   and it's going to take that timer id that we  passed through so we just make sure we're passing   this through within determine winner right here  we're going to pass through timer id and that's   going to prevent this from being called when our  timer runs out but we need to do the same thing   down below within our animation loop so when we go  ahead and determine a winner right here we're also   going to pass through the timer id so we'll go  ahead and save and then refresh over here and then   be up on player two get them down to zero and it  doesn't look like it's stopping so let's go ahead   and whenever this happens you always want to go  ahead and right click inspect element and then see   what's happening in the console looks like cancel  timeout is not defined it's a dumb error on my   part let's go ahead and find where we're calling  counts timeout it's going to be within determine   winner it's not actually cancelled timeout i don't  know why this first thing that comes to mind for   me but it's actually going to be clear timeout  instead just a little bit of a syntax difference   so we save that we try again over here get out of  the console and then be up on player two one more   time you're going to see that stops completely  because we called clear timeout correctly we also   show player 1 wins which is great we can test  the exact same thing for player 2 when they win   we're going to see that stops completely  and we're still displaying the correct   text so perfect and i think with that we can go on  over to to do and check off game timers and game   overs we just created the basic functionality  that we needed to get a basic fighting game   set up so now we're going to go ahead and move  on to sprites and animation so we're going to   be inserting images into our screen and also  animations for our characters our background   and a little bit of our ui so we're going to go  ahead and start off with our background sprite   what is a background sprite well it's going to be  simply an image we put in the background like this   although this is not what our game currently looks  like it really looks like this with just a black   background so we want to go ahead and get that  image into our game how would we go about getting   this image in the first place well over on itch.io  this is a website specifically for game assets   and a lot of these assets are free provided to  us by really talented authors such as brew love   right here i went over to itch.io and i went into  the oak woods environment asset pack so this is   completely free to use on personal and commercial  projects if you want to go ahead and download this   yourself you can go ahead and hit download now  and i really recommend leaving a donation for   the author because they definitely put a lot of  effort into creating this artwork but if you just   want to download this for free you can click this  right here it's going to lead you to the downloads   you just click download and it's going to go ahead  and initiate your download so i already downloaded   this and all the assets i want to use in our  game actually moved into a folder within finder   it's going to be called fighting game assets so  you see we have a folder for a character named   kenji a folder for a character named samurai mac  and then a background and then a shop so this is   going to be available to you within the google  drive link within the description of the video   but the main thing we want to focus on  right now is going to be background.png   so you'll see i took this image from the asset  pack and i resized it down to 1024x576 so it's   going to go ahead and fit our screen perfectly  it's going to cover up the whole black background   if we want to go ahead and use this in our game  what we're going to do is we're going to simply   select all the assets within this folder i'm  going to select shop hold shift and then i'm   going to click on kenji to make sure that i select  everything and then i'm going to hit command c to   copy these it's going to be ctrl c if you're  a windows user but once you have these copied   you can head back to your web directory  or wherever you store this project   i'm going to go inside of fighting game and then  inside of here i'm going to create a new folder   called img for images and then i'm going to paste  that in by hitting command v control v if you're   a windows user so that's going to go ahead and  paste these within our project and then if we look   at sublime text you're going to see that we have  an image folder with all those images available   to us that we can now use within our code so we  want to go ahead and make use of background.png   right here how would we go about inserting that  into our game well i made the sprite class for a   reason i want to use this class not just for our  fighters but also for our background images our   shop image whatever it may be but at the same time  this class currently has a lot of functionality   related to a fighter rather than just rendering  out a simple image onto our canvas as a result   it kind of makes sense to refactor this class into  a separate clause we're going to keep this as is   called sprite but we're also going to create a  class called fighter which is going to resemble   our player and player 2. so what we want to do  here is is basically duplicate our class all the   way down to the very bottom i'm going to copy that  and paste and then i'm going to call this class   fighter so this is actually going to be the  class that we use for player one and player two   but this class up here of just sprite we're  going to go ahead and refactor this so this   is just responsible for rendering out an image so  we go ahead and look at this class of sprite what   do we need and what do we not need well we know  a sprite is not going to have any attack method   associated with it so we can go ahead and delete  that within update well what does a sprite need to   do over time well it's going to need to update its  frames if we want to add in some sort of animation   but a lot of this is related to our player's  attack and gravity we don't want any of that   we just want to go ahead and make sure that we're  drawing this and we're going to be using update a   little later on to update the variables associated  with each of our sprites if we scroll on up we   have draw right here now what does a sprite look  like well they're not going to be rectangles   because we're actually drawing out images onto our  screen we don't need anything related to drawing   out rectangles we're just going to delete  all this we're going to go ahead and edit   this within this individual lesson and then if i  scroll on up what else do we not need for a sprite   we can get rid of health because sprites are not  going to have health that's going to be related   to our fighter his attacking is also related to  fighting we don't need a color because we're going   to be using images we do not need an attack box  we can get rid of that we don't need a last key   but we do need a width and a height associated  with our image at least later on so we're going to   leave this right now and we don't need a velocity  either because these aren't going to be moving   around the screen at least not yet that's mostly  going to be just our fighter down here so with all   this in place what do we need to get rid of within  our constructor argument we get rid of velocity   color and also offset so we just have a very  basic sprite class at the moment so we added   this class in and now we have a class of fighter  and it's kind of muddying up our code a bit within   index.js we have our design in here but we also  have code related to our game implementation   so it kind of makes sense at this point if you're  having trouble finding certain things within your   file to refactor this into a separate file  and that's exactly what we're going to do   for code maintenance purposes so what i want to  do is i want to go ahead and make sure that our   classes are in their own separate class file  in order to do this i'm going to go to file   new file and then i'm just going to  hit command s to immediately save this   and then i want to save this as classes.js  but i'm not going to save this within our root   i'm actually going to go ahead and create a folder  called js all of our new js files are going to go   inside of here so i'm going to save that and now  we have a folder of js with classes.js inside of   it so great now we can go ahead and select our  classes go with class of sprite all the way down   to class fighter i'm going to cut these out with  command x and then over in classes.js i'm going   to paste that in with command v i can hit save  save on index.js as well but this isn't going to   work if we save and refresh everything because we  need to make sure we're pulling in classes.js into   index.html in order for that file to be read so  we want to make sure that we pull this in before   index.js and we want to reference classes.js so  in order to do this we need to go inside over js   folder and then reference classes.js so now our  classes within this file right here are going to   be available to us within index.js so we save this  we want to go back to index.js and here you'll see   that we're currently creating our player and our  enemy from our sprite class we know we created   within classes.js a new fighter class that's  what we want to reference for our player and our   enemies so here we're going to change new sprite  to new fighter for both our player and our enemy   if we save everything index.js index.html and  classes.js accordingly if everything went well and   we refresh over here well we have our player and  our enemy in place and everything still functions   as expected so great so now that this is cleaned  up a bit it definitely makes it a little easier   to focus on what we need to focus on so within  classes.js we want to focus in on this class of   sprite so sprite like i said is just going to  be an image and it can be animated over time   but we're going to do the most basic one which  is just going to be a static image to start   so in order to render an image on the screen  what we're going to do is whenever we create   a new sprite we're going to pass through an image  source so src and we're going to use this image   source to create a new image whenever we create  a new instance of sprite so we're going to create   an image property called this.image and to create  an image within javascript we can use a native api   object called new image so this basically  creates an html image but within a javascript   property such as this dot image and once we  have this available to us well we need to set   this dot image dot source equal to the source  of the image we want to actually show so it's   going to go ahead and store the image within  the property of this dot image but if we want   to go ahead and draw this out we need to use a  canvas function within our draw method right here   so the canvas function we're going to use is  going to be c dot draw image like so so the first   argument here is going to be an html image element  and that's already created for us right up above   with new image stored in this dot image so that's  going to go right here as the first argument   this dot image and then for our second argument  we want to go ahead and add in an x coordinate   thankfully we set this up already when we're  creating our fighter class and duplicating this   so we can get the x coordinate with this dot  position dot x and then we need a y coordinate   which we get with this dot position dot y this  is all we need to do to create an image and draw   out on the screen using canvas so we save that  now within index.js we need to do the actual   implementation for this class so we can either do  this above our players beneath our players doesn't   really matter i'm going to do it above them i'm  going to create a new const called background i'm   going to set the sequel to a new sprite so this is  going to take one argument with a few properties   inside of it what properties does this take well  it's going to take a position so we'll put in   position for a property position is going to be  equal to an object with an x and a y property so   what is the x coordinate of this background well i  want to start at the very top left hand corner of   our screen so that's going to be 0 for x and also  0 for y now what else does a sprite class take   well we can always look within classes.js we see  it takes a position and it takes an image source   so now we just need to add in an image source  attribute and this is just going to reference   the file location in which we want to put on  the screen so it's going to be a string and   from index.js how do we get background.png right  here well we need to go inside of img and this   dot slash right here just means we're starting  within the directory of index.js so we go from   this directory we go inside of image and then we  need to reference background.png so background.png   so we want to make sure we save that and now we  have a background sprite in which we should be   able to render out on the screen with either draw  or update update right now does the same exact   thing as draw but that's okay because we're going  to be using update later on so within index.js we   can scroll down to our animation loop right about  here and we're going to put this as the very first   thing before playerupdate and before enemy update  because we want this drawn in the background   not on top of them we're going to reference  our background and then we're going to call   update on top of it which in return is  going to call draw and the draw image method   so we save that go back over here and refresh  you're going to see now we have a background in   place so great that is how you want to render  out a sprite or at least a static sprite onto   your screen so there's no better time than now to  continue refactoring our code and make it as clean   as possible how would i continue to refactor this  while scrolling down i noticed that there was a   lot of code in between that wasn't really related  to the actual implementation of our game but   more so just making our code cleaner specifically  these functions right here such as decreased timer   determine winner rectangular collision those are  more utility functions rather than stuff that's   actually directly related to our game as a result  i think it makes sense to put these in their own   separate files so i'm going to grab all these  functions and their associated luts and const   and then i'm going to save it i'm going to keep  decreased timer in here because that is part of   implementation it helps make our game actually  function but once i cut those functions out   i want to go ahead and create a new file so i'm  going to go to file new file and i'm going to   paste these on in so once i paste these in i can  hit command s and then i'm going to save these   inside of our js folder and i'm going to call this  utils.js for utilities so i'm going to save that   and once i save this i just need to make sure  that i put it within index.html so that all these   functions that we created are still available  to us and we know that this should come after js   classes.js but before index.js because they're  really only used within index.js in the first   place not so much within classes and i'm actually  going to go ahead and put this before both   of these because even though utils.js only has  functions that is used within index.js right now   maybe we'll use these later on for classes.js  but even though it's not required at the moment   we're kind of just preparing for the future right  here so we just want to make sure that we save all   these files and then refresh everything still  works and functions the same so great but our   code is a lot cleaner within index.js for sure  so we have our background sprite in place but   what else what do we want to do here well it looks  like our background right here has a ground for us   and our player and our enemy are currently at the  bottom of our canvas let's go ahead and make him   stand on this actual ground how would we go ahead  and do that well we're going to go ahead and fake   it essentially we're just going to say that we  want our player and our enemy to fall as long   as they are above 200 pixels from the  bottom of our canvas rather than the   bottom of the canvas directly so we want to go  into classes.js specifically our fighter class   because we know within here within update this  is where our fighters are affected by gravity   we are saying we want our fighters to continue  falling as long as their position plus velocity   are greater than our canvas height right here  so this right here is determining when should   our fighter stop moving when should they hit  the ground it's going to be this value right   here that determines that so we're saying right  now they should hit the ground when they reach a   value of canvas height which is right here at the  very bottom but what if we go ahead and subtract   something like 200 from our canvas height maybe  we can go ahead and get them to stop right about   here so we go ahead and do that from this location  within classes.js we save canvas.height minus 200   and refresh over here you're going to see that  it's 200 pixels from the bottom of our canvas   so obviously that's way too high up let's go  ahead and decrease that do something like 100   we're just going to eye this until we get  this perfect and that is definitely a lot   closer but if you look really closely you can  see there's still a little bit of space right   there so we can go ahead and get rid of that by  subtracting a smaller value like something like 97   we'll save that and refresh and i think that is  directly touching the floor maybe one more pixel   96 and yeah i think that looks pretty good we're  definitely on the ground right there it looks like   we're actually traveling across this background  we created which is really freaking cool in my   opinion so that's going to go ahead and allow us  to check off background sprite now we can go ahead   and do the shop sprite with animation so what  does this mean well if we look within our finder   specifically within our image folder you're going  to see that we have a shop.png and this is what it   looks like if i go ahead and bring this up you're  going to see that it contains multiple instances   of basically the same image the only difference  is going to be if you look at the smoke stacks   you're going to notice that it's different for  each frame that we go through and if we go ahead   and loop through these frames continuously it's  going to give off the effect of animation that's   kind of how video in general works actually  as we just go through a bunch of frames and   as we overlap these frames on top of each  other we create some sort of movement effect   so we're going to use this shop to create an  animation and we're going to place this shop   right here with this empty area i used the  asset pack to create this background and i   left this open space specifically so we could  put the shop right here and create some sort   of cool background animation so the first thing  we're going to want to do is simply place the   shop right here and we're going to show all  frames of the image and then we're going to   go ahead and animate it from there so let's go  ahead and get our shop placed right about here   so to get our shop.png rendered out into our  game we can go inside index.js and we want to   find where we created our background essentially  we're just going to create a new sprite and what   we can do is we can simply copy this constant  background with new sprite paste it down below   say this is going to be our shop sequel to a new  sprite we're going to start it off at a position   of zero zero let's just do that to star to  get it rendered on the screen and then our   image source is going to be image shop.png so now  that we have this created we want to go on down   and where do we want to render this in relation to  everything else well it makes sense to render this   after our background but before our player and our  enemies we're just rendering these out in layers   on top of each other so we're going to reference  shop dot update save that and then we can go back   to our game and refresh you're going to notice  this is where our shop is on screen so now we need   to do two things the shop is pretty small at the  moment so what we want to do is scale it up so it   fits in this large area right here and once it's  scaled up we just want to make sure that we place   it in the exact location so how do we go ahead  and scale this image up well we need to focus on   our sprite class within classes.js so if we go  ahead and add some arguments on a c dot draw image   we're going to add a fourth argument right  here this is going to be the width of the image   so if i go ahead and make this something like 300  i'm going to add in a fifth argument this is going   to be the height of image i'm going to make this  something like let's just say 200. if i'm going   to save this right here and refresh you're going  to notice both our background image and our shop   right here change to that exact dimension so we  don't want to add a static value within our sprite   class because we know our background is not going  to have the same dimensions as our shop we want   to make sure that these right here are determined  by the image we're actually pulling in using image   source and this html image object so to do that  instead of referencing 300 right here we're going   to reference this dot image dot width someone  off right and then for our height we're going   to reference this.image dot height so let's go  ahead and save this and refresh and you'll see   that takes care of things in regards to the width  but now that we have this width and height listed   out right here for c.draw image we can go ahead  and multiply this by some value to scale it up so   within our sprite class we're going to add a new  property called this dot scale and this is going   to vary based on the sprite that we're currently  using so we want to make sure that we're passing   this through as a constructor so within our  constructor arguments i'm going to add in scale   and say by default this should always be equal to  one but we have the chance to change this later   on if we want to so now that we have this that  scale in place we want to go ahead and multiply   this.image.width by this dot scale to scale up an  image same thing with height just multiply it by   that scale so this isn't going to do anything by  default if we refresh everything looks the same   but it gives us the ability to increase  this number right here to something like two   and it's going to increase the sizes of our images  as you can see but we only want to increase the   size of our shop so we want to make sure scale is  always by default one and then within index.js we   can find where we created our shop which is  going to be right here we can say that our   shop is going to have a separate scale from  our background by assigning a scale property   equal to something like 1.5 let's go and see what  that looks like let's save that and refresh it   now you see our shop is a little bigger maybe we  can make this even larger let's go into up to 2   for our shop save that and then refresh and  you'll see that looks pretty good but i think   we can make it even bigger let's go on up to 2.75  save that and refresh so you see this definitely   loses some clarity but i think for our game it's  okay because it definitely has a pixel art style   showing some pixelation is definitely okay at  least in my case so we're going to go ahead and   say this is going to be the size of our shop now  we want to make sure that one frame of the shop   fits right over here so we're going to go back  to our shop or at least where we're creating it   and where do we want to position this well  let's just start guessing we're going to put   in 300 for x save and refresh moving a little  closer maybe we want to double that up to 600   save and refresh that seems to be in a pretty  good spot i'm going to go ahead and keep that   for now let's go ahead and focus on the y-axis  let's put 300 for y so 300 pixels from the top   that seems to be way too much obviously so  we're going to go to 100 getting a little closer   let's go ahead and add 20 to 100 so 120 and now  let's start adding smaller numbers such as five   it looks like we just need like two three more  pixels so i'm going to put 128 right there   and that seems to be in a pretty good spot for  our shop so now that this is relatively within the   right place we want to begin animating this and  animating sprites can be a little tricky at first   but once you get the basic concepts it's going to  be a cinch so basically to get this animated what   we're going to do is we have our whole image  rendered out currently and that's totally okay   we're going to keep this rendered out but we're  going to do is we're going to crop this so that   we only show one frame at a time so when we crop  this we're only showing this first image and then   what we're going to do is over time we're going  to animate this so our crop location starts moving   through these images so we're going to say shift  this over one frame to the right and then render   out this version then eventually we're going to  shift it over to another one and then another one   and then another until we get to the very end  and we're going to shift back to the beginning   and over time as we do this we're going to create  the illusion as if the shop is actually animating   and any other sprites that we might use within  our game but that's basically the gist of it we   want to go ahead and crop this whole image down  to this little square right here and then we're   going to go ahead and push this crop through the  whole thing to create the illusion of animation   so to create this crop we're going to go over  to our sprite class we're going to focus in on   c.draw image so we want to go ahead and crop this  while we need to change up the arguments a little   bit it's a little confusing with canvas  unfortunately but it's nothing we can't   deal with so the crop location is actually  going to be these first four arguments and   these four arguments that are here currently  are going to be pushed down by four arguments   so these still remain the same this is going to  be the x and y position of our image and also the   width and height of the overall image but if we  want to go ahead and crop this we need to add in   four more arguments before these i don't know why  canvas does it this way but it does so the second   argument now is going to be the crop location  so where do we want this crop mark to start   we want it to start at zero zero from our image  because that's going to be right about here and   then we're going to determine its width and height  to only cover just one of these shop images so x   is going to be zero y is going to be zero it's  going to start our crop mark at the top left-hand   corner what is our width going to be well we can  base this off of this.image.width we want to go   ahead and grab this paste it in right here we  know that our crop height should be this image   dot height well make sure we add a comma to  the end of that but this is what our crop code   is going to look like now when we're cropping our  image by its image width and image height the full   width of our image right now is this entire thing  so we don't want to crop it by the entire thing we   only want to crop it by this small section right  here so if we get the entire image width which is   going to be from here to here and we divide it by  the amount of frames within the image so 1 2 3 4   5 6 we're going to get the exact width of just one  of these frames so let's go ahead and do that over   in sublime text we're going to divide our image  width by 6 specifically for our shop save that   and refresh and that's going to initiate the  crop but you'll see everything is just completely   stretched out that is obviously not what we want  why is it being stretched out well if we look   back at our code over here this line right here is  going to determine the actual width of our image   so we're grabbing this by getting this.image.width  we're saying the full width of our image should   still be the size of this even though we just  cropped it down so we want to make sure that   this is also dependent on the amount of frames  within the actual image so i'm going to divide   this by six as well i'm gonna make sure that  we do this first before multiplying it by scale   and if we save that and refresh you're going to  see now our shop looks pretty perfect that is   cropped perfectly so you want to go ahead and crop  an image you need to make sure that you set the   crop location the crop width and the crop height  this is also going to be dependent on the amount   of frames within the actual image and then down  here you want to say well what width and height   should the image actually be well it's going to  be the image width divided by the amount of frames   times the scale so that's how you're going to  do it but you're going to notice that affects   our background image as well now our background  image is 1 6 the size of its full width so if we   want these two to work nicely together what  we need to do is edit this so the six right   here the amount of frames within our image  is variable rather than just always being six   so what i'm going to do is i'm going to create a  new property for our sprites this is going to be   called frames max so what is the max amount of  frames that we have within our image and this   is going to be variable so we want to make sure  that we pass it through as a constructor argument   so right here i'm going to say frames max  can be passed through and by default this   is going to be equal to one which just means  we have one image such as our background image   for this sprite so this stop frame's max is going  to be equal to frames max and now when we go ahead   and divide by six instead we're going to divide  this by this dot frames max in both locations   so we want to go ahead and save that and on  refresh you're going to see our background   image is back to normal but our shop is not  how annoying but this is really easy to fix now   because we set this up correctly now we can pass  through a new frames max specifically for our shop   so over in index.js we want to find our shop we're  going to set the frames max equal to well what are   the max amount of frames within our shop we  said it was six so we save that and refresh   now everything is laid out correctly we're setting  ourselves up for success when we want to go ahead   and animate the shop so if we go ahead and compare  this to our actual spreadsheet within finder   we are currently at this position right here we  took our large image showing the entire thing   and we sized it all the way down to this location  this is the step we're currently at the next step   is going to be actually moving the square through  our entire sprite sheet so to do this we want to   go back to closets.js and basically what we want  to do is we want to move the x-coordinate of our   crop mark so this is our x-coordinate if i were  to go ahead and change this to something like 200   and refresh you're going to see we basically moved  that crop mark over to the right but we want to go   ahead and move this perfectly to give off the  illusion as if the shop is actually animating   rather than just shifting it to side slowly so  how many pixels would we have to move this crop   mark over by in order to get it to exact location  right here we can do a little bit of math within   our code to get this exact result so we're going  to go ahead and get this dot image dot width   and if we divide that by our frames max well we're  going to get the exact amount of width we need   to move over by so we'll divide this by this dot  frames max and if we save this and refresh you're   going to see that our shop looks the same but i  promise you the smoke stack is a little different   we just move the crop over by one frame and  it's in the perfect location to where we're   only showing one part of the image once again our  background image is gone we need to take that into   account based on this new code we added in for  a crop mark so the reason our background isn't   showing right now is because our background image  has a width of 10 24. and if we divide that by one   well that's going to be equal to 10 24. so we're  saying we want to move our whole crop mark for our   background image to the right by 10 24 pixels  obviously there's nothing there for our first   image because well there's only one specific  frame for that background image so all we need   to do here to make sure that this works for  both our background image and our actual shop   is we need to multiply this by a current  frame so i'm going to add in here this   dot frame current and i want to make  sure that these two equations over here   are performed before we go ahead and multiply  that by frame current and then we need to actually   create frame current up above so here i'll say  this that frames current is equal to zero so i   just wanna make sure i actually call this frame  current sorry about that so this is going to be   equal to zero which means now by default we're  multiplying this equation over here by zero so   we're no longer moving that crop mark over for a  background image let's save and refresh background   image is back this is back to its original  location as well but we're still continuing   to set ourselves up for success we're making a  completely reusable sprite class for the future so   now over time if we increase this value right here  from zero to something like one and we use that on   our shop class well we're effectively moving over  our crop mark by one frame if we increase this by   two we're going to be moving it over by two frames  and we can keep going until we hit the frame's max   and that's when we're going to go back to the very  beginning and reshow this animation but if we're   never increasing frames current in the first place  well the image is going to be static which is for   images like our background image so if we go ahead  and focus in on our shop we'll just say by default   each frame is equal to 200 pixels and that is the  result of this right about here that's going to   be equal to 200 but if we multiply that by frames  current and the default is zero we're going to get   zero so there is no crop but if we go  ahead and change the zero right here   to one instead well now we're going to move that  crop location over by 200 so we're just going to   keep moving that until frames dot current is equal  to frame's max which is going to be six or five i   can't remember which but once it hits that we're  going to go back to zero and repeat the process   so that our crop mark moves well back to zero so  to get this effect we wanna make sure that we're   increasing frames current over time which we're  going to do within update so after we call draw   we're going to add onto this dot frames current  one frame but we only want to do this as long as   frames current is less than frames max so here  we'll write if this dot frames current is less   than this dot frames max then we want to go ahead  and call the following but we want to add in an   else statement here that says if this is not true  what do we want to do we want to set this that   frame's current so the current frame back to zero  and that's going to repeat the animation process   so let's kind of save this and then refresh and  you're going to see well we definitely have some   sort of crazy animation going on here so one  issue is is our background is animating for   some reason it seems to be flickering between the  background image in black why is that happening   well frame's current starts at zero so we can  actually render out our background image and   set our crop x position equal to zero but right  now our frame's max for our image is one because   we still want to make sure that we're showing that  background image in the first place so when we go   ahead and run this if statement down here frame's  current is equal to zero and then frames to max is   equal to one therefore this is still true for our  background image which means we're adding one onto   our frame's current therefore we're pushing that  crop mark off of our background image so we're   showing black and then we're going back to the  background image which is creating that flicker   effect so to fix this we just make sure that we're  subtracting one from frames max over here save and   refresh that fixes background image and now we  have our animation in place for the shop although   it is really really fast we want to make sure that  we slow this down to create something that looks   a little more realistic and a little less jank  so how are we going to slow this animation down   well to do this we're going to go ahead and add  in two more properties they're going to be this   dot frames dot elapsed and then this dot frames  hold so this stuff frames the lapse is going to   be how many frames have we currently elapsed over  throughout our whole animation this is just going   to increase over time as our game continues to run  and then our frames hold is for how many frames   should we actually go through before we change  frames current the actual animation so by default   this is equal to 1 with our current animation  because we're just looping through every frame   but if we set this to something like 10 what we're  saying is for every 10th frame we're going to loop   through this animation rather than for every one  frame so how do we go about using this right here   well we know frames elapsed should be increasing  over time so within this dot update we're going   to add in this dot frames elapsed is going to have  one added on to it for every iteration of update   and now that that has a value being added onto it  at all times we'd say if this dot frames elapsed   modulo this dot frames hold is equal to  zero then we want to go ahead and call   the following if statement so what does this mean  right here well basically what this means is take   frames elapsed divide it by frame's hold and if  the remainder is zero then we want to call the   following code that's the difference between the  modulo operator and the division operator like so   but we just want to make sure we get the  remainder so we're going to go ahead and use the   modulo operator so we go ahead and save this and  refresh you're going to see just by adding that   in our animation is way slowed down and this looks  way more realistic in regards to a shop animation   and you can always change the speed of this by  changing your frame's hold value right here the   lower it is the faster it's going to go so if  i change frames hold to five second refresh you   can see that looks even better than before but if  you want to make this super slow you just increase   this number it can be 50. now for every 50th frame  this is gonna go but i think it looked good at   five so i'm going to go ahead and keep it at that  now later on we are going to have different frame   holds for different sprites so we're going  to change this and add it into a constructor   at some point but we don't need it right now so  we'll leave it as is and we'll head back to to do   and we'll check off shop sprite with animation so  now we're going to go ahead and add in a sprite   for our player specifically one named samurai mac  so we're going to start with the idle animation   for this and this just means we're going to be  standing but moving up and down to show that   our character has some movement so where did i  get these sprites well over on itch.io i search   for some fighter sprites and this is what i was  able to find was marshall hero by lewis mello   he supplied this sprite and the other spray i'm  going to use in this tutorial for completely free   but if you want to go ahead and donate to him make  sure you click download now and then send him a   donation so if you want to go ahead and get the  sprites for this you can either download it here   or it's going to be within a google drive link  you'll see that we already pulled that into our   project within the samurai mac folder so we have  a bunch of different sprites associated with   animations related to our player right here we  have attack sprites we have a death sprite a false   sprite an idol sprite jump sprite run sprite take  hit sprite and so forth you kind of get the idea   these are all the animations associated  with the movement of our character   so the one we want to focus on is idle  and if we look really closely right here   you'll see this is what an idle animation  looks like we're kind of just bobbing up   and down it's actually kind of hard to see but  you'll see once we actually get this animating   that our player is going to be bobbing up and  down so let's go ahead and get this into our game   so we know we already pulled samurai mac into our  image folder earlier on and now we have a couple   of animations in which we can use so to begin  using this we want to go ahead and extend our   sprite class because right now our fighter class  does not use any images we need to make sure that   the fighter class is able to use the same code  that we have up above for our sprite but the   fighter class is going to be a little different  which is why we have it in the first place   so we can go ahead and call things like attack and  different update functions so we want to go ahead   and make sure that our fighter clause can use  the draw method associated with our sprite class   we just go ahead and extend the fighter class by  adding extends right here and then declare we are   extending the sprite class so by extending this  we're going to take all the methods within sprite   and put them within our fighter class if they  are not available if they are available within   our fighter class then our methods are going to  overwrite the same ones that are within sprite so   we need to determine what do we want overwritten  and what do we want to keep directly from sprite   well we know our fighters are no longer going to  be rectangles unfortunately so sad as a result   we can go ahead and get rid of this draw method  right here and if we get rid of this within our   fighter class that means since we're extending  sprite we're going to use the draw method up   above instead but in order to use this draw method  directly within our fighter class we need these   different properties available to us we just added  a ton of properties into our sprite class up above   such as scale frames max we need to make sure that  these are available within our fighter class as   well so we're going to go ahead and inherit these  but before we inherit these we need to make sure   that we can pass them through within our fighter  constructor so we're going to take the properties   that are not currently available within fighter  it's going to be image source scale and frames max   we're going to go ahead and copy these we're  going to add them to the end of our constructor   for fighter just paste those on in once you have  those added in we can go ahead and call a function   called super what does super do well it simply  calls the constructor of the parent so since we   know the parent of fighter is sprite we're going  to go ahead and call this constructor right here   which sets some properties for us such as scale  image frames max frames current you get the idea   but we have to declare what properties we want  to set within that parent constructor so we   list them out within super and to call the parent  constructor we know it takes one argument which is   going to be an object and here we're going to list  out the properties that we want set within the   parent so what are the properties we want set well  let's start off with image we want to go ahead and   set that what else do we want set scale frames  max and frames current let's add those in scale   frames max and then frames current and then what  else we also have frames elapsed and frames hold   so we'll add those in two frames elapsed and  then finally frames hold so we know that these   are going to be set with our parent constructor  is there anything else within our properties right   here that can be set by the parent there is one  it's going to be positioned because we know our   parent sprite has a property of position being set  right here so what we can do is we no longer need   this line of code we can simply just put position  within super instead to say we're going to inherit   that property directly from our parent sprite  so we want to go ahead and save that and refresh   over here to see what things look like we're going  refresh looks like our game is just broken this is   a great time to inspect our elements go to console  and see what's going on so right here we just have   the issue of images not defined online 55 within  classes.js so we want to make sure within super   we're not referencing image we're referencing  image source because that is the actual property   we're passing through right here and so we just  want to make sure we set that correctly we save   go back again and we have one more issue it just  says frames current is not defined so if we go   back to our code you're going to see that this is  the issue right here frames current is not defined   because we're trying to pass it through our  parents constructor right here but we don't   actually have anything set to that by default  right now frames current is being set to a   static value and if you want to call super  and make it work well we need to make sure   that zero right here is actually set to 2 frames  current passed through as an argument right here   so we can either change this right here and add  an argument to our parent class i think that's   a little overkill though instead what we can do  is we can just go ahead and copy anywhere where   there's a static value so these three lines right  here we're going to go ahead and copy those and   then we can get rid of these within our super  method so these three right here then we can   paste them on in directly within our fighter class  it's all up to you on how you want to do this it's   more of a preference in my opinion rather than a  strict standard so let's save that and refresh and   things are back to normal we have errors in here  but that is totally okay because we never actually   passed through an image to our fighter objects so  that's going to be the next thing we want to do   so over in index.js we know that we just  refactored our fighters to take an image source   so i'm going to grab our shop image source  and i'm going to put it in where our player   is going to be created now i don't want the image  source for our player to be sharp of course that   wouldn't make sense to have a shop as a fighter so  instead i want to go ahead and reference samurai   mac specifically the idle.png image so to get  that i'm going to go inside of our image folder   i'm going to say i want to go inside of samurai  mac and then i want to go ahead and get idle.png   so if we look at idle.png how many frames is this  image well let's go ahead and count one two three   four five six seven eight so it's going to be an 8  frame image as a result we want to make sure that   we set our frames max equal to 8 for our fighter  a samurai mac so let's go ahead and save that go   back over here and refresh you're going to see  we have a fighter sprite on the screen cropped   almost perfectly because we're not showing the  eight different frames we're only showing one   we just need to go ahead and make him bigger make  him animate and then i'm going to show you how to   crop this perfectly so that he's touching the  ground so to make him bigger that's going to   be quite easy all we have to do is pass through a  scale property let's set sailrite max scale to 2.5   save and refresh that and definitely bigger  but we're still falling down a little bit   and the reason we're falling down is if  we go ahead and look at this actual image   you're going to see that there is a lot of  space around each instance of samurai mac   each frame is image right now is actually about  this large this means we have padding on the top   left bottom and right of our image and we need it  this way because later on when we go into one of   our attack sprites that attack is going to extend  almost the full remaining width of the square   right here so we need this extra space but when  we have all this extra space around our sprite   while the calculations are going to be off when  we're trying to run collision detection between   the bottom of our sprite right here and the  actual ground on our game so what we need to do   is offset our sprite right here so we're  going to move our sprite from this location   to the very top left hand corner of where we're  cropping it and we need to define what is the   width and height of one of these images to get  the correct collision detection so let's start   by translating our actual image towards the top  left hand corner of our crop to do this we're   going to head over to classes.js and this is going  to be actually within our class of sprite we want   to do it here because we might be using this  not just for our fighters but for other sprite   sheets in the future so i want to add in an offset  property and here i'm going to set this dot offset   equal to offset and now that i have this offset in  place i want to go ahead and use this within c dot   draw image so all i'm going to do here is from the  position in which we're actually placing our image   i'm going to subtract from this this dot offset  dot x and i'm going to do the same thing for   this dot offset dot y now right now this the  offset.x and y is equal to undefined because   we never actually passed anything through our  sprite constructor as a result if you want this   equal to a default value and you don't want to  go ahead and subtract something undefined from   something that actually exists we can go ahead  and set the offset equal to an object with an x   a 0 and a y of 0 because by default images  should not be offset by any value and then   finally if we want to use this within our fighter  class we need to go ahead and take this argument   put it within our fighter clause constructor put  it within super to make sure that we set that   property up above and we should be good to go with  just that so now over in index.js we can define   the offset in which we want our player moved so  we can move it to the top left-hand corner of   all that padding so here i'm going to say that our  offset is going to be equal to an object with an x   and also a y what is our x going to be i already  did the calculations on this it's going to be   215 pixels and then y was around 180 we're  going to fine tune this as needed so now we   have offset being passed through if we look within  classes.js it's being passed through right here   going into super being called above and you'll  actually notice offset's being defined twice   right here within our constructor we want to  make sure that is not the case let's get rid   of this first offset make sure that we only have  one that's set to a default right here and then   we're going to save and on refresh you'll see this  is looking a lot better so we essentially got rid   of that padding on the left hand side that's fine  to start let's go ahead and make sure that we get   rid of more padding on the bottom right here so  to get rid of that padding we want to decrease our   offset value right here let's go to 170 that  should reduce us by 10 pixels on the bottom   looks like we're getting a little closer  let's go down to 160 save and then refresh   and then let's subtract about 3 pixels from  that so 1 57 save and refresh that and now   we are touching the floor so perfect now let's go  ahead and get our sprite moving up and down why is   this not moving up and down currently well within  classes.js if we go ahead and look with an update   we don't have any code responsible for moving  frames elapsed or frames current through their   iterations we need to make sure that's happening  in order for our draw method right here to go   through our sprite sheets correctly so how do we  go ahead and add this code up above with an update   into the update function down below well what we  could do is we can simply just copy all this code   right here and then paste it into update like so  save and refresh you're going to see now we have   that perfect animation in place that's totally  fine well the only issue is we repeat our code   if we're trying to follow do not repeat yourself  principles well it makes sense to put this in its   own method rather than just duplicate it in two  places so rather than duplicate it right here   i'm going to delete that and then up above  in sprite i'm going to add in a new method   called animate frames because that is exactly what  this function does if i go ahead and paste this   code in there well now in update i don't even need  to call all this code i can simply call the method   animate frame should actually be animate frames  miss s right there we're going to call anime   frames right here which calls this in return  and now that this is within the parent class of   sprite i can go ahead and use this method within  the child class down here i don't even need to   define it i can just call right within the update  function this dot to animate frames and it should   still work accordingly so let's save that and  refresh and that still works we have clean code   because we're using do not repeat yourself  principles now one issue is well if we try   moving this character with wasd we're not able  to move and if we inspect the element and go   into console while we're getting a bunch of red  errors regarding classes.js and line23 we're not   able to draw some sort of image do you know what  image that is well it's going to be our player   2 over here we never actually set an image for  player 2 and that's ok because we're not ready   to do that but we do want to make sure we're not  getting that error so we can make sure that our   game functions accordingly for what we have right  now so to make sure that our player is not being   rendered out on the screen we're going to go down  to animate and we're simply going to comment out   enemy dot update so we do that save and refresh  and then start moving well now we can move again   and if we right click and inspect element we no  longer get any errors within our console because   we just commented out our enemy and since our  enemy did not have an image source associated with   it it was just trying to error out continuously  so that's going to allow us to check off the idle   animation for our player sprite so next up we're  going to go ahead and implement our run sprite we   want to be able to switch between being idle and  then running back and forth so how do we go about   implementing this sprite right here where we're  going to be using a running animation well we're   going to want to start off in classes.js and we  want to find our fighter class so we're going   to be adding a property within our constructor  right here and this is going to be called sprites   essentially this is going to be an object that  contains all the sprites for our specific fighter   so since we're putting sprites right here now we  can go ahead and use it as a property within the   constructor saying this dot sprites is equal  to the sprites that we actually passed through   so let's go ahead and save this and then go to  index.js so we can actually begin passing these   sprites through into our fighter class so we're  going to focus on passing this through into our   player right beneath offset we'll go ahead and  add a sprites property and this is going to   be equal to an object so what kind of sprites  is our player going to have well right now we   have an idle sprite and we also want to have a run  sprite so we're going to list those out right here   let's start with idle this is going to be eagle 2  an object and it's going to have an image source   and that is going to be equal to the same image  source we used prior so this one right here and   this is also going to have a frames max associated  with it this has 8 frames associated with that   idle.png sprite and then we want to go ahead and  do the same thing not just for idle but for run   as well so i'm going to go ahead and copy that  property paste it below and change idle to run   now what is the image source of run right here  well it's going to be samurai mac and run so   we're going to go ahead and change idle right here  to run to reference the correct image and how many   frames is run png going to be well we can go ahead  and open this and count one two three four five   six 7 8. so lucky for us this is the same amount  of frames as our idle png sprite so we don't   actually have to change anything for frames max  right here so how this is going to work is we're   going to switch between these sprites by setting  this dot image to whatever sprite we want to go to   so where is this.image once within our parent  class up above you'll see we are setting an image   equal to a new image based on the image source in  order to switch between these sprites we need to   make sure that we create a new javascript image  based on those sprites and then switch this that   image to the new image we just created sounds a  little confusing but let's go ahead and do this   within class of fighter so we just passed our  sprites through they're now equal to this dot   sprite well we need to go ahead and create that  javascript object for each object within this main   sprites object so we're going to go ahead and loop  through our sprites object by saying for sprite   in sprites so what is this going to do well if we  look within index.js this is what sprites looks   like and basically we're just going to be looping  through each object within the object of sprites   so first we're going to loop through idle and  then we're going to loop through run that's all   this means within classes.js when we use syntax  like this now our goal here is to essentially   create an image property dynamically that is  going to be equal to a new image object we're   going to go ahead and do that as we loop through  sprites over here within classes.js so to add on   a property to this object we're currently looping  over we can go ahead and select our main sprites   object and then we're going to reference which  object we want to grab with sprite right here   so sprite right here is actually going to be  the object key so when we reference sprite   we're actually referencing either idle or run that  is the key of the object so when we go ahead and   use this syntax right here we're basically saying  this is the object we're currently looping over   and if we want to add a property onto this we can  simply type dot and then say what property do we   want to add well we have to add an image property  and this is going to be equal to a new javascript   image object so now that we have this we want to  go ahead and set the source of this right here so   we're going to paste this below and say that the  source of this image is going to be equal to what   well we can go ahead and grab sprite's bracket  sprite and then say that the source of this should   be image src and make sure that s is capital so  let's go ahead and save this and at the very end   i want to go ahead and copy this dot sprites and  looking at this well let's go ahead and make sure   we're referencing this. sprites right here within  our for loop so we're going to loop through this   dot sprites get the individual sprite and then  set everything we need down here and then finally   we're going to log this out and before we save  and refresh this just make sure that you declare   a sprite right here as a cost because sprite is  never actually going to change you need to make   sure that you declare this as a cost far or left  when you're looking through this for the syntax to   work so we're going to go ahead and save that go  over here and refresh and then open up our console   to see exactly what we're cause logging out so  right now it looks like we're console logging   out to this object we'll open it and now we have  an idle object and a run object you'll see right   now we have an image set to a javascript  image for both idle and run so technically   we should be able to use this and switch back  and forth between these two different actions   within our fighter sprite now let's delete this  console.log and think to ourselves what is going   to determine when we switch between either our  running sprite or our idle sprite well we're going   to determine that within index.js specifically  within our animation loop because we know whenever   we press a or whenever we press d we want to go  ahead and run rather than idle so since we just   set up everything within classes.js whenever we  move to the left what do we want to do well we   can select our player dot image and we're going to  set our player image equal to our player sprites   specifically the sprite of run and we want to go  ahead and grab that exact javascript image so on   top of this we need a reference dot image and with  that when we press a we should switch over to the   running sprite let's save this make sure you have  classes js saved as well refresh and then when we   go ahead and hit a you're going to see now we  have a running sprite and i can go ahead and   move back and forth because we're not switching  back to idle when we let go of it so technically   this works whenever we hold down d or a we can see  this is what the sprite looks like and since this   is eight frames it just works right out of the box  not too much extra we have to do right there but   we do know we want to go back to an idle state  when no keys are being pressed so what we can   do is right above player movement we can grab this  line of code where we're setting our player image   and what we're going to do is say that our  default player image is going to be equal to player.sprites.idle.image instead of run.image  so now if we save and refresh that we're going   to idle and then if i move to the left we'll  go into a running animation as soon as i let   go we're going to go back to idle because we're  setting that for every frame we go into but now   if i hold down left we're only in running if  i come back over here you'll see we go back to   idle so that's how we're going to be switching  back and forth between these to start but we   do want to make sure that we're running to the  right whenever we hold down d as well so let's   go ahead and make sure that we switch our player  image whenever we hold down d2 so i'm going to   go ahead and paste that on in there and we can  save that and refresh and then hold down d and   now we're running to the right whenever we hold  down d running to the left when we hold down a   and then when we stop we're going to go back  to that idle animation so now we can go ahead   and check off run so now we're going to go ahead  and switch to a jump animation how do we go about   doing that well we want to go ahead and within  our player const we want to add in a new sprite   into our sprites object so to do this really  quick i'm going to go ahead and copy run   and then add a comma at the end of run paste  that on in and then i can call this our jump   sprite right here so i just need to make sure i'm  referencing our jump image right there so instead   of run i'll call jump and i need to see how many  frames does this jump image actually consist of   so if i look within jump.png that's actually going  to be two frames it's going to be our first frame   switch within our sprite switching right here  so i'm going to change frames max equal to 2   and now what i need to do is determine where do we  want to switch to a jump animation so i think it   makes sense to switch to jump animation with our  animation loop when our velocity is less than zero   because that means we are currently going upwards  in the air and when we're going upwards in the air   while it makes sense to switch to a jump animation  so where are we going up in the air with our   animation loop but we don't really have anything  directly in our animation loop so we need to make   sure we add that right beneath player movement i'm  going to add an if statement that says for player   dot velocity on the y-axis is less than zero this  means we're currently up in the air so if this is   the case we can go ahead and select our player  image and set this equal to our player sprite   jump image and that's going to go ahead and switch  us on over there but if we save and then refresh   and try jumping you're going to notice well that  looks very weird not very good because whenever   we go ahead and jump we need to make sure that  we're also switching our player dot frames max   equal to our player sprites jump frames max  basically we're just sending this eagle to two   frames because if we try using our sprite sheet  animation logic with a frame rate that is greater   than the actual sprite sheet well it's just not  going to work we're going to get this effect we're   getting over here where we don't actually see  the image in place so we want to make sure that   we switch that on over to 2 but we're not done  just yet you'll notice if i save this refresh   try jumping well we have a jump animation in place  when we go up but then we get some sort of weird   effect where we get a duplicate of our player  and it looks like honestly they are teabagging   the ground not very good for what we are going for  so one of the reasons this is occurring is because   our frame's max right here is now set equal to  two we're trying to set our player image equal   to our idle and a run image when those have eight  frames associated with them but right now we're   saying that our frame's max is equal to two so  we're just running the animation really quickly   and it throws off the whole width calculation that  actually keeps our crop mark in the correct place   so we want to make sure that when we go ahead  and set player image equals something like idle   or run that we also set the frame's max back to  those original values as well we only want to do   it once too because it's kind of inefficient to be  setting this for every frame when we're in the air   when we really only need to set this stuff once  for that action so with all that in mind if we   look at this this code is kind of getting hard  to read and understand just at first glance so   this is a case in which we want to go ahead and  abstract this to abstract this i'm going to go   inside of classes.js and i'm going to add onto our  fighter class what am i going to add i'm going to   add a method called switch sprite this method is  going to be responsible for switching between our   different sprites it's going to take an argument  which sprites do we want to switch to and then   i'm going to add a switch case statement that  switches out to the sprite we're passing through   and then finds a case as something along the  lines of idle and a break statement for that   we're going to add in a case of run break there  and then add in a case of jump as well we want to   break at the end of this too so now when we call  switch sprite we want to do all that setting code   that we currently have within our animation loop  and we're going to detect within here to make sure   that we only do it exactly once for each action  we take so let's start off with our case of idle   within index.js we know we switch over to our  idle state with this line right here where we set   player image equal to dot sprites.idle.image  let's go ahead and cut this out from here and   instead let's go and select player dot switch  sprite what sprite do we want to switch to   well we want to switch to a sprite of idle so now  we're calling this within classes.js essentially   we're going to run whatever code is within this  case statement right here i want to paste in that   line we just cut out and we can't really reference  player because that is an instance of the class   instead we need to make sure we're referencing  this that image and this dot sprites so this   is the exact same thing as we had before except  we're going to call that switch sprite makes a   little more sense it's a little easier to read  but within classes.js what we can do is within   a case of idle we can add an if statement  that says if this dot image is not equal to   this dot sprites dot idle dot image then we want  to switch our image to idle we're only going to do   it once with this if statement as soon as this is  set this will no longer be called but we're still   going to be running a case statement with our  animation loop but we're only switching over to   that sprite sheet just once now so let's go ahead  and refactor run we're going to go into index.js   and where are we setting our player image equal  to our run sprite it's going to be right here   so i'm going to cut this out and then i'm going to  call player dot switch sprite equal to run instead   so let's save that go back to classes.js and then  within our case of run i can write an if statement   that says if this dot image is not equal to this  dot sprites dot run dot image then i want to go   ahead and set this.image equal to our run sprite  so we can save that go back to index.js and then   we want to go ahead and call this right here as  well because this is just basically duplicate code   let's paste that on in there and now finally we  want to do the same thing for when we're jumping   up in the air for our jump sprite we're going to  go ahead and cut these two lines out right here   select our player dot switch sprite method and  then call jump on that so now that we're calling   switch sprite jump in classes.js we're going to  run whatever is within this jump case right here   we're going to paste in that code and say instead  of player for these four instances we're going to   reference this so we're switching our image over  to our jump image and then we're setting our   frames max equals to the jump sprites frames max  which is going to be 2. so we're going to go ahead   and make sure that we're setting this frames max  within each if statement right here for run and   idle so if we're going to use more than one line  within an if statement we need to make sure it has   brackets and then we can go ahead and set this dot  frame's max equal to that sprites action which is   going to be run so we want to switch jump right  here to run frames max property then we're going   to go back to 8. so let's go ahead and do the  same thing for idle we'll go ahead and take this   line of code right here add some curly brackets  into this if statement and then right beneath   where we're setting our image we'll say that our  frame's max is going to be equal to our sprite   of idle dot frames max property now it's important  to note within this jump case we want to make sure   we have this exact conditional within here too so  we'll add if dot this dot image is not equal to   this dot sprites dot dot then we want to go ahead  and call the following code to set our image and   our frames max just once so before we go ahead and  save this and check it out let's go ahead and make   sure that we're setting everything to the correct  action so it looks like right here for idle we   are indeed referencing all idle instances for run  we're referencing run run we want to make sure we   definitely change jump right here to run otherwise  we're going to have the wrong amount of frames   being rendered and then for jump we're referencing  jump we need to change run right here to jump as   well jump and jump with this we should be good  to go so make sure that all those are correct   save that and then save index.js and let's  test it out so on refresh we start moving it   looks like running and idle are good to go so  perfect now if we jump if i hit w we do have a   pretty good jump animation but you might notice  there's a little bit of flashing going on right   there what is that flashing why is it happening  well what's happening here is is during our run   animation we're going to go from one to two then  to two to three then to three to four and we're   going to keep going until we hit eight and then  we're going to go back to the beginning but the   thing is we might leave off on our fourth frame if  we try to immediately switch to the fourth frame   of our jump animation down below while there is no  fourth frame therefore we're going to be rendering   out just a blank space which is what's causing  that flash effect to occur we need to make sure   that whenever we switch between run and jump or  some other sprite that we reset our current frame   equal to no other than just zero that means we're  going to start at the beginning of our animation   so whenever we call switch sprite over in  classes.js and we actually go through the   process of switching the sprite within these  if statements we want to go ahead and say that   this dot frames dot current so the current frame  is equal to zero when we switch to a different   sprite so let's go ahead and copy this and paste  it within each case paste it within jump as well   save that head over here refresh and now when i  jump we're no longer getting that flash in place   when we start running to the right you're going to  notice we kind of lost a running animation right   here that is because we are furiously trying  to switch between our idle and run animation   we're always going to switch back to idle because  this is the first thing we call but if we go ahead   and press down a or d we're going to switch to  run which just means we're still switching back   and forth between these different sprite sheets  we want to make sure that we only switch back to   idle if we're not pressing down a or d so to do  that we want to make sure this is inside of an   l statement next says if and else if so we'll  paste in player that switch sprite to idle if   we're not moving on the x-axis so now if we save  that and refresh we look good in our idle position   we begin running and the running animation is  back we can even jump we still get that jump   animation right there so to finish off our jump  animation we want to also add a fall animation   for when we're going back down right now as soon  as our y velocity turns positive we switch back   to our idle animation we want to switch that over  to a fall animation to give off a realistic effect   so to do this we'll find where we're creating  our player specifically the player sprites   it's going to be right here and i want  to add into this a fall category as well   so i know i need an image source and a frame's  max for this i'm going to copy these two lines   paste it into fall and then determine what  image do i want to reference for our fall sprite   it's going to be fall.png this is going to be two  frames so we'll go ahead and change jump to fall   for the fall sprite and we can keep frames max  the same right here but now that we just added   in a sprite we also need to determine what happens  when we switch over to a sprite within closet.js   so we need to add in a case statement paste  this down below and say when we have a case   of fall then we want to switch everything to  the fall sprite so all we need to change here   are these three instances of jump i'm going  to do it at the same time with sublime text by   selecting one instance and holding down command  d to select those three and i'll change jump to   fall instead which is now available to us because  we added that in when we were creating our player   fighter in the first place so now we just  need to determine when we call switch sprite   fall that's going to be within index.js when our  y velocity is going to be positive so right here   when we're jumping we're going to want to add  in an else f that gets our player velocity on   the y-axis and say if this is greater than zero  then we know we are currently falling so this is   a perfect time to switch to not a jump sprite  but rather a fall sprite instead so let's save   that refresh and then we jump now when we fall we  have a fall sprite in place so that's pretty cool   but you may notice when we go ahead and hit the  ground while we switch between it looks like idle   and our fall sprite really quickly so why is  that well if we look within classes.js we're   going to want to focus in on our fighter's update  class so this right here is our gravity function   and this is actually what's causing that error to  occur so when we look at this position y plus this   dot height we are getting the bottom of our player  right here and when we're falling down towards the   ground we're also adding on this top velocity  which is increasing over time so eventually this   could be something pretty big like 21 for our  velocity so if the bottom of our player plus 21   which is going to be down here is greater than  our ground which it indeed is then we're going to   go ahead and set our velocity equal to zero which  means next time we go through this update function   we're going to go ahead and run this if statement  again so that means the bottom of our player is   going to be around here plus this.velocity y and  since we set our y velocity equal to zero well   this whole statement right here might no longer  be true because we're adding on such a miniscule   value even though we might be a little farther up  in the air so since this isn't true as a result   we add gravity back onto this.velocity.y what  happens when we add gravity onto our y velocity   while we switch on over to the fall animation so  we're going from our idle animation to our fall   animation and eventually this is going to be true  again but our position is going to be low enough   to the point where we're not switching between if  and else if and we go back to the idle animation   fully so i know that's a little confusing but  here's how we're going to fix it when this is   true we're going to set our y velocity but we're  also going to set the position of the player to   be in the exact location in which it can no longer  move so what i'm going to do is beneath this i'm   going to cause log out this dot position dot y i'm  going to save that and then open up our console   and then i want to refresh just to see what that  is so we want our y position to be set to around   3 30 for this to not fall any further without  any weird velocity issues going on so not only   are we going to set our velocity y to zero we're  also going to set this dot position dot y equal   to this exact value right here in which we're no  longer moving up or down it's going to be 3 30 so   let's go ahead and set that equal to 330 and now  we can go ahead and delete this console.log save   and then refresh makes it out of this and now when  we jump and hit the ground you're going to see we   no longer get that weird flash effect when you're  switching between our idle and our fall sprite   because we took care of that small little gap that  was appearing due to our velocity and gravity code   so now we can run we can also jump and fall and  then we go back to an idle position no matter   what we let up on so now we can go ahead and check  off jump so now let's add in our attack animation   so to do this we're going to go to index.js and  find our player and then our sprites object so   at the very bottom right here we want to add in a  new property and this is going to reference attack   dot one so we can see right here this is one two  three four five six frames now with an index.js we   can reference our image source which is going  to be attack one change our frames max equal   to the max amount of frames within that sprite  sheet which is six we always want to make sure   that we change the property name to the exact same  name as we have over here it's going to be attack   one so now that we have attack one in place we  always want to go to classes.js and then add in   the corresponding case statement so at the very  bottom i'm going to copy this case right here   paste in a new one and say for the case of attack  one then i want to make sure that i switch our   image over to not fall but rather attack one for  these four lines of code and now when do i want to   activate attack one well if we go into index.js we  want to look for our event listener where we press   on the spacebar so if i scroll on down we're going  to see when we key down on space right here we're   calling player attack that is perfect which means  within classes.js where we actually defined attack   right here we can also call this dot switch sprite  equal to attack one so we're just calling this in   a different location but this is going to activate  this code right here so if we were to save this   and then refresh and then hit space bar well it  looks like we're trying to attack but we're not   able to fully that is because within our animation  loop we're saying as soon as we activate the   attack animation we'll go directly back to idle  because we're not moving left or right and we're   not jumping currently it shouldn't really matter  if we're moving if we're jumping or standing still   when we press spacebar we only want to show that  attack animation and nothing else so basically   when we activate an attack we want to make sure  that the switch case code can no longer be called   so we're going to do this with an if statement  we're going to say if this dot image is currently   equal to this dot sprites dot attack 1 dot image  then we're going to go ahead and return we're not   going to call any of the following code which  might switch us to a different sprite sheet   if we save this refresh everything still works  but as soon as we activate our attack with space   we're going to get that attack animation  and that's pretty darn cool but you'll see   my hands are up and this just keeps going over  time what we want to do is say when this attack   animation completes just once then we're going to  reactivate our sprite switching code so we can do   that by extending this conditional right here by  adding an and statement saying if this dot frames   current is less than this dot sprites dot attack  1 dot frames max and we want to subtract 1 from   this because frames current starts at zero while  our frames max is the actual amount of frames   starting at 1 and now in all what we're saying is  if our image is the attack image and our current   frame is less than the frame's max of the actual  sprite sheet then we just want to return we don't   want to call any of the following code but as  soon as frame's current goes above the frame's max   right here then we're going to continue allowing  us to switch back to either idle run jump or fall   or even attack one if we decide to press spacebar  again so by saving this going back over here and   refreshing all of our jump code run code  idle code seems to work if we hit space   now we're only attacking once because  we added in this conditional right here   so that's how we're going to add in our animation  for our attack we're going to implement decreasing   our health bar with this new animation once we get  our second player in there and if we look at to do   we'll see that's coming up next so we have our  sprites for our player but now it's time to   bring our enemy back into the game and replace  our rectangle with an actual sprite sheet so to   do this we want to go to where we are creating  our enemy it's going to be down here on line   73 for me we need to add in all the properties  responsible for adding sprites into our fighter   so those sprite properties are going to start at  image source within our player instance right here   so we can grab everything from image source all  the way down to where our sprites object ends   and we're going to copy this and paste it into our  fighter instantiation so now we want to go ahead   and reference a different image not samurai mac  because well they should be different from each   other these are different fighters so instead of  referencing samurai mac we're going to go into a   kenji directory and then reference the idle image  from there so if we look at the idle image for   kenji it's going to look like this we're facing  to the left and we only have four frames within   the sprite sheet so now within index.js we can say  our default frame's max is going to be 4 and for   our enemy we're no longer referencing samurai mac  we're going to reference kenji instead so we're   going inside of this folder we want to make sure  that we change each instance in order samurai mac   to kenji to make sure we're referencing the  correct image name so now we just need to go into   each image and make sure that the frames match up  with the actual image so we know for idle we just   change this up here to have a frames max of four  if we're going to check out run for kenji as well   we have one two three four five six seven eight  so that's going to stay the same if we check out   jump that's two stay the same and then if we  fall we also have two that's going to stay the   same as well and then finally we have attack  one this is going to be a four frame animation   so over in index.js we just want to make sure we  change attack one to have 4 frames max instead   of 6. so with all this in place back down in  our animation loop you can see we commented   out enemy.update because we were getting some  errors before just rendering out a rectangle but   now that we have all the sprite animation stuff  in place we can go ahead and uncomment this out   save and then let's refresh just to see what  happens well looks like our sprite is already in   the game we're not really in the correct location  because it seems the sprite is supposed to be a   little taller than samurai mac over here so let's  go ahead and fix that now in order to make sure   that they're placed directly on top of the ground  we can go ahead and change the offset value for   our fighter so we're going to go ahead and change  this y value equal to 167 instead of 157 and   that should raise us a little bit if we refresh  we're definitely more on top of the ground now   but if i try moving our enemy with our arrow keys  you're going to see that we are stuck in this idle   position no matter what i do if we run if we jump  even if i attack we're not actually doing anything   so we need to go ahead and add the implementation  in for our actual enemy and it's going to be   really easy since we already did this for samurai  mac if we scroll on down into our animation loop   we can see that this code right here all relates  to samurai max sprite switching this code right   here relates to our enemy movement but we're  currently not doing any sprite switching for our   enemy all we need to do is grab one of these lines  right here where we call player.switch sprite   and then paste it into one of these estimates  where we're holding down our arrow left   or arrow right the only difference is going to  be we're no longer switching our player sprite   but rather our enemy sprite we want to make sure  we do this in both locations right here and we're   basically just replicating the code above but  for our enemy player so if we look at samurai   mac we have an l statement right here for idling  we're going to add in the l statement right here   for our enemy this is going to be kenji so our  enemy should switch the sprite over to idle when   we're not moving on the x axis and then we need to  take into account jumping as well i'm just going   to copy these five to six lines right here paste  it beneath our enemy movement and then say when   our enemy's velocity is less than zero meaning we  are currently moving upwards we want to switch the   enemy sprite over to jump and then finally for our  fall animation we just want to make sure that when   our enemy velocity is greater than zero meaning  that our enemy is currently falling we're going   to switch our enemy sprite over to fall so now  that's all we have to do if we save this go back   over here and refresh we start running we switch  over to our running sprite for kenji if i jump   we have a jump sprite and when we fall we have a  fall sprite all that is implemented all we have   to do now is make sure that when we press down  on the arrow key that we actually launched the   attack so let's check out where we are currently  attacking with kenji it's going to be within our   event listeners on key down this is where player  1 is attacking this is going to be samurai mac but   when we arrow down well we're no longer using this  method down here where we're setting is attacking   equal to true we're just calling dot attack on  the fighter instance so here we're going to call   our enemy and then call attack on top of that and  that's automatically going to activate attack one   so it's going to save this refresh and  then when we hit down on our keyboard now   you're going to see now kenji attacks so perfect  and we can move these two independent one another   attack at the same time so we really has some good  physics in place with spray animations as well   to make sure that our fighting game is set up  for success so with that i'm going to go ahead   and check off enemy sprite so now we're going  to go ahead and react to our sprite attacks   so thankfully we set this up a little bit when  we're dealing with just rectangles but you'll   notice over here when we try attacking well it  really only works sometimes so we need to go ahead   and edit that functionality to get our attack  box in the correct location so that it's overlaid   directly on top of our player's sword attack so  the first thing we're going to do here is go into   classes.js so we want to get that rectangle  overlaid on top of our sword so we want to   go ahead and show that rectangle again to do this  we can go into our fighter clause and we're going   to go into our update function right here this is  what manages our attack box position on the x and   y axis currently so it's the perfect location to  actually draw this attack box back out so right   beneath where we set our tack box position we can  call c dot fill rect to bring back that rectangle   that was overlaid on top of our rectangles  previously so we want to create an attack   box rectangle and we can do that with this dot  attack box dot position dot x for the x coordinate   the y coordinate is going to be this dot attack  box dot position dot y our third argument is going   to be this dot attack box dot width and then our  fourth argument is going to be this dot attack box   dot so we're going to save this and then refresh  we're going to see our attack box is drawn back   out so right now it's way over here rather than on  top of our player because this is affected by our   attack box offset remember we added that in when  we are still dealing with rectangles but we went   ahead and we created a new offset property  which actually determines the offset of our   sprite relative to the actual image as a result  we need to add in a new property that actually   references the offset of this one attack box  right here rather than the offset of our sprite   so we're going to go back into our fighter  class and we're going to add in a new property   called attack box so this is just going to be  one object and we can go ahead and define a   default right here to see what this looks like and  inside of this object we want to add in an offset   property that's going to be equal to an object  and then we also want to add in a width which we   can set to undefined by default to start and also  a height which will also set equal to undefined   we're only using this for visual purposes we  know exactly what an attack box consists of   so we know we want to pass through a property of  attack box whenever we create a fighter but if   we go ahead and pass this through then down here  where we actually define our attack box property   we want to make use of what we're passing through  so our offset for our attack box is actually going   to be equal to our attack box dot offset which is  going to be this object right here then for our   width this is no longer going to be equal to 100  to start it's going to be equal to our attack box   dot width and then down here for height  we're going to say our attack box height   should be equal to the height we passed  through our attack box object so now that   we just set this up we need to make sure that  we're actually passing through data related to   our attack box for each fighter so we're going to  do that within index.js find our player fighter   and at the very bottom right here beneath  our sprites property we can go in and add in   an attack box property this is going to take  three properties inside of it it's going to be   the offset we're just going to have an x and also  a y i'm going to set these equal to zero to start   we're going to have a width let's go  ahead and say this is equal to 100   and then a height we'll say this is equal to 50.  so now we can go ahead and define a different   attack box for an enemy and we're going to do that  now we'll just copy this property right here that   contains all of our attack box data copy that  and then within our fighter beneath our sprites   object we're going to go ahead and paste in a tag  box so if we save this and then refresh well now   this is placed in the correct location because  our attack box offset is based off of what we   just passed through into each individual fighter  and this will still function the same you'll see   if i go ahead and hit space to attack well we're  only going to go ahead and subtract from our enemy   health when this attack box is actually touching  our enemy so i go ahead and move over to the right   now when i attack it's going to decrease but only  when this is touching so we want to set the offset   for this to make sure that it covers the full  width of our attack so we're going to go ahead   move it in front of our player and then we're  going to extend the width of our attack box   so that it extends all the way to where our sword  ends so to go ahead and set that we're going to   go up to where our player attacks and we're  going to focus in on the attack box property   so we know our offset should be around 100 pixels  i believe that is the width of our player we can   just go ahead and kind of guesstimate this if we  save and refresh that that is definitely in front   of our player and i'd say that's a good location  in front of our player in which this attack should   actually activate it's not too close to the player  where they wouldn't actually be hit by a sword   but it is far away enough where we actually see  the animation in place where someone gets hit   so i think this is an okay location but we do want  to go ahead and move this attack box down in the   middle of our player so you might be thinking  can't we just go ahead and add on 50 to y right   here save and refresh well you're going to notice  this didn't actually move at all because if we   look within classes.js we never take into account  how our attack box should be affected by the   offset of our attack box on the y-axis and you can  see that directly within update specifically where   we're dealing with our attack boxes right here so  for attack box position y we're saying we want to   go ahead and offset the position by our attack  box offset on the x-axis but we never actually   did that for position y right here so we're going  to add on to this this dot attack box offset y   and that's going to go ahead and make sure our  offset actually affects the attack box position   on the y-axis so we save that and refresh now  that has moved down by 50 pixels it looks to be   in more of a correct location so now we just want  to make sure this extends the full width of this   attack so we're going to extend the width over  in index.js by saying our width of our attack   box should be equal to let's go ahead and say 200  to start refresh and it looks to be a little too   large we'll subtract 40 or 50 from that let's go  ahead and start with 40 by saying our width should   be equal to 160 save and refresh and that looks to  be almost perfect so now when we move forward and   we attack our enemy with our attack box over them  you're going to see health is subtracted and when   we move back and this is not touching nothing  happens so we're just going ahead and edit our   attack box to work with this animation but you're  going to notice that this health bar goes down   at the very beginning of our animation it doesn't  actually go down when the sword hits the enemy   watch again when i hit it immediately goes  down rather than when the sword hits the enemy   so we want to go ahead and fix that we want to say  we only want this to go down when we're through   the fourth or fifth frame of our actual attack  animation so where we're detecting for a collision   it's going to be down here within our animation  loop right here this is where we're detecting   for collision with our player we do want to run  these conditionals but we also want to add in   another condition now this condition is going to  get our player dot frames current so the current   frame we're on within this animation we want to  say we only want to go ahead and subtract from our   player health if this hits the enemy when player  frames current is equal to about four because that   is going to be the exact frame in which the sword  actually comes out and we can always check this by   looking in simran max attack one you're going to  see this is going to be our zeroth frame this is   going to be your first second third and fourth  so our fourth frame is what we want to monitor   to say this is when we should actually subtract  from the health of the enemy so with the index.js   we want to make sure player that frames current is  equal to four when we actually subtract our health   and if we save this and refresh and try attacking  well you're going to notice this doesn't really   work unfortunately why is that well this shouldn't  be true technically but if we look at when player   is attacking over in classes.js we're going to  be setting that whenever we call this attack   method right here so we're setting this equal to  true as soon as we press down on the spacebar and   then after about 0.1 seconds we're setting that  equal to false so we're setting this back equal   to false before we even get to frame 4 within  our animation and as a result it's causing that   conditional to not fire so to make sure this isn't  set back to false immediately we can go ahead and   increase the time right here to something like a  second but that's not going to be as accurate to   say when our animation actually ends we want  to make sure that we set his attacking evil   falls when our animation actually completes  whether or not we hit our enemy so we're going   to go ahead and remove this set timeout right  now so now if i go ahead and hit our enemy you're   going to see that only activates when the sword  actually touches him but now watch what happens   if i go back here and i attack nothing happens  but if i run into our enemy without attacking   we decrease their health because is attacking is  equal to true still we want to make sure that we   set that back equal to false when we miss our  enemy with the attack so we're going to do this   within index.js so this right here says when we  detect for collision but beneath it we can say if   player misses then we want to call the following  conditional we can say if our player is attacking   and our player dot frames dot current is equal  to 4 meaning we're at the end of our attack   then we're going to go ahead and set player  that is attacking back equal to false   so we're going to go ahead and do that anyways  but this is only if we're actually touching our   enemy with our sword but right here in case we  missed then we want to set it back equal to false   so we don't accidentally subtract from  the enemy's health it's going to save that   and then refresh and test this out so we should  miss first which we do and then when we run into   the enemy we're no longer attacking so we don't  subtract from their health now if we go ahead   and cover this attack box with our enemy right  here attack you're going to see that subtracts   go back here attack and run into them no more  issues regarding that so now let's go ahead   and add in the attack for player 2 over here we  want to make sure that this attack box is over   our sword swing so we're going to go back  to our code and find where we are creating   player 2 which is our enemy we want to focus in  on this attack box property so our offset for x   is going to be around negative 100 because that's  going to make sure we shift that over by the width   save that and that seems to be in a pretty  good spot in regards to its x position   but we do want to move it down a little bit as  well so let's go ahead and say that y is going to   be down 50 pixels save and refresh and now i like  the looks of that let's go ahead and extend this   so that it actually reaches the end of this  white little slash we're going to say the width   for this should be eagle 2 150 save and refresh  that and now since we're increasing the width   right here the offset also needs to be taken into  account because objects on the canvas are drawn   from the top left hand corner and we're kind of  trying to do this in reverse for this attack box   so we're going to subtract 150 here for our offset  and now almost there we need to add about 10 to 15   pixels onto that width which means we need to  do it for right here and width we'll say that's   but we also need to subtract 165 as well so we  go ahead and save that and then attack you're   going to see almost there let's go ahead and add  on five more pixels and i think that should do it   so our width is going to be 170 and then our x  offset is also going to be 170. so now when we   save that that pretty much reaches the end and i  think that's a good location to say this is when   we should actually hit player 1. so now if i go  ahead and move over and move that over our player   start attacking you're going to see that decreases  over time but we have the same issue that we had   with player 1 you'll see if i attack and then  just run into player 1 with this attack box   your health goes down anyways we want to make  sure we prevent that we're going to do that   within our animation loop the same way we did  it for player one so we want to copy this code   right here go beneath our conditional for if we  actually hit player one which is right here and   paste that on it but now we know we're dealing  with our enemy rather than our player so we're   going to go ahead and switch all instances of  player with enemy that is attacking instead   we want to make sure that we select the correct  frame in which this attack should hit so we can   always look within kenji that attack 1 and here  we're going to say well this should actually be   frame two so kenji has a little bit of an  advantage because their attacks are a lot quicker   basically we can say samurai mac is going to  be slower but more powerful kenji is going to   be quicker but weaker in regards to damage so  we want to make sure within index.js that the   frame's current is equal to 2 that is when the  enemy sword attack is basically over we want   to do this right here and we also want to add in  this and statement into this conditional so that   we don't just subtract from our player's health  immediately we need to wait at least one frame   by adding in this and statement that says  enemy.frame's current should be equal to 2   before we actually go ahead and subtract from  our player health so we save that and refresh now   if i go ahead and attack over here and run into  player 1 we don't subtract from their health but   if i go ahead and move this attack box over  them then attack that's all i'm going to go   ahead and subtract on frame 2 instead so now  really the last thing we need to do is simply   remove these boxes so to remove these boxes we  can go to classes.js and all we need to do here   is find out where we actually drew them out it's  going to be this.c dot philrect we can go ahead   and say this is where we draw the attack box and  then we don't really need this code right now so   we can go ahead and comment it out save refresh  and now our attacks should work and subtract as   needed but without showing that attack box so  i attack with player 1 right here you're going   to see that subtracts and then when i attack with  player 2 that subtracts as well so we're beginning   to finish up this fighting game but using attacks  with actual sprites so now we're going to go ahead   and add in a receive hit animations like these  two in on you both receive hit death animation   but we want to go ahead and react whenever our  player or the enemy is hit so when we go ahead   and attack there should be some sort of reaction  right here for our enemy how are we going to go   about implementing that well we're going to start  by heading on to where we are creating our enemy   so that's going to be right here on line 81  for me and i know i want to add in a new sprite   for this animation so i'm going to go to the  bottom of sprites right here and i'm going to   call this take hit so this is going to be equal  to an object and this object has two properties   image source and where do i want to go  ahead and grab this image well simply within   our image directory so img and then i want  to go ahead and say this is referencing kenji   and i want to get this right here it's going to  be slash take space hit with a lowercase h dot png   so we look within take hit right here you're going  to see this is a three frame animation and it's   just kenji reacting to getting hit going backwards  so back within index.js we want to say that our   frames max the max amount of frames we're going to  have here is going to be equal to 3 because that's   how many frames we're within take hit right here  so now that we have this here within our enemy   constructor we need to go into classes.js and  define a case for taking a hit so i'm going to   go ahead and copy this case right here right below  paste in a case of take hit with a capital h and   then i want to say if our image is not currently  equal to the sprite of take hit and i want to make   sure that i change out attack one in each location  where it is currently swap that out with take hit   then we're going to go ahead and swap that image  change its frames max and set the frame's current   equal to zero so this is going to actually give  us an option to take a hit and activate that   animation but where would we actually call switch  sprite to activate take hit well within index.js   we want to scroll on down to our animation loop  and right where we are detecting for collision   we know that this is currently where our enemy  gets hit so we can add a comment here that says   and enemy gets hit so within this if statement we  also want to go ahead and select our enemy we're   going to call a new method on top of this because  although we could write the code directly in here   sometimes it's good to abstract things to make  our code more readable so we're going to say enemy   dot takes a hit so take it right here when we go  ahead and collide the attack box with our enemy   now for enemies going to go ahead and take a hit  well we're going to go ahead and subtract from   our enemy health that's already happening right  here but if we want to go ahead and simplify   this we can go ahead and take out enemy health  minus 20 cut that out we're actually going to   go ahead and paste it within a take hit method  directly within our fighter class so let's go   to classes.js if we're scrolling up right beneath  the tag we're going to add in a method of take hit   now we can go ahead and paste in dot health minus  equal to 20 but we can't reference enemy anymore   because that actually referenced the direct object  instead we need to reference this fighter's health   so this will function exactly the same as we have  right now when we go ahead and launch an attack   but what else do we want to do when we take a hit  we want to go ahead and switch our sprite over to   take hit so you'll notice if we go ahead and  save this and refresh and then we hit kenji   over here but we're not actually going back  to that take it animation even though we are   definitely calling switch sprite to take hit why  are we not showing that animation well we need to   make sure that we're not reverting to this idle  animation at any point in time when that take hit   animation activates we're basically going to do  the same thing that we did for creating attacks   you'll notice when i jump up in the air and credit  attack when i move forward and create an attack   well that attack animation always goes because  we're overriding all the other animations   available to us when we take a hit we also want to  override those animations so that's exactly what   we're going to do so where are we overriding those  animations it's going to be right here within   switch sprite you'll see this estimate right here  it's actually representative of overriding all   other animations with the attack animation so we  want to do the exact same thing not for when we   attack but rather override when fighter gets  hit so if we're not currently attacking with   this right here we can proceed onwards to this if  statement where we're going to say if the current   image being displayed is equal to this sprites dot  take it dot image and what else if this dot frames   current is less than the frames associated with  the sprites of take hit we're going to get that   with dot sprites dot take hit frames max -1 is  basically the same thing we have up here we're   just using take hit instead of attack one we go  ahead and add in this if statement we can go ahead   and return basically what this means is if we're  not attacking but we are getting hit we don't want   to run any of the following switch case statements  we're going to go ahead and force ourselves   to return if we're currently in the take kit  animation and we're only going to allow ourselves   to go onwards if the current frame is greater than  the max amount of frames associated with our take   hit sprite if that's the case then we can go back  to switching over to a different sprite including   back to an animation such as idle so this should  be good to go if we're going to save this and   refresh over here and we try moving while we're  not actually able to move at all none of our keys   seem to be listening so let's go ahead and inspect  our element and we'll head over to our console   and you'll see we have an error right there that  says cannot read properties of undefined reading   image let's go and click into this well basically  that code we just added in for the if statement is   not being read why is that well although we have  a take hit sprite associated with kenji right here   we do not have a take hit sprite associated  with samurai mac over here on the left so   we need to make sure that we add take hit and two  sprites specifically for samurai mac so to do this   we'll go over to index.js and find where we are  creating our player which is basically samurai mac   it's going to be right here on line 29 for me  and we want to head into our sprites object we're   going to be adding in a new sprite so we can just  go ahead and copy one of these properties and then   we're going to paste in a duplicate but we don't  want to create a spray of attack 1 but rather   take it make sure this is spelled exactly the same  as it was within our enemy right down here which   it is so we'll scroll on back up and say that  our image source for take hit for samurai mac   is going to be in our samurai mac folder that is  great and we want to go ahead and select either   take hit white silhouette or just take it let's  go ahead and look at these if we look at take hit   you're going to notice samurai mac goes backwards  a little bit when he gets hit but the white   silhouette we have samurai mac getting this white  silhouette laid on top of him and i would actually   prefer this version simply because it shows better  that he has been hit it's kind of like a hidden   animation where the player flashes once they've  been hit it just indicates better that they've   been hit so we want to go ahead and use this  version instead of just a normal take hit png   so for our image source we're going to say we  want to reference inside of our samurai mac folder   take space hit capital h on this one we're going  to add a space and a dash and then another space   and then white silhouette and i have trouble  spelling that so i'm going to need to look at it   silhouette dot png so just make sure this matches  what you have over here and then we need to   determine how many frames we have in here so we  saw that had not six frames but rather four so   let's go ahead and save that and then refresh and  now if we try to move we're able to move once more   if i go ahead and use our space bar you're  going to see that now we have that react   animation in place for kenji let's go ahead  and attack samurai mac with kenji instead   you're going to see we do have an issue  here with samurai mac not reacting   why is he not reacting well because when samurai  mac gets hit we need to activate that take   hit method right now that is not happening so  let's go ahead and make it happen to do this we're   going to go scroll on down back to our animation  loop and we'll keep on going until we find our   collision detection this is where our enemy gets  hit but right here above this if statement this   is where our player gets hit so we know inside of  here we want to call player dot take hit that's   going to automatically subtract from our player  health so we don't need this anymore right here   now if we save that and refresh with take kit in  place and we attack samurai mac you're going to   see now we have that hit animation in place move  them out a little bit so we can see it better   and that looks really cool for being attacked  so great we have react animations for when both   of our characters get attacked so over in to do  we can now check off the receive hit animation   so now let's go ahead and take care of the death  animation that's supposed to occur when our health   bar reaches zero so the first thing we're going to  do to add in any new sprite is find where we have   our constructors for both our player and our enemy  we're going to do this in both spots early on just   so we don't have any bugs as we proceed so right  up here i'm on 29 this is where we're creating our   player sprite i want to go into our sprites object  and i'm going to add in a new property and this is   going to be called it's going to call this death  so this is going to be equal to an image source   any frames max i'm going to go ahead and grab this  from take it paste it into death and i want to say   the image source of our death is going to be for  samurai mack to simply death with a capital d   so instead of take hit white silhouette  we're going to go ahead and get rid of that   and say we're referencing death dot png how  many frames is our death let's go and select it   it's going to be one two three four five  six frames so let's go back to index.js   and change our frames max equal to six now we can  go ahead and take this death object copy it from   our player go inside of kenji's sprites object  right here and at the end of take hit add in a   comma and then this new death object but we know  we don't want the same death for samurai mag we   want one that's referenced from our kenji folder  that's going to be death capital d dot png as well   how many frames is this it's going to be one two  three four five six seven it looks like so back   within index.js we could say our frame's max is  equal to seven for when kenji dies now whenever   we add in a new sprite right here we need to go  over to classes.js and focus on our switch sprite   method we need to add in a new case so i'm going  to copy the take hit case paste it down below and   the case of death is going to go ahead and switch  our image over to the sprite of death in all these   locations and it's going to change our frame's max  equal to the max amount of frames associated with   this death animation so when should we actually  switch to a sprite of death well we can actually   do this whenever we go ahead and take a hit  after we subtract 20 from our health we can   go ahead and say if this dot health is less than  or equal to zero that means we know we're dead   well we can go ahead and call this dot switch  sprite specifically over to the death sprite   else we can go ahead and switch our sprite over  to take hit so we're going to go ahead and paste   that within our else image right here now similar  to take hit and when we actually launch an attack   we need to make sure that our death animation  does not allow anything to override it as a result   we're going to go into switch sprite and none of  these animations should run as long as our death   animation is activated we should never be able  to come back to life unless we refresh the game   so in here we're going to say if this dot image  is currently equal to this dot sprites dot death   dot image then we're going to go ahead and just  return we're not allowed to run any other code so   we're going to save this and refresh we'll start  beating up on kenji over here eventually when he   goes ahead and hits a zero for his health you're  going to see that we activate that death animation   now it's just running over and over again because  even when we hit the ground our frame is resetting   back to zero once it resets back to zero well it  just runs the animation even if the sprite sheet   is currently overriding everything so really all  we need now is a property that declares our player   dead and if they are dead well we are not going  to call what well animate frames anymore because   that's what's responsible for creating this kind  of movement we don't want any more movement as   soon as they hit the ground so for our fighters  we're going to add in a new property called this   dot dead by default it's going to be equal to  false and then what we can say is if this dot   dead is not true so we are not dead then we want  to continue animating our frames so now we just   need to determine the location in which we set  this dot dead equal to true and that's going to   be down here within this if statement that we just  wrote so let's wrap this in curly brackets like so   so we can write multiple lines of code within this  and we want to say if this dot frames current is   equal to this dot sprites dot death dot frames  max -1 then we'll set this dot dead is equal to   true our fighter has officially died how sad so  let's refresh and then we're going to go ahead   and beat up kenji some more and once you hit zero  you're going to see that death animation activates   we can still move around a little bit that's  okay for the time being but let's go ahead and   test whether or not samurai max death animation  is in place correctly so we're going to go ahead   and beat up on him and eventually when he hit zero  hit seems to be in the correct spot too although   he can move around as well so the last thing we'll  do here for our death animation is make sure that   we can't move or jump around like this even if one  of our fighters is dead and we can do that within   index.js specifically at the bottom of our file  where we write out our event listeners so within   key down we can write an if statement that says  if our player is not dead so we need to preface   this with an exclamation point then we want to be  able to run the following switch case statements   which activate player movement jumps and attacks  but if our player is dead well the enemy should   still be able to jump around and celebrate a  little bit so we basically need to split up   the switch case statement right here so that our  cases for our enemy are in a separate switch case   so i'm going to go ahead and grab these last four  case statements and then beneath the switch i'll   add in a new one and say when event dot key has  the following cases which i'm going to paste in   then we want the enemy to be able to attack and  move so if our player is not dead we're going   to go ahead and activate this switch right  here but if our enemy is not dead preface by   an exclamation point then we want to be able to  call the following switch case right here as well   so we'll add that in save go back to our game  and refresh and now we go ahead and beat up kenji   bring it back down to zero we can no longer move  on kenji when i'm pressing any of the arrow keys   and we can test this with samurai mag as well  when i go ahead and bring him back down to zero   now he falls and i can't really move around at  all pressing any of the arrow keys but i can still   move with kenji so with that we can go ahead and  check off our death animation so we're going to go   ahead and work on interface design and animation  next so basically what this means is we want to   go ahead and make this up here our health bar and  our timer look a lot better make it mesh into our   game to make it seem like it's part of that rather  than something that's just thrown on there so the   first thing i want to do is change this yellow to  red because that is going to represent the amount   of health we have left kind of represents  blood i would suppose but you typically   see that within fighting games is the further  health bar goes down the more red it becomes   so let's go ahead and do that first in order to do  this we're going to go into index.html and we're   going to find where we have our player and our  enemy health let's go ahead and start with player   health first so we know right here we have a  background color of yellow this is our background   bar we just go ahead and change this to something  like red refresh and then we start hitting samurai   mac you're going to see that now that is red that  is more representative of health that is left   we need to do the same thing for kenji's health  as well though so we'll scroll on down until we   find enemy health and wherever we have yellow it's  going to be right here we're going to change that   to red save and refresh that and now when we hit  kenji that is red as well so that's looking great   but now i kind of want to change this blue color  to something more purple just so it meshes in with   the purple that we have within our game so if i  need a good place to choose a certain color what   i like doing is i like opening up a new tab and  searching for tailwind color palette so tailwind   is a css framework but with it comes a lot of  great color palettes that we can use within our   game so this first result right here is going  to be tailwindcolor.com and if we click on that   you're going to see that we have all these  different colors that we can use within our game   so i kind of want something that's purplish  i'm going to go to indigo and let's go ahead   and choose about 400 i'm just going to click on  this and what this does is is it stores a hex code   to our clipboard so where we have a background  in blue for enemy health let's get rid of that   paste it in and the hex code is going to be 818  cf8 this is just a hex code representation of   that color indigo so if we save this go back to  our game and refresh you're going to see that now   we have it indigo color bar i think that meshes  in with our background a lot better we hit kenji   we still have that red so i really like where  this is going it's going to make our blue over   here that indigo color as well we're going to copy  this hex code to make sure we still have it in our   clipboard and then find where we have a background  in blue specifically for our player health and   it's going to be right here we can replace that  with the hex code save and refresh and that's   already looking a lot better now the square up  here takes up a lot of space and i don't really   think it makes sense to keep it red because that's  really directing our eyes towards that the timer   is important but it's not that important it's not  the main thing we should be looking at so we want   to go ahead and detract the user's eye from this  we can go ahead and darken this to something like   black or gray we're just going to go ahead and use  black here so let's go ahead and find our timer   and where we have a background color of red we're  going to switch this over to black so we do that   save and refresh and now our eyes are definitely  not attracted to that as much let's go ahead and   make this smaller to further de-emphasize this  location we're going to decrease the height of   this let's make it to around 50 pixels and now  that's even less apparent which is great but we   can't see our timer inside of it because the timer  has a text color of black as well so on top of the   same div we'll add in a style of color say that  our color should be equal to white so i'm gonna   refresh that now we can see our timer and this is  already looking much better than what we had prior   but we can still take it a step further to really  give it a nice look so i think our health bars   would look good with some sort of border around  them same thing with our timer in the middle so if   we wanted to go ahead and add a border we would go  over to our player health bar and find this parent   div right here so we're going to add in a style of  border and this is going to take the width of the   border we want to say around 4 pixels it's going  to be what kind of border do we want to use is   it going to be solid is it going to be dashed we  pretty much always want to use a solid border then   we want to go ahead and choose the color of the  border i'm going to go ahead and make this white   so we save that and refresh we do have a white  border around this bar but you'll see it kind of   threw things off a bit now our red bar is below  our indigo bar up here we want to make sure that   the indigo bar is always on top of this red bar  so what we can do is for this parent to do we're   currently assigning it a height of 30 pixels  but it doesn't really make sense to do that   since our child div right here already has a  height of 30 pixels this parent div is always   going to be the height of whatever is inside of it  as long as it does not have a position of absolute   so we're saying that the parent div right  here should be the height of this div because   it is the one div that does not contain position  absolute so we'll get rid of height 30 right here   save and refresh and that automatically fixes that  issue i go ahead and hit samurai mac we still get   the same effect everything is looking great so  now let's go ahead and add a border to our timer   as well if we want to add the same border we  can simply copy that style find our container   for our timer it's going to be right here paste  in that same border style save and refresh and   now that has a border as well let's go ahead  and add a border for enemy health bar over here   our enemy health is right here and we want to add  this on the parent div so we're going to add it   right here at the end of our enemy health  parent div we go and save and refresh that   and we get the same issue here because our  parent div currently has a height of 30 pixels   we're going to make our parent divs height  dependent on this div right here so we can get rid   of height equal to 30 pixels saving a refresh  and that fixes that as well now with our   borders it looks a little silly for us to have a  border on the right side here of our health bar   when we already have a border on the left hand  side here of our timer instead of having two   borders touch each other let's go ahead and  make sure that we only have one border there   so to do this we're going to go ahead and find  playerhealth right where we added that border   now we don't want to just say we want a border  on all four sides and that's what the border   property does it says add a border on the top left  bottom and right sides of this container instead   what we're going to do is say we want a border  on the top i'm going to duplicate this style   say i also want a border on the left i'm going to  duplicate this paste it in and then say i want a   border at the bottom as well so now we don't have  a border right property here and that is perfect   because if we refresh now we have only one border  right here on the left hand side of our timer it   looks a lot better we're going to want to do  the same thing for enemy health bar over here   so let's find our enemy health bar it's going to  be down here and we currently have one border set   to all four sides to be four pixels solid and  white let's say we only want this to apply on   the border top i'm going to copy this right  here add in a semicolon paste it in again say   now i want this on border bottom as well and then  finally i want to add in one more border on the   right side so when i add in border right save and  refresh and now that fixes that issue right here   so this is already looking pretty great one  more thing i would want to change here is   the font of this text this is just the default  font that comes with your computer at the moment   but i think it would look a lot better if we  actually use some sort of 8-bit text so how do we   actually go ahead and change this to some sort of  8-bit font well if i ever want some sort of free   font to use on either personal or commercial  projects i like searching for google font   we're just going to go ahead and click the  first result right here at fonts.google.com   so this is going to give us a list of free  fonts that we can use within our project   and the font we're going to want to use is called  press start so if i type that up here it's going   to filter out the fonts and this is the one we  want you'll see this is a nice 8-bit font that   would be perfect for our game so we're going to  go ahead and click this this is going to bring   us inside that direct font what we want to do is  click select this style right here this is going   to open up a tab on the right hand side and what  we want to do is copy these link tags right here   if i go ahead and copy all these with command  c head back to our project and then within   index.html scroll to the very top right above our  head tag i want to go ahead and paste these on   and you'll see this consists of three link tags  that reference google fonts and specifically   our press start font so now back within google  fonts if we scroll down a little further on this   right-hand sidebar they'll give us some css rules  in regards to how we can use this font so to use   this we can copy this line down here go back to  index.html and say what elements do we want to   use as font within our css well we know right here  we're selecting all elements with this asterisk   so we can just go ahead and paste in font family  is equal to press start 2p and now this is going   to work because we're actually pulling the  font in before we actually call this style   so if we save this and then go back to our game  and refresh now we have that really cool font   in place where we have that 8-bit styling you can  see even when we get rid of kenji or samurai mac   we have that font in place as well so great  now i think the very last thing i would do   to finish up this game is add a little bit of  contrast between our players in the background   because even though we do have a good amount of  contrast we can still see kenji in front of the   shop it wouldn't make it easier to see him if we  added a white overlay behind kenji and samurai   mac and on top of our background layer just so  we can really see our players and not have any   issue in regards to where kenji or samurai mac  is at any point in time so to add that layer we   don't actually need to add in any image we can  do this directly within index.js we're going to   scroll on up to our animation loop we're going  to find where we're currently drawing out our   players it's going to be right here for our enemy  for our player for our shop and for our background   so if we say right after we update our shop we  want to call c dot fill rect specify we want this   at the x coordinate of zero the y coordinate is  zero and we want this to fill up our whole canvas   with a canvas width and canvas height as our last  argument and right before this we declare a c dot   fill style equal to rgba and specify that our red  is going to be 255 our green is going to be 255   and that our blue is going to be 255. this last  value right here is going to be the alpha value   so if we use 255 for all three colors right here  red green and blue that's going to give us a color   of white that's how colors work if we mix those  three together at full strength it's going to   give us a color of white but for this last value  of alpha this is going to determine the opacity of   this white so if we bring this down to something  like point 1 save and then refresh you're going to   see that our background just faded out a bit with  that white overlay on top of it it becomes even   more apparent if we increase this alpha value to  something like 0.7 save and refresh now we really   have that white opacity in place and we really  see our players but it just looks kind of silly   at this point to go this drastic so i think a  good medium for this game is going to be point 15   save and refresh that so now we do have a white  overlay but it helps our player contrast from   things like the shop a bit better than it was  prior so i think this is a good addition to   our game to really make sure that we can see  our players overlaid on top of this background   with colors that might not contrast as well  together now the very last thing i want to do here   to add a little more pizzazz to the game is that  when samurai mac or kenji attack each other i want   this health bar to animate downwards rather  than it being so drastic and sudden so to get   this to animate we're going to do one more google  search and this is going to be a google search for   dsap cdn so gsap is an animation library it's  pretty much the go to for any project on the web   and we want to go ahead and click cdnjs.com this  is pretty much always available to us and a cdn is   just a link that we can grab from the internet  and directly insert that library into our game   it's super easy to do which is why we're doing  it so we want to make sure that our version right   here is 3.9.1 we're going to grab this first  link by clicking on copy script tag right here   so we'll click on that and then if we want to  import this we'll head on over to index.html   we don't want to insert this within our head  tag because typically scripts go at the bottom   of your file so we can say right above our custom  scripts we want to paste in that script we copied   and by doing that we're going to import gsap into  our project so to make use of gsap we want to find   where we are actually decreasing this health bar  right here and it's going to be within index.js   where we are selecting a specific element so  you'll see this is where we're selecting that with   document.query selector for our enemy health we're  not going to decrease our enemy health this way   but rather the gsap way so make sure that you have  index.html saved with that new gsat file pulled in   and once it's saved and pulled in you can now  reference it with gsap and use a method like two   so the first argument for two is going to be the  element you want to animate what is the element   we want to animate what's going to be enemy  health the same thing that we have right here   the second argument in usap.2 is going to be what  do you actually want to animate well we want to   animate the width so we're going to add in a width  property right here and to what value do we want   to animate this to well our new enemy health  with a percentage sign so we can copy that paste   it into gsab.2 and now we can get rid of this  document.queryselector which sets our width let's   delete that save and then refresh and then when  we hit kenji we should see this animate downwards   now that definitely does animate downwards it's a  lot smoother than that drawing animation that we   had before but all we need to do now is make sure  that it occurs whenever we hit samurai mac as well   we can just simply copy gsap.2 and find where  we are selecting our player health it's going   to be right here we're going to paste in what we  just copied and then swap out enemy health right   here for player health instead and now we can go  ahead and get rid of this document.queryselector   the last thing we want to do is make sure  that we're not referencing our enemy health   but rather replay our health instead save and  refresh that and now when we hit samurai mac   that animates downward as well it's really  that simple what we use something like gsap   so i think with this we have a complete game in  which we have two characters that can jump around   attack each other and then get their health bars  down to zero and eventually when one hits zero   we have a winner the first player cannot win  we can still move around and then we can start   a new game by refreshing to take this to the next  level you'd probably want to have more characters   you probably want a restart button but i think  this is a really good base version of this game   to show you exactly how a fighter would work  with attack boxes animations and collisions so   with that we're going to be able to check off  interface design and animation so the very last   thing we're going to do is push our project  live to the web so you and your friends can   play it live so how would i go about doing this  while we're going to go ahead and use a platform   called nutlify simply because we can push it up  to the web for free under one of their unique   urls so to begin doing this we do need to know a  little bit about github so i do recommend watching   some sort of basic github video but i'm still  going to walk you through the entire process   so we need to go ahead and create a git repo to  do this we're going to go on over to github.com   and once you're here you want to make sure that  you have an account and that you are logged in   as soon as you log in you're going to be  redirected to a dashboard like this you can   go ahead and hit new to create a new repository  which is basically a new folder in which your   game exists it's just going to be stored within  github on the web so once you're here you want   to create a repository name we know our game is  called fighting bash game we don't really need   to do anything else in regards to description we  can make this a private repository meaning no one   can see our code so it's going to do that and then  if we scroll down we want to make sure that we can   create a repository and sometimes we just need to  make sure that we reselect this that github knows   yes this is available of course it is and then we  can go ahead and hit create repository so that's   going to go ahead and create the location in which  we want to store our game online and now what we   need to do is activate a few commands within our  terminal so i'm going to copy these lines right   here and then i want to open up my terminal on  mac so if you're a windows user you're going to   open up powershell and you should be presented  with something similar to what we have right now   right now we have a squiggly which just means  we're within our home directory on our computer   and this is just a one to one representation of  our finder you'll see right here if i list out   the contents of the squiggly or home directory the  contents of this directory are the exact same as   the content within my home directory within finder  these folders over here match up with the folders   listed out within this directory so we want to  change our directory within terminal to where we   have our game and we can do this pretty easily  we want to search for our game within finder   i'm going to go to web and then find fighting  game right here so once we find this directory   we want to type cd into our terminal which means  change directory and then what we can do is drag   this folder on top of that cd within our terminal  and this is where our game is currently located   so if we cd into this now we are currently within  our fighting game so now what you would want to   do is paste in all that code and then hit enter  and it might ask you a few prompts such as what   is your github username and what is your password  if you just set this up just go ahead and enter   those in i promise it's safe and it's going to go  ahead and push that up to your git repo the reason   i am not inserting this is because i already had a  git running within our game for tutorial purposes   so if you already had to get running within your  game you just want to select these other commands   so i'm going to go ahead and grab those paste  those in and that's going to go ahead and push   everything up to github so once this finishes  running i can go back to github and refresh   and you're going to see our game has officially  been uploaded to github and this is really all   we need to do to start getting our game live  on the web so once that's in place we want to   open up a new tab and then we're going to go to  netlify.com so nullify is going to host our game   and if you're new you're going to want to sign up  it's completely free i already have an account so   i'm going to go to login i'm going to log in with  my github account so that's going to take me to   my team which is reserver and that is pretty much  my company in which i manage clients i'm going to   go ahead and push this site up to this as well  i'm going to go over to the sites tab and once   i'm here i want to go over to add new site and  i'm going to import from an existing project   so whether or not you have a team already  you should eventually come to this screen   and you're going to want to go ahead and connect  to your git provider our git provider is going   to be github so we'll select that and now  if it's going to ask you for authorization   so if you're not automatically redirected back you  can simply exit out of this tab and you'll see now   we are currently authorized so i authorized all my  repos to be available within netlify so i'm going   to go ahead and search for my repos specifically  for fighting dash game you're going to see there   it is we want to go ahead and click on this and  then this is going to ask us for a few settings to   get this set up and deployed so the owner is going  to be our team name that's reserved that's totally   fine which branch we want to deploy well we only  have one branch associated with our project which   is main you don't really have to worry about this  too much just go ahead and select main right here   and then it's going to ask for build settings so  if you're using a site generator such as veet or   webpack or something to build your project then  you would go ahead and specify where is the output   directory right here we're not really using that  so we don't really need to do anything right here   we don't need a base directory we don't need a  build command we don't need a publish directory   we're just going to hit deploy site with all  that that's going to begin deploying our site   from github so whenever you push changes up to  github nullify is going to make note of those   changes and automatically update your site on  their platform so after about a minute or two   if this is not updated automatically you can  always refresh with the command r you're going   to see as soon as i refresh while our site has  already been deployed and you can see a preview of   it right here so perfect so this is the url they  gave us we're going to go ahead and click on that   and now our site is live on the web at that  exact url and our game works exactly as it   did before because we pushed everything up  with github keeping our code the exact same   so that's pretty much all we need to do to get  this live on the web one more thing you could do   to make this a little better is change this domain  right here so if we go over to domain settings we   have the ability to add in a custom domain and a  custom domain is something like chriscourses.com   that is the root domain if you don't want to use  nullify.app you would go here and add a custom   domain but to keep this as simple as possible  we're just going to go ahead and change the   sub domain name right here i'm going to go to  options and then edit site name so now we can   edit this to something that makes more sense such  as chris courses fighting game obviously that's a   lot easier to read than whatever nonsense they  put in there by default so now i can save this   and now when i visit chris corso's dash fighting  game at netlify.app i have a game in which i can   play live on the web for completely free so  finally that's going to allow us to check off   pushing live so that's going to be it for this  one folks and i hope to see you in the next one you
Info
Channel: Chris Courses
Views: 1,411,019
Rating: undefined out of 5
Keywords:
Id: vyqbNFMDRGQ
Channel Id: undefined
Length: 236min 19sec (14179 seconds)
Published: Sun Mar 27 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.