Estimation Game with Vanilla JavaScript + SVG + Web Audio API [ Live Coding Tutorial ]

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey guys I am so embarrassed today someone asked me about this event I went to and I told them about it after that they asked me about the number of people that turned up and I said between 30 and 200 it was definitely crowded and they gave me this look of disdain that haunts me till now and they said that doesn't tell me much that's a huge range and I understand they were right I should get better at estimating the number of things I see I've been thinking about ways to get better and I I have thought of a game that I want to try coding I think it would be fun to code and it might help me get better so let's see how it goes all right so the image I have in my head involves bubbles or nice looking circles so let's call our project bubble estimator and let's open it in visual Studio code and now let's create an index.html file and an index index.js file and we're probably going to need an index. CSS file I I mean a style sheet a styles.css file so let's create that and let's add the boil plate to our index.html and let's change the title to let's say estimator trainer this how you spell estimator maybe and let's link the stylesheet and let's add the script tag to link the index.js file okay so I'm thinking that we could create a function that generates cre a random number of circles and uh within an SVG element so I think we could make a recursive function what do you guys think I'm just going to create a recursive function I'm going to call it function create circles cuz that's what it's going to do or let's call it create bubbles bubbles are nicer than circles right okay um and it's going to take a bunch of params like SVG we're going to create it and pass it in okay and then we need to add an x coordinate and a y coordinate for where we want to draw our Circle so Center X and Center Y and I guess it would be cool to have our circles be of different sizes so we could specify a radius and let's add depth as well the depth would specify how many times we want our function to run all right next up let's create the base case and it's if depth is zero return okay so that means that our function will stop running when depth is zero so I'm imagining a group of colorful bubbles appearing a few at a time okay so to do this I'm going to create a for Loop for let I equals z not o Zer as long as I is less than non bubbles which is a variable we're going to create right away let's keep adding one to I all right before we forget let's create the very variable non bubbles so const non Bubbles and we want to create a random range let's say math. floor math. random * 6 + 2 so this would give us a random number between two and8 okay and inside the four loop I would like to create the recursive case cuz that would make it easier for me to decide on which variables to mess around with over here so recursive case I'm thinking that I want a bunch of bubbles to appear a few at a time so maybe um we should do it like this set Time Out Create Bubbles and we're passing in the SVG again it's not going to change and we are going to add an altered coordinates so remember we're passing in Center X and Center y when we call our function again we want our X and Y coordinates to be different so let's make it new X and New Y also we want our new Circle to have a different radius we want to randomize that so we'll be passing in new radius and of course with every recursion we want to take away one from the depth okay and we want to run our recursive function every I times 500 milliseconds okay so now that we've uh written this we know which variables we want to declare so let's get to it so we would want to declare also New Y new radius yep that's it let's think how can we calculate new X and New Y so so with every recursion we will be passing in this value so this value would be a polar coordinate we want we want to get cartisian coordinate so I actually don't remember how to do that so I'm going to Google it okay I think I'm going to use this formula just going to copy it so let's create const X um where we're going to store the value of uh the cartisian coordinates it will be radius times the cosine of an angle times sorry U math do cosine angle and we need an angle plus Center X right and const uh y would be same thing but sign so let's just copy it and make it sign and this would be Center y okay and let's erase this here we have cartisian coordinates okay um and what did I want to do oh I I want to declare a variable to hold the angle I'm thinking that we should create a variable here above the for Loop and call it angle increment and like let's say 3 * math. pi over non bubbles that feels like it could be nice right maybe maybe I'm not making any sense we'll see okay so the angle would be maybe I * angle increment all right so now that we have const X and const Y I guess we can um we can set new X and New Y I think no we need to First declare the new radius because we're going to need it to calculate new new X and new y um so your radius we want the radius to be a bit random what if we make a radius over math. random + one that seems reasonable oh I forgot to add the word const here okay all right and now new X how about x + new radius time math. cosine angle and UI would be the same idea but here this will be Y and this will be sign okay and now it's time to create our Circle okay so const Circle equals document. create element I want to create element NS NS stands for name space okay and we want to use use the name space for SVG which is this one and here we should specify what we're drawing and we'll be drawing a circle and now let's set the center x coordinate of our Circle so Circle do set attribute I'm going to set CX oops CX not CV and it should be new X and now we want to set the Cy the y coordinate of the center of our Circle Center Point and it would be u y and of course we also want to set the radius and R is for radius you want to set it to New radius okay next up we want to set the color of our circle in my mind I want the circles to have different colors that would be cool right also they're bubbles not circles I want the bubbles to have different colors should we create a function for generating random colors why not let's do it okay um let's call it Generate random color all right I'm thinking let's create colors in hsl color mode which is H saturation lightness hsl color mode all right so looks like Q can be a value between 3 and 60 and saturation and lightness are percentages so let's create a hue variable a saturation variable and a lightness variable okay so H would be math. floor math. random time 360 okay um for the saturation how about we kind of make the saturation a bit high so let's make it math. floor math. random time 50 + 50 so this will give us a range between 50 and 99 right yeah I think that would be cool right okay and lightness we also want to make it a range as well how about I thought random time 30 + 50 so that would be like a random number between 50 and 79 I'm okay with that I can live with that Okie doie now let's return the strength with with our randomly generated color okay so hsl dollar sign funny bracket U comma dollar sign curly braces or bracket or whatever it's called percentage and then dollar sign and curly bracket or braces or whatever they're called and then lightness and then percentage okay I think that looks correct probably okay and now let's use our Generate random color function on our Circle so const random color equals Generate random color and now let's set so Circle do attribute fill and then random color okay and now I think we can append our Circle to our SVG so SVG do append child Circle and now how about we create another function and we call it start game we're going to use it to start our game obviously later on so within our start game function we are going to call our create bubbles function and we're going to pass in the SVG element that we're going to create and then we're going to need to pass a bunch of params such as the center X and Y and all of that okay let's take it step by step so step one let's create the SVG element document. create element n s that's the name space we want to create an SVG okay excellent all right and how about for Center X we make it the middle of our SVG element so why not create a variable to hold SVG height and that will be window nner height over two and then const s VG width and let's make it window do inner width so here let's make Center X SVG width over 2 uh let's make uh Center y s VG height for now we can change it after and the circle radius I don't know let's start it out with 100 and then we need to pass a value for the depth let's make three the value for now okay and now let's um set our svg's width and height so SVG do set attribute height and will be SVG height and then SVG do set attribute width uh be SVG width okay and now let's add it to the body of the page so pen child SVG no no no not AVG SVG oh my gosh SVG now let's check it out in the live server nothing shows why okay H oh I didn't call the function didn't call store game I always forget get to call functions and then I freak out okay um let's see oh why why are they black oh I like how they're showing a bunch after the other Bunch but like why are they black though okay oh I forgot to add the brackets or whatever they're called oh yay now they're colorful okay but not all of them are showing um hm maybe we could like uh change the Overflow of the SVG to visible yay that's awesome okay since we're here in the styles.css how about we also try changing the opacity of the circle maybe we could make a 0.7 yay now the circles look more like bubbles cool all right I think I should move the camera to the side and make it smaller so you guys can see uh the browser and the code so um let's see how they look when we don't have to wait for all of them to load I think the the like the waiting thing would be fun but like when we add sound effects and stuff for now it feels so satisfying to just just refresh and have these bubbles show up they're so nice right I I love them okay so H I want to be able to play this game on my phone as well so I want to make it responsive and the most important thing is to be able to see all the bubbles right since it's a bubble estimation game and this is not good you can't see all the bub on the phone looks so cool and I can't stop refreshing but you know what if we make the circle radius smaller right yeah that helps okay but we don't want it that small on a PC screen so how about we create a variable Circle radius so const C Circle radius and we're going to make it that if window do inner width is greater than 1,800 then we want uh the size of the radius to be 100 lse let's make a window do inner width times let's say 0.09 oh so the circles look tiny but we can see all of them which is cool I guess I could use my phone to practice okay let's see how it would look on a big screen I think it looks good I think this might work all right what if we like give circles a shadow so when if we do filter drop shadow three pixels three pixels 5 pixels and then we want it black so zero 0 Z and then 0.7 yeah that looks nice all right right so now how about we increase the time between every layer of circle being added and now just for fun let's add animation so circle. style. transform equals translate let's say Z 0 and %. oh wow this looks interesting let's make it let's say 5% wow cool okay also let's add a transition effect guess we can add it here transition transform form one second is and out oh very nice all right so I am getting very very very sleepy so I'm just going to go to bed now and continue working on this tomorrow um if you guys are watching and enjoying this video please hit the like button and subscribe for more content thank you see you next time I mean see you tomorrow for for me but for you it would be like a couple of seconds see you in a couple of seconds that is tomorrow for me hello again guys it's tomorrow and I am happy to see you so let's make a Todo file I would like to be able to see if I can estimate the number of bubbles so we want to find a way to conso log the number of bubbles maybe and I also want to add sound effects cuz I I think that would be cool also I want to be able to input my estimation and check if it's a good estimation or not okay so let's start with finding a way to estimate the number all right so in order to keep track of circles drawn let's go somewhere above our crate bubbles function and uh let's declare a variable and let's call it circles drawn and let's set it to zero okay and now let's find where we append our Circle okay and circles drawn add one yeah where we draw the circle or maybe where we append it right it doesn't matter I think um and then in the stored game we want to um set circles drawn to zero again oh and also we want to console log the number so console log circles let's make it bubbles num bubbles circles strong all right oh oh my gosh I forgot to move my camera again I'm yeah okay sorry about that let's move the camera and let's see if it works works I'm excited okay um inspect let's check our console oh it says there are 134 bubbles drawn okay let's see if I can guess the number of bubbles drawn so I see so many bubbles here um maybe somewhere around um maybe uh 500 it says 156 I'm really really really really really really bad at this okay all right um what if this number is lying what if it's not the correct number let's let's make it smaller right like like let's copy this and cause our function to generate less bubbles so I can keep track of them and see if it's lying I'm really bad at estimating so I'm just going to count so there are three three three that's nine and then uh 12 right and then two more so that's like 14 right 14 bubbles oh yeah yeah yeah yeah so it's it's not lying it's it's saying the truth so the problem is me okay let's change some things about how these things are displayed let's make it if it's greater than 1,500 let's inspect yeah this is this is better and I've noticed that sometimes bubbles are too high up you're right because we added the this animation so let's make it SVG height times oops 0.9 and what if we change the opacity make it a bit lower is this better yeah I I think so I think it's better you can see more bubbles that way so how about we start hunting for sound effects like I'm thinking a blob sound effect or something like that um so plop free sound effect oh my gosh no how about I Google royalty free sounds okay free sound let's say blop okay I don't like what the water I think I like this one okay so I'm going to download the Sound I guess the creative comment sound okay download it okay and now let's put it in our project directory let's drag and drop it and let's change the name I'm just gonna call it blop let's hear it next up let's try to use the sound effect and use it to make our game more interesting so in order to get it to work we're going to need to use web audio API and in order to use it we're first going to need to declare variable audio context and then uh we're going to attempt to create an instance of the audio context the reason I say attempt is because some browsers do not support the web audio API that's why we'll wrap it in a try and catch block so try audio context equals new window. audio context or window. webkit audio context and then we'll add parentheses here okay and then catch error console do error web audio API is not supported okay and then we want to create a function for sound loading all right let's create it here under our store game function let's call it load sound file okay and it's going to take two pams which are the URL and call back so the URL represents the location of our sound clip and call back is a function that we're going to pass in later on and it's going to actually be our create bubbles function okay so fetch URL then response dot array buffer then buffer audio audio oops audio context dot decode audio data buffer then audio buffer plop buffer equals audio buffer and then we want to check if a call back function is provided and if so we want to invoke it so if call back call back okay so first thing we're getting the audio file and then we are converting our response to an array buffer and then we are decoding the array buffer and then we are handling the decoded array buffer storing it in the blob buffer variable okay and we also want to catch errors during the fetch so let's add that catch error console. error error loading sound right next we want to create another function and call it function play blop sound okay so const Source equals audio context do create buffer source and source. buffer equals plop buffer and then source. connect audio context do destination and then source. start zero okay and now let's go to our um main function the create bubbles function and let's play the [Music] sound oh and we create the circles so how about we put it here so play BL sound okay and the next thing we need to do in order to get it to work is we should go down to our stored game function and we want to load the sound file first and then the game so load sound and start game so we load sound file and this plop wav and our call back function is the create bubbles function yes I think this is good right okay um let's open with live server oh my god it worked okay so uh the web audio API gets initialized with user input I think um so now since since we don't have a dialogue or anything if you want to hear the sound we should click okay so let's try it again okay again not sure if I'm involed with the sound how about we change the timeout here make it 500 this is nicer I think this is nicer yes I I like it I'm not sure if I'm crazy about the sound but for now I like it okay so let's create the game interface every game needs a start game button I'm guessing Okay so let's go to our index.html and in the body let's create oh my gosh this is so loud shut up okay and then the body let's create a button I should say say start game okay let's give it the ID start game okay now let's go to our styles.css and start adding some styling to our start game button since it's a button let's make the cursor pointer and we want it to be a circle so and we want it to be big so let's make first of all the width and the height the same size let's say the width should be 40 view width uh we want to make the height the same size so also 40 view width and then we want the border to be none and uh the Border rate radius to be 50% yeah that looks good maybe we could also give it box Shadow so let's make the Box Shadow Zero for pixels 8 pixels and then RGB a z0 z and then 0.2 opacity yeah this looks better it looks a bit 3D okay and let's make the font size a bit bigger let's make it large yeah this looks good okay and now of course we want to make our button useful right now it doesn't do anything so let's go to our index.js file and let's remove this line const start game button equals document. getet element by ID start game right okay and now start game button. add event listener click and we want our game to start so start game and I also want it to work on the phone as well so start game button do add event listener touch start start game all right and then let's go to our start game function and we want to set the display of the button to none once the game starts we don't want to see the button so start game game button do style do display equals none okay let's try it cool it works and the Sound Works I think that our button would look much nicer if it were in the middle of our page so I think we could accomplish this by adding some styling to the body so let's make it margin zero display X justify content Center align items also Center Height 100 view height yeah I think it looks pretty good let's click on it awesome okay and now let's create a div to hold our question prompt um div let's give it the ID question okay and we want to make a lay T that says input the number of bubbles or maybe estimate the number of Bubbles and then we want an input area we'll give it the ID input area and the name input and then let's create a submit but button and give it the ID submit answer and then we'll create another div nested within our question div and this div will have the ID result div because that's where we'll be showing the results okay and within it we're going to need a paragraph where we're going to actually write the result like tell our user how bad badly or how well they've performed and we are also going to need a button that would allow the user to play again let's give it the ID Restort game and should say again okay and since we only want this button to show up after the user has submitted an answer let's set its display To None now let's add some styling to our question div so bottom 20 V height position absolute nice and then background color black opacity let's say 80% padding let's say 20 pixels border radius let's say 30 pixels a color white maybe we could decrease the opacity some more let's make it 60% or 70 yeah cool okay and I'm not like the biggest fan of this font so let's go back to the body and make the font family s serif okay and at first we also don't want to see the question um we want to dynamically make it show later so let's set the display To None okay so let's go to our index.js and the first thing we should do I'm thinking is go to our start game function and we want our question div to appear uh like sometime after we hit the start game button right so set timeout document do get element by ID question do style. display block the heck and we want this to happen let's say after 4 seconds maybe let's try it yeah I think I think that works right like we can see all the bubbles okay I feel like our bubbles show up closer to the bottom what if we change this value like make it window do inner height over 4 I think this looks better okay what if the screen is bigger let's refresh yeah I think that looks good and I think the div shows up nicely as well okay let's make the game playable so first um let's create a variable to hold the submit answer button document. getet element by ID submit answer we also want to get hold of the input area as well get element by ID input area Okay and then we want to add an event listener to to the submit answer button click and and on a click event we want to first of all prevent default and then we want to do many things based on that answer that's why we should Define a submit answer function I'm just going to call it but we haven't defined it yet so let's define it so function submit answer okay so the first thing we want to do is retrieve the user's response let's create variable user input and it would be input area dot value and then we want to use the trim method to uh remove any white spaces before the inputed number or after okay next thing we want to do is we want to check if the inputed value is composed of numbers so I don't remember how to do that I'm going to Google it oh yes I've checked this answer before yes this is what I am looking for so I'm just going to copy it okay so if not user input alert please enter a valid number okay let's check if it works so let's say I write Oh yay it works okay and if I write numbers nothing happens awesome okay and then we want to clear the put area after we make the alert so input area dot value let's make it an empty string and submit answer button do disabled equals false okay and then we want to input put area focus and then let's end this with return okay and then let's convert the inputed value to a number so we can compare it so const user and answer POR in user input 10 okay and then we want to calculate how off the estimation is cuz honestly I don't expect myself definitely not myself to come up with the exact number of bubbles um I want to see how terrible of an estimation I made so I want to calculate the percentage difference so const percentage difference difference equals math do apps and then we want user answer minus circles drawn over circles drawn times 100 okay I'm thinking that we should add a scoring system and you get a higher score the closer your estimation is to the actual number okay so let's go back to our index.html file and and let's add an H5 element and give it the ID user score now we start out with score zero so we want our score to show up on a top corner so let's go to our styles. CSS file and add some styling so ID user score and let's make the position no not inherit fixed top zero and left 80% yes perfect okay and at first we want to have it invisible so display none all right now let's go back to our index.js and let's initiate a mutable variable to hold our score let's put it here above our stored game so let score equal zero and now let's go to our start game and we want to display the score once the game starts so document. get element by ID user score do style. this play block awesome oh and since we're here let's also input area. Focus yes okay very cool let's go back to our submit answer function if percentage difference equals equals z which is the best possible scenario then document. getet element by ID result um remember uh the element with the ID result is a p element a paragraph element and we want the inner text of result to be correct well done you got plus 100 I wonder if I could ever achieve this without cheating okay then user score or actually and then score plus equal 100 okay and then else if percentage difference is less than or equal 20 let's copy and paste this we want to say close and then we want to tell the user how off they were so let's make it a template literal close you wear percentage difference let's make it to fixed 2% the fix helps us round it up and then let's also say you get 50 and let's also tell the user the number we were looking for so so the number we were looking for is circles drawn and then Square = 50 okay and then let's say else if percentage difference is less than or equals 45 we could say close also and then percentage difference to fixed and then we tell them also the number we were looking for but this time they get plus 25 points and then finally else can say oops instead of close and then we say the percentage difference also and then the number we are looking looking for and our loser user doesn't get any points added to their score okay um let's try it so um why doesn't the score show I wrot Direction here instead of display um brilliant God damn it okay yes there is okay all right so okay so I'm going to try to estimate something let's say 58 really I was 5,7 100% off that makes no sense is my calculation incorrect my calculation is incorrect isn't it okay so yes I think my calculation is incorrect I should add parentheses here like this yeah I think that should fix it and also I should delete this because the user doesn't get plus 25 and while we're at it uh let's also update the score in the window uh the the user score element so document. get element by ID you user score. nner text equals score score all right okay let's try now okay let's say 58 okay the score updates and 34% % off doesn't seem so crazy okay let's try to cheat okay so 182 yay I think we're good right I think we're good and now I want to also be able to submit an answer by hitting enter okay um let's just copy this bit and change this to key down and then let's add an if statement so if if event. key is is enter then this to happen oh and also let's disable the submit answer button once an answer is submitted so submit answer button dot disabled is true let's do the same here oh my God we don't want to add an event listener to submit answer button it should be input area sorry okay um remember the restore short button we have created earlier to allow users to play once more after submitting an answer uh let's change its display to block once the user submits an answer all right um now let's create a restored game function uh that would contain the logic for restoring the game okay so function Restort game we want to make sure to set the display of our St button to none and so submit answer button should no longer be disabled so disabled [Music] false and we want to set the display of the question div to n as well and then we want to remove the existing SVG element that we have created earlier because we want to have have an empty page to display our new SVG with our new bubbles so const existing SVG document do query selector SVG and if existing SVG document.body do remove child existing s BG and then we want to also empty the input area and also empty the result paragraph element we've created so iner text then we want to run the start game function and now let's add an event listener to our restor button so restor button add event listener click so rest start game and how about we also allow users to rest the game by hitting the space button so document. add event listener key down event if event do key equals space then restored game let's check if it works oh actually I I should fix this input area. value all right let's see if it works okay I hit space and yay it keeps resetting great uhoh why is this guy disabled why is the submit button disabled um let me see I thought we said disabled to false oh maybe I should remove the quotations right yay it works okay let's say 185 I I wrote 400 I want to 185 submit okay I'm getting better or maybe cuz I know the range I don't know let's see how it would look on a telephone so I have a Samsung let's refresh it looks decent I've noticed that it do not focused on the input although I thought I said input area Focus I want to try to fix this let's go to our start game function and um maybe let's add input area do Focus here maybe that would help right I'm not sure let's try okay yay it worked okay so I want to share this game with some of the people I know and see if they're as bad as me at estimating so I want to create a rule section I'm going to create a button and just make it have a question mark and give it the ID rules and I'll make it so that when people hover on that button they will see a set of rules um let's create a div element that will contain the rules and let's give it the ID rules box now let's add some styling okay so our rules button which we've given the ID rules should have position fixed top zero cuz we want it on top um and write 80% um border radius 50% because I love circles excellent and then height same as width cool all right and we want border none and we want to give it Shadow just like our big St game button so I'm just going to copy the Box Shadow and paste it and okay we have many buttons so let's make all our buttons have cursor pointer right okay and now let's add styling to our rules box oops okay um it should be on top of everything else so let's make the index 50 uh background color let's say black uh border radius let's say 30 pixels opacity let's say [Music] 75% padding 20 pixels and we want the text to be white and we want it to be at the top uh close to the bottom and right would be 60% and position should be fixed let's see how it looks on a normal sized window I think it actually looks kind of cool so now let's get back to our index.js file and let's get a hold of our our rules button so conrols buttton is document. getet element by ID rules and rules box okay and now let's create a function to toggle the display of the rules box let's call it function toggle rules box okay if rules box do tile do [Music] display equals equals block rules box do style do style dot display should be none else rules style do display should be block and now let's add an event listener for Mouse over so rules button Dot add event listener Mouse over rules box. style. display equals block and then we want to add another event listener it would be on Mouse leave so rules button to add event listener and then should be Mouse leave rules box do style do display equals none okay and now for mobile that's where we're going to be using the function we've created a bu so rules button. add event listener touch start and then event not prevent default then we want to use the function toggle rules box and we also want to add an event listener for touch end and we also want a color function so let's see if it works okay um oh I I think I forgot to set uh the rules box display to none at first so display should be none okay and now this is how it will be on a mobile phone so you press the rules show stop pressing they go away okay let's try it on a big screen yay you hover and there are the rules I think it's good enough for me I mean it's not perfect but I like it and now I'm thinking it could be fun to um maybe make the rules button have a random color background color equals Generate random color um see if yeah it worked nice okay and also let's do the same to our start game button um style background color Generate random color yay I think that's cool right it has the spirit of the game okay so I'm thinking that I should um get it and deploy it on netlify so I'm just going to do that yay here it is it's deployed that was so easy okay let's try it number of bubbles I don't know maybe let's say 178 oh I was 35. 88% off okay let's try it on the phone here it is let's Head Start game yay wait oh the sound it works there's sound okay let's input the number it works y we did it we made a terrible game but it was fun right I hope you guys Eno enjoyed watching the video uh thank you for watching have a lovely day if you haven't subscribed make sure to subscribe and see you later goodbye hi
Info
Channel: Piko Can Fly
Views: 1,529
Rating: undefined out of 5
Keywords: js, javascript, game, game dev, easy game, project, beginner, tutorial, fun, cute, colorful, creative coding, bubbles, creator, svg, function, web audio, soundeffect, sound effects, programming, coding, live coding, recursion, pretty, art, girl coder
Id: X_uD39rsyrM
Channel Id: undefined
Length: 71min 55sec (4315 seconds)
Published: Sat Dec 16 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.