Beginner JavaScript Game Dev Project

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
if you're getting into game dev you need to create a pawn clone because it's the perfect beginner project with how simple the rule set is in this tutorial i'm going to show you exactly how to do that and make it even cooler by adding fancy css animations a computer ai and also a scaling difficulty [Music] welcome back to web dev simplified my name is kyle and my job is to simplify the web for you so you can start building your dream project sooner and in this video we're going to create this really interesting pong clone here so to get started all that we need to do is have an empty project open and we need to create an index.html file so let's create an index.html we're also going to create a styles.css file and we're going to create a script.js where all of our javascript logic is going to rely and what we can do is we can just open up this index html after we create all the content by hitting exclamation point enter that's going to create this boilerplate code and then we can open that with live server so we can just come over here save this right click open with live server and that's going to open up on the right hand side of our screen and this is going to be just a blank html page now to get started i want to put all the html that we're going to use then i'm going to work on the css and then finally work on the logic for the game now in our html we need a few different sections we're going to have a score section where we're going to put all the score so this section is going to have essentially a player score and that player score is going to be zero and it's also going to have a computer score which is going to be zero as well then below that we're going to have a ball in this ball we're going to give both an idea ball and a class of ball as you can see here and the reason i'm separating the ids and the classes is so i can use the classes in css and the ids in javascript it just makes the code a little bit cleaner and easier to work with then we're going to have essentially the same thing we're going to have some paddles we're going to have a paddle for the left player and this is going to be our player paddle since they're going to be on the left and we're going to copy that down for a paddle on the right hand side and this is going to be for our computer player right here this is all the html we need it's really quite simple because pong doesn't have very many moving parts but the styles and the logic behind it is much more complex so let's import our style sheet by just coming in here saying link and we want to say styles.css for our stylesheet and while we're at it let's do our script tag as well and we'll give this script.js we're also going to set here a type equal to module now if you're unfamiliar what this type module does i have an entire tutorial covering i'll link in the cards and description for you but essentially it allows us to use modules in our code now let's move over to our style css and start styling everything the first thing i like to do in every style sheet that i work on is i like to select everything including all the before and after elements i like to set my box sizing to be a border box this just makes sizing my widths and heights so much easier then i also almost always set the margin on my body to zero and again that just makes working with this so much easier and the next thing i want to do is actually start working on the paddles and background colors so let's come in here and we're going to say for now just a background color of black is going to be the background for our board and since that's a little harsh let's just do like 333 so it's not quite as harsh of a black color and then what i want to do is i want to select my paddles and the paddle here is where we're going to have these things on the side of our screen one on the left and one on the right so in order to style these we can do like paddle dot left that will select our left paddle and paddle dot right we'll select our right pedal and this main paddle class is going to be the styles for all of our paddles so first i want to set the position to absolute so i can position these absolutely and our paddle on the left i just want to have a left position here which is going to be 1vw so it's going to be one percent of the screen away from the left-hand side and same thing down here with our paddle right i'm going to use right is 1vw so it's one percent of the screen width away from the right hand side now if you're unfamiliar with like vw and vh and so on units i have an entire video covering that i'll link in the cards and description for you and the next thing i want to do is i want to specify the background color for now i'm just going to set this to white and i'm going to come in here with a width of 1vh and i'm going to come in here with a height of 10 vh if we save you can see we now have our paddles on the left and right of our screen and the reason i'm using vh for the width and height is because i want the paddle to always be 10 of the height on my screen to make sure that the game is always fair no matter what size screen we play on so if i set this to like 100 pixels and you made your screen 100 pixels tall the paddle would cover the entire screen obviously that wouldn't work so now no matter what size my screen is it's always 10 percent of the height and i used 1vh on the width and that way the paddle is always 10 times higher than it is wide it just makes it look a little better because if i set this to 1vw the paddle just doesn't quite look good on all screen sizes while 1vh means it'll look a little bit better and the next thing i want to do is i want to specify the top position in the top position here i want to set to 50vh just like that and make sure i put a semicolon here so that way it's going to be positioned in the center but you'll notice the top of it is 50 percent of the way down the screen i want the center to be 50 of the way down the screen so we can just do a simple transform translate and what we want to do is translate in the y direction negative 50 that moves it back up half of its own height that way it's dead center in our screen which looks really good now this top position of 50 vh is something that we're going to set in our javascript so i want to make that a css variable we're going to call this position i'm going to set this here to 50. and we're going to be setting this in our javascript so down here what i need to do is i need to use that variable which is position and i need to convert that to a vh value to do that i can just use calc and i can say times 1vh just like that when i save we get the exact same result but the important thing is i can actually change this position in my javascript code incredibly easily and it's going to update this top position for us now the next thing i want to do is to work on my colors a little bit because right now i have it hard-coded to this like black and white color scheme and instead i want to make these colors dynamic so i can change them in javascript so let's just come up here and select our root element where we can put css variables that go across our entire application i want to create a few different variables the first variable i want to select here is called hue i'm going to set that to 200 and i also want to select a saturation which i'm going to set to 50 percent and these values we're going to be using in hsl color format if you're unfamiliar with that format i have an entire video covering i'll link in the cards and description for you but essentially if we just create a foreground color here so we'll say foreground color we can set it to hsl we can get our hue portion from that variable hue we can come in here and we can get our saturation portion from that saturation variable and then we can specify our lightness value which in our case is just going to be 75 because we want our foreground color to be a very light color now let's just make sure that we close off all of these this just has an extra var here there we go now our foreground color is set so down here instead of using the color of white we can specify this as our foreground color now when we save you can see we kind of have that light blue color we can do the same thing with our background color we can say background color here and i want the same hue and saturation but the lightness is going to be 20 so it's going to be much darker and if i set this to our background color and save you can now see we kind of get this dark blue color and the great thing is we can change our hue for example i can change it to 100. now we get green zero is going to give us red we need 300 to get this like purpley color or i could change our saturation to like zero and now you can see we've kind of gone back to that black and white style so i really like this because it allows you to actually really easily change the look and feel of your site and we're going to be modifying this in our javascript so as you play the game it's going to cycle through the hues and just give you a more pleasing experience by being all these different colors and the next thing that we can focus on styling is going to be the ball and our ball is actually not that much different from the paddle to be honest they share a lot of the same characteristics i'm just going to copy all of this down here for now so instead of having a position we're going to have an x and a y so i'm going to say x here and y and both those by default are going to start at 50 because that's going to be the very center and then instead of having a top here we're going to have this be our left and our left position is going to be x and we're going to do here our top position which is going to be our y and our left is going to scale off of the width units while our top is scaling off of vh units now if we come in here with a width and height which in our case we're going to do 2.5 v h for both of those that way it gives us a perfect circle you can see we have that square right in the middle of our screen the only thing we have left to do is fix this translate this should say translate and we want it to be negative 50 percent in both the x and y direction to make sure it's perfectly dead center in our screen so that right there gives us the ball pretty much exactly how we want it the only thing left just to set a border radius and we want to set that to 50 so we get a circle instead of a square now the final thing we have to work on is our score and we want that to be in the top center of our screen so let's come down here we're going to select our score and this is right here the thing that wraps both of our different individual scores so we want this to be a display here of flex and we want to justify our content in the center and we're going to change the font weight here be bold we're also going to change the font size the 7 bh again we're going to make it just scale with the screen size so as you can see we right now have our text in the very center we can also specify the color of this text and our color is just going to be that nice foreground color so as we change the color of our paddles and everything the text is going to change along with it it's going to look really nice now the next thing i need to do is style the actual scores themselves so i can say score i want to get every single direct child so this is just selecting all the things inside of score i can change them to have a flex grow of one and a flex basis of zero what this is going to do is it's going to make sure that exactly half of the screen is taken up by one score and the other half of the screen is taken up by the other score you'll notice now this score is all the way on the left side of our screen what i want to do is i want to select the first child so pretty much get the first score i want to set the text alignment to the right side of my screen that's just going to make sure it matches back up onto the right so these are both side by side and they always take up fifty percent of the screen no matter how much text is in one so if this is a really large number you can see it always stays on the left hand side of our screen while this is a large number it always stays on the right hand side of our screen set those back to zero and zero and we can go into our styles again to finish this off so inside of our score here let's add a little bit of padding so we're going to do 0 on the top and bottom and 2 vh between them so it gives a little bit of space between the elements which looks good and our margin we're going to set one vh on the top and bottom and 0 on the left right that way just spaces out from the top of our screen and the bottom of our screen a little bit and then finally i'm going to set the opacity to 0.5 because i just don't want this to be quite as in your face as the rest of the game since it's not as important now lastly i want a line to show up between them so i can just put a simple border on the right hand side of our first child which is going to be 0.5 vh wide so pretty thin make it solid and i'm going to make it that same foreground color now if i save you can see we have a border between them so we can easily distinguish which score is which with that that's all of our styles and all of our html done and we can finally move on to the fun part which is the javascript now to get started with this game essentially we have a few things we need to understand the first thing is that our game is going to run inside of something called an update loop so every single frame that passes we're going to be calling a function and that function is going to update the positions and the logic of all the pieces of our game so for example the computer ai is going to move the paddle the ball is going to move in the current direction it's going and we can move our paddle with our mouse as well this is going to update all the positions and paint everything on the screen exactly where it needs to go inside of the update loop then the next important thing to note is we're going to break out everything in our game into separate classes just to make them easier to work with but for example our ball we're going to put in its own file called ball js we're going to set an export default of our class which we're going to call ball and inside the constructor we're just going to pass in the element that corresponds to our ball so we can say this.ball elem equals our ball element this element right here for our ball is just being passed into this ball class so we can actually use it and interact with it so to do that inside of our script here we can just come to the very top get rid of this we don't need it we can say import all this is the default export from and i want to get it from dot slash ball.js then i can say that our ball is equal to a new ball and i just want to pass in that ball element which we gave an id of ball this is selecting the ball html element and creating a new class for that ball and now we have access to it here and we can use that inside of our update loop if we want what we can do is we can create a function called update and this update loop is going to take in a time variable for how much time has passed since the start of our program and then in order to call this we can say window.requestanimationframe and we're going to put in that update function now many tutorials that you see will probably have like a set interval here where it calls update every like 10 milliseconds or something this is a bad practice the reason for that is because set interval is not really super accurate it may not always run every 10 milliseconds so you kind of have some problems there and also it's going to run in between frames with request animation frame what happens is every time that you can change what's on the screen this function is going to be cold so javascript is smart enough to say hey you can't change anything on the screen so don't even bother running code but now as soon as you can run something on the screen it calls this function for us and as long as we keep calling window.requestanimationframe it's going to infinitely loop so right here we've created an infinite loop which is called update every single time that something on our screen is allowed to change so every frame it's going to call this function for us and all we need to do is set this up and now we have that update loop i can say console.log time and now if i come over here and i inspect our page go over to our console you can see it's printing out that time and it's just constantly getting bigger as you can see it's incrementing by about 5 10 milliseconds at a time it's a very small amount of time between each render of our screen now what i need to do is i need to take this time that gets passed in and convert it to something called a delta so we can determine how much time has passed from the previous frame to the new frame to do that is actually quite simple let me just say const delta is equal to time minus i need to get the last time so let's create a variable called last time by default it's going to be nothing and then every single render we're going to set our last time equal to our current time now what happened here is every single time we call update we're taking our last time and we're subtracting our time from that last time to get our delta and then we're setting our current time to the last time and then it'll repeat but the first time we call update last time is null we don't have a last time we need to check for that so if last time is not equal to null then we're going to do all of our important code so here we're doing all of our important code for updating everything and then what we want to do is come down here and we're going to set our last time in our window.request animation frame so inside of here we're going to do our update code and we're only doing our update code if we have a last time because if we don't have a last time that means that we don't have anything to compare to to get our delta so the first time we call update nothing in here runs we just set our last time and call it again the second time it runs we have it last time so then we can use this delta and so on so now if we just console.log our delta and i inspect our page over here go to our console you can see we get our delta being logged out and it's around seven milliseconds every single time you can see there's a little bit of fluctuation which is okay now inside of here where we're doing our update code what i want to do is i want to take our ball i want to call the update function on it i'm going to pass in that delta this update function is a function we're going to create and we're passing in the delta into this function the reason we're passing that delta in is because as you saw that delta fluctuated sometimes it was like 6.9 milliseconds sometimes it was like 7.1 it fluctuated a little bit so it's important to use that delta to make sure all of our movements in our game are based on that because if for example we have a big frame drop and the time between frames is like 50 milliseconds we want to make sure we take that into account when we're performing our calculations so inside of our ball let's create an update function which takes in a delta now before we get right in this function we need to think about what are we updating with our ball well we know our ball has a position it's going to have an x and y position and it's also going to have some kind of velocity which it is moving and it's also going to have a direction which it's moving so in our update what we want to do is we want to take that velocity and the direction and add that onto our current position and then do all the calculations to see if it's bouncing off a wall or bouncing off a paddle so inside of our update we need to first get all this information so we need to create some helper functions so we can do that so let's create a helper function for getting our x variable and this is just going to return to us a value which is x and if you remember in our styles way up here we set our x right here to 50 and it's that css property well to get that css property what we need to do is we need to call git computed style and we passed it in our ball element and then we want to call the get computed property i'm sorry get property value and pass it in the name of that css variable which is just x then what we want to do is we want to parse this as a float so essentially what we've done is we've taken the value from our css right here of 50 and we've converted that into a javascript number that we can use i'm also going to create a setter for x and the setter here is going to be ball dot style dot set property and it's going to be that x property and we're going to set it to a value which gets passed into set x and these getters and setters here are really nice in that you can just say like this dot x equals 5 and it's going to call this set x function pass in five and do all this code for us so it's going to set our position to five and now if i save you can see our ball has moved to have an x position of five because we're calling update repeatedly and we're just setting x to five inside that update so we now have essentially called our update and we can set our x position let's just copy this so we can set our y position as well we're going to come down here with y and just change these also to be y so now i can say this dot x is 5 and let's say that this dot y is 15. so now when i save you can see our ball is up here in the top left corner five percent away from the left and fifteen percent away from the top so now we have our x and y position taken care of but we still need to worry about our velocity and the direction that we're traveling in and this is something we probably want to set up when we create our ball so i'm going to create a nice helper function called reset and this reset function is going to allow us to set all those properties so when we create a ball we're going to make sure we call that reset function inside of here i just want to take our x and i want to set it to 50. i want to take our y i want to set it to 50 as well so i'm just going to default these to those initial values in the middle of the screen and then what i want to do is i want to find out what our direction is and this direction is a little bit complex so our direction is going to be essentially an x and a y coordinate so let's just say like 0.75 and y is going to be like 0.5 let's just pretend that these are the values for x and y and that's what our direction is going to look like so to visualize this let's take a look at this diagram here we have a y direction and we have an x direction so our x value of 0.75 represents this x direction here and y represents the 0.5 going upwards and then we have this a line this a line is going to be the actual direction that our ball is traveling which is essentially a combination of our x and our y but the really important thing we need to make sure we do is we need to make sure the length of a here is one so whenever we calculate a the length is always going to be one the reason that's important is because this is giving us something called a unit vector and then we can multiply our unit vector which is one by our velocity so let's say our velocity is 20 and it's going to mean that we're going to move 20 units in the direction of a and the reason that we need this to be a unit vector is because if our vector here for a was like 30 units long well then when we multiplied 30 times 20 we would be moving 600 units in the same direction so by having a unit vector for our direction it means that our velocity is the only thing that determines how fast we go and our direction only determines which direction we're going and not the actual velocity that may sound a little bit confusing but as we get to the actual code i'll explain it a little bit more depth and show you exactly what i'm talking about so in order to calculate our direction we need to do is we need to essentially create a value for x and our y and i'm actually going to do this inside of a while loop which you'll see why in just a second for now we're just going to set this to wild true but i'm going to actually put the code for while inside of here so what i want to do is i want to get the heading essentially where are we heading in a rotation so like 0 to 360 degrees and this heading variable i want to make sure that this heading is going to be set in terms of radians i'm going to try to get a random number between i want to get a random number between 0 and 2 pi and that's because 2 pi is essentially the equivalent of 360 degrees we'll say math.pi so now this random number between will give us a random number from 0 to 360 degrees but it gives it to us in radians with radians we can use cosine and sine to actually determine the x and the y direction so what we can do here is we can say this dot direction is equal to which i spell direction correctly and x where x is the cosine of our heading and the y is going to be the sign of our heading now what we've done here essentially is we've created a random value between 0 and 2 pi to determine our direction and then we say taken that direction and we've converted to an x and a y position and this is going to be a unit vector for those positions it's going to give us an x direction for example 0.75 that says we move 0.75 units to the right and we're moving 0.5 units up and when you combine those together we're going to get a unit vector that points 1 in the direction of the x and the y combined together confusing i know but you'll see how it works once we get the code actually running now the reason i have a while loop here is because the game isn't very fun if the ball always moves up and down and not very far left or right so i want to make sure our x direction is at least big enough or small enough that it's going to move far enough to the left and right to make the game enjoyable i'm just going to come in here i'm going to say if this dot direction dot x is less than or equal to 0.2 or the direction oops direction is greater than or equal to 0.9 that just means that the game is not going to work very fun because it's going to be mostly up and down and not very far side to side make sure this is dot x and the reason we're doing a check for both less than 0.2 and greater than 0.9 is because if it's greater than 0.9 it means the ball moves almost side to side completely without very much up and down motion and less than 0.2 means it's moving almost entirely up and down not very far left to right and since we can get negative numbers i want to make sure we absolute value this so by doing this we're saying hey is the absolute value going to be less than or equal to 0.2 because sometimes we'll have a negative value like negative 0.8 and that's going to be fine so we want to make sure we do the absolute value for both of these so math.absolute value of this one as well now if we just set our x here to like a default of zero that's going to make sure that our while statement here is true and then we're going to come into here and we're going to do all those checks so now if i save this i just console.log dot direction and come over here you can see that we get a random direction but of course random number between is not defined so let's create that function ourselves we'll say random number between a minimum and a maximum and this function is pretty simple we're just going to take a math.random multiplied by our maximum minus our minimum oops just like that and then we're going to add our minimum on the end so essentially what this does it gives us a random number between 0 and 1. we're using this max minus min trick to make sure that it's going to scale this value to be within our range and then add the minimum on just so it's always making sure the minimum is the lowest number we can get now you can see we get an x direction of 0.6 and a y direction of negative 0.7 and if we just refresh our page you can see we get completely random directions again and again and again and every single time we're getting random directions now the very last thing we need to do is just specify our velocity so we can say this dot velocity is going to be equal to some initial velocity value i'm going to make this a constant variable which we're going to define way at the top of our file so we'll say const initial velocity and we're going to set this to 0.025 you can mess around with this number all you want to try to tweak it to find the exact value you want but this is a value that i think works pretty well as a starting value it's slow enough but fast enough is not too boring so now that we finally have all of our value set we can actually do our update like we want to so the very first thing i want to do is i want to take our x value and i want to add it the direction we're going so i'm going to say plus equals so this is going to add to our x value and what i don't do is take our direction in the x i want to multiply that by our velocity and right here what we've done is essentially said hey take the direction we're going in the x direction and multiply it by our velocity and we're going to move the x position that much but the important thing to note is we make sure that we multiply our delta on to the end of this that's because again if we have long delays in between animations of our frames that's going to be a large delta so we want to make sure our ball moves a large distance if there's a large pause between frames and if there's a small pause between frames the delta is going to be small so the ball moves in a smaller increment i want to do the same thing for our y down here i'm going to change this to our direction in the y direction now if i save you can notice our ball is moving but of course it doesn't quite look right that's because i need this to be plus equal for our y now if i save you can see our ball is moving down to the bottom right if i refresh you see our ball is moving down to the bottom left it's moving up this time it's moving to the right this time as you can see every single time it moves in a random direction one thing you'll notice though is when it goes off the page we get a scroll bar fix this we can go to our body and we can set our overflow to hidden and now when i save you notice that even though it's outside the bounds of our screen we don't get those scroll bars anymore now the next thing to do is to make it so it bounces off the top and bottoms of our screen so what we want to do is we want to create a simple function called rect and this function is going to get it as the position of our ball so we can just say return oops return this dot all element dot get bounding client correct and then down inside of our update we just say const rect is equal to this dot erect then what i can do is i can just put a simple if check i can say hey if the bottom of our rectangle is greater or equal to our window whoops window dot inner height and that means that we've gone past the bottom of our screen or if our rect.top is less than or equal to zero that means we've gone off the top of our screen so what i can do here is i can say hey this dot direction dot y is going to be multiplied by negative one so all we're doing is flipping the y direction so when we hit the top of the screen instead move downwards and we'll hit the bottom instead move upwards now if i save this we get a ball that moves upwards so let's just refresh till we get one that moves mostly up or down you can see once it hits the top it'll now bounce and changes direction that's exactly what we want you can also do the same thing so it bounces off the left and right side of our screen the only reason that we're doing this right now is so that we actually can test to make sure everything's working eventually we're going to make it so this only bounces off the paddles and not the screen so if our right side is greater than or equal to our inner width or our left is less than or equal to zero we're going to multiply our y by negative or x i'm sorry by negative one now no matter what wall we hit we should be bouncing off of it you notice the ball is kind of slow and it always stays slow we want this to speed up as time goes on what we can do is we can take our velocity and we can multiply our velocity by some kind of increasing value so we can say velocity oops velocity increase and of course make sure we include the delta as well so that it scales with the frame times and then up here we can set that value we want this to be a very small value because this is going to be adding in every single time i want to make sure down here i do a plus equal instead of a minus or multiply equal there we go we could do velocity increase and this value like i said very very small we're going to do .0001 now when i save you notice the ball starts out slow but as you can see over time it starts to get faster and faster it starts to ramp up pretty quickly even though our value is really small and then eventually it's going to become so fast that one of the players is going to use lose either the computer or u and then hopefully once someone loses we're going to reset the ball back in the center move it back down to the slower speed using this reset function and have it move in a random direction as you can see it's continually getting faster and faster and faster and faster now what we can do is we can go back to our script and for now i'm just going to comment out that ball update so we don't have it flying around all over the screen what i want to do is i want to focus on the paddle portions of the game instead we're going to first focus on the player paddle and then we're going to work on the computer paddle so let me get our player paddle we could say player paddle is going to be equal to a new paddle this is just going to be document.getelementbyid and this is player battle i'm going to do the exact same thing for our computer paddle there we go computer paddle computer paddle and we just need to create this paddle class let me just make sure we import it and then we can create a paddle class title.js export default class paddle and it's going to have a constructor that takes in our paddle element we could just say this dot paddle element equals paddle element there we go now we have a player paddle and a computer paddle that we can use and for our player pedal it's going to be very easy to update because we don't even need to use an update function since we're just going to make the y position of our paddle the same as our mouse the way down here we can say document dot add event listener on mouse move we're going to get that event object this event object has a y property all i want to do is i want to take our paddle for our player so player paddle i want to set the position equal to e dot y simple as that but this position in our css if we go over to it you can see our position here is using percentages so it's 50 of our screen 50vh for example here this is a pixel value so we need to convert this to a percentage by dividing it by a window dot inner height and then multiplying by 100 so this is going to convert it to a value between 0 and 1 and this will give us a value between 0 and 100 for our position now let's make it so we can set the position of our paddle by using a getter and a setter for our position position there we go here we're going to do position and here it's going to pass in a value this is going to work exactly the same as our ball so up here we can just copy the git for our position here and this instead of saying x is going to say position and then we can copy this set again it's going to be the exact same thing but instead of x it's going to be position instead of ball element we're using our paddle element now if we save and i move my mouse you can see that the position of our paddle is exactly the same as the position of our mouse no matter where i move it my paddle is falling the reason it's doing that is because right here we're just setting our position paddle equal to wherever our mouse moves we didn't even need to worry about the update code at all for our paddle which is really nice but for our computer generated paddle we're going to need an update for that for our computer paddle we're going to come in here and we're going to call that update function of course we're going to pass in the delta and also we're going to need to pass in the y position of our ball because the paddle needs to know where the wall is so we can move to that position so we're passing in the delta and the y position of our ball then inside of the paddle class we can set that update function inside here all we need to do is just make it so our paddle follows whatever the ball is on the screen so we could make it super simple by just saying here this is going to be our ball height we could just say that the paddle position is going to be equal to ball height and that would mean that the essentially the paddle is going to move to exactly where the ball is instantaneously but then you would never be able to win the computer would be impossible to beat so instead what i want to do is i want to make it so that the computer has a maximum speed it's set to a variable called speed and this speed variable we'll just say is 0.02 and then what i want to do is i want to say hey our position is going to be incremented by an amount which is going to be our speed times the delta and then what i want to do to determine if we're going to move up or down is i just take our ball height minus our current position so if the ball is above our current position we move upward and if our ball is below our current position we're going to move downwards this is going to just give us a negative or positive number also this number is going to be larger when our paddle is further away from the ball so that the computer can move faster when it is further away from the ball now if we save this you're going to notice nothing at all changes but if we go over to our script and make it so the ball starts moving we should hopefully see that the computer paddle is following the ball exactly which is what we want but eventually once the ball starts to move too fast the computer is no longer going to be able to keep up and then the player will be able to score so that's kind of the idea behind this ai it's a very simple ai you can make it more complex less complex whatever you want but i kind of like the ai how it is now let's turn off the ball update again so we don't have that flying all over the screen instead what i want to do is i want to create a setup position for our paddle so it always resets to the center of our screen to do that we're just going to create a simple reset function reset and this reset function is just going to take our position and set it to 50 and then when we create our paddle we're just going to say this dot reset there we go now we've reset our paddle in the center every single time we call that reset function and in order to actually do this reset what we need to do is to determine if we've lost the game essentially if the ball has gone off the side of the screen so in our script let's actually worry about that so here inside of our update we want to say if we'll say is lose then what we want to do is we want to run some code and we can create that function is lose now this is loose function is actually really simple in our ball you remember down here where we calculated hey is the ball outside of bounds let's just copy that code we're going to paste it inside of here so if our ball is outside of bounds then we have lost this is our lose code right here so really all i want to do is i just want to return this as a variable so i can say return right here and i just want to get the rect for our ball which is equal to ball.rect so this is just saying hey is our ball out of bounds on the right or left-hand side if so we have lost so inside of here i can just say console.log then in our ball we can just make it so it doesn't rebound we'll just comment out this code for now and if we go into our script and we update our ball as soon as it goes out of bounds we should see in our console it prints out booze as our text and it's just continually printing out because our ball is continually out of bounds so what we need to do instead is now handle when our ball is out of bounds once again just turn off that ball update for now and inside of our is lose we want to call a handle lose function call function called handle lose this function is going to do everything for resetting our game back to where it was before we'll say handle loose make sure i spell that correctly what i want to do here is i want to take my ball i want to reset it into the center of the screen i want to take the computer paddle i want to reset that back into the center of the screen as well and then i want to increment the score so we could say our rect is equal to our ball.rect and then i want to say hey if we went off the right side of the screen the player actually scored so if rec.write is greater than or equal to window dot inner width width there we go then that means the player has scored so i'm going to take the player score element which is a variable we're going to create just say const player score element is document dot get element by id and this is just player score that's what we called it i'll do the same thing for our computer score but we want to get our player score element i want to get the text content inside of it and what i want to do is i want to set this equal to essentially one more than the text that's currently in it i'm going to parse an integer version of the text that's in there right now player score element dot x content add one and that's because by default the text is set to zero and then the other thing we need to do is just check to see if the computer won so we can just use else here instead if the computer won all we need to do is just copy this line down and use the computer score instead of the player score i take the computer score and increment it by one so now if i save and i make it so our ball updates and i let the ball go off the right hand side of the screen or the left hand let's just let it go off the left hand because that's easier to just lose and actually it went off the right hand side because we don't have our paddles working yet but you can see the score is incrementing properly when it falls off the right hand side the score for me goes up by one if it falls off the left hand side the score for the computer goes up by one that's working as expected but we're not bouncing off the paddles let's work on that next again i'm just going to comment this out so it's not moving all over the place and we can go into our all and we want to be able to check hey did we bounce off the paddles here if so then change our direction we need to pass in our paddle rex this is the rectangles for our paddles now in order to get this inside of our paddle we need to create a rect function and this rect function is just going to return this dot paddle element that get bounding client correct there we go that's going to be our rectangle then in our script what we can do is we can just pass in oops we can pass in our rectangles so we can say player paddle dot wrecked and we can say computer paddle direct that's going to be both of our rectangles passed into our ball then inside of our update here for our if check we want to check to see if any of our paddle rectangles had a collision we can just say cattlerecks.sum we're going to take that rect and we're going to call an is collision function passing in our rex for both the paddle and our actual ball so this function just loops through all of our different paddle rectangles if any of them return true for this is click collision function it's going to return true for the entire thing let's create that function is collision this function is pretty simple we're going to take in rect 1 and rack 2. all we're going to do here is just do a simple return where we're taking our rect 1 checking that the left side of it is less than or equal to the right side of our rack 2. we essentially just want to check all the sides of our rect 1. so if the right side is greater than or equal to the left side of our rack two then that means that we're currently overlapped same thing we're going to do for top and bottom so if top is less than or equal to rect two dot bottom and then finally lastly we have our rect one dot bottom needs to be greater than or equal to our rect two dot top this is going to check for a collision so if we have a collision with any of our paddles swap our x direction now if we come over here comment this back in we could hopefully see that if it hits our paddle it's going to bounce the other side of the screen and as you can see it's working pretty good and if it hits our paddle again it's going to bounce but if it misses the paddle so for example if i miss you can see that it goes through and it's going to score for the opponent now the very last thing that we have left to do is to come into our styles here you can see we have this hue variable we can actually change this in our javascript if i go into the script js what i could do is i could say document whoops document dot document element that's going to select this root element here that has our hue variable inside of it what i want to do is i want to get the computed style so i could say get muted style and i want to get the computed style i want to get the property value for hue and of course i want to parse this as a float just like that i'm going to set this to a variable called view there we go and then what i want to do is i want to take that hue value and set it so we can say document.documentelement.style.set property in our case this is going to be our hue i want to just change our hue so i'm going to take rq i'm going to add in our delta and i'm going to multiply our delta by 0.01 so there we go all we're doing is slowly changing our cube by the small amount every single time that our frame changes if we save you can see over here that our color starts out as blue and now it's kind of darker blue and purpley color and as time goes on a little bit longer it's going to become a red color then green and yellow and so on this is just a cool way to be able to shift through all the different hues give our game a little bit more visual feel now if you enjoyed this project you're definitely going to love some of my other game clones such as the snake game or the flappy bird game they're both linked over here highly recommend you check them out and with that said thank you very much for watching and have a good day
Info
Channel: Web Dev Simplified
Views: 20,038
Rating: 4.9593906 out of 5
Keywords: webdevsimplified, pong game, pong game js, pong game javascript, js game dev, javascript game dev, javascript game, js game, pong js, pong javascript, pong game dev, web dev game dev, js game development, pong game development, pong game tutorial, pong game js tutorial
Id: PeY6lXPrPaA
Channel Id: undefined
Length: 39min 14sec (2354 seconds)
Published: Sat Dec 04 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.