Memory Card Game - JavaScript Tutorial

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello everybody welcome to the tutorial which is a memory card game built in pure JavaScript so to follow this tutorial you don't have to know a lot just the basics of HTML CSS and GS like basic tags basic CSS selectors and what's a function you can find the files for each video at github comm slash called sketch in a written tutorial in the game demo at Medina slash fajita dot github.com so if you got lost along the way please refer to those ok let's get started we are gonna start with the basic file structure so in our terminal let's make a directory called memory game let's change directory into that new directory to create the files we're gonna touch index dot HTML styles dot CSS and scripts yes we are also going to make a directory called MiG for our images so in the editor let's open our index dot HTML and declare our file as an html5 document with doctype in the root tag let's specify the language as English and inside the head tag that set our character encoding to utf-8 set the title to memory game and Link the stylesheet and inside our body tag we are going to add this script in style.css we are going to add a reset to all items by setting padding to zero margin to zero and box-sizing to border box the box size improperly handles how padding in border will be added to an element the default value for box sizing is content box which means that any border are padding applied to the element will add to its total width and height the other options border box which adds padding and border to the element without changing its dimensions so it shrinks the available space for the content keeping its original size one thing to keep in mind box-sizing does not apply to margin okay either option you choose margin will never be accounted as elements dimensions let's set the body height to a hundred pH so V H stands for viewport height and viewport is the visible area of your webpage so the unit VH corresponds to one percent of the viewport height by setting it to 100 our body will take a hundred percent of the available height space and finally let's set the background color our board will be composed of a container div called memory game and by 12 cards each card consists of a memory card div that holds two images one representing the cards back face and the other representing its front face so back in the editor let's make that into HTML to download the images please visit the project repo at github you so now that we have added all the elements let's also add a temporary width of a hundred pixels to all images so we can have a better idea of what's going on you in style.css we're going to be styling our memory game game container and the memory card front face and back face elements so let's add a border to each one of them so you can better visualize them let's remove that temporary image width and let's add a 640 pixel width and height to our container you let's also set display to flex so what's going on here is that when we apply display flex to a container we kind of get some other property set for us by default so what does properties tell our items is each one of you will take the same amount of space in the screen into the container it says your items should be laid out in a row in just one row and they're going to be positioned from left to right and there will be stretched out across the containers height our board has three rows for card speech so let's apply to the memory card a 25% width and at 3333 % height well we can see that the height is being correctly applied but the width is not so remember when I said that we had some default properties in the Flex container one of them is flex wrap which is set to no wrap and is preventing the items from being laid out across multiple rows so let's reset it to wrap now we have to position the front face and the back face on top of each other so let's add a position:absolute to them and well this is not what we wanted at all so let's take a closer look here when you add position:absolute on element the element has to find out relative to what am I gonna position myself it doesn't know so it asks its parent in which in this case is box 3 so he goes box 3 are you positioned in the an element is only positioned to the screen if it has a position relative set box 3 does not have that so it answers no I'm not positioned the element then goes okay not a problem I'm gonna ask your parent box - are you positioned box 2 is gonna go no I'm not positioned okay I'll ask your parent box 1 are you positioned box one's gonna go no I'm not then the element says since none of you is positioned I'm gonna position myself relative to the body and this is why right now the element is sitting at the top left corner if we apply position relative to the box 1 when the element asks box 1 are you positioned box one box one's gonna go yes I am positioned the element says qu then I'm gonna position myself relative to you and the same goes if we apply position relative to box 2 and 3 which means that an element with absolute positions itself relative to the nearest positioned ancestor back in our template what's going on here is that since none of our elements are positioned to the screen front face and back face are positioning themselves relative to the body and we want them to be positioned relative to the memory card so let's add a position relative to it let's make the images take the whole width and height of its container and let's also apply some padding border radius and background color let's remove the borders and apply a 5 pixel margin to our memory card the layout has broken because the margin makes our cards overflow the available space okay so on calculating our width and height we have to take that margin under consideration the CSS calc function allows us to subtract the margin value from the width and height so let's apply that for centering the memory game container we are going to apply a display flex to the body and margin Auto to the memory game and that's going to Center it vertically and horizontally you let's set a click effect to the memory card so the active pseudo class is going to be triggered whenever an element gets clicked so we're going to apply a transform scale of nine ninety seven percent of its original size let's make that a bit smoother by applying a transition to it and for that transition to work we have to have a starting place so let's apply transforms ko1 to the memory card there's a typo here and there you go so now let's make the card flip when we click it the first thing you have to do is to make a list of all memory card elements and store it inside a constant named cards to do that we are going to use document dot carry selector all passing the memory card class so then we are going to loop through that list into each one of the cards we are going to attach an event listener we are going to listen for a click event and whenever that event is fired we are going to execute a function named flip card let's declare the Flipkart function and let's log a message to see if it's working and let's also see what's inside that this keyword okay because this value is dynamically set according to the context so let's see in this context what our this keyword represents so you can see our functions being cold and inside the dis variable we can see that we have our memory card so in this context that this keyword represents the element that fired the event okay so what we want here is to I access the class list of the memory card and to toggle the flipped class what toggle means is if the class is there remove it if it's not added okay so let's navigate to our elements tab and we can say that it's toggling the class so back in Styles dot CSS let's set that flip class so we want to select the memory card element that also has a flip class remember that there is no space between the names because the two classes belong to the same element okay so when the flip class is present we are gonna rotate the y-axis 180 degrees let's add a 3d effect to the card flipping so the perspective property is what's gonna give some depth to our elements okay so we're gonna add a 1000 pixel perspective to the memory game container and also a property that's called transform style preserve 3d to the memory card because that's what's gonna insert our memory card element inside the 3d space which is created in the memory game container because otherwise the memory card is gonna keep being flat sitting on the 2d plane so back in the editor let's add those properties 1000 pixel perspective to memory gain and transform style preserved 3d to the memory card we still don't see that with the effect because we have to add a transition to the transform property and there we have it the 3d effect well when we flip the card we should be seeing the front face right and right now what we are seeing is the inverted J s badge that happens because every HTML element has a back face which is a mirrored image of itself okay there's also properly called back face visibility that defaults to visible and this is why we are seeing the inverted badge so the first thing you have to do is to hide the back face another it's hidden we have to rotate the front face 180 degrees in the y-axis so you can see it you so when the player clicks a card we have to know if it's the first or the second card that he clicks so we can perform the matching logic okay so let's declare a variable called has flipped card and set it to false and also declare a first and a first card and second card variables let's update here toggle to add and we are going to add a condition okay so if has flipped card is false this means this is the first time the player has clicked a card so then we're gonna set has flipped card to true and we are gonna set the first card to the dis keyword remember that this the element that has fired the event so in this case is our memory card so let's console.log both variables so we can see we have the card we clicked and has flipped card is now true and when we click again on other cards it does not enter the condition because has flipped card is not true so if has flipped card is set to false it means the player is clicking at the first card if it is set to true it means the player is clicking in the second card and it's gonna fall inside the else clause so we are gonna set has flipped card back to false and we are gonna set the second card variable to this and let's console.log those okay so it fires only at the second click and we can see we have the both cards we just clicked so now that we have both cards which just clicked we have to check if those cards match and how we're gonna do that so we're gonna make use of a very handy attribute in HTML which is the data attribute with that you can add to your elements any kind of information you want okay you can call it also whatever you want you can call it data name you can call it data image we're gonna call it data framework and pass the name of the framework the UM it's holding so let's add that to every one of our memory cards you in order to access the data attribute that you defined in your HTML we do this through the data set object okay so it goes your element dot data set dot the name you have chosen you now that we can identify our cards we have to check if the data set dot framework from the first card and the second card are the same if they are we are going to remove the event listener from the cards to prevent them from being clicked again and if it's not we are gonna then I'll flip the cards back to the original state okay so let's add that condition and if it's a match we disable the event listener with remove event listener so it works you have to add the event and the function your code to make sure they have been removed let's add a blog message here all right they were correctly executed and then when we click again it won't fire because it's not going to the function anymore and then if it's not a match we won't flip the cards to do that we are going to remove the flip class from the card you okay so the second card hasn't turned so when we clicked the card it has immediately removed the flipped class so we don't even we cannot even see it being flipped what we have to do is to add a set timeout with a 1500 second delay so there's enough time available for us to see the flipping right now we have a bunch of nested conditions inside our code and that makes our method very hard to read so let's make some refactoring here and first of all we are going to extract the matching logic to its own own method and we are going to call it check for match the code inside the he fails blocks are also going to be extracted to their own methods in case it is a match we're gonna call disable cards and in case it's not we're gonna call I'll flip cards now that we have just one statement being executed inside our if/else block there's an even shorter way we can write this by using a ternary operator so a ternary operator has three blocks the first one we place our condition the second one is the statement to be executed if the condition evaluates to true and a third one if the condition evaluates to false all right so a ternary operator allows you to write an if/else block in just one line and up here we can switch the else clause for a return statement in the end of our if cuz if the condition evaluates to true the return statement is gonna stop the function execution there and in case it's not true the code executed it's the one that would be inside the else clause so this makes the condition a bit cleaner you right now our games a bit buggy because there are some corner cases we have to take care of one of them is if we try to flip a second set of cards before the first set have finished and flipping then that crashes our logic so in case it's not a match we have to lock the board and wait until the cards finish on flipping so let's declare a lock board variable and set it to false and the first statements are inside our flip card function will be to return from the function if lock board is true so the rest won't get executed in case is not a match we are going to lock the board and not only unlock it after cards have been flipped the second corner case we have to pay attention to is if we click twice over in the same card because in that case is a match is gonna runway to true and it's going to disable the cards by removing its event listener so the card is going to remain flipped we have to add a condition to the beginning of our flip card function to avoid that so if it is the first card click then the disable holds the first card but the first card variable is still on set so that conditions going to evaluate to false and the function will be executed normally if it is the second card click then the disable holds the second card and in case that equals first card then it will return from the function in order for our condition to work after each round we have to set first card a second card to know so let's extract that to to a method of its own called reset board and they're gonna set has flipped card and lock board false and first and second cardinal and we can do this using the es6 destructuring assignment which keeps our code very very short you the last thing left first to do in our game is to shuffle our cards we are gonna do this with a flexbox properly called order that's a flex items property and need the force to zero which means that every flex item belongs to the same group and then they will be grouped by source order if you assign a different integer to the order property items will get ordered first by ascending order according to the value in the order properly and then they will get ordered by source order so to shuffle our deck of cards we are going to generate a random number between 0 and 11 and assign to each one of our cards let's start iterating through our deck of cards and to generate our random number we are going to use the math dot random function which returns us a random number between 0 & 1 excluding 1 since we want a number that goes from 0 to 11 we are going to multiply that number by 12 and since the order property needs an integer we have to apply math dot floor in order to get that so now that we have our random number we can apply it to the order properly we need our deck of cards to be shuffled before the player starts the game so instead of calling the shuffle function as we normally would let's wrap it inside a parenthesis and net next repair of parenthesis to the end of it and that makes that function into an immediately invoked function expression which means that that function will be executed right after its definition and that's it for our memory game tutorial I hope you have enjoyed it please subscribe to the channel so you get our updates ok see ya
Info
Channel: freeCodeCamp.org
Views: 130,074
Rating: undefined out of 5
Keywords: javascript, javascript tutorial, learn javascript, javascript tutorial for beginners, vanilla javascript, javascript course, javascript game, pure javascript, pure javascript game, pure javascript projects, pure js game, pure js project, vanilla js, learn javascript for beginners, vanilla javascript project, vanilla javascript game, vanilla js game, vanilla js project, vanilla js tutorial, javascript game for beginners, javascript game tutorial, tutorial, beginners, how-to
Id: ZniVgo8U7ek
Channel Id: undefined
Length: 34min 16sec (2056 seconds)
Published: Mon Aug 13 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.