JavaScript + HTML5 GameDev Tutorial: 8-Ball Pool Game (part 2)
Key Takeaways
Creates an 8-ball pool game with HTML5 and JavaScript
Full Transcript
hi everybody and welcome to the second video on a series that shows you how to build an 8-ball pool game with javascript and html5 in the last video we implemented the shoot method on both the stick class and the ball class so that when we'll release the left button on our mouse it will shoot the ball towards the position of the pointer and we also display this shooting animation as you can see right here on the canvas okay so now i'll open the vector2.js file and there i want to add a method so i could get the length of a given vector so vector2.prototype.length and that will be equal a function and here i'm going to return the result of the length formula on the given vector and i'm going to calculate that using the math object of javascript [Music] okay great inside ball.js i want to add another property to the ball class that will indicate whether the ball is moving or not so this dot moving will be initially false and inside the update method i want to set it to be false if dot this dot velocity dot length is less than let's say five so if that happens i want to set this dot moving to be false and before that i want to set uh this dot velocity to be a new vector 2 so its x and y values will be zeros and inside the shoot method after i um change the velocity i want to set this dot moving to be true and i'm going to add another uh property to the stick class and i'm going to call this property this dot shot and initially it will be false maybe i can find a better name but for now that will do and inside the shoot method i want to um set this dot shot to be true and inside the game world uh we'll implement another method that i will call gameworld. dot balls moving and that will be equal a function and for now we only have one bow that this object contains so we'll return this dot white ball dot moving inside the update method so if all the balls uh stop moving so if um this dot balls moving and if um this dot stick dot shot is true um so sorry if not this dot balls moving i'll call a method inside the stick object that i will name reposition and i will send this dot white ball dot position so i want to reposition the stick to the new position of the white ball so let's open stick.js again and here i'm going to implement this method stick dot prototype dot reposition and that will be equal a function that will get a position as an argument and it will set this dot position to be a copy of this position the the position argument and i'm going to set uh this dot origin to be equal the stick origin constant a copy of it now back in the browser let me refresh and once the ball stops moving the stick changes its position to be the same as the new position of the white ball just one final thing before we move on on the reposition method that we just wrote let's set this dot shot to be false and let's see that everything still works as it should okay great in assets.js let's load some more sprites um so the first one will be the sprite of the red ball and the second one will be the sprite of the yellow bowl and the last one will be the sprite of the black ball now i will create a new file that will go by the name of color.js and there i'm going to define something that we call in other languages and enum and it will contain all the different colors that we use on our game so uh red yellow black and white and each color is going to have a different value back in assets.js i will implement a helper function that will provide me the sprite that i want based on the color that i will send it so i will call this function get ball sprite by color and it will get as an argument a color and here i'm going to um create a switch case statement so switch color and in case the color is color dot red i will return the red sprite okay so i filled it up with the rest of the colors and now we can uh go to the bowl class and change the function constructor so it will get a color as an argument and here i'm going to set the sprite this dot sprite to be get ball sprite by color and send the color that we got as an argument and here in the draw method we can just delete sprites dot white ball and send this dot sprite instead so now we have to go back to the game world and to send the color that we want for the white ball which is of course white and let's go to the index.html file and add a reference to the color.js file that we just wrote so script src and that will be equal color.js back in our browser everything still works fine in purpose of testing let's uh change the color to be red and let's refresh the browser and that also works great so let's change it back to be white as we want it to be okay so let me paste a bit of code here because i don't see the point of writing it all again what you see here in front of you is an array that contains all the different arguments that we need in order to create our ball objects so you can see that each element in this array is actually a pair that contains a position and a color and eventually we use the map function in order to take every parameter and to pass it into the bowl function constructor to create a new bowl so at the end of the day what you get is that this dot balls contains all the balls other ball objects that we need in our game so down here instead of creating a new object for the white ball member we can just refer it to the last object in the array that we just created and maybe we'll change it in future but for now that will do and down here in the update method we can just loop over this array and right for let i equals zero i is less than this dot balls dot length i plus plus and to call this dot balls at i dot update and to send the delta of course and let's copy that and paste that on the draw method so we can loop over the array and instead of calling the update method we can call the drill method so back in our browser finally you can see that our setup at least visually is pretty much complete and if i'll shoot the ball towards any direction really as soon as the white ball stops moving the stick repositions itself to the new position of the white ball okay so there's something that i need to fix before we move on now that we have more ball objects it's not enough to uh check only if the white ball is moving on the ball's moving method we want to uh loop over the array and to see if any of the ball object is moving so i will set a new boolean ball's moving to be false and let's loop over the array this dot balls dot length i plus plus and if this dot balls at i is moving we can set both moving to be true and we can break out of the loop now we will return [Music] both moving back in our browser let's see that everything still works yep that looks fine now in vector2.js we'll need to add some more operations to support the collision system that we're going to implement later on so um we'll add here a new um method so vector2.prototype.add and that will be equal a function that will get another vector and we're just going to return a new vector that will be the sum of both vectors so this dot x plus vector dot x and this dot y plus vector dot y [Music] let's add another one and let's call this one subtract [Music] and here i will return the subtraction result of this of the vector argument from this vector and the last one for now will be the dot product so vector 2 dot prototype dot dot that will be equal function that will get another vector and this function will return the result of a dot product operation between both vectors so that will be this dot x multiplied by vector dot x plus this dot y multiplied by vector dot y now let's go to our game world and there on the update method before we do anything we want to check if collisions occur so let's write a new uh method for that and let's call it on the update method let's call this method this dot handle collisions so um gameworld.prototype.handle collisions and that will be equal function [Music] and inside this function i want to loop over the array in a certain manner that will provide me all the possible pairs of objects so uh for let i equal zero is less than this.length i plus plus and inside the nested loop i'm going to declare let j be i plus one [Music] j is less than this dot both dot length i and i plus plus [Music] okay so inside this loop let's get the first ball out of the array so first ball that will be equal this dot balls at i and const second wall and that will be equal this dot both at j and i want to write something like first ball dot collide with um second ball and of course we need to implement uh this method in order for that to work let's see that everything is fine here um oh actually i have a mistake inside the nested loop and we need to increase j so j plus plus okay so now let's implement the collide with method inside the bowl class so bowl.prototype dot collide with and that will be equal a function that will get a ball as an argument okay so this is the moment we all have been waiting for elastic collision in two dimensions and before i begin i must give a huge credit to chad burchek who wrote an article about this subject in 2009 and this article explains everything in a very simple manner and even if you don't have a mathematical background i really encourage you to go and read this article i will leave a link in the description down below and really it's very easy to read and it's it explains everything um just beautifully so go and read this article one more thing that i want to say before we begin is that i'm going to provide you with steps on how to implement elastic collision in your code but i'm not going to get too deep inside the mathematical proofs and concepts okay so now that we're all set let's begin step one finding a unit normal vector a unit normal vector is a vector that has length of one which is perpendicular to the surfaces of the balls at the point of the collision in order to find the unit normal vector we need to find a normal vector first and we can do that by subtracting one of the ball's position from the other ball's position so back in our code in the collide with method let's find a normal vector and let's scroll down a little bit so it will be easier to see okay that's better so const n and that will be equal this dot position sub subtract and we'll send ball dot position [Music] from this normal vector we can also get the distance between the centers of both balls and this will indicate us whether a collision occurred or not so let's um find the distance and let's set const dist to be n dot length and if the distance is greater than the ball's diameter then we want to return from this function because there is no collision between both balls let's not forget to set another constant that will call ball diameter and in our case that will be 38. okay so now let's find a unit vector of n and we can do that by taking n and multiplying it by one divided by its length okay so now back in our code let's write a new comment and we'll declare here that um here we're going to find unit normal vector [Music] let's set uh const u n uh to be n multiplied by 1 divided by n dot length [Music] step 2 finding the unit tangent vector back to the drawing you can see that the unit tangent vector is a vector that has a length of one and is tangent to the surfaces of the balls at the point of the collision we can find it by using our unit normal vector that we already found we just take the x value to be minus u n dot y and the y value of the unit tangent vector to be u n dot x back in our code let's write a new comment finding unit tangent vector and we'll set const u t to be a new vector to object [Music] that its x value will be minus u n dot y and is its y value will be u n dot x [Music] step 3 resolving the velocities into normal and tangential components so we're doing that by performing a dot product operation between the velocities of the bows and the u n and u t vectors that we already found back in our code let's write a comment uh project velocities onto the unit normal and unit tangent vectors okay let's go one by one so const v one n and that will be equal u n dot this dot velocity const v one t and that will be uh u t dot this dot velocity [Music] const v to n and that will be u n dot bo dot velocity [Music] and finally const v2 t and that will be equal ut dot ball dot velocity [Music] step 4 find new normal velocities we want to find the normal velocities after the collision and for that we can use the formula for collisions for elastic collisions in one dimension and because both of our objects have the same mass what we get here is rather simple if we just put our values inside we get that v tag v1 and tag tag means after the collision will be equals to uh will be equal to v2 n and v2 and tag tag stands for after the collision will be equal to v1 and that we already calculated in the previous step so back in our code that will be pretty easy to implement so let's just write a new comment first find new normal velocities and we'll set um let v1 and tag be equals v to n and let v to n tag b equals v one n step five now we want to convert the scalar normal and the tangential velocities into vectors and for that we need to make some few multiplications between the vectors and the unit normals and the unit tangent that we calculated before so let's go back to the code and implement that so back in our code let's write a new comment convert the scalar normal and the tangential velocities [Music] into vectors so v1 and tag will be um the unit normal multiplied by v1 and tag [Music] and let's set const v1t tag to be ut multiplied by v1t and let's set v2 and tag to be equal um un multiplied by v2 and tag and let's set const v2 t tag to be equals um the ut multiplied by v2 t [Music] step 6 the final step for now update velocities now we need to update the velocities of our ball objects according to the equations that you see right here in front of you so back in our code let's write a new comment and let's write update velocities yeah finally so let's set this.velocity to be v1n tag add [Music] v1t tag and ball dot velocity to be v to n tag dot add v to t tag [Music] and now let's set this dot moving to be true and let's also set ball dot moving to be true [Music] okay so now back in our browser let's test the results i'm really excited let's see what happens okay um so we do have collisions but we also have an issue here because you see that the balls kind of merge together and that's not good for us there is a way to fix that and let's do that let's fix that okay so back in our code we will need to find the minimum translation distance which is the minimum distance that an object a colliding object can be moved in order to not collide anymore with the other object so const minimum translation distance mtd will be equal the normal that we calculated before multiplied by the ball diameter minus the distance divided by the distance and i should put this part in parenthesis okay so now let's push and pull the balls apart um okay so let's do that by setting this dot position to be this dot position dot add and i will add the empty d multiplied by half and i will set ball.position to be the ball.position dot subtract mtd multiplied by half [Music] okay so back in the browser let's test the results and hey whoa this is actually working so let's try another one here yay great okay so even though the physics that we implemented in this game are 100 correct we still got an issue here let me demonstrate and let's see if you can spot it ok did you get it let's watch that again in slow motion here you'll see that at the time of the collision some of the balls overlap each other and that happens because it detects the collision too late when the balls are already on the same area back in our code in order to minimize that unwanted effect i will try to tune some of the constants so let me start with the delta and let's set it to be 1 divided by 177 and that's just the number that i came up with and let me just remind you that the delta defines how much of the ball's velocities we will add to the ball's positions on each iteration of the main loop [Music] now in the bose update method we will multiply the velocity by 0.984 in the part of the code where we apply friction and let me just write it in in a comment so here we apply friction and again you can choose any number that suits your needs back in our browser now it looks much better but since we decreased the value of delta it seems like the stick doesn't hit the white ball with enough power so back in our code inside the increased power method of the stick class we will increase every time by 120 and let's set a max power maximum power so if this dot power is greater than max power i want to return from this function and let me just set const max power to be for now 8 000 now let's check the result and i don't know maybe we'll change it to 7500 okay so i think that's better please take your time and tune those numbers until you will get a result that will satisfy you of course that's not a perfect solution to the problem but that will do for now if you want you can read more about something called quad trees and how to use it for collision detection but that's beyond the scope of this tutorial inside the game world i'm going to create a new member that i will call table and this dot table will be a new object literal that will contain the x and y values of the borders of the table [Music] so top y is 57 and the right x value the right borders x value is 1443 and the bottom y value is 706 and the left borders x value is 57 [Music] now inside the handle collisions method inside the first loop i want to write something like this dot balls at i dot collide with and it's instead of sending a ball i want to send a table the table that we created so in order for that to work i will create two more methods inside the ball class and the first one i will call ball dot prototype dot collide with ball and that will be equal a function that will get a ball as an argument and the second one will be ball dot prototype dot collide with table and that will be equal a function that will get a table as an argument so now let me just copy all the content of the collide with method that we wrote for ball to ball collision and let me paste that inside the collide with ball method that we just wrote [Music] and here i'm going to change uh the argument to be called object instead of bo inside the collide with method and i'm going to check if object is instance of ball and if it is i'm going to call the collide with ball method and i'm going to send this object and else i want to call this dot collide with table and to send the object [Music] okay so back in the browser we see that table is not defined so let's go back to the game world and instead of sending table we need to send this dot table and let's check again so again table is not defined and this time it's on the collide with method so here i sent um accidentally table instead of object so let's go back to the browser and let's refresh and see that everything still works yeah it does so back in our code in the collide with table method the first thing i want to do is to check if the ball is moving and if it's not i want to return from this function [Music] next i will set a new variable that i will call collided to be false [Music] and before i move on i need to create a new constant that i will call the ball radius and it will be half of the ball's diameter [Music] now i want to check if this dot position dot y is less or equal to the table dot top y plus the ball radius and if that happens i want to set the velocity to be a new velocity that its x value will be the same x value of the previous velocity and its y value will be minus this dot velocity dot y and i want to set collided to be true now let's test the results on the browser and that looks like it's working so now let's do the same thing for the right border so this should be x instead of y and this should be right x instead of top y and this should be greater or equal and this should be minus i hope you guys are following and here instead of minus this dot velocity dot y i need to make the x value to be minus the x value of the previous velocity [Music] so now let's refresh the browser and test the right border and that seems like it works so back in our code we need to do the same for the bottom one and the left one so let's start with the bottom and that should be greater or equal and that this should be bottom y and that should be minus the ball radius and the code inside should stay the same so let's refresh and let's test and that looks fine so now the last border let me copy that and paste that here and instead of um greater it should be less than or equal to left x plus ball radius and same here we don't need to change the code inside the if statement let me just refresh the browser and let's see and yet all the borders collisions are working so one final thing that i want to do inside this method is to decrease the velocity in case of collision so if collided so this dot velocity will be this dot velocity multiplied by 0.98 to simulate energy loss okay so let's test the results let me refresh and let's shoot the white ball towards the other balls and hooray so you can see that we pretty much finished implementing the physics for this game i'm sure there are still some bugs here and there but we'll find them on the go and we'll fix them all and this was it for this video thank you very much for watching it and stay tuned for more goodbye
Original Description
Learn to build an 8-ball pool game from scratch with HTML5 and Javascript. This is part 2 of a 3-part series.
Part 1: https://youtu.be/aXwCrtAo4Wc
Part 3: coming soon
🔗Github repo: https://github.com/henshmi/Classic-Pool-Game
🔗Game demo: https://henshmi.github.io/Classic-Pool-Game/
⭐️ Tutorial created by Chen Shmilovich.
🔗Chen's YouTube channel: https://www.youtube.com/channel/UCLUtNUb2G2XHp9Zty__D3xw
🔗Chen on LinkedIn: https://www.linkedin.com/in/chen-shmilovich/
--
Learn to code for free and get a developer job: https://www.freecodecamp.com
Read hundreds of articles on programming: https://medium.freecodecamp.com
❤️ Support for this channel comes from our friends at Scrimba – the coding platform that's reinvented interactive learning: https://scrimba.com/freecodecamp
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from freeCodeCamp.org · freeCodeCamp.org · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
React: Production Server Setup Part 2 - Live Coding with Jesse
freeCodeCamp.org
cookies vs localStorage vs sessionStorage - Beau teaches JavaScript
freeCodeCamp.org
Browser history tutorial - Beau teaches JavaScript
freeCodeCamp.org
Graph Data Structure Intro (inc. adjacency list, adjacency matrix, incidence matrix)
freeCodeCamp.org
React: Parameterized Routing with Next.js - Live Coding with Jesse
freeCodeCamp.org
React: Dealing with jQuery Issues - Live Coding with Jesse
freeCodeCamp.org
setInterval and setTimeout: timing events - Beau teaches JavaScript
freeCodeCamp.org
Browser and Device Testing - Live Coding with Jesse
freeCodeCamp.org
Last Minute Updates - Live Coding with Jesse
freeCodeCamp.org
Post Launch Updates - Live Coding with Jesse
freeCodeCamp.org
React: Setting Up Google Analytics - Live Coding with Jesse
freeCodeCamp.org
React: Masonry Layout - Live Coding with Jesse
freeCodeCamp.org
Load Balancing Digital Ocean Droplets - Live Coding with Jesse
freeCodeCamp.org
try, catch, finally, throw - error handling in JavaScript
freeCodeCamp.org
Load Balancing: SSL Passthrough Setup - Live Coding with Jesse
freeCodeCamp.org
Graphs: breadth-first search - Beau teaches JavaScript
freeCodeCamp.org
React: Masonry Layout Part 2 - Live Coding with Jesse
freeCodeCamp.org
React: WordPress API Live Search - Live Coding with Jesse
freeCodeCamp.org
Creating WordPress Custom Post Types - Live Coding With Jesse
freeCodeCamp.org
Dates - Beau teaches JavaScript
freeCodeCamp.org
Miscellaneous Front End Updates - Live Coding with Jesse
freeCodeCamp.org
Merging a Pull Request from GitHub - Live Coding with Jesse
freeCodeCamp.org
React + Prettier + Standard JS - Live Coding with Jesse
freeCodeCamp.org
React: Sortable Responsive Table - Live Coding with Jesse
freeCodeCamp.org
Geolocation Sorting by Distance - Live Coding with Jesse
freeCodeCamp.org
Tradeoff Matrix - Agile Software Development
freeCodeCamp.org
The Definition of Ready - Agile Software Development
freeCodeCamp.org
Getting first React job without experience - Ask Preethi
freeCodeCamp.org
React: Google Analytics Click Tracking - Live Coding with Jesse
freeCodeCamp.org
Submitting a PR to an Open Source Project - Live Coding with Jesse
freeCodeCamp.org
Should I go back to school to get CS degree? - Ask Preethi
freeCodeCamp.org
Hero Section CSS Changes - Live Coding with Jesse
freeCodeCamp.org
Working Agreement - Agile Software Development
freeCodeCamp.org
A day at Pennybox with Co-Founder Reji Eapen
freeCodeCamp.org
React: Sorting and Filtering Data - Live Coding with Jesse
freeCodeCamp.org
React: Sorting and Filtering Data Part 2 - Live Coding with Jesse
freeCodeCamp.org
React: Building a New UI - Live Coding with Jesse
freeCodeCamp.org
Definition of Done - Agile Software Development
freeCodeCamp.org
Getting started with jQuery (tutorial) - Beau teaches JavaScript
freeCodeCamp.org
Making a React Blog with WordPress Content - Live Coding with Jesse
freeCodeCamp.org
React, NextJS, CSS - Live Coding with Jesse
freeCodeCamp.org
jQuery events - Beau teaches JavaScript
freeCodeCamp.org
React/NextJS Routing and WordPress API Custom Types - Live Coding with Jesse
freeCodeCamp.org
React: Working with API Data - Live Coding with Jesse
freeCodeCamp.org
React: Refactoring Components - Live Streaming with Jesse
freeCodeCamp.org
jQuery effects - Beau teaches JavaScript
freeCodeCamp.org
More React Refactoring - Live Coding with Jesse
freeCodeCamp.org
animate in jQuery - Beau teaches JavaScript
freeCodeCamp.org
"Finishing" My React Site - Live Coding with Jesse
freeCodeCamp.org
Starting a New React Project (P2D1) - Live Coding with Jesse
freeCodeCamp.org
React Project 2 Day 2: Learning Material UI - Live Coding with Jesse
freeCodeCamp.org
The Agile Manifesto - Agile Software Development
freeCodeCamp.org
jQuery: get and set with http, text, val, and attr - Beau teaches JavaScript
freeCodeCamp.org
React Project 2 Day 3 - Live Coding with Jesse
freeCodeCamp.org
The INVEST approach to product backlog items
freeCodeCamp.org
React Project 2 Day 4 - Live Coding with Jesse
freeCodeCamp.org
Chickens and Pigs - Agile Software Development
freeCodeCamp.org
React Project 2 Day 5 - Live Coding with Jesse
freeCodeCamp.org
jQuery: add and remove DOM elements - Beau teaches JavaScript
freeCodeCamp.org
React Project 2 Day 6 - Live Coding with Jesse
freeCodeCamp.org
More on: JavaScript Fundamentals
View skill →Related Reads
📰
📰
📰
📰
Why AI Makes Legacy Modernization More Feasible But Not More Automatic
Forbes Innovation
AI Stack Online Training | New Batch Starts Soon!
Medium · Python
I Started Tracking How Much Time I Spent Correcting AI Output. The Number Changed Everything.
Dev.to · Avery
The Top 5 AI Tools You Can Use Every Day to Save Hours
Medium · ChatGPT
🎓
Tutor Explanation
DeepCamp AI