Coding Pac-Man in JavaScript Complete Tutorial Every Step Explained

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
in this exciting tutorial we're going to be creating pacman for this tutorial we'll be using pure javascript that means no game frameworks or libraries by doing this we can learn the fundamentals of game development if you understand everything that we do here it'll make it much easier to understand gaming libraries in the future not only will we make pacman but also learn a lot of modern javascript as with all my tutorials we'll start with a blank canvas and code every single part no copy and pasting of large chunks of code here this is the final game that we'll have by the end of this epic tutorial as you can see the game starts off paused as soon as i hit an arrow key pac-man starts to move and so do the enemies you can hear that every single time he eats a pellet there's a noise every time he moves his mouth opens and closes so he animates i can't go through walls once you get a power pellet those ghosts turn blue when it wears off you can see the ghost is flashing blue and white and then i can go around my level here as you can see i'm colliding at the walls nothing bad's happening i can eat those pellets and as soon as i eat that last pellet it says you win and it plays that iconic pac-man music that's normally at the beginning of the level but i put it at the end of the level when you win then if i collide into an enemy i get game over and also you'll notice that when i get game over or i win it pauses the game so the enemies stop and i can see where i lost so this is where i ran into the enemy when i got game over and it plays some music as well if you enjoy my tutorials please subscribe like and share some of the topics i'm going to be covering in this video are creating a tile map what you see over here this level that's a tile map it's going to be 100 customizable from the code you don't even have to create the same map that i create you can create your own version of this map any size also it lets the ability to add additional levels so you could have multiple levels once you pass this level maybe you go on to a new level that looks completely different we also take keyboard input so when pac-man moves he moves in a continuous direction if i hit left he continues to move in the direction if i hit down and then right once he gets to the bottom he will move right i got lucky there and ate that ghost by the way there's animations as pac-man moves his mouth opens and closes when we're in a new game like this you can see that the power palettes flash pink and yellow and then also the ghosts as the power pellets wear off they flash blue and white these are the animations that we'll be implementing there's also collision detection that ghost that i just ate while he ran into me he collided with me and i ate him this ghost if i fly it into him well that's a collision where i actually lose and pac-man dies the other collision detection too are the walls i can't go through any of these brick walls there's also collision detection when i'm eating these pellets or eating power pellets i'm detecting that collision and then doing something we need a yellow pellet i just make it disappear off the screen when i collide into a ghost well you can die or you can eat them also sound sound is extremely important any time i go over a pellet you hear a sound when i run into a ghost you hear sound the game over music so sound is extremely important for that immersiveness of your game and our enemy ai we're implementing a very simple enemy ai they move randomly sometimes they look like they're chasing you it's kind of like when you play music on shuffle and you think it's playing all your favorite music that day it's just pure coincidence and that's exactly what's happening here every once in a while it looks like the enemies are chasing you but they're not it's just a random coincidence they happen to be going in that direction before we get started this is what the final solution will look like as you can see we have several files to represent the different parts of the game here in our src directory we have our enemy we have pac-man we have the game moving direction as utility and the tile map that i spoke of which builds out the level all being driven through our index.html which is our main entry point for our application so as you can see over here we're using index.html and that is where everything runs through and then we have a little bit of organization as well for our folders so we've taken our code and put it into this src directory we have a sounds directory for all the different sounds that we have within our application and then we have our images as well if we really wanted to we could even make more directories inside images to represent the ghost or pac-man but this for now for this smaller game seems to work fairly well for this tutorial we're going to be using visual studio code if you don't have visual studio code just go to google type in visual studio code and go ahead and download it otherwise you can use any editor for this tutorial we're also using chrome here so i got chrome on my right hand side and visual studio over here to get going we're just going to want to open up a blank folder to do that we could just click open inside visual studio code and then inside here you can see i have snake green blob these are previous tutorials that i've made great thing is that green blob is your introduction to game development snake takes it to the next level with a little bit more complexity and then pac-man takes it to an entirely new level so what we'll do is from inside this folder we'll just call this pacman i just made it all lower case click open and then visual studio will open up to this new project that we have where we don't have any files yet let's get started by setting our project up so first thing you could do is go ahead and close that welcome screen i'm also going to click this button over here just to so open editors don't appear here and then underneath pacman what we'll do is we'll go ahead and start adding some files that we need so click the new file button and we'll add index.html and then we're going to add a folder called src and then inside src we're going to go ahead and add all these blank files that we we don't have yet but miners will add them anyways so we're going to add an enemy.js we're going to add game.js glad moving direction so these are all things we haven't implemented yet but what i want to do is create them all now so that we don't have to do it later if you don't know what you're building you wouldn't know these files but because this is a tutorial that i prepared ahead of time i can tell you exactly which files we need so there's the files that we net we have we have five files with no code inside them right now so inside our index.html we're gonna kick off this this html that we need it's gonna be very little html because most of the code is actually coming from the source code over here inside of our index.html all we have to do really is put an exclamation like that and then if you hit tab on your keyboard it will create the html template for you then inside of the title we can do is we can put pacman just like that and then inside of our body we're just going to put some really simple html and that really simple html that we're going to put is a div inside there we'll put in h1 we'll put pacman just like we did for our title and then we're going to put a canvas this is where our game is going to be drawn so if we take a look at our canvas we're going to add an id and that id we're just going to call it game canvas and we're going to use this id in the javascript in order to access this canvas and then draw to it and then we're going to add a script file we're going to start off by just adding the one script file our script file is located so our index.html is outside the folder since it's outside the folder we need to go inside that folder src and then inside src we're going to get game.js and then this because we're going to be using something called imports and exports we're going to have to call this type a module very important that we have this module here so you need this type equals module for the rest of the code to work and this kind of sets up our basic html next we should display our html we want to see that title pacman over here on the left hand side and we could open up the index.html file locally on our computer but i think a better way of doing it is to use something called live server it's an extension for visual studio code and every time i click save in visual studio code it'll refresh over here it makes development so much faster so to get that extension go to extensions over here in this box up above type live server find live server and click install i have it installed so my only option is to disable or uninstall then when we go back to our project you're probably not going to have this button available right away when it's a new project what you can do is you can right click on the file and say open with live server click that and then over here it'll open up the html that we're currently working on to show you how this works once it's already open it's going to show us which port it's using so we're using port 5500 and you can see that in our url it's one two seven zero zero one which is our current computer and then 5500 is the port and the page that's opened is index.html so to show how this works if we just delete part of our title instead of pac manager says pack and then we undo that and then click save you can see it just refreshes the screen automatically another quick little extension that you can install that i currently have installed is every time i click save you see that it gets reformatted so that all the code looks nice so go to extensions look up prettier find prettier code formatter click install and then once you have it installed you got to do two things one is go to settings look up save check that check box so it says format on save then look for code formatter and then what i've done on my machine at least is i've changed this drop down over here to say prettier code formatter so then it uses prettier to format my documents then just as i showed you go back to our index.html and i add additional spaces or things like that change the indentation it changes it to match a very specific format now that we've got our live server running our extensions installed let's make this look a little bit nicer inside of our head we're going to go ahead and add a style tag so that's style tag over here we'll add and the first thing that we're going to format is our game canvas so let's go ahead and add some formatting to our game canvas as you can see our game canvas has this identifier so we use that identifier up here with a little hash in front of it to say that we're using the identifier and then for the canvas we're going to go ahead and add a box shadow that box shadow we're going to set to 10 pixels 10 pixels this is the position of where it's going to be and 20 pixels and then a color black and then our box will appear here so it's always been there we just couldn't see it but as soon as we added a shadow below it kind of makes it pop up the screen and just gives it a nice visual effect we can also style our body and we're also going to style our h1 so let's start with that h1 it's a little simpler for the h1 we're going to text align center so now you can see it goes center then we're going to give it a different font so the font that i want to give it is something a little bit more fun the font is going to be comic sans so let's look up comic sans ms when i click save you can see how that changed if i get rid of that you can see it changes because it's a game this seems pretty appropriate and then we're going to change the color because the background is going to be a dark color so let's just make that light gray lastly we'll go ahead and style our body for the body we're going to go ahead and add a few properties one is we're going to display a flex so right now if we take a look at this our canvas is always on the left hand side we want it to be centered so we're going to use something called flex so once i add the justify content center and the flex then it becomes centered just like that the other thing is just in case scroll bars appear i don't want them to take away from the game experience so i'm just adding an overflow hidden you this is optional don't really need it but just in case scroll bars appear this is going to for the height we're going to send it to 100 vertical height this is going to affect the background color now the background color i don't know how to do this off the top of my head but i normally look this up and there's a lot of tools out there that let you kind of create a linear gradient and they're all visual tools and it's really great and really easy to use so normally i would just copy and paste the values from there what i have here is something that i kind of created earlier but if you just change these numbers you can get so many different effects and i'll show you an easy easy way to change these after you type this in so we're going from a blue color to this purple color and let's just fill that in right there with these numbers so basically we're saying start at zero percent with blue then go to purple now if we want to change these you can hover over these little colors inside visual studio code of course and then we can go ahead and change this so now this color becomes green save it and then our pacman looks like this so really cool how you can easily change it from here and that's it and then you can play around with these numbers if you wanted to as well and provided you type it correctly it'll do different things so you can see that looks even cooler yeah and that's just that's just one one way of setting up your linear gradient background so now let's just kind of undo what we had there we'll just kind of go with the sample that we had before with the purple and the white text now that we have our setup out of the way we can focus on making our game so in order to start programming we're going to jump into a game js so gamejs over here and our src will be our entry point for our application inside game.js we're going to get a reference to our canvas we'll define a constant called canvas and we're going to find our canvas by the element id the element id that we defined it as is game canvas so game canvas we're going to pass that into our git element by id i'm going to minimize this over here and then what we're going to do is we need to get a reference to our context from the canvas simply achieve by going get context on our canvas and we can ask for different kinds 3d and 2d so we're going to use 2d and then we need to define a game loop now a game loop to be any function i'm going to call a game loop could be called game and what it's going to do is it's going to basically redraw the screen a certain number of times every one second in order to achieve that we're going to use something called set interval set interval calls a function every x period of time and it takes in milliseconds so we're going to take in a thousand milliseconds which is one second and then we're going to divide by 75 so that we know that we can call this method 75 times every one second to redraw the screen now the game loop is the most important part of our application it's going to run every single time to update the screen so in order to show you how it's working i do have my console open here but to get to this console you can go to three dots over here in chrome go to more tools and then go to developer tools and that'll pop up your console it might be on the left right normally it pops up on the bottom but if you want to put in a different place click the three dots on that pop up and then decide what location you want to put it at then click on the console tab over here and then what we're going to do inside our application is we're just going to console.log gameloop so you can see that it's being called and now in the console you can see that we're calling game loop over and over and this is happening 75 times every one second in order to refresh our screen next we're going to build our tile map so let's do a bit of that setup first inside of our game js we're going to want to call our tile map and get our tile map to draw the screen in our game loop so the way we're going to do that is we're going to import something so this is going to be the concept of modules and importing and exporting we're going to use it very simply so in our tile map if you don't know the syntax yet you're going to learn it so in our tile map we're going to export a default item here and we're going to export our class map so tile map recruiting class called tile map and then that tile map we're just going to just give it the bare description over here they have a constructor and it's going to have a draw method that doesn't do anything yet and inside the draw we'll just call draw we haven't done anything we haven't drawn a tile map yet but we define an empty method called draw and one other piece of information that we're going to want to give to our tile map is how big each tile is going to be so it's going to take in something called a tile size so inside our constructor we'll set up our tile size and we'll say that's equal to tile size now that we've exported this we're going to import it so if we go on over to our game over here at the top of the screen what we're going to do is we're going to do something called an import and we're going to import the tile map from and we give it the location of this item so the location of this item is in the same directory so we put a dot right there we say slash then it's the name of the file tile map and we use dot js at the end to make sure this is working we're going to do the following so after we've defined our canvas and our context we'll define another value called tilemap with a lowercase t is equal to new tile map so we're going to initialize our tile map and if you remember our tile map has an item in its constructor called tile size so in addition to that we're going to define a tile size we'll do that at the very top here and we're going to say tile size is equal to 32 and i'll be explaining shortly why we're going to pass in our tile size to our tile map and then make sure everything is saved as well and then over here in our tile map what we're going to do oh little typo so be careful to make sure you type everything right you can see i got an error tilemap is not defined at line six so over here at line six it's saying that this doesn't exist and it doesn't exist because of the typo that i have over there that m was a lowercase m and now it's a capital m now you can see it's still printing my game loop and it's working so we know that part of our application is working always important to see any errors you see in your console and fix them right away otherwise you'll be fixing lots and lots of errors you want to always kind of code in a good state so then to make sure that this works we can say tilemap dot draw and call that function and remember inside the draw method we printed out draw so now that we can see that working we know that our tile map is essentially doing something all right next step is to implement our tile map so our tile map i'm just going to comment out actually our draw method over here i don't want that continuously printing to implement our tile map what what is a tile map well i have the original game right here and the game is actually created with images and each image is 32 pixels your images could be any size that you want but that's the size that i've chosen here for this tile map this is built basically with little squares so each square is 32 pixels and contains a different image at the top we have about 13 bricks over here we have one brick and then we have a whole bunch of dots and each dot is its own image as well except it takes up you know most of it is a little yellow in the middle and the rest of it is the black to better illustrate this i've created an image and what i've done is shown you that there's little blocks and these little blocks are different little images each one of these squares just as i said so there's a roughly about 13 above then over here there's the dots you can see pac-man is its own image as well that is 32 pixels the power pellet is 32 pixels so that's kind of what a tile map is and you build a tile map using an array so we're going to create an array inside our tile map that's going to define what the map looks like and this will be completely configurable and you'll be able to manipulate this to basically make your own maps which could be any size i've just chosen this number of blocks this way this number of blocks that way but you could add even more rows make your columns have even more columns to make it as big and as complicated as you like let's get that code started for the tile map so inside our tilemap file what we're going to do is we're going to define an array we're going to call that array map and then this array right this array is going to represent this entire array here and then we're going to have rows okay so we have an array of arrays so each array so let's go here if we add another array so we have brackets inside brackets it looks a little confusing but it's gonna it's gonna be clear soon what we're gonna do is we're gonna sign a number to say what each item is so bricks will be number one pellets will be zero so going back over here to our array we know that the very top it's all going to be bricks so it's all going to be ones so what i'm going to do here just to match the example that i have is i'll put about 13 of these ones over here just to match the example that i have and one more okay so far we've drawn the first row the next row so i'm going to do over here is i'm just going to expand this just so i can get inside here is there's going to be a second array so we put a comma and i'm going to copy that one there i'm going to paste it now for this row over here there's only one brick on the end and one brick on the end everything else we're just going to make a zero for now so everything else is just going to be a pellet then what we can do to overwrite all of these here one quick way would be to highlight the one then on mac you would hit command d and you'd see it adds all these cursors if you're on windows hit control d and just continue tapping it and it keeps adding a new cursor then you see i have all these cursors here that i can move in unison i can then highlight the previous number put 0 and then hit escape to make all those cursors go away so now i have two rows i've built the first row and the second row now i'm not going to build out all of these the same what we're going to do is we're going to start off with just a whole bunch of coins and then we'll add the other bricks after we'll just do a few rows here and then at the very bottom what i'm going to do is i'm going to copy what we had at the top and then paste that at the bottom so what we have here is you can see all ones all along the outside so that's our walls and then inside we're just gonna have pellets we'll just click save on that and then our prettier formatter if you set that up earlier will format this really nicely so it's easier to look at all right so before we draw let's go ahead and add a new folder called images click on index.html then click that folder so it's on the outside of your src directory call it images and i'm going to provide a way to download those images in the description so for now i'm just dragging in the ones that i need and you'll be able to do the same from the description by getting those assets so let's see i'm going to go bring in a few images we got our pink dot our wall and our yellow dot if i click on those images you can see it's just a 32-bit image you can actually see that here at the bottom visual studio 32 by 32 and yeah it's just one image for the bricks and it just comes together to make this cool uh brick structure around the end of our thing and then uh the pink dot and the yellow dot pink dot slightly bigger than the yellow that's for the animation and then the yellow dot over here is obviously our pellets that we can eat so step one of drawing our tile map inside of our tile map inside the constructor over here we're going to get some references to those images because we're going to need those so we'll say this dot yellow dot is equal to new image and then we'll say this dot yellow dot dot so we want to set up the location of that images so we are in this country src so we need to go up one directory so go dot dot then we need to go inside the images directory so we put images there and then we go yellow dot and it's yellow.png and then we need to set up our wall as well so we say wall is equal to new image do the same thing we say this dot wall dot src is equal to and then slash images and then wall dot eng and then we have our images set up all right before we can draw our canvas the first thing we're going to want to do is to resize the canvas to fit whatever shape this is going to be so if this is longer shorter or whatever we want this size to change right now it's just whatever the default size is so we're going to want to see that changing on our screen so in order to do that what we're going to do is we're going to define a method on our tile map and we're just going to call this one time so if we kind of go from the beginning of our application we go to our game over here before we we don't want to do this with every single game loop there's no point might as well just set the size one time so the way we can do this is we can ask our tile map we're going to actually tell our tile map to set the size and we're going to create a method called set canvas size and set canvas size is going to take in the canvas itself and then we'll get an error because it'll tell us that the method doesn't exist so what we'll do is we'll copy that method name go into our tile map and you can put this method anywhere but i'll put it here at the bottom and we're going to set our canvas size it's going to take in the canvas and then all we have to do inside of this method over here is just set up the width and the height based on the length of our map so to set up the width we're going to have to look at each row we have an array but we want to look at like the first row because they should all be the same size and then build our canvas out to be that big so in order to do that we say canvas.width is equal to this dot map and then we're going to access that first row of data inside there we're going to get its length and then we'll say times this and then we know how big each tile is each tile is 32 pixels so if we get the rows over here and we know how many there are we times it by 32 and then that will give us our width so you can see that on my screen here that my map actually got bigger there so now it's like a rectangular shape like that so let's get that height on there so we can say canvas dot height is equal to this and now to get the height we just need to know how many rows there are to get the number of rows we don't access the first item we just say how big is this array how many rows does it contain well that array will contain that times and once again we need to times the number of tiles there are or the size of the tiles and you can see that got bigger if i delete a bunch of these rows you don't have to do this and then click save you'll see that it just gets bigger and smaller so this will allow us to create different level sizes and different complexities and allow our canvas to grow and fit that shape all right here's the exciting part we are finally going to draw something to the screen so let's do this so inside our draw method we're going to want to loop over our map we're going to use the concept of rows and columns so what we'll do is we'll define a row count over here and we'll just say that's equal to zero and we'll say well the row is less than this dot map dot length so that's the number of arrays inside of our map over here so from line 13 to 23 and then we'll just increment that that row then inside of each row we're going to loop over the number of items inside it so that would be the array so the first row we're going to loop over we're going to say 4 let and we're going to call that a column and that column will be equal to zero and that column will be less than this stop map and now we're accessing that row and then we're getting the length of that row and then we're gonna go column plus plus and then inside of that row we're going to get the tile so we're going to say each cell like this or this or or this item here is going to be called a tile what we can do is we can say let tile equal to this dot map dot row and then check this out we use our columns that nice little loops that we have here translate into getting this variable for us i guess we give it the row and we give it the column then we can take this tile and decide which kind of image to draw so the value of this tile is going to be one or zero right now if the tile is equal to 1 we're going to draw our wall and we'll use curly braces just makes it a little bit easier to read so let's say this dot and we're going to create a brand new method called draw wall and i'm using this new notation with the hash over here to denote that this is a private method it's no different if we do that really there won't be anything noticeable in our application it's just a better way of writing code if you're like this method should not be accessible which means that technically in the game if we went to the game over here i shouldn't be able to call this over here so i shouldn't be able to say tilemap or whatever it should not let me call any method that starts with the hash because it's private and should only be used internally so going back to our tile map over here so now we're going to draw that wall okay so let's go ahead and implement that method so it gives us an error letting us know that draw wall is not implemented it doesn't really matter where you put it i'll put it below the draw method and we'll have a draw wall and that draw wall is going to need some information the information that we're going to pass the draw wall will be the ctx the column the row and the size and the size is just going to be this dot dial size for now so there's there's really no different size or anything that we're building here we're giving it the ctx row and column so column first then row and then the tile size so then we go over here we have to define our function so just the same things that we just typed up there we have ctx we have column we have row and we have something called size now all we have to do is take that ctx and call draw image and then inside of draw image we're going to give it the image that we defined earlier which is our wall so we'll say this dot wall and then we have to give it over here it says our x position so our x position will be the column so that's our left to right and then we figure that out by using the tile size that we defined earlier so that will position us in the right place then we take our row and we say this dot tile size so same thing we're setting up our y position and then the size of this image we decided to just use that so the size is going to be a width and a height so we have to put that number in twice over here because our width and height will be the same that's pretty amazing we have something being drawn on the screen so our walls are now being drawn which is really really cool next we can go ahead and draw our pellets so we can say else if the tile is equal to zero let's go ahead and draw our pellet or our dot we'll call it a dot in our code here so we'll just do another function called this dot and we'll give it the pound again just making this private we'll say this.draw.dot and we give it the ctx we give it the column we give it the row and just in case we wanted things to be different sizes we can pass this in and then for our draw dot we're gonna do exactly the same thing so if you really want you can copy and paste that if not you can just type it out but you can just probably copy and paste that so draw dot same thing ctx column row and the size and then what we do is pretty much the same and we're just going to say draw image and then say this dot yellow dot and then we give it the column times this dot tile size and then row times this dot tile size and then we need to give it the size of the width and the height which are exactly the same and then we save that and we have our map not exactly the same map but we have our map set up let's go ahead and make this map look a little bit nicer by adding more walls so we have all the coins in the middle so that's really really cool what we could do now is kind of like update update our map to emulate something that we had in the original one like this over here i'm sure enough we could code probably some kind of editor or whatever this is this is a form of an editor but you could probably have something where you click click click click click and the numbers change or something like that so what we'll do here is we'll kind of just quickly build this out build it out however you want but i'll just show you a quick example of how i'm going to build it out so i'm just going to same trick here i'm going to use command d command d or control d on windows i'm going to change the value of these to 1 over here just to make like a little column and then what i'll do over here is probably just type these in because it's a little bit easier and then i'll just type one over there and one over there and then one over there so you have this nice little row and then let's hit save to see what we got so far and you can see we've started to build out our map hopefully you're doing this as well too it's really cool just to see it being built out and then along here let's do exactly the same thing too so what you could do is just put ones oh not there that would be that'd be the wrong place that was just about to put that so every time i hit save i could see the change so there you go we got a brick we got a brick brick and then brick so we're building like another little another little line there kind of like the example that we had yeah and we can kind of build this out however you want i'll just pause here for a quick sec and build it out and be right back all right here's the final little example that i've created so far i'll make sure to paste this into the description so that if you want to just copy the one i have but you probably won't want to because it's kind of fun to go ahead and just make your own so give it a shot it's just so cool to be able to change these numbers here and see that reflected here one extra thing that we can do to visualize our tile map is just add a little bit of code in our tile map in the draw method so in the draw method what we're going to do is every single time we draw one of our tiles we're going to draw a little border around each tile so we can actually visualize how it's adding these items we'll use ctx and we're going to do something called a stroke style and which just basically sets the color that we're going to use for our stroke and we'll use yellow then what we do is we're going to draw a rectangle but we're not going to do a fill rectangle we're going to do a stroke rectangle which means it'll draw an outline and then all we have to do is give it the column we need the x position which will column will be this dot tiles times tile size then we get the row with this dot tile size so that finds our y position to put it and then we have to give it a size so for this we can just use this dot tile size and this dot tile size save that and then look at this we get a visualization of each and every single piece that we drew so as we traverse over this for loop we're going to go left to right so first we draw this brick then we draw the next brick the next brick until we've drawn that entire row then we go ahead and draw the next row where we draw a brick and then a dot and just continue going along that path but now you can see how this map is broken into tiny little tiles each representing a 32 by 32 square in order to draw this map and then what we can do is we can just comment this out and leave this here for whenever we want to visualize how this map looks and where those little squares are the next thing that we're going to focus on now that we have our tile map drawing to the screen is getting pac-man on the screen pac-man's going to be a little bit complicated there are a number of things that we need to do which include displaying him rotating him collisions but we'll break those down into small steps that we can achieve so for the first thing that we want to achieve is displaying pac-man now whenever we play pac-man we can have different levels and those different levels pac-man could be in a different place a different starting position we'll start with that starting position in mind we're gonna let our tile map help us with that what we're going to do is inside of our tile map we're going to define where pac-man starts and once again we'll just use a number for that so in our little example over here we'll get pac-man to start somewhere at the beginning of the level and we're going to give it a number 4. we didn't define what happens if we don't know what a number is so all of a sudden we get this blank spot on our screen where it didn't draw that's actually really good that we're seeing that we're gonna do over here is also in our code we're just gonna make a little legend we're gonna say one one is walls zero is we'll just call them dots for now and then command will be number four so that's where that where that dot is next is in our main application within our game js what we're going to want to do is define pac-man here this pac-man will have its own draw method in that and we'll need a way to get pac-man after we've defined our tile map now our tile map is kind of dictating where pac-man comes from so we'll also let the tile map create pac-man for us so we'll create a constant called pacman and we're going to use tilemap dot get actually that's a capital dot get pacman and get pacman will include some additional information that pac-man needs for its creation which will be its velocity and above our or below our tile size we'll just define one of these other parameters here called velocity maybe i'll put a gap between these kind of different components here that we have so our velocity will be equal to one that's just how much pacman will move every single time the screen gets updated during this game loop this is going to let us know that the method is not implemented what we will do then is we'll go into our tile map and we're going to implement that new method we'll implement it below all the drawing stuff here so we'll implement get pac-man here and then get pac-man as we mentioned takes in a velocity which is just some information it needs when it's constructed and what we're going to do is we need to find where pac-man is before we can draw it so we're just going to loop over our collection just like we did before very same thing we're going to find all the rows and then for each row we're going to go ahead then and loop over the columns and each one of those columns we'll just do column is less than this.map and then the row.length just a little bit repetitive but looping over that and then inside of that column we get our cell and our cell is our tile so we say our tile is equal to this dot map and we just give it the row we give it the column and then just do an if and we say if the tile is equal to number four that just number four we're going to get pac-man here we're going to build pac-man actually we'll return pac-man back to the user so what we'll do over here is we're going to return a new pacman object to get pac-man so pac-man doesn't exist just yet one is we're going to need to import it so this is back to our importing and exporting so we're going to get something from another file we need to import and we're going to import pacman from and we're gonna go current directory so that's what dot means and we're gonna go to the pacman.js file so that's the file that's over here then if we scroll on down to our method we're returning pacman and then when we return pacman as well we're going to replace this spot on the map so this spot on the map contained pac-man if the spot on the map contains pac-man we're gonna set it to a dot we're gonna set it to zero so if we for example get rid of this over here and then we go to pac-man we just need to do an export so we're going to do the same thing here we're going to export default pac-man and then that needs to be a class and then our curly braces at the end to define our class now where pac-man was that just got replaced so let me show you over here i'm going to get rid of this here so we found pac-man's position and then we're going to replace it with a pellet because wherever pac-man starts he'll also be starting on top of a pellet so now we're going to return pac-man okay and pac-man needs about a bunch of information it's going to need to know its x and y position so we can figure out the x and y position by taking the column that we found and the row that we found and then timesing it by this dot tile size and then we do the same thing for the row we say this dot tile and i'll minimize that dot tile size save that and then the other thing that's going to know is how big is its tile so it needs to know the size so this dot tile size and then it needs to know the velocity which is that extra information that we passed in and then we can also give it a reference to the tile map so for future reference pacman will know about the tile map so you can figure out if he's colliding with something so this is a lot of information that we passed into pac-man so what we can do here to make this easy to see is we can copy that just for now and then we can head on over to the pacman file and then what we're gonna do is this i'm gonna minimize that and i'm just pasting this here if you highlight everything and if you hit control question mark it will comment it out on a windows machine on a mac machine hit command question mark and it puts a comment like that because we don't need that information and what we've done here is when we construct batman pac-man we need these fields in it so we go ahead and add constructor and we know that's going to be the x position the y position so that's the x is the column the y is that then there's going to be a size or the we can also call it tile size and then there's the velocity and then there's the tile map so then all we have to do is set all those things up on our object so we connect those things to our object so we're connecting the x connecting the y connecting the tile size is equal to tile size then there is the velocity as well that we need to connect and lastly this dot tile map and now we can go ahead and delete this over here because we don't need it anymore that was just for reference next we're going to go ahead and copy in the images that we need to represent pac-man we have three images to represent pac-man those three images are when pac-man's mouth is fully closed batman's mouth is partially open and then also when pac-man's mouth is completely open and we'll also go ahead and add a draw method that draw method will take in a ctx just like that and then back inside of our game.js all we're going to do inside of our game loop after we draw the tile map is we're going to tell pacman to go ahead and draw and pass in that ctx of value now we can go ahead and start to load those images so what we're going to do to load the images is we're going to create a little method over here this method is going to be another private method and we'll just call it load pacman images right there and then we can just copy that name there as well go define our function we can define it after the draw a method that we're going to define we need to get references to our three different images that we have pack 0 1 and 2. so the way that we're going to get reference to those images is we just do the same thing we did before we define a constant and we say pacman image 1 is equal to a new image pacman image1.src is equal to wherever that image is and that image is in images slash packpack0.png then we're going to define a few more of these actually we're going to define four this is going to come back later when we're animating but for now we're going to define all of these images so rename all of these appropriately so i'm going to rename this to 2 and rename this one to three and i'll rename this one to four we just need to also rename these over here now what about this we only have zero one and two well that very last image over there is going to be used when we do some looping before for the animation as we loop over the animation items so i'm just going to define that as number one but it will make sense a little later on but for now we'll you could start off with those three and then add the fourth one later but i'd rather add them all now because it's gonna be required for how we implement the implementation then the only thing that we really need to do is we need to just create an array of all these images so all of these are just defined inside here with these const but to attach it to the object we have to use this we use this.pacman images is equal to an array and we give it the pacman image1 the pacman 2 pac-man image 3 and pac-man image 4. and then the only last piece of information that we're really going to need to know is which image are we currently using so we'll call that pacman image index and we're going to set that to a number we'll set it to zero that's going to be the first image we'll start with pacman fully closed so that's what we'll be using okay so then the next step is that we actually need to draw to draw pac-man we're gonna start with the simple way of doing it so the simple way that we're gonna draw pac-man to start off with because later we're gonna deal with rotations and changing pac-man if you've noticed so far the pac-man images that we have they only face one direction they're all facing right we need them to go left down different directions and that's what you saw in the pac-man game that we had earlier but we're going to use one image and rotate it which is going to be very very interesting before we can do that we need to just get pac-man drawn on the screen and we need to get pac-man moving so we're only worried about that later but for now go back to pacman.js inside the draw it's going to take in a few things so one is we have access to all our pacman images that array that we made before then inside that array we're going to say axis the pacman image index so that's the current image that we want to display just like the other ones we need to give it the x position the y position let me actually minimize that so x position y position and after those ones we need to give it the size so we're just going to use this dot tile size and this dot tile size so that's the size of pac-man and then we get pac-man on the screen if you want to show a different pac-man image let's go into our load images scroll on down see the pac-man image index let's change that number change it to one his mouth is open change it to two his mouth is completely open and you can see remember we did think to draw the dot behind pac-man well pac-man starts off with a dot already there it's right there on the screen which is kind of cool you can see our image has also got some transparency on it because we can see behind pac-man to see that dot next we're going to implement moving pac-man so pac-man's kind of interesting in how he moves so if we take this diagram over here if we told pac-man to start moving left over here he'd be moving in this direction as soon as if he's on top of these bricks over here and we head down well he's moving left he's not going to go down he's going to continue to move left until he gets to an empty space then he'll move down so his current direction will be left and then requested direction will be down which means we need to keep track of two variables for pac-man's movement the current direction and the requested direction that's something we'll be doing now as we implement pac-man moving on the screen to get pac-man moving we're going to set up a few things one of those things is we created a file earlier called moving direction so far let's go finally implement that because we're going to be using these values to track the direction that pac-man is going in what this is simply going to be is just an object called moving direction and it's just going to have several properties it's going to have an up represented by zero a down represented by one left represented by two and a right represented by three and i mistyped that one over there so that's two then all we have to do with this value that we create over here just like we've done in the other files is we need to export it so we'll just export the moving direction inside of pac-man what we're going to do is at the top of that file we're going to import it so pac-man file is going to use the moving direction we'll just do import moving direction my auto fill over here but if you're typing it out from and then dot and then slash moving direction remember dot means the current directory that file is in the same directory as pacman so all i have to do is just put a dot a slash and then the name of the file so the only thing i'm missing here is the dot js errors right now so i'll just also open up our console here just to make sure that we're not getting any errors so we're all good at the moment so what we'll do now and make sure you click save on your files so that you know you're not getting an error make sure you don't have an error and let's continue as i mentioned before pacman's gonna have a current moving direction and a requested moving direction so let's go implement that go to pacman or go to our constructor and inside our constructor we'll just add those values i'm going to add that after these initializations over here i'm going to say this dot current moving direction is equal to null so we're just going to say it's empty and this dot requested moving direction you can see these variables are very descriptive so that you know exactly what they do what we're going to do is we need to take keyboard input so now what we're going to do is access the document and we are going to add an event listener we're going to listen for any events for the keyboard and we're going to listen to a particular one called key down and make sure that this is key down with a lower d and i'll hide this over here key down with a lower d very important so that event fires we're going to create a brand new method that doesn't exist yet called key down it's same name as that except we have a hash in front of it meaning that it's a private method to make these things just a little easier here will just collapse really nice being able to collapse your code so it's easier to see below here we'll just continue putting all our private methods at the bottom we'll add a new one called key down and the key down function does take a parameter inside of it and that's going to be the event we'll write our function like such um actually and we're gonna we're gonna make this an arrow function the reason for that is we don't want this to be the wrong thing we want this to always be equal to pacman that may be a new concept so anyhow we're gonna take in an event and we're using an arrow function over here inside of our arrow function when it gets executed this will always represent the pacman object so we have access to these variables if we weren't doing that then there's a good chance that this will be equal to the dom element who's invoking the key down method now all we want to do is capture all our different events we want to capture our key code so when a keyboard event fires when you need a key code and the key code number 38 is actually equal to our up arrow you can also map these to your wasda keys the wasd which traditionally you use for gaming but i'm going to hook it up to the arrow keys so it's a little bit more old school that way so here we go we got our key code we're going to get our up key and we're just going to implement all the keys here so i'm just duplicating these lines over here and we're going to do line 40 is going to be our down key 30 let's see what the next one is 37 so 37 is left and then uh 39 is right i'm just adding comments above them so we know exactly which key is which key so we got all of those saved there prettier is formatted a little bit nicer and now once we've done this we can start to actually capture that input and do something with these moving directions that we have what we're going to do next is actually set the variable for the current moving direction and the requested moving direction so inside of our up over here we're going to do is we're going to say if this dot current moving direction is equal to the moving direction that we imported we'll say moving direction dot down then what we're going to say is this dot current moving direction will be equal to moving direction dot up so we're doing here is if you're already moving in the down direction you can switch to the up direction so we're going to switch your moving direction to up otherwise it we're just going to leave it so let's go ahead and do that and then we'll say this dot requested moving direction is going to be equal to moving direction dot up so this is the direction that you're going to request like i said if you're moving down it's okay to switch to up but if you're moving in a different direction well we're gonna check the requested direction and then maybe set it if you're allowed to move so pac-man's movement is a little bit more complicated than other parts of the game and then this pattern that we have here we would repeat for the down the left and the right so you're allowed to go the opposite direction but if you're already moving right and you request to move up we don't want to move you right away we're going to do a check later to see if there's a collision a wall in the way before you're allowed to move in that direction for the down we're going to do exactly the same thing so what we can do is we can actually copy this over here and then inside of the down we can say if your current moving direction is up then you're allowed to go down because you're already moving in that direction then your requested direction is going to be down like that then we can copy this again and we implement the same thing for left so if we say if your current direction is going right then you're allowed to go left because clearly you've moved away from the left area if not we're going to capture the fact that you want to move left but you haven't been allowed to move left yet because maybe there's something in the way and then we do exactly the same thing again for the right if you're moving left currently and you request to move right that's okay with us you can go ahead and do that because you were on the right side if not if you were moving up or down and all of a sudden you asked to move right we're gonna check this comes into play when pac-man is moving here's pac-man here if he starts to move left then i hit down well we're gonna say that's your requested direction because i can't move down yet can't move down yet but once i get here i'm allowed to move down if i'm moving left right now and i hit the right key over here because my current direction is left and i just requested to move right well i know that there was empty space on the side so of course let's go ahead and just automatically set your moving direction to right and then you can start to move in the right direction to get pacman moving we're going to implement a method called move so if we scroll on up to the draw method we're going to go ahead and add a brand new method called move and move will be in charge of moving pacman i'm shooting a little typo error there and then we're going to implement this new method might as well put it with the rest of our methods down here that are all private i'm going to collapse that and we'll add this move method and move there are a few things that we're going to do with pac-man one before we get pac-man moving i'm going to head on over to the tile map and earlier we implemented some code that i'm going to uncomment have this code right now feel free to type it out but what this is doing is it's overlaying our tile map with a grid when pac-man moves he never really moves in between a grid item he's going to move all the way inside of a grid so in order to figure that out we'll have to do a little bit of math fortunately the math is pretty simple we're just going to figure out if pac-man wants to move down you can't move halfway through a square you have to move when you're perfectly aligned within one of our 32 by 32 squares so let's go ahead back to pacman and i'll minimize that there and inside our move method let's implement this logic first thing we're going to do is we're going to check whether or not we can change or set the direction of pac-man when pac-man starts if i hit any key right now on the keyboard what's going to happen is the requested move direction is going to be set but the current move direction will never be set so the first thing that we need to do is to check if the current moving direction which is going to be null initially is equal to this dot requested moving direction if it is first we need to check if pacman's current position using number is an even number divisible by 32. so we're just going to check if the number is an integer if it has no decimal points and the way we're going to do this is we're going to take the x position and divided by the tile size and we're going to check the x position and the y position essentially i go ahead and do the same thing here i go number dot is integer and i give it this dot y and then we divide by this dot tile size and if i hit save we can see we're doing this division over here and if that is true then what we're going to do is we're going to say the current moving direction is allowed to be set to the requested moving direction when that happens so this is just our first kind of block of code inside here to get the current direction all set up with that set up we can then implement a switch statement so this switch statement will take in the current moving direction then depending on the direction it's moving in it's going to increase or decrease pac-man's x or y so that it begins to move on the screen over here on the switch let's do one at a time we're going to use that moving direction value so the way this works we pass in the current direction and then we say hey is this instance over here equal to up if it is equal to the up then what we're going to do is we're going to say oops let me get rid of that typo we're going to say this dot y and the way the grid works is if your y position is here if you want to move up you go negative going to move down you go positive because the coordinates of one of these grids is zero zero over here so x and y are zero then to move x this way you go positive go negative so here we go so we're going to use our y and we're going to say y is equal to minus equal this dot velocity and our velocity currently is set to 1 i believe so we'll go ahead and save that now if i hit up over here our pac-man starts to move that's incredible let's get this example going a little bit better now we're just going to grab the y position and we're going to do the same thing for the down so for that down we're just gonna put down inside there and then we're going to plus on the y so now let's go give this a try so now when i push down on pac-man he'll go down if i push up it'll go up because that requested direction so remember if i'm going down and i push up it'll immediately change directions because we don't need to do that check to make sure you're in a perfect little 32 by 32 space not in between something before you can move because we're just going to go the opposite direction now let's go get those other bases down so we're going to do left and right so if you're moving left we're changing the x position so this dot x and we do minus our velocity so we should move in the opposite direction and then our our right when you're moving right it's going to be a positive number because you're going right so since it's a positive number we just take that x and we say plus equals and then over here when i move i can move if i hit down it'll only go down when it's inside of that grid it's not something you typically notice unless you have this little grid here and it looks like i'm moving along the walls but we haven't implemented collision detection yet and our pac-man is moving a little bit slow so to speed up his movement we can go to our game where we defined a velocity so this velocity let's just double it doubling that velocity yes yeah that's much better now our pac-man moves really fast a bit more of a fast-paced game i can pretend that there's collision detection by trying to avoid those walls eventually when we head down pac-man will move the way he's intended to so right now if i were to hit down and this isn't going to work but let's pretend i hit down he should only move when he gets to that end and the same thing here that's why we have the requested direction we're gonna check for collisions and we're gonna make sure pac-man also can't exit the game area like he just did right now next we're gonna implement collision detection how we're going to implement collision detection is inside pac-man when we're moving and you request a different direction a direction that's not equal to the current direction the only way that we can set or change your current direction is if you're not going to collide into something so if you're moving let's say left over here i'm not and i push down it won't let me go down until i get to the end over here right now if i push it it just go down automatically so that's kind of what we want to do we want to check so entire time we're moving left we're going to say is there am i colliding with something when i push down am i colliding am i colliding i'm colliding until i get to here and we're not colliding with something so in order to do that we're going to need a check and that check that we're going to put is over here once we see that it's a positive integer value an even value we're going to check hey is this a brick is this a brick and the way that we do that is we're going to ask the tile map we're going to leverage the tile map to ask question we're going to say hey tile map did i collide with the environment we say did collide with environment pac-man's exposition pac-man's y position and the direction that pac-man wants to go in so the requested moving direction i'll save that so it's a little easier to read so first we do the if statement to see if we're inside a positive area then since i push down we'll say for my example here we'll check if there's something to collide with now we haven't implemented this method yet but remember we take the tile map inside our constructor that was the reason that pac-man knows about the tile map it's so that pac-man can say hey are we going to collide with something before i change my moving direction so over here we said this that tilemap did collide with environment if we did not so that's what the exclamation is for if we did not collide with the environment then what happens is we can change the moving direction right now if i click save and i try this it's broken so it's not working so now we'll go ahead and implement this method inside the tile map let's implement did collide with environment i'm going to copy the name from pac-man js over here i'm going to go to my tile map and i've kind of just minimized all these methods over here and then i'm going to add did collide with environment here it has an x a y and a direction and then what we're going to do is we need to use the moving direction over here i'm going to go ahead and import moving direction one thing to note it just automatically imported here for me might not do that for you i have some other extensions installed but just dot slash then moving direction for the current directory and make sure to put that js at the end if you don't put that js you're going to get an error saying that i can't find that file so just add that js there then inside did collide with environment we're going to do the following one we only want to execute this method if you're inside of one of these squares to check if you're inside one of those squares we do that same check that we did before where we say number dot is integer and we take the x and we divided by the tile size to figure out whether or not it's a decimal number and we do the same thing for the y as well then if once we're good over there and we are inside a square this is where we'll just do a little bit of work to go ahead and figure out inside the tile map which row and column we are inside here and then what's that number is it a zero is it a one is it a brick is it not a brick basically we want to know if there's a collision with something so the way we're going to achieve that we'll set up several variables over here we're going to set up the row we're using a case statement so we'll have to set up another variable called next column and we'll also set one up for next row and we'll just set all these variables to zero and you'll see how we use them over here in our switch statement our switch statement will take in the direction that comes from our method using that switch statement we're just going to set up a few of these we're going to do that using that import we're going to set these up so we'll start with right so if our case is right we're going to figure out our our next column and our next column so if i'm moving right over here and pac-man was stopped over here then our next column would be this brick over here so it's a positive number it's moving to the next direction so we're going to take the x position say this dot tile size then we're going to take the figure out which column we are inside the array and we're going to say column is equal to next column divided by this dot tile size do we move the pac-man over one to the right to check its position then divided it to get what that number is inside of our array and then the row is basically just going to be using that y divided by this dot tile size and then we always put a break at the end of our case because we don't want the next case to be executed no point and then what we're going to do is we're going to copy that and then for the left we do exactly the same thing for the left over here the only difference is when you're moving left it's a negative on the grid then we can go ahead and kind of copy and paste this for we'll just copy and paste the right one that we had and we'll rename this one over here to up remember when you move up you actually move negative this over here we're going to look up the next row is what we're actually interested in let's just we should have just deleted all of that that might be easier so the next row is going to be equal to y minus this tile size which means the row next row will be equal to this divided by tile size so we have our tile size and then the column kind of becomes like the other ones where we just use x divided by this dot tile size and then don't forget that equal over there and then this one's a little easier to copy and paste because all we have to do is just reverse the sign over there so we'll change that from a negative to a plus don't forget to change this part over here to down now that we have this data using the column and the row we can figure out which tile you are inside this map and the way we do that is we just style equal to this dot map we give it the row we give it the column and then once we have that we say if tile if it's equal to one that means we are colliding with a wall since we're colliding with a wall and the method name is did collide with environment we return true otherwise we're going to return false at the very end of our if statement over here so at the very end of our if statement after that curly brace we return false so right now there's a little bit of an error so that when pac-man can go through walls you may not always follow as a direction and sometimes can go through walls as you can see to resolve that error what we need to do is we need to go into pac-man and before we can move like this movement always happens no matter what before we move pac-man we should check if there's a collision so now we're going to do additional collision tech where we'll say did you collide with the environment and we're going to say this dot x this dot y and then lastly the instead of the requested moving direction this is the current moving direction and then if you did collide we're just going to return so you're not allowed to move anymore now if we go back to pac-man and we start moving around we shouldn't collide into any walls so here's my classic example i'm going to go left now i push down as soon as i get to the end he moves down and push right he moves that way so it's listening for that requested direction only executing the requested direction if we're in a place that allows us to move and now we have pac-man moving on the screen let's go ahead and animate pac-man so in the draw method of the pac-man file we're gonna add a new function called animate the job of animate will be to animate pac-man to open and close the mouth and we're going to be using these images that we created earlier we're going to loop over this array and one by one show the mouth opening and closing and we're going to use a timer to do that a timer that starts at 10 counts down to zero and as soon as it gets to zero it switches from one image to another restarts the timer at 10 and then does the same thing again now the reason that we created this array of four images is in this one pac-man's mouth is completely closed partially open completely open and then to make the transition when his pat when his mouth is open all the way to opening just part of the way i created another variable called pacman image four that's the same as one but at least in our array over here we'll follow that order to closed partially open completely open and then partially open and then closing the mouth so it's this nice little transition between the different images so let's go ahead and add that timer so in our constructor we'll go ahead and add the pacman animation timer and we're going to set one one variable is going to be called a default and the other one's going to be the one that actually counts down so the animation timer by default will be equal to no we'll go down into our animation over here what we're going to do with our animation is first we're going to check whether or not that value is null if that value is null then we will not do anything then the animation timer won't do a thing we'll just say if this dot pacman animation timer is equal to null then don't do anything so we just do null and we do return like that so nothing happens so then the next thing we need to do is we need to take that pacman animation timer and minus it so this is the value that starts at 10 and so the first pass of this loop will reduce it to 9 but once the next time we call this method and the value is equal to 0 that means we need to change which image we're showing for pacman we see it's equal to zero and then once it's equal to zero we're also going to do a little administrative work of resetting that timer back to ten so the next time we call it we'll just do that and say it's equal to 10 again so we use that default value so that we can easily change the value in the future to make it slower or faster then what we do is we increment the image that we're using so remember up over here in the draw method of pacman let's just go up so we'll minimize move minimize the images up over here in pac-man to select the image we use the image index so we just go to the next image in the list once we get to the end of that list we'll just want to go back to image zero so once we get to the end and the end will be equal to the pacman images dot length once it's equal to that just go ahead and simply set that pacman image index back to zero so it restarts the animation the reason pacman's not animating yet is that value is actually set to null by default in our constructor so nothing is going to happen so our move method will be the one who kind of controls when we're animating and the important part of our move is after we do these initial checks for the requested direction and we're working with the current moving direction this is where we'll do a little check so after this if we'll do an else if and we're going to check if we have a moving direction so we're going to say the current moving direction does not equal no if the current moving direction doesn't equal no and this dot pacman animation frame timer is equal to null equal equal to no then what we can do let me make sure i got this right over here looks a little bit messy but give it a second what we can do then and we'll just move our switch down a little bit for inside this elsif over here that means our moving direction we got one we are moving and our pacman animation frame is equal to null if that's the situation then we're going to say pacman animation frame timer you're equal to the default value now you can see why the default value is useful is we use it in multiple places we use it here on line 113 and then later on down we also use it in the animate method to reset the value if i was trying to remember those values i'd have to put 10 here and 10 there and if i change one to five then all of a sudden you'll get some weird animations depending on what's happening now when our pac-man moves he starts animating and he doesn't rotate yet that's that's for later but the one thing we also want to do is we want pac-man to stop animating when pac-man runs into a wall taking a look at our pac-man over here and our move method and we look at our collide so when we collide this is where we can stop that animation so we can say the pacman animation timer will be equal to null and then we can also say the pacman animation image index is equal to one because i want you to stop on a particular thing now you notice our pacman opened his mouth when we started even though it's supposed to start on image zero now that's because of a bug in our did collide with environment and this is easy to fix we just can go to our tile map over here and right now we have a direction so we can say if the direction is equal to null because when we first start using this we don't have a direction if the direction is equal to no return if we return now pacman's mouth would be closed again this method was returning the wrong value what was happening was it was passing in zero here zero here and a current moving direction of null and it thought that there was a wall which is not even our current location that's why we did that little fix there so anyhow pac-man now starts in the right position when pac-man starts moving pac-man will animate opening closing its mouth we did this little thing over here to set a particular image otherwise it'll be kind of random what pac-man gets so let's go and collide into a wall and see what happens let's partially open it's all the way open it's like that it looks kind of funny when pac-man just does different things i just forced pac-man to cap his mouth partially open when pac-man collides into a wall no matter which wall pac-man is colliding into and now we have pac-man animating as pac-man moves so one of the things that we're gonna do next is rotate pac-man but just to make this look a little bit nicer let's go back to our tile map and if we go back to our tile map file over here let's just remove if you have this on i'm going to remove the code that goes ahead and actually adds that extra little yellow line around everything and there you are now we can have pac-man here in our actual game animating so pac-man's animating other cool things you can do just real quick is if we remove drawing the bricks and we just keep the outlines you can see this cool little grid that we got here you can't see where the walls are so it's like playing invisible pac-man and then pac-man we're not really redrawing the background so you get this really interesting thing here if i can remember exactly what the level looks like i can kind of traverse traverse around it as you can see so kind of a neat little thing how you can accidentally create games while creating pac-man let's just go ahead and undo what we had over here and also get rid of those yellow lines and now what we're gonna do is we want pac-man to actually rotate so instead of using images that face left down up whatever we're going to actually rotate the image so that pacman when he's going left is facing left and when he's going down he's facing down and up and all those right now he's only facing the right direction and animating in that direction but to achieve that we're going to be making changes in our pacman file and then inside of our pacman file we're going to create a new variable inside here so we're going to create some variable called rotation rotation is going to be this thing that just tracks our values and lets us use words over here so we're going to do right down so down will be 1 left will be 2. and up will be three and then we'll create another value inside our constructor so inside our constructor we're gonna do pac-man rotation pac-man rotation by default will be equal to this dot rotation dot right we're using that new variable that we just added over here to assign a value over here it makes it easy to use switch statements if we decide to let's go ahead and jump into our move we're going to track that rotation so let's go ahead and start doing that over here so the pacman rotation that we just set up if you're moving up means our rotation will be equal to up as well let's do this dot rotation dot up and then we'll do exactly the same thing for all these other directions that we have so the pac-man rotation will be equal to this rotation dot down exactly the same thing for the left we got our rotation dot left we only got one more to go here just gonna copy and paste that one see how i'm missing that semicolon but as soon as i click save because of prettier it adds it in that's really really nice now i'm not gonna lie but this next part is just a little bit complicated what we're going to do is we're going to modify our draw method over here and we're going to do some fairly complex stuff with the canvas it's not a lot of code like we just had before it's just complicated code but i wouldn't worry too much about it in theory if you really wanted to you could have different images for the different directions but this is a novel way of reusing the images that you have in order to have face different directions or even your enemies if you decided to so what we'll do here is we'll just minimize everything that we're not using and in the draw method we're no longer going to be we're going to be drawing like this but we're going to pass in some different variables so i'll comment that out for the time being because we're not going to be using that and this is what we're going to do so over here i'm going to define a variable called size and my size will be equal to half that of my tile so divided by two then what we're going to do using this we're going to take our ctx so that's our context represents this canvas and we're going to save the current state the current state right now would be this this size with this information on it so we're going to call a method called save now we're going to take that canvas and we're gonna translate it so let's do a translate so basically we're trying to we're telling the canvas the x and y positions are going to be different they're going to be found in a in a different way then we're going to take our canvas and we're actually going to flip the entire canvas we're going to rotate this whole canvas right here so we're going to say rotate inside here we're going to do a little bit of math we're going to say this so i'm putting an extra bracket that you saw here and we're going to do is we're going to say this dot pacman rotation okay time so these numbers are important actually these numbers that i set up above for the pac-man rotation in our rotation variable they must be 0 1 2 and 3. don't use any other values so then we're going to times 90 degrees and then we're going to times math with a capital pi divide that by 180 and i'm not kidding this is complicated look at the weird stuff that's already happening now our canvas is getting rotated and translated and the background that we're drawing or tile map is kind of getting messed up but not to worry the next thing that we do is we want to draw our image and now we're going to draw our pac-man so this this part is the same as before we're going to go to our pac-man images we're going to say this dot pacman image index find the image that we want and now here's the part that i don't really quite understand as well but we do minus size minus size and if you recall those are half the tile size and then we say this dot tile size and this dot tile size i'll save that so that it formats it better so then pacman will be drawn on the screen still as you can see because we translate which says the x and y positions start instead of x and y starting here they might start here or here or here depending on the number of degrees that we rotate our our canvas then when we draw pac-man we're drawing him from a different perspective because we've flipped this whole thing around really hard to understand then we draw pac-man and then at the very end we say okay rotate everything back to where it was so we say ctx dot restores this save over here saves the state it was here and then we restore that state at the end so it comes back and then our board comes back but now if we move pac-man that way and that way he changes directions all of that code does this this little code over here does that little bit of magic to rotate our image in a future video i'll try better to explain this with a lot more diagrams and pictures for simplicity's sake and building pac-man it's not quite as important as you could really just use different images to animate and show this but this lets you use four images or three images actually for pac-man and we don't have to recreate that it's kind of neat i go left i go right pac-man's facing that direction once you do this yourself you'll see how cool it is and how neat to have pac-man going in these different directions now that we have pac-man animating and moving the next next logical step is to go ahead and eat those dots when we eat a dot we're also going to make a sound so in order to implement this we're going to open up our pacman js file and then in the draw method we're going to add another method that we're going to call and we're going to call eat dot we'll make that lower case right there inside of each dot we'll go implement that at the bottom and we're doing it as a private method once again what we're going to do here is we're going to do an if statement and pac-man's not really responsible for reading the dot pac-man is going to ask the tile map to eat a dot for it and if a dot is eaten then it'll make it disappear from the screen so the way this is going to happen is we'll do an if statement and the reason for the if is if a dot is eaten we're going to play a sound so that's what we plan to do then we're going to say this.tilemap dot e dot that we're going to do it based on pac-man's current position the background's current position will be its x and y coordinates and that's all we have to do over here for pacman is call this method and then inside of tile map actually before we move on you'll notice that in pacman e dot is private because only pacman calls that method but e dot for tile map is public so we don't have that little hash in front of it it's only on this method for pacman but eat dot on tile map well we need to expose it so that pac-man can use it so then we'll go into the tile map and we're going to implement that method we'll just put that at the bottom as well so i'm just going to minimize did collide and we'll put e dot over here and then e dot what we're going to do is we're going to have to look at the tile map and then figure out whether or not that x and y position is equal to a tile that has a dot on it as you saw we take in an x and we take in a y and then what we're going to do is we're going to figure out the column and the row so the way we figure out the column in the row from the x and y is we take the y we divided by this dot tile size to figure out the column we take the x position divide that by this dot tile size then what we do is we check if those numbers are integers because we need to make sure that you're actually in a square the collision detection we're going to use is pac-man needs to be directly on top of the dot and then it's eaten this is a really simple form of collision detection you could detect if you're halfway through a dot but the form we're going to use right here is just to make sure that you're directly on it so really simple form and then later on when we do enemy and player hits we're going to do a little bit more complicated form of collision detection so let's do it this way is integer we're going to check if the row is an integer and we're going to check if the column is also an integer so give it the column if they are integers then we're going to use those numbers to go ahead and figure out if this dot map give it the row give it the column that's going to give us back a number and if that number is equal to 1 then we know that we've landed on top of a dot because we defined our map as such so that oh sorry one are walls and zero our dots so if it's equal to zero so if we've landed on a dot we might wanna flip that to something that's a blank space so so far we said zero or dots for pac-man so we'll say that five is an empty space so that's what five will be so then we'll go down over here so when pac-man lands on something that's a zero we're going to take this exact position that's over here this dot map.row.column and we'll go ahead and we're going to set its value to 5 which should set it to an empty space as we go over it so right now it's not doing that this is actually really kind of cool it looks like it's leaving the previous drawn pac-man there because we don't overwrite it but i have to say that looks amazing it's kind of cool like i mentioned earlier the mistakes that you make actually end up looking really really neat and kind of you end up creating something you didn't expect so this i think is actually really really cool but that's not really what we want so we need to go into our draw method over here and look we're checking if a tile is equal to one we're checking if a tile is equal to zero but when something's not one of those we leave whatever we draw drew earlier and we drew pac-man as pac-man was moving across that area so remember pac-man increments slowly across the screen you just don't see it because it's refreshing really quickly so you get this kind of ghosting effect especially here and then when you go over the second time it looks even more interesting to solve this problem what we could do is we could over here say else like a final else over here and that final else will basically just draw a black rectangle this dot draw and we're going to do draw blank we'll create a private function that does that for us and we'll give it the ctx the column the row and this dot tile size then we'll do the same thing that we did for our wall so we'll just implement another method we'll say draw blank and we'll give it the ctx the column the row and the size and then for this one we're not using like this one we used ctx.draw image but we're actually going to draw to the screen over here so we'll go ahead and say style is equal to black so this is kind of like our paint brush and we're going to say ctx fill rectangle and we have to give it the x and y position so as always go column times this dot tile size and then our row times this dot uh column size our tile size and then we have to give it the the width and the height so we're just going to use size and size and then save it and then when we go over each item it's now drawing a black rectangle so if you wanted to instead of black just to illustrate it we could draw say green and just save that now you can see it's drawing green like that so anytime we go over one of these spots it draws a green spot but we're going to keep it as black because that makes it look like it's disappearing and then let's just go double check here so when we draw a blank we're good and then if we go to our eat dot we also expected this to return a true or a false what we're going to do is if we eat a dot we're going to return true and if we don't eat a dot we'll just return false what we can do is just do it on the outside if we go inside this if statement and we eventually do find a dot that's equal to zero we'll go ahead and flip that map so that all of a sudden or that map that area so that it becomes a blank spot we could also use null instead of five you could put null but i'm putting five there in case you actually intentionally wanted to within your map draw some blank spots you could put five putting null would just get a little bit messy so right now we're tracking these things just with these variables you could change these variables into well-defined variables if you wanted to but the map is just really nice when you use single digits because it's really easy to look at and see where the dots are and where the walls are and there you go now our pacman is eating the dots on the screen so next we're going to add a little bit of sound to this before we can add sound we're going to go ahead and add a brand new folder so clicking on index.html and clicking that new folder button will make sure that it's on the same level as images and src we'll go ahead and add sound and then i'm going to drag over the waka sound over here which is the wakawaka sound that pacman makes and the description will tell you how you can get the different assets once we have the sound over here we can go to pacman js and in the constructor we're going to define a new variable this variable is going to represent the sound so i'm going to call this waka sound and waka sound is going to be equal to something called an audio object the audio object will let us play a sound so we're going to do here is i'm going to go to that directory you need to go back a directory then into sounds and then we can get the waka dot wave so it needs to be the same name as here then we can save that in order to use this sound all we need to do is go down to where we eat the dot and remember if we eat a dot the eat dot method will return true which means we can do something so that thing that we're going to do is play the waka sound so the variable that we just named is called waka sound so right down here we'll go this dot waka sound in order to play it we just need to call the method play and now we should have sound so every time we go over one of those dots it makes the wakka wakka noise if we go over a blank space it doesn't make any noise but going over the dots will make a noise because this method over here returns true we then play the sound before we continue i'm gonna go ahead and comment out the sound for now you can leave the sound in your game but for my game i'm gonna leave a comment it out since i'll be moving around a lot and that noise could become annoying so i'll just get rid of that for a little bit the next part of the application that we're going to be focusing on is the enemies we're going to go ahead and create our enemies in a similar fashion to how we create pac-man if we go to our game.js you'll notice that pac-man is created by the tile map we call tilemap.getpacman if we take a look at our tile map you'll see that pacman is actually positioned in the tile map to be over here i could change pac-man's position over here by setting it to four there should only ever be one so i'm just gonna remove the other and now pac-man's position changes so we're gonna do exactly the same thing with our enemies so we'll add a brand new comment here to identify that our enemies will be number six and this will be an enemy and then the enemy over here we'll just place a few of them on the screen i'm gonna put one in the corner over here one in the corner over here and since pac-man's over here i guess they'll probably be pretty good to have two here and let's put one right there as well just to make it a little bit more difficult so these are the areas where the enemies will be since we don't know what we're drawing at the moment we just said a if we don't know what it is put a blank space there and that's why we have a blank space right now because we haven't identified what six is yet but then in our game js what we need to do over here is define a constant we're going to make a variable called enemies which will be equal to our tilemap.getenemies and this is going to be returning an array this array that gets returned we could loop over each enemy and then call draw but a shortcut that we could use is we could call for each so this for each takes in a function or a lambda that gets called for each enemy so what we're going to do is we're going to give it a lambda expression like this and we're just going to call draw on each enemy and as we do with the draw we always pass in the ctx so that it can actually do that drawing now when i click save here the map will be broken because we don't have an enemy and we don't have a draw method so we have a few things that we need to implement we'll start by jumping into the tile map and implementing the get enemies so inside our tile map we'll go add a brand new method called get enemies so let me just clean this up over here and hide the sidebar right around get pac-man let's go ahead and add that get enemies doesn't really matter where you add it and remember get enemies also takes in a velocity now we're gonna follow the same pattern we did with pacman where we need to basically get the row the column and then find out where these items are the one difference for this method that we're writing and we could do some reusability here but why not let's just go ahead and write that code but in your own code remember you could go ahead and just refactor this to some kind of common solution between the two methods but essentially this is how it's gonna work we're gonna say let our row equal to zero and then we're going to say row is less than this.map.length and then row plus plus and then once we get our row we can go ahead and get our column and then our column will be equal to zero our column will be less than this.map we give it the row and then the length of that row we're going to get all the columns inside there and then column plus plus and then once we're inside there what we can do is go ahead and get our tile our tile we can define as a const since we're not changing it and we'll say this stop map so we can simply do the thing that we always do and get our column our row and our column and that will give us our tile and then what we want to do is we want to check if our tile is an enemy and remember if we go up over here enemies will be number six so we're going to look for number six i'm going to say if our tile is equal to 6 then we can do something with it so we'll go ahead say column and then we're going to put that dot there we're going to say dots equal to zero because if you remember we look at our diagram over here dots are equal to zero and since that dot is equal to zero we just set that particular position within the tile map to zero and then what we're going to want to do is we want to grab our enemies so we're going to have our list of enemies over here and we're going to push on a new enemy we don't have an enemy yet so we're going to have to go ahead and implement an enemy but i know that an enemy will take in an x and y position so the x and y will be based on your column and row so that's going to be our row times tile size our column times tile size which will give us the x position over here and the y position over here we're also going to give it the size so we're going to give it the tile size we also need a velocity and we're also going to give the enemy a reference to the map which is something similar that we did to pac-man as well after we've collected all of the enemies and replaced the enemies with dots we're gonna go ahead and then return that at the end of this for loop so i'm just to highlight the bracket over here to figure out where the for loop ends and it looks like it ends right here so at the very end of this for loop we can return enemies if we decided not to add any enemies to our tile map then we would just return an empty list of enemies and we would never draw any to the screen we're still going to have an error and our next step is going to go ahead and implement an enemy so we don't have any enemies at the moment so let's go implement an actual enemy first thing we're going to want to do inside of our tile map right now is go ahead and import the enemy even though it doesn't exist right now so i'm going to put this between these two but it doesn't really matter where you put the import here at the top we're going to import the enemy from and we're going to use the current directory and enemy.js so inside here we got our enemy.js file and we're importing that then inside our enemy class we still need to export something you can see we get that error over here that request module does not provide an export name default we're going to do export default class enemy and that class enemy over here so now we'll satisfy that error but our enemy still doesn't have a draw method we could add a draw method right now we'll just go ahead and add that draw method not going to do anything but it gets rid of our error message for now the next step that we'll do is we'll go ahead and implement the constructor back in our tile map where we have our enemy we've gone ahead and defined kind of the constructor so we have an x position a y position a tile size a velocity and a reference back to the map so let's go ahead and implement that so we'll start by creating that constructor and the constructor takes the x the y then we go back over here it takes our tile size velocity so tile size velocity and the tile map itself then we have to do what we typically do inside our constructor over here so i'll just close that up and then this dot x is equal to x and this dot y is equal to y and this dot tile size is equal to tile size and then this dot velocity is equal to our velocity and the same thing for the tile map it's quite a bit of setup but there we go and then is equal to the tile map now let's go ahead and load the ghost images before we draw to the screen so i'm going to create a private function called load images and we'll put that below our draw over here and load images will go ahead and load several different images so these images once again i'll be providing them in the description and also in the full project i'll go ahead and just copy these images over because i don't have them in my current project so we have several different images to represent our ghost our ghost is going to be represented by the ghost image which is just green as you can see right there and it's a 32 by 32 pixel image that i drew myself and then there's also the scared ghost the scared ghost would turn blue with pink eyes when it's kind of losing its scared state and you can't eat it anymore it'll flash between white and blue so back and forth it'll flash between these two animating letting you know that if you try and eat it you might die because it'll change back to the green color where it's a normal ghost so let's go ahead and implement using these images inside our enemy so we have our load images over here and we're just going to load several different variables we're going to call one of them just the the normal ghost so this is the normal state of the ghost and we'll just load an image oops little typo there and this dot normal ghost dot src is equal to and then we just go into our images directory and we grab that ghost.png and then we do the same thing for we're going to call this one scared ghost is equal to new image dot scared ghost dot src is equal to images slash guard ghost dot png and then we'll do the same thing for our second scared ghost so we'll just copy and paste those lines and put them there and then we'll just change this to a 2 and this one is scared ghost 2 like that not a very original name but it works and then what we're going to do is for the current image of the ghost we're going to have a property just called image so this is the current image and the current image will be normal ghost and we'll flip between these other ones in just a little bit to see what they look like now we can go ahead and implement the draw method so for draw we're going to take in our ctx because if you recall inside our game over here we passed ctx to the draw method and then backer inside our enemy over here all we want to do is ctx dot draw image we'll do this dot image not scared but image and then this dot x this dot y and this and we'll just minimize this for a sec here this dot tile size and then lastly we also need the tile size again because that's the width the height the x and y position and the image and then we click save and we have ghosts on the screen if you want to try out our other images to make sure they're working we can put this dot scared ghost and we should get blue and then uh scared ghost two we should get the white ghost there so there we go we have all our images working for the ghosts next we're going to look at moving our ghosts on the screen first thing we could do is switch our ghosts back to the normal ghosts and then inside our constructor what we're going to do is set up a couple of properties that we need to achieve moving our ghosts we're going to be using a timer to change the direction our ghosts now all the ghosts are going to move differently so they'll have different timers so while one moves up the other could all of a sudden change its direction and each of them will appear to be moving differently because we'll have some more random numbers generated just like pac-man we're gonna need to import the moving direction and we're just going to import that from the current directory and remember to put the js at the end over there and we don't have any errors so good old ways to save and double check that you don't have any errors then what we're going to do is we'll set up this dot move direction the move direction will be equal to actually we'll call that moving direction the moving direction will be equal to math dot floor so we're going to do some random here we're going to randomly select the moving direction that the ghost starts with so we're going to do that over here by doing math dot random and what we want to do is times it by the number of items there are in the moving direction now the moving direction is an object and it's an object of key value pairs there is this handy javascript method called object.keys which can get us the up down left right key and then that will tell us that there's four items in the list so that's why we name them zero one two three kind of like it's an array so what we're gonna do back inside our enemy is we'll use this nice little handy javascript method because we're going to use math.random times 4 then round it down and they'll give us a random number between 0 and 4 so not including 4 so it goes 0 1 2 3. those will be one of the numbers that we get so over here we're going to say object uh that's a capital over there object dot keys and it's we give it the moving direction object so this is the object up here and then we just ask for the length which will return four so that will give us a random moving direction for each of the ghosts then we're also going to set up two other properties a direction timer default so this will be the default value for our timer now we don't want the timer to be the same because then that would mean that every single ghost would change its direction at the same time so we'll do something random and we'll do it between two numbers so this method doesn't exist we called it random and i'll make that private as well so just a little typo there so this dot random so let's go ahead and implement a random function so we're doing random between two numbers so we'll implement another private method and we'll call it random the random function will go ahead and take a min and a max value so for example our min here is 10 and our max is 50. and then what we're going to do with that is we're going to return math.floor and math.random and what we do is we say times the max minus the min plus one plus min right there and we have to actually move that min outside the math.floor so there you go that's a little hard to follow but math.floor encompasses all of this over here and then we add min so this will give us the value between 10 and 50 for our ghosts let's go ahead and implement moving our enemies so we'll start by creating a private method called move this move method over here that we're going to define will move our enemies based on the current moving direction so what we'll do is we need to first check if well there's a collision and we can do that using our tile map we actually made a generic method called did collide with environment if you want to make sure we don't misspell that we can go to our tile map look for the did collide method and there it is and it's a pretty generic method it takes in an x position a y position and the moving direction and then checks for a collision so going back to our enemy over here and using that function we can go ahead and give it the current x position the y position and this stop moving direction and then if we don't that's why we put a not over here if we don't have a collision we can go ahead and move our enemy to move our enemy we're going to use a switch statement just like we do with pacman and we'll give it this dot moving direction then we can build several cases over here we'll start with moving direction dot up and then for moving direction up what we do for that if you recall is the y needs to be minus so then we do a velocity like that and then we do a break and then we build another case for moving direction dot down and for that you're going to do positive for the y so this dot y plus equals this dot velocity and then do a break and then we'll do another case for moving direction dot left and left is also going to be a negative direction so minus equals are this dot velocity and then we do a break as well and our very last case if we really want we could just copy that paste that in format a little bit nicer and then that is our right and right is a positive direction for the x and then save it now you can see these two enemies moved in the same way i'm going to hit refresh on the screen here and we'll get different results so they must have tried to move left or down that one's moving up and now they all moved in unison which is kind of cool so we'll see different behaviors some of them are colliding with walls so they're not moving if they had timer set up they'll change directions and that is moving our enemies next we're gonna go ahead and implementing changing the direction of the enemies just in case it wasn't clear i was hitting refresh on my keyboard in order to show the enemies moving they only move once right now but as soon as we implement the change direction using the timer the enemies will continue to move on the screen let's go ahead and implement the change direction so we're going to do that in our draw method right after the move we'll go ahead and call a method called change direction and that's going to go ahead and use that timer that we spoke about we'll just minimize the move for now and these other methods just to keep the screen a little bit more cleaner and we'll head go ahead and add change direction and change direction doesn't take any parameters in inside change direction what we're going to do is first decrement the timer then we'll check the timer to see if it's at 0 and then go ahead and do something so we'll go our direction timer minus minus to reduce that number i'm also going to declare a variable called new move direction and we'll just set that to null initially let's see the first thing we're going to do is say is the direction timer equal to zero if the direction is equal to zero we're going to do what we always do and we're going to go ahead and reset that timer and then do an action and this action will be to change the direction so to simply do that we're go ahead and say the new move direction is equal to exactly the same code that we wrote above in our constructor we'll just go ahead and redo that here so all we're going to do is math.floor and then math.random and then do that time object dot keys to get the number of items that we have inside our moving direction which is equal to 4 but instead of hard coding in that to 4 we're going to get it directly from that object just in case we decide to add other moving directions in the future next what we're going to do is inside the change direction over here we're going to check if we have a new moving direction so if the new moving direction does get set we're going to do a little if statement over here to say if the new moving direction does not equal to null and we'll say if this dot current moving direction so the direction the enemy is moving in is not equal to the new move direction basically what this is guarding against is the fact that we got a new moving direction so that means we got into this if statement and then what we're doing is we're checking if the enemy is not already moving in the same direction what this prevents is the fact that an enemy is going into a wall and keeps on trying to go into a wall and just never stops doing that so what we do over here is we prevent that then what we're going to do before we even change your moving direction is we're going to check that your x and your y position are within a grid so you can only change directions if you're perfectly within one of these grids so we're going to do that same check that we've done before with pac-man before we can move which is checking the number is an integer for the y and for the x when we divide that by the tile size it will do exactly the same thing for the y over here this dot y divided by this dot tile size and then if that's good then the next thing that we can do is check if there's a collision so we'll do another if statement and we'll say if this dot tile map because remember our tile map has the collision check on it and all we have to do is give it the x the y and the new move direction so we'll type that in over there new move direction and then if that is good and there wasn't a collision what we're going to do is go ahead and say this dot move direction or moving direction is equal to the new move direction so now the enemies will continue to move on the screen and they'll move kind of randomly you can see they're not really getting stuck in the walls they do stay sometimes more towards the outside so it depends where the enemies are as remember this is just really simple basic basic ai for enemies so they will randomly move and sometimes they may not gravitate as much to the middle they'll stay on the outsides and keep you guessing as you move around if you want more of a challenge with your enemies instead of using 10 and 15 over here for your min and your max you can just go ahead and use one and three and then you'll notice that the enemies really kind of start to move around sporadically i'll even hit refresh there so we can see a little bit differently so as i move around and i'm trying not to get hit it's it's hard you can see there i got hit a bunch of times uh it's they're a lot more random this way and they do sometimes go more up into these middle areas from what i could see with the current logic that we're using of course you can implement a lot more complicated logic for your enemies but this is the simplest way to get it going let's go ahead and implement some pause logic for our enemies when the game first starts the enemies shouldn't be moving if they were then they could kill you before you even start the game so in order to do that we're gonna go to our game.js and what our goal is to do is pass pause into our enemy we'll just have a little function called pause and this function that we're going to implement we'll do the following so we'll call pause and what pause does at least initially eventually we're going to implement this for game win and game over but for now what we're going to do is we're going to ask the pac-man object if pac-man made the first move made first move means pac-man started to move so as soon as pac-man starts to move the enemies should start to move so let's go ahead and do that i'm going to save this file then i'm going to go into the pacman js over here and i'll go add a property called made first move so inside these the constructor over here go ahead and add made first move and we're going to set that equal to false like that as soon as any key is pressed and it's for one of the directions that our game supports we'll go ahead and set the first move equal to true we can go into our key down method over here so it's just at the bottom of the file for our pacman and then inside of each and every single one of these uh if statements that we over here we could do simply as say this dot dot made first move is equal to true and we can just do the same thing in every single one of these if statements these probably could be refactored to some common code but for this simple example right now this is probably the easiest right now to understand and see that we're setting this on every single key press that we listen for then the last step is inside of our enemy js as you remember in our game.js we're passing that pause method in inside our drop method if it's not pause so let's get to that draw method that we have inside of our enemy over here and we're gonna pass in a value over here called pause and what we'll do is we'll just do a little if statement and we'll say if it's not paused then go ahead and execute the following two methods but i'll just cut them so we're gonna move these two methods over here into the pause logic now when we start our game the enemies won't move but as soon as pac-man's made the first move in our game js over here this will become true and then it won't be paused anymore and our enemies will start to move when we move to continue the theme of working with our ghosts the next thing we're going to do is we're going to implement the power dot if a pac-man needs a power dot then the ghosts will flash blue and white and they'll be vulnerable to pac-man eating them the power dot will be implemented inside the tile map so once again we're going to go back to our map over here and we're going to find a new number to represent the power dot on the map so let's go with number seven will be equal to a power dot and we'll sprinkle a few of these power dots on our map so we'll put one over here in the corner one over here and then perhaps we'll put one in the middle of the screen as well so we'll put one over here so now if i click save we'll see these empty spots where our our dots will be so i'll be able to get one there there and there next what we'll do is we'll go inside our draw method and if we find a tile that's equal to 7 then we're going to go ahead and draw a power dot so let's go ahead and do that over here and we'll just do it after this last l stem in here because we always want that one to be there to draw a blank dot like we just did right now and we'll go ahead and we'll say else if the tile is equal to 7 and we'll just make a brand new function that's private once again called draw power dot and then we'll go ahead and implement that method so right now we're getting an error message that says power dot doesn't exist so we'll go ahead and implement that method just scroll down over here i'll just collapse a few of these i'm going to keep all these draw methods together i'll just go ahead and put it after the dot and we'll call that draw power dot then our power dot should be just like our other ones and take in the same values so we can take in the ctx the column the row and the tile size i don't copy paste often but minus will do it there so we have those values being passed in and then we'll define our function down over here with those values and we have our ctx our column our row and our tile size so now we're not getting an error anymore now it's not drawing anything so we're getting the background that's on our screen so we're just getting the purple there because now it's entering this method saying draw and nothing happens so we just get the background of our application our power dot is going to be represented by our yellow dot over here and our pink dot we want it to flash on the screen since it's going to flash on the screen we're going to use that same concept of a timer back up in our constructor what we're going to do is go ahead and define that timer and we'll give it a default value and a timer value so just like we've done before we're going to go ahead and say this dot power dot power dot animation timer is uh we'll set the default actually default will be equal to 30 and then we'll have that same value here but just without the default and we're going to say this is equal to this dot power animation default there the other thing we need is our image so we have the yellow dot but we don't have the pink dot we can go ahead and get that image so we'll get the pink dot and we'll say it's equal to a new image and then we'll do this dot pink dot dot src is equal to and then dot dot images pink dot dot png then what we can do is go ahead we can actually test this real quick to make sure that it works so i can say this dot yellow dot is equal to this dot pink dot and then if i look at the screen all the yellow dots turn to pink dots so that means that i have this reference correct and that it's working but i'm going to delete that because we don't need that since they're going to flash between them we're going to define a variable called power dot and to start off with it's going to be equal to the pink dot and we're going to use this timer to switch to a yellow dot and a pink dot every 30 ticks we're going to do that so now we can go ahead and implement the power.draw method so we can go down to the draw method for the power dot so inside of here first thing we want to do is take that timer that we have and minus 1 from it then as soon as we call this method and the power dot animation timer is equal to zero then the first thing that we always do is we reset that timer so this dot power dot animation timer is equal to this dot power animation power dot animation timer default so it sets it back to 30. after we've set it back to 30 what we're going to want to do is check which image is set to so if the power dot current image is the pink image then we're gonna switch it to the yellow image so we say this dot power dot is equal to this dot yellow dot so we're gonna switch it from pink to yellow otherwise we'll just do a little fl statement over here and we'll say this dot power dot is equal to this dot pink dot we'll save that there and then the last thing that we need to do is once we've done this little image switch over here we always display it so we use that ctx and we call draw image we say this dot power dot which is either going to be a yellow one or a pink one and then we call column times this dot tile size and row times this dot tile size actually instead of yeah tile size works so we could just use this variable actually instead i'm going to rename this to size just to make it a little bit cleaner so just quick little refactoring here to make this a little bit cleaner code so we can just use size there and size over here as well and then the last two variables that you could pass in are the size and size if you don't then it'll just use the size that's there but there you go now we have our power dots flashing if you want to make them slower or faster you can go ahead and change this timer so now this flash a little bit slower if you wanted to be ultra quick then you could have something like that so it depends whatever style you're kind of going for in your game i kind of like the 30 but uh feel free to play with that and choose any number that you want now let's go ahead and get pac-man to eat one of these power dots right now pac-man can't eat a power dot so we're going to go ahead and open up the pac-man js inside pac-man js inside the draw method you can see we have the e-dot so now we're going to have the eat our dot so the power dot we're going to implement that at this bottom of this page over here eat our dot over here and what we're going to do is we're going to delegate to the tile map so we'll go tile map dot eat power dot and we're gonna give it pac-man's exposition and y position thou allow us to check pac-man's position and see if pac-man is on top of a power dot we're also going to be returning true or false if pac-man's eaten a dot if pac-man has eaten a dot the ghosts will become blue they'll turn into their scared state let's go into our tile map and implement eat power dot so within our tile map we'll just go to the bottom of the tile map i'm going to put it beside e dot because it seems like a logical place and we give it the x and y position and then within here what we're going to do is we're going to use the x to get the column and y to get the row we'll define our row is equal to y divided by this dot tile size and then we'll do const column equals x divided by this dot tile size so that gives us our column in row then we're going to double check as pacman moves we always want to make sure that he's within a grid but we'll go ahead and we'll just do a little if statement here and we'll do is integer and give it the row and then number dot is integer and give it the column [Music] then if that is true we can do is we can get the tile so we can say the tile is equal to this dot map and give it the row and then give it the column once we have the tile we can check if that tile is equal to the power dot and our power dot we defined as number seven so let's go ahead over here and say if tilemap or tile is equal to seven then what we're going to do is go ahead and set that part of the map as being blank so we'll say this.map row column and then we'll say that is equal to and we'll do exactly what we did for for the e dot as well over here we set it to 5 as being blank and i believe we might have defined that up top which is an empty space so 5 over here will be an empty space and then we'll just say return true otherwise we're always just going to return false which means that a power dot hasn't been eaten so now when pacman goes over a power dot it gets eaten so now that we've eaten a power dot we'll have to do something with it let's start by playing a sound when pac-man goes over a power dot so in order to do that we're going to go and add a new sound you may already have the sound if you got the project or if you've downloaded the resources so over here for sound i'm going to pull in power dot wave and that power dot wave will be the sound that is played when we go over one of the power dots so within a pacman js we'll go ahead and we'll set up a sound variable that we're going to be using just like our waka sound we're gonna go have a power dot sound so let's go ahead and implement that next to our audio over here for the waka and we'll just call this dot power dot sound is equal to new audio and it's just like the other one so dot dot and then slash sounds slash power dot wave and then once we have our sound over here which i think i misspelled there we go just missing so it's always good to have your console open as you can see and now that i know i have no errors i know that the power dot is working for the sound then we can go down to our method over here and what we'll do is we'll say this dot power dot sound and if we have gone over a dot we're going to play that sound and then every time we go over one of those dots there should be a sound being played and there we go so let's go get that last one over there the ghosts aren't turning blue just yet but they will be soon now that we have a sound playing we're gonna go ahead and set up a few variables for pac-man one of them is going to be a variable that's going to indicate that the power dot is active and one variable is going to indicate that the power dot is about to expire so what i'm going to do right now is within my constructor i'll go set up the default values for those variables so we'll just do that it doesn't really matter where in your constructor perhaps we can do it just after the sound over here just so it's all together with the power dots we can say this dot power dot active is going to be equal to false by default because it's not active and then the power dot about to expire we're going to set that to false as well so these two things will cause different things to happen if the power dot is active these guys will be blue if the power dot is about to expire the ghosts will flash white and blue now back in the eat power dot method we're going to go ahead and use these variables so we're playing the sound i'll delete that comment and then what we're going to do is we're going to set the power dot active equal to true and then this dot power dot about to expire will be equal to false so if you click one power dot and you continue moving along and these guys start flashing blue but all of a sudden you hit another power dot then they should turn back to blue so that's why we set this to true and then this defaults in case they're already fast and flashing blue and we want to reset that state now what we're going to do is we're going to have a list of timers and these timers that we're going to set up so we're going to be using the set timeout method the first thing we're going to do is if we have any timers what we're going to do is go ahead and clear them we're going to be using the set timeout method and the set timeout method for each timer has essentially a way to stop the timer if you want to stop it so there's this method called clear timeout and you give it a timer so essentially we're going to have a list of timers i know not super clear right now but you'll see in a second what this means once we've cleared all the timers we're going to clear this array which will be a list of timers and there's only two timers we're ever going to have one is going to be a timer that's going to count down from six seconds to say these guys are blue then there'll be another timer that activates about three seconds in to basically say hey we're halfway through the enemy being scared and they're about to turn back to regular enemies so watch out pac-man in order to implement this what we're going to do is we're using our timers over here we're going to keep a list of these timers and we're going to push a timer on the first thing we're going to do is we're going to implement we'll do this one we'll do let and we'll do power dot timer is going to be equal to set timeout and our set timeout will do the following so timeout takes on a function that will execute once once a certain amount of time has gone by and that certain amount of time over here is going to be six seconds this thing takes in milliseconds but to do a thousand which is one second times six so i'll give us six seconds and then when those six seconds are done what we're going to do is we're going to say this dot power dot active is equal to false and we'll say this dot power dot about to expire is also set to false then we're going to take that power dot timer and push it onto this list of timers and then when this method finishes and comes back into the method and someone's like oh we ate another power dot okay well first get rid of this timer and the way we get rid of it is by looping over this timers now we're going to have one more timer that we're going to add so we're going to say let the power dot about to expire timer and that timer over here will be equal to a set timeout as well and then that set timeout is going to take in a function and that function will do something after three seconds we're going to go ahead and we're gonna say this dot power dot about to expire is equal to true so this timer will start and it'll say the power dot is active and it'll be blue then this timer will kick in after three seconds and say power dot about to expire is true then when these three seconds are done this one should probably be finishing up it'll go ahead and set power dot active to false and power dot about to expire to false so our last thing that we need to do over here is say this dot timers dot push and push the power and misspelled that over there right there so power dot about to expire timer and that will push that one on there and then nothing will change right now but the only thing we want to ensure is that our game does work now one issue we're running into here is it's telling us that our for each over here is undefined so cannot read property for each of undefined so timers looks like it is undefined so we'll do is inside our constructor by default what we'll do over here is we'll say this dot timers is equal to an empty array and that will resolve that issue because that array doesn't exist and now we're good and we're just getting a favorite icon if you had a favorite icon we wouldn't get that little error there to get rid of that fave icon error there that we see whenever we go over the audio there we can do is simply within the root of our project so if you just click on index.html inside the main area here and then click add file we can just add a fave dot fave icon dot ico just like they have right there and then add that icon now when we move you'll no longer get that favorite icon error another possible error that you might see when it loads up i had the sound disabled before for the waka sound is you get this dom exception play failed because the user didn't interact with the dom first easy way to fix this one over here for pac-man if we go down to the e dot method is we could just say you know did you eat a dot and this dot well do you say made first move so if you made the first move it'll play the sound if you didn't made that first move then the sound won't play you won't get that error about trying to play sounds without interacting with the dom so chrome is trying to do something smart where basically it doesn't want it playing sounds if you haven't actually interacted with the browser that means clicking or typing into your browser window now that we've set up these new variables on pacman for power.active and power.about to expire we're going to be using those variables so within our game js we're gonna go and find our game loop and our enemies when we draw an enemy we're gonna give the enemy a reference to pac-man so with a reference to pac-man the enemy will now be able to call pac-man dot power dot about to expire and power dot active so within our draw method so i just went to enemy over there and we're inside our enemy class our draw method will now have a reference to pacman and our draw logic will increase and i don't want to put all of that code inside here so what i'm going to do is i'm going to define a private method once again called set image and set image will be in charge of setting the different image depending on the state and that will take in pacman as well so it has a reference to those variables so we'll pass pacman in and then we'll go ahead and implement that over here as set image with pacman and then what we'll do is we'll go ahead and just cut that ctx over there and paste that into the image we still also need to pass in ctx so you can see by our error ctx is not defined once ctx is defined we should be okay and there we are now our enemies are showing up again let's go ahead and use our pacman object over here to determine whether or not the power dot is active and if the power dot is active we're going to do is go ahead and change the current image that's the one that we pass into ctx.draw and we're going to change that to the scared ghost then in the else statement if the power dot is not active we're going to go ahead and change it back to our normal ghost and we'll save that and then as we move over those pellets now the ghosts are blue then we'll just wait and see what happens over here we can't eat them and they changed back so that is working together goes to flash blue and white when the power dot is about to expire we're going to go ahead and add a timer we're going to add these scared about to expire default timer default then i'm just going to duplicate that line over here so let me just copy that as well we're going to put that over here but remove the default and say that's equal to the default value so now we have a timer that we can use when we're going to be flashing blue and white then inside the set images we're going to refactor this because this code can get a little bit more complicated with a few more if statements i want to keep this method looking clean so what i'm going to do is define a new private method it'd be called set image when power dot is active and we're just going to pass in pac-man because we need a bit of additional information then what we'll do is define it over here with our other private methods and we're taking pac-man in then we got our what we're going to do inside here is we'll just do a little if statement and we're going to ask pacman if the power dot is about to expire and then inside here if the power dot is about to expire we normally take our scared about to expire timer and we decrement that value and then once the value of that timer of the scared about to timer is equal to zero what we do then is we reset the timer and then we perform an action let's just reset that timer over there back to the default then the action we're going to perform is we're going to check if the image is currently equal to this dot scared ghost and if it is equal to the scared ghost well we're going to flip it to the scared ghost 2 which is the ghost that is the color white what we'll do in the else statement otherwise if it's not the scared coast or if it is then we're gonna switch it back to this dot scared ghost we're gonna flip between scared ghost two and scared ghost for these two images and then the last thing that we need to do is if the power dot is not about to expire that means the power dot is active you know the power dot is active at the bottom of this if statement we'll just put an else and that else over here will say this dot image is equal to this dot scared ghost because otherwise you're just a regular scared ghost then let's go ahead over here see what happens underneath the pellet after about three seconds you can see they start to flash blue and white and then they turn back to green if we eat one power dot and we're moving along and they start to flash but then we pick up another power dot you see it resets the ghosts and then they go back to that blue state and then back to the blue and white flashing next we're going to look at colliding with enemies getting our game over and game win scenarios so inside of our game js one of the first things we're going to do is go ahead and initialize a few properties that we're going to need so at the top of the screen i'm going to go define a game over equals false a let game win equals false and then there's a couple of sounds that we're going to pull into our project so those two sounds that i'm going to pull into our project are the game over and game wind sound so let's go ahead and grab those both and i'm just going to pull those in so we have our game over sound and our game win let's go to find two game audio objects so we'll have game over sound is equal to a new audio and audio always as you know takes in the path to the object so game over dot wave oops a little typo and then to make this a little bit simpler i'll just duplicate that line and this will be our game win sound and we'll just modify this to say win as well we don't have any errors on the screen so that means we must have the path right if i were to modify one of those you could see that we get an error telling us that the path doesn't exist because we get a 404 but if i put that back it's all good in our game loop let's go ahead and add a method called check game over over here we're just going to add check game over and then check game over his job will be while you guessed it to check if it's game over i'll go ahead and add a function check game over inside check a game over what we're going to do is the following we're going to check if it's not already a game over so that's why we have this variable over here because we don't want to check that over and over then what we're going to do inside that if statement if it's not game over we're going to go ahead and check if it is game over that's another method that we're going to add and then uh otherwise what we're going to do inside here is if it is game over we'll go ahead and play the game over sound so we don't you only want to play that game over sound once you don't want to play it multiple times just one time so that's why we have this little guard over here we only enter here if it's not game over then we check if it is game over if game over is true then we go ahead and play that sound and it's only going to play at one time be very annoying if it played it over and over and over so then what we have is we're missing a function called is game over and is game over it's going to be determined whether or not we have collided with an enemy so inside is game over we're going to ask each enemy whether or not we have collided with them so simply we can do this by using a return statement and we're going to go to all the enemies and we're going to say have one of you at least that's what the sum method has one of you at least collided with pac-man and then what we're going to do over here is we're going to check first is the power dot not active because if the power dot is active then that would mean that you know we can't you're not allowed to collide you can't collide with an enemy then or you can't be killed by an enemy so if a power dot not active and we go ahead and we collide with an enemy then it is game over so we'll say enemy dot lied with and that's going to be a new method that we're going to add and let me just minimize my sidebar there so we're saying enemy pacman dot power dot is currently not active which means they're green and then one of the enemies collides with pac-man this will return true because some is going like is anything inside this list and this list being our enemies producing a true return statement over here something returns true even one of them then all of a sudden it stops returns true and it is game over let's go ahead and implement the collide with method inside of our enemy within our enemy we'll go ahead and go create this method called collide with so opening up our enemy js let's go ahead and set that function i'm gonna go set it after the draw so that's one of the public methods that we have and we'll open that up and then back inside of our game.js we see that we pass pacman in so we'll pass pacman into that function as well and save that so that error message is now away because the clyde with method is here doesn't do anything yet the way this collide method is going to work is we're going to be checking this rectangle and the enemies rectangle and seeing if they overlap with each other the best example of collision detection is here on mdn 2d collision detection so there's basically this kind of formula that we can follow in order to see if two squares are overlapping with each other so in this example over here when you move the square it's blue and as soon as it touches that's considered an overlap so we could modify this so that you only overlap when you're halfway through so it's still blue over here but this example shows as soon as they start to touch you see that it turns that color so we're going to use that same formula and i'll link this in the description over here because this is a great resource for colliding with boxes colliding with circles so it depends on the types of shapes that you have so in our example over here we're going to be following pretty much that example there and what we're going to do is we're going to say if it collides with pacman and we're going to say const size is equal to this tile size and divided by 2 so we're getting the size divided by 2 by dividing the size by two we're going to be able to check when pac-man is halfway on top of an enemy to check for the collision collision instead of having them collide when they're touching unlike this example here they're touching if we divide our size by two our collision will be detected when we're halfway over the other rectangle and then what we're doing is we're comparing the enemies x and we're checking if it's less than pacman dot x plus the size so that's the number that we just calculated over there and then it's going to be a few of these statements that we're going to have here it's going to be on a couple of lines so once we've checked the x there we're going to do another check of the x and we're going to say if the x plus 1 is greater than the pacman.x and then there's another one so we need to check our y positions and then we're going to check our y is less than the pacman dot y plus half the size and then we're going to do an n there and we'll say this dot y it plus size is greater than the pacman i keep writing sprite because that's how i originally wrote the code but i thought we would make it more towards pacman here and then dot y so let's make sure that we got this right we got our pattern over here in that so we're just getting error right now because we haven't opened and closed and used this if statement yet uh once we save that we're back to normal so we're doing our this.x is less than the pacman.x plus half the size and then this this dot x plus oh there's a typo there that says one that would not work uh this.x plus size is greater than our pacman.x and then we do the same thing with our y over here we do half that size and our y over here where we do half that size so then you can see we're doing one side is pac-man comparison the very same thing another sign is the enemy's side right there so then if this is true we'll just return true because that means we have a collision otherwise we go ahead and just return false we could do it two ways we can do an l statement or we can just return over here so we'll just do an else since that looks a little bit cleaner and we'll just return false then if we go back to our game.js you can see that we're colliding over here and then it's going to determine if there's a game over all right let's go ahead and move pac-man and collide with an enemy there we go we just collided with an enemy as you went through me and you heard the game over music but the game doesn't pause let's go ahead and implement pausing the enemies and pac-man when they collide so inside our pause method we're just going to put an or over here and use that game over variable that we defined at the top of the screen then you notice that our enemies are currently reacting to pause and using it but pac-man isn't so let's go ahead and pass pause into pac-man inside the pac-man file we're gonna go use pause so let's go to that pac-man file and then inside the draw method of pacman over there we're gonna pass that variable in so we have our ctx and now we also have a pause and then we can go ahead and use that pause just like in our enemies we wrap several of our methods which pac-man uses to move around on the screen we're gonna wrap the move and the animate so that pac-man stops animating and moving so we'll just say pause there and we're just gonna wrap our move and our animate and we're actually gonna check that it's not paused so if it's not paused then we can execute those methods so let's go ahead and move into one of the ghosts and now we got that game over music and the game is paused so this gives us an opportunity to see where we went wrong and how that enemy got us all right let's give pac-man the ability to fight back and defend himself by eating a power dot and being able to eat a ghost inside the game loop when we draw our pacman we're going to go ahead and pass in a list of enemies pac-man is in gonna use that list of enemies to determine whether or not pac-man is able to eat a ghost let's go ahead and we'll add a new private method and we're gonna call it eat ghosts just like our eat dot eat power dot we're gonna have an eat ghost method so that list of enemies that we just passed in we're gonna pass it into our draw method and then we'll take that list of enemies and we'll pass it into our ghost list then we'll go implement a method called e to ghost and we'll put that next to our other eat methods let's go over here and we'll go ahead and implement that over here next to the other methods when we eat that ghost we're also going to want to play a sound so i'm going to go ahead and pull in another sound called eat ghost so using that sound we're going to go set up an audio object for that within our constructor so within our constructor we'll just go add that brand new sound doesn't matter where we add it but we'll go ahead and call that eat ghost sound and we're going to make that equal to a new audio object and that new audio object will be in our sounds directory and we called it eat underscore ghost dot wave if we save that we shouldn't get any errors and if we don't get any errors we'll see that here because that means we got the eat ghost wave file properly and then down below in our new method eat ghost or go ahead and implement this let's go ahead and say if the this dot power dot is active that's when we're allowed to eat a ghost and then within this if statement over here what we're going to do is we're going to figure out whether or not we are colliding with our enemies so we're going to look at that entire list of enemies and we'll just get back a variable called collide with enemies and we'll go to that enemies and we're going to use a little helper method called filter filter takes in a function and that function will represent one enemy and we're going to check each enemy one at a time kind of like a for loop and we're going to ask each enemy if we are colliding with them we'll call collide with and inside the collide with method we pass this which is equal to pacman then we get a list of enemies that we've collided with we then use that list of enemies that we collided with and we say collide blighted enemies and we loop over that list and then we're going to remove those enemies from the game so let's go ahead and do that so each enemy over here that we got back so this is all the enemies that have collided with pac-man because who knows two of the enemies could be on one square when pac-man runs into them so we're going to use a method called splice and what splice is going to do is it's going to modify our array by removing an item from it to do this we have to ask where that item is that we're going to remove so we look at enemies and we find the index of well that current enemy that we're looking at we pass enemy in then outside of that splice method we say remove one item then what we do is if this is successful inside of this for loop we're going to make this into actually a full-on method so let's put braces right there around it then it'll be a little bit clearer save that we can see our for each here so first thing we do is we remove that enemy and then after we remove that enemy we play the eat ghost sound so now we'll be able to eat a ghost when the power dot is active so let's go ahead and give that a try so pac-man we're gonna get pac-man moving over here eat one of those power dots try and quickly get the enemy as you can see the enemy disappeared off the screen and it played a sound oh and we got him too as well next we're gonna go ahead and implement winning the game winning the game means eating every single dot on the screen so in order to do that we're going to go to our game.js and kind of like our check game over we're going to have a check game win so we'll implement that method over here and then inside check win it's going to look very similar to the game over we're going to use that same pattern of checking if the game hasn't already been won and if the game hasn't been won then we're going to set that gamewin variable that we have up here equal to our tile map so our tile map is what knows if we won the game or not the tile map knows about every single dot on the screen it will be able to calculate and figure out whether or not we've eaten all the dots so on the tile map we'll be able to call did win autocorrect kicked in there but did win and then once we've won we'll go ahead and we'll play a sound and that sound that we're going to play is the one that we set up over here so the game wins sound and all we have to do is called game win sound dot play and then that sound will only play one time next let's go ahead and implement the didwin method because as we can see over here it's telling us it's not implemented so we'll switch into the tilemap file and then what i'm going to do is i'll just put it over here it doesn't really matter where just putting it with the other public methods and we're going to create a method called didwin we're going to save that and then the error message goes away and inside din win what i'm going to do is i'm going to create another method called dots left that we're going to call and we're going to check how many dots are left on our screen if there are no more dots left that means that we've won so if it's equal to zero we're good what i'm going to do now is i'm just going to check which number we use to represent our dots so we use zero to represent our dots so now when i write the dots left method i'm going to use that information we're going to add a method over here that's private and it's called dots left what we're going to do with it is we're going to check the map and we're going to find how many dots there are and and calculate that so in order to do that i'm going to use this method called flat what flat does is that's going to transform our two-dimensional array so we have two dimensions we have a ray on the outside and then rays inside so it's kind of like rows and what this method does is it transforms an array so i'll show you an example over here if we had an array called let's say items and items had three values over here one two three actually that's not a great example let's say items had an array of arrays so we'll have one two and then we'll have two arrays inside here and then another array three four and then an outer bracket so now items as we can see is an array of arrays as i expand that it's got this array which has more items in it in this array which has more then i'll create another a variable over here and we'll call that flat array is equal to items dot flat so when i call flat array now and look at its value it made it into a single array and items looked like that it was it had two items and each one had two other items in it so flat does this so flat is going to make this into one big flat array which which would look exactly like this if i were to remove all these things over here that's what a flat array would look like so let's put that back let's go down here and we're going to call that flat method and then after flat we're going to call filter so we're going to filter our array down to only tiles so each one of these represents a tile and we're going to check if that tile is equal to zero then we'll get the length of that array so this will let us know how many dots are left how many items in our array are equal to zero then over here if there are no more dots left and it's equal to zero you've won the game the other thing that we're going to want to do when you win the game is we also want to pause the game so what we're going to do is we're going to go to our game js you can just select your game.js file and then within our pause game we are checking if it's pacman hasn't made his first move if it's game over and we'll say if game win because then you also want to pause when the game is won so now if we give this a quick little test and we win the game we go ahead and eat these ghosts to ensure that i win the game and he's not gonna he's not gonna make it easy there but let's go ahead there we go so got lucky now go ahead and just finish off all those dots and there we are and now the game is paused i can't move anymore pac-man stopped moving it played the win game music and we've won the game let's go ahead and implement that last part of the game that shows that either you have won or you have lost so what we're going to do is we'll go into our game.js and then inside our game.js inside this game loop over here we're going to call a function called draw game end and i'm putting it here on purpose because i want it to be after the tile map is drawn and then i want pac-man and the enemies to be able to be drawn on top of the title screen so that's the reason that we put this here because the tile map will get drawn this will get drawn on time on top of the tile map and then enemies and pac-man will be drawn on top of the text so very purposefully put here between these two methods then we'll go ahead and implement that method we'll just put it here at the bottom of the file you can put it anywhere within anywhere inside that file and we'll call that draw game end now this function will only be executed if it is game over or is game win and then inside this function what we're going to do first is we'll set up some text the default text by default we're going to say will be you win there's a reason i'm putting a space here it just perfectly sets it up on our map you can do more math and whatnot to figure out how to get text just in the right place but for this particular example in this particular map this works pretty well however if it is game over we're gonna change that text to say game over and then what we'll do is we're going to do some drawing so we're going to use our ctx so in this file our ctx is globally available to us and we have our ctx fill style we're going to set that to the color black then we're going to use a ctx dot fill rectangle because we're going to draw a rectangle on the screen we'll start at position 0 there able to get the canvas dot height so for the y position we're going to take the height of the canvas divide that by 3.2 so i figured this out ahead of time playing with the numbers and we'll keep the canvas dot width the full width of it for that size oh we'll change this to just width over here and then we're going to use 80 for the height and we can quickly see that if i lose and you can see it played all our music and you can see that pac-man and the enemies are drawn on top of this black area then what we're going to do is we're going to do some more ctx stuff to create a font and we're going to use 80 pixels and we're going to use comic sans we'll save that then we'll go ahead and define something called a gradient so at the beginning of this demo had some kind of neat colors and they kind of transition from one color to another kind of like our purple background goes from purple to blue we're going to use another gradient here but this is within the context of our canvas then we're going to use something called create linear gradient and this linear gradient takes in a couple of properties we won't go too much into those but we're just going to pass in these particular values over here then what we're going to do is for this gradient we're going to go add something called a color stop and we're going to put 0 over here and then we're using the color magenta so if you just google canvas text gradients there's some really great examples on w3schools as well but normally just play around with them you can do some different colors and whatnot so we're going to say at 0.5 go to the color blue if we duplicate that line over here we can then say let's add red we can say that color will go from 1.0 over there so just kind of marking where these different colors will be then the last step that we need to do is we need to say that our fill style instead of being equal to black we would say that our fill style is equal to radiant and then we can use ctx dot fill text and fill text we give it our text so which is either going to be you win or game over and then we also give it x number and the y number so we say canvas dot height divided by two is trying to place it in the same position as our little black rectangle that we drew over here and then finally we click save go ahead and test that out and by running into an enemy and we get this nice little game over so if we decided to just do something like the color white or whatever and we ran into one of our enemies over here we would get something like that so you can see how it just immediately impacts kind of how cool it is to see the gradient color there it really makes the game feel a little bit more professional than having the white text and then we can also go ahead and win the game as well oh he's not going to let me win so there we go so let's go ahead and win the win the game so we get the you win text on there so i've eaten both enemies which makes it really easy now just need to eat the dots you can also see from the movement that we implemented it's really easy to move pac-man on the screen you get the you win text could have put a few more spaces or something to center that text but there you are you get that nice little you win and then optionally you know what you could do after this is you could create more levels change the tile map to a different tile map increase the difficulty make the enemies move more quicker there's a lot of possibilities with this pac-man here and what you can do with it if you made it to the end of this video congratulations you just made pac-man i hope that from this video you've learned a lot of modern javascript gaming concepts and how you can use javascript to make games if you enjoy videos about game development in javascript using react and just modern javascript in general please like subscribe and share my channel thank you
Info
Channel: Coding With Adam
Views: 3,365
Rating: undefined out of 5
Keywords: JavaScript Game Development, javascript, pacman, pacman javascript, pacman js, game, game tutorial, game loop, animations, pacman animation, pac-man tutorial, pac-man javascript, collision detection, javascript game development, game development tutorial, complete game development tutorial, enemy ai, simple enemy ai, best pacman tutorial, pacman canvas js, pacman canvas, html 5 canvas, pacman html5 canvas, pacman js canvas, pac-man canvas, pac-man html5, js, pacman animations
Id: Tk48dQCdQ3E
Channel Id: undefined
Length: 186min 25sec (11185 seconds)
Published: Mon Jul 26 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.