title
How to Build Tetris in React - GameDev Tutorial (with React Hooks!)
description
Learn to create a Tetris game with React Hooks in this tutorial course for beginners. You will learn how to build Tetris from scratch using hooks like useState, useEffect, useCallback and custom hooks. Styling is done with Styled Components.
💻 Starter files: https://github.com/weibenfalk/react-tetris-starter-files
🎥 Tutorial from Thomas Weibenfalk. Check out his YouTube channel: https://www.youtube.com/channel/UCnnnWy4UTYN258FfVGeXBbg
🔗 Watch more courses from Thomas on his website: https://www.weibenfalk.com/
⭐️ Course Contents ⭐️
⌨️ (00:00) Introduction
⌨️ (03:40) create-react-app and tooling
⌨️ (06:57) Scaffolding Components
⌨️ (15:49) Stage and Tetrominos
⌨️ (32:05) Styling with Styled Components
⌨️ (57:19) usePlayer and useStage
⌨️ (1:12:51) Stage update and player movement
⌨️ (1:37:02) Collision Detection
⌨️ (1:50:46) Player RotationG
⌨️ (2:04:12) Clear Rows
⌨️ (2:11:37) drop with useInterval
⌨️ (2:18:47) useGameStatus and React.memo
--
Learn to code for free and get a developer job: https://www.freecodecamp.org
Read hundreds of articles on programming: https://www.freecodecamp.org/news
detail
{'title': 'How to Build Tetris in React - GameDev Tutorial (with React Hooks!)', 'heatmap': [{'end': 1298.116, 'start': 1104.114, 'weight': 0.7}, {'end': 2880.07, 'start': 2776.199, 'weight': 0.941}, {'end': 3058.266, 'start': 2962.351, 'weight': 0.947}, {'end': 4814.924, 'start': 4719.964, 'weight': 0.853}, {'end': 5097.046, 'start': 4996.415, 'weight': 0.774}, {'end': 5660.849, 'start': 5547.959, 'weight': 0.942}, {'end': 6486.765, 'start': 6289.376, 'weight': 0.906}, {'end': 6670.519, 'start': 6570.998, 'weight': 0.702}], 'summary': 'Learn to build a tetris game using react and react hooks, exploring the choice of react for game development, creating custom hooks, utilizing state, useeffect, usecallback, and react memo, setting up a create react app, installing styled-components, and copying necessary files. the tutorial covers creating five different components for a tetris application, styling the tetris game using style components, implementing collision detection, optimizing game performance, creating a game status hook, and calculating scores and level increase.', 'chapters': [{'end': 179.89, 'segs': [{'end': 35.503, 'src': 'embed', 'start': 1.926, 'weight': 0, 'content': [{'end': 3.388, 'text': 'Welcome to this tutorial.', 'start': 1.926, 'duration': 1.462}, {'end': 6.172, 'text': "We're going to build a Tetris game with React.", 'start': 3.448, 'duration': 2.724}, {'end': 14.402, 'text': "And the first question you should ask yourself is, is React a good choice for making a game like this? And to be honest, I don't know.", 'start': 6.552, 'duration': 7.85}, {'end': 23.772, 'text': 'It is probably better to build it with vanilla JavaScript, but i wanted to do this for myself, to test how this game can work out with react,', 'start': 14.742, 'duration': 9.03}, {'end': 30.158, 'text': 'and sometimes i do this kind of projects just to, yeah, kind of expand my knowledge and try things out.', 'start': 23.772, 'duration': 6.386}, {'end': 35.503, 'text': 'and the idea for this started when i was looking at the tutorial at youtube,', 'start': 30.158, 'duration': 5.345}], 'summary': 'Building tetris game using react for learning and experimentation.', 'duration': 33.577, 'max_score': 1.926, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1926.jpg'}, {'end': 155.334, 'src': 'embed', 'start': 89.982, 'weight': 1, 'content': [{'end': 95.945, 'text': "and especially the one where we're going to check for collision when we rotate our Tetromino.", 'start': 89.982, 'duration': 5.963}, {'end': 98.266, 'text': 'that is the name of the blocks in Tetris.', 'start': 95.945, 'duration': 2.321}, {'end': 106.271, 'text': 'Big credits to this channel, MathMathMethod and the video where this guy shows how to create a Tetris game in just.', 'start': 99.107, 'duration': 7.164}, {'end': 108.372, 'text': "I think it's 50 minutes or so, yeah.", 'start': 106.271, 'duration': 2.101}, {'end': 113.154, 'text': "And it's a really good tutorial if you want to learn how to build a Tetris in plain JavaScript.", 'start': 108.572, 'duration': 4.582}, {'end': 113.755, 'text': 'All right.', 'start': 113.435, 'duration': 0.32}, {'end': 118.076, 'text': "Let's get to the app then and here's the Tetris game that we're going to build.", 'start': 114.395, 'duration': 3.681}, {'end': 122.557, 'text': 'I choose to have kind of a retro style to it with these stars in the background.', 'start': 118.216, 'duration': 4.341}, {'end': 131.699, 'text': "This is just an image I found on Unsplash and we're going to show the score, the rows and the level and then we have a start button.", 'start': 123.017, 'duration': 8.682}, {'end': 137.741, 'text': "So if we press start again we can play the game and we're using the arrow keys on the keyboard for this one.", 'start': 131.76, 'duration': 5.981}, {'end': 151.03, 'text': 'You rotate the tetromino with the up arrow and you kind of go left and right with other arrows and down will make it go faster down there and there will be some limitation in this game,', 'start': 138.181, 'duration': 12.849}, {'end': 153.633, 'text': 'because this is not a perfect tetris game.', 'start': 151.03, 'duration': 2.603}, {'end': 155.334, 'text': 'for example, the key input.', 'start': 153.633, 'duration': 1.701}], 'summary': 'Creating a tetris game in javascript with retro style and arrow key controls.', 'duration': 65.352, 'max_score': 89.982, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU89982.jpg'}], 'start': 1.926, 'title': 'Building tetris game with react', 'summary': 'Discusses the process of building a tetris game using react, exploring the choice of react for game development, utilizing regular divs and a grid instead of canvas, and acknowledging the influence of a tutorial on building tetris in plain javascript.', 'chapters': [{'end': 179.89, 'start': 1.926, 'title': 'Building tetris game with react', 'summary': 'Discusses the process of building a tetris game using react, exploring the choice of react for game development, utilizing regular divs and a grid instead of canvas, and acknowledging the influence of a tutorial on building tetris in plain javascript.', 'duration': 177.964, 'highlights': ['The process of building a Tetris game with React is discussed, exploring the choice of React for game development and the decision to use regular divs and a grid instead of canvas.', 'The influence of a tutorial on building Tetris in plain JavaScript is acknowledged, with credit given to the channel MathMathMethod for the valuable insights provided.', 'The game design includes a retro style with stars in the background, displaying the score, rows, and level, and providing a start button for gameplay.', 'The gameplay mechanics are explained, involving the use of arrow keys for rotation and movement, limitations in the game, and considerations for improving key input and animation control.']}], 'duration': 177.964, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1926.jpg', 'highlights': ['The process of building a Tetris game with React is discussed, exploring the choice of React for game development and the decision to use regular divs and a grid instead of canvas.', 'The influence of a tutorial on building Tetris in plain JavaScript is acknowledged, with credit given to the channel MathMathMethod for the valuable insights provided.', 'The game design includes a retro style with stars in the background, displaying the score, rows, and level, and providing a start button for gameplay.', 'The gameplay mechanics are explained, involving the use of arrow keys for rotation and movement, limitations in the game, and considerations for improving key input and animation control.']}, {'end': 1916.687, 'segs': [{'end': 207.874, 'src': 'embed', 'start': 182.344, 'weight': 0, 'content': [{'end': 187.411, 'text': 'So it will not be a perfect Tetris game, but it will be a good practice in React,', 'start': 182.344, 'duration': 5.067}, {'end': 193.679, 'text': 'and especially React Hooks that so many people are talking about now on the internet.', 'start': 187.411, 'duration': 6.268}, {'end': 201.328, 'text': 'So we will be creating custom hooks and we will use state, we will use useEffect and use callback,', 'start': 193.759, 'duration': 7.569}, {'end': 207.874, 'text': "and also we're going to use react memo for minimizing our re-renders of the cells.", 'start': 201.328, 'duration': 6.546}], 'summary': 'Create a tetris game in react using custom hooks and minimizing re-renders.', 'duration': 25.53, 'max_score': 182.344, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU182344.jpg'}, {'end': 257.497, 'src': 'embed', 'start': 229.904, 'weight': 1, 'content': [{'end': 234.686, 'text': "You don't have to set up your webpack and Babel config and everything like that from scratch.", 'start': 229.904, 'duration': 4.782}, {'end': 237.747, 'text': 'So I highly recommend you use Create React app.', 'start': 234.926, 'duration': 2.821}, {'end': 238.468, 'text': "It's great.", 'start': 237.868, 'duration': 0.6}, {'end': 241.729, 'text': 'And we create a project by going into our console.', 'start': 238.888, 'duration': 2.841}, {'end': 243.79, 'text': "In my case, I'm using Hyper.", 'start': 242.21, 'duration': 1.58}, {'end': 247.852, 'text': 'And we just type npx create-react-app.', 'start': 244.311, 'duration': 3.541}, {'end': 253.655, 'text': 'And we can call our application react-tetris.', 'start': 249.233, 'duration': 4.422}, {'end': 257.497, 'text': "This will create the folder that's called react-tetris.", 'start': 254.135, 'duration': 3.362}], 'summary': 'Use create react app for easy setup. create project with npx create-react-app. name it react-tetris.', 'duration': 27.593, 'max_score': 229.904, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU229904.jpg'}, {'end': 574.62, 'src': 'embed', 'start': 543.971, 'weight': 2, 'content': [{'end': 551.438, 'text': "Or yeah, maybe you don't name your components like that, but I like to name them with capital letter because it's a component.", 'start': 543.971, 'duration': 7.467}, {'end': 555.982, 'text': "So we create another file that's called display.js.", 'start': 552.439, 'duration': 3.543}, {'end': 559.766, 'text': "And we have a new file that's called stage.js.", 'start': 557.263, 'duration': 2.503}, {'end': 566.338, 'text': "And we have a new file that's called startButton.js.", 'start': 562.777, 'duration': 3.561}, {'end': 572.02, 'text': 'And the last one is going to be the Tetris.js file.', 'start': 567.878, 'duration': 4.142}, {'end': 574.62, 'text': 'Alright, these are our five components.', 'start': 572.44, 'duration': 2.18}], 'summary': 'Five components named with capital letters created: display.js, stage.js, startbutton.js, tetris.js.', 'duration': 30.649, 'max_score': 543.971, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU543971.jpg'}, {'end': 1007.285, 'src': 'embed', 'start': 977.827, 'weight': 3, 'content': [{'end': 980.832, 'text': "Make sure you're inside the gamehelpers.js file.", 'start': 977.827, 'duration': 3.005}, {'end': 987.429, 'text': "Here we're going to create a stage and we are going to have two consts where we can set the stage width and height.", 'start': 981.704, 'duration': 5.725}, {'end': 990.671, 'text': 'And we have to import these ones into our components.', 'start': 987.829, 'duration': 2.842}, {'end': 993.534, 'text': 'So we have to export them from this file.', 'start': 991.312, 'duration': 2.222}, {'end': 999.178, 'text': 'So we export const and then with capital letters we can have stage width.', 'start': 993.854, 'duration': 5.324}, {'end': 1003.502, 'text': 'And we can set that one to 12.', 'start': 1000.699, 'duration': 2.803}, {'end': 1007.285, 'text': 'And we export const stage height.', 'start': 1003.502, 'duration': 3.783}], 'summary': 'Create stage with consts for width and height, set width to 12.', 'duration': 29.458, 'max_score': 977.827, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU977827.jpg'}, {'end': 1298.116, 'src': 'heatmap', 'start': 1104.114, 'weight': 0.7, 'content': [{'end': 1111.679, 'text': 'And we also have this clear property here that is going to be set to merge when we have a tetromino merge into the stage.', 'start': 1104.114, 'duration': 7.565}, {'end': 1118.363, 'text': 'That means when we have collided, so the tetromino should stay in the stage and not be cleared in the next render.', 'start': 1112.159, 'duration': 6.204}, {'end': 1121.524, 'text': 'and, as i said, i will explain this later on.', 'start': 1118.983, 'duration': 2.541}, {'end': 1124.286, 'text': "so i hope you understand this function, what it's doing.", 'start': 1121.524, 'duration': 2.762}, {'end': 1129.468, 'text': "we're creating a new array from an array that we're creating here with a state height.", 'start': 1124.286, 'duration': 5.182}, {'end': 1136.052, 'text': "that's the 20 rows we're going to have in our grid, and we're supplying an inline function that, for each row,", 'start': 1129.468, 'duration': 6.584}, {'end': 1141.815, 'text': "create a new array with our cells and we're filling them up with this array here,", 'start': 1136.052, 'duration': 5.763}, {'end': 1147.486, 'text': 'and that has one value that is zero and that represents a clean cell.', 'start': 1141.815, 'duration': 5.671}, {'end': 1149.647, 'text': "There's nothing in that cell on the stage.", 'start': 1147.666, 'duration': 1.981}, {'end': 1157.773, 'text': "And we also have this string here that says clear for now, and that means that there's no tetra minor that has collided in this cell,", 'start': 1150.208, 'duration': 7.565}, {'end': 1161.256, 'text': 'and we should wipe it out from the stage in the next render.', 'start': 1157.773, 'duration': 3.483}, {'end': 1164.786, 'text': "Okay, so that's how we create our stage.", 'start': 1162.904, 'duration': 1.882}, {'end': 1171.732, 'text': "And if you remember up here in the components, we had our stage here and we had our prop that's called stage.", 'start': 1165.246, 'duration': 6.486}, {'end': 1175.316, 'text': "And this is the stage we're sending in from the Tetris component.", 'start': 1172.173, 'duration': 3.143}, {'end': 1179.76, 'text': 'So we can actually import this one here in the Tetris.js file.', 'start': 1175.956, 'duration': 3.804}, {'end': 1182.943, 'text': 'We can import our createStage function here.', 'start': 1180.44, 'duration': 2.503}, {'end': 1190.069, 'text': 'and we grab it from dot, dot forward, slash game.', 'start': 1186.388, 'duration': 3.681}, {'end': 1196.272, 'text': 'help us, like so, and for now we can just send it in to this one.', 'start': 1190.069, 'duration': 6.203}, {'end': 1206.495, 'text': 'we have the stage prop equals, curly braces create stage and parenthesis, because we invoke this function here just checking,', 'start': 1196.272, 'duration': 10.223}, {'end': 1208.616, 'text': "so we're not breaking anything here.", 'start': 1206.495, 'duration': 2.121}, {'end': 1217.971, 'text': "no, And we're going to change this later on because we're going to have the stage in a custom hook and a state for this one.", 'start': 1208.616, 'duration': 9.355}, {'end': 1221.372, 'text': 'But for now, we can just send it in so it renders something.', 'start': 1218.491, 'duration': 2.881}, {'end': 1225.573, 'text': 'Inside our stage component, we can remove this one.', 'start': 1222.412, 'duration': 3.161}, {'end': 1232.554, 'text': "And inside the div here, we create the curly braces because we're going to use JavaScript now and map over our stage prop.", 'start': 1225.713, 'duration': 6.841}, {'end': 1235.274, 'text': 'So we have a row.', 'start': 1234.254, 'duration': 1.02}, {'end': 1238.355, 'text': 'And we also map through that row.', 'start': 1236.575, 'duration': 1.78}, {'end': 1243.113, 'text': 'And then we get our cell and our x value for that one.', 'start': 1239.892, 'duration': 3.221}, {'end': 1249.735, 'text': "So what are we doing here? Well, we have the stage, that's the one we created.", 'start': 1245.914, 'duration': 3.821}, {'end': 1257.957, 'text': 'We map through that, and when we map through that stage array, we get the row, and each row is also an array that holds the cells.', 'start': 1250.115, 'duration': 7.842}, {'end': 1261.238, 'text': 'So we map through that row also, and we get the cell.', 'start': 1258.197, 'duration': 3.041}, {'end': 1265.059, 'text': 'So for each cell, we are going to render out a cell component.', 'start': 1261.638, 'duration': 3.421}, {'end': 1274.122, 'text': 'We can set the key to X.', 'start': 1270, 'duration': 4.122}, {'end': 1277.985, 'text': 'And our type are going to be the first value in the cell array.', 'start': 1274.122, 'duration': 3.863}, {'end': 1281.366, 'text': "And that's the one we created down here.", 'start': 1278.985, 'duration': 2.381}, {'end': 1287.23, 'text': "We're telling it when we initially do the render, we're telling it that this stage is clean.", 'start': 1283.067, 'duration': 4.163}, {'end': 1289.871, 'text': "We don't have any tetromino in the stage.", 'start': 1287.31, 'duration': 2.561}, {'end': 1294.974, 'text': "So we're grabbing this value here, and that's a zero that we set it to initially.", 'start': 1290.732, 'duration': 4.242}, {'end': 1298.116, 'text': 'Go back into your stage component.', 'start': 1296.555, 'duration': 1.561}], 'summary': 'The function creates a grid with clean cells and handles rendering of the stage in the tetris game.', 'duration': 194.002, 'max_score': 1104.114, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1104114.jpg'}, {'end': 1405.287, 'src': 'embed', 'start': 1375.385, 'weight': 4, 'content': [{'end': 1377.808, 'text': "And then we have another property that's called color.", 'start': 1375.385, 'duration': 2.423}, {'end': 1385.655, 'text': 'And this is just going to be a string, zero, comma, zero, comma, zero, like that.', 'start': 1379.809, 'duration': 5.846}, {'end': 1388.637, 'text': "that's our clean cell.", 'start': 1387.336, 'duration': 1.301}, {'end': 1394.02, 'text': "that's what we're using when we're not showing any tetromino, and then we have seven different tetrominoes.", 'start': 1388.637, 'duration': 5.383}, {'end': 1401.645, 'text': 'we have the i, j, l o s, t and z, so we can start by creating the i.', 'start': 1394.02, 'duration': 7.625}, {'end': 1405.287, 'text': "so we create a new property that's called i and we create a new object.", 'start': 1401.645, 'duration': 3.642}], 'summary': 'Describes properties and tetrominoes for a game.', 'duration': 29.902, 'max_score': 1375.385, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1375385.jpg'}, {'end': 1798.622, 'src': 'embed', 'start': 1763.03, 'weight': 6, 'content': [{'end': 1768.754, 'text': 'And we have one more thing to do because we want to have a function that generates a random tetromino for us.', 'start': 1763.03, 'duration': 5.724}, {'end': 1774.678, 'text': 'So we export const randomTetromino.', 'start': 1769.374, 'duration': 5.304}, {'end': 1778.02, 'text': 'And we create the function for that one.', 'start': 1776.259, 'duration': 1.761}, {'end': 1779.601, 'text': 'We have curly braces here.', 'start': 1778.32, 'duration': 1.281}, {'end': 1785.065, 'text': 'So first we create a const called tetrominos, lowercase letters.', 'start': 1780.862, 'duration': 4.203}, {'end': 1791.269, 'text': 'And we create a string with capital letters IJLOSTZ.', 'start': 1786.105, 'duration': 5.164}, {'end': 1798.622, 'text': 'this is of course the string with all our seven tetrominoes.', 'start': 1794.64, 'duration': 3.982}], 'summary': 'Create a function to generate a random tetromino from ijlostz.', 'duration': 35.592, 'max_score': 1763.03, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1763030.jpg'}], 'start': 182.344, 'title': 'Building react tetris game', 'summary': 'Details the process of building a react tetris game using react and react hooks, creating custom hooks, utilizing state, useeffect, usecallback, and react memo, setting up a create react app, installing styled-components, and copying necessary files. it also explains the creation of five different components for a tetris application, setting the stage and tetrominoes, creating tetromino shapes and colors, and styling the stage and tetromino shapes in css.', 'chapters': [{'end': 459.491, 'start': 182.344, 'title': 'Building react tetris game', 'summary': 'Details the process of building a react tetris game, utilizing react and react hooks, creating custom hooks, using state, useeffect, usecallback, and react memo, setting up a create react app, installing styled-components, and copying necessary files for the project.', 'duration': 277.147, 'highlights': ['The chapter explains the process of building a React Tetris game using React and React Hooks, including creating custom hooks and utilizing state, useEffect, useCallback, and react memo. Building React Tetris game, Utilizing React and React Hooks, Creating custom hooks, Using state, useEffect, useCallback, React memo', 'Setting up a Create React app is recommended as it helps in bootstrapping the project without the need to set up webpack and Babel config from scratch. Create React app, Recommended for bootstrapping projects, Avoids setting up webpack and Babel config from scratch', 'The process involves installing styled-components for the game design. Installing styled-components, Designing the game', 'Necessary files for the project, including bg.png, pixel font, and useIndival.js, need to be copied to the project folder, and specific folders need to be created and files pasted inside these folders. Copying necessary files, Creating specific folders, Pasting files', 'Scaffolding out components is emphasized as the initial step in creating the React application. Scaffolding out components, Initial step in creating React application']}, {'end': 917.383, 'start': 460.666, 'title': 'Creating tetris components', 'summary': 'Explains the process of creating five different components for a tetris application, including cell.js, display.js, stage.js, startbutton.js, and tetris.js, and their respective functionalities.', 'duration': 456.717, 'highlights': ['The chapter explains the process of creating five different components for a Tetris application The transcript covers the creation of five different components for a Tetris application, namely cell.js, display.js, stage.js, startButton.js, and Tetris.js, which form the core of the application.', 'Creating Tetris.js, the heart of the application Tetris.js is highlighted as the central component of the application, suggesting its critical role in the Tetris game implementation.', 'The creation and functionality of the cell.js component The process of creating and scaffolding the cell.js component is explained, including the use of props and an implicit return for the component.']}, {'end': 1281.366, 'start': 918.343, 'title': 'Creating tetris stage and tetrominoes', 'summary': 'Covers creating the stage and tetrominoes for the tetris game, including setting the stage width to 12, the stage height to 20, and explaining the process of creating a multi-dimensional array to represent the grid.', 'duration': 363.023, 'highlights': ['Setting the stage width and height The stage width is set to 12, and the stage height is set to 20, defining the dimensions of the Tetris game stage.', 'Creating a multi-dimensional array for the stage The process involves creating a nested array to represent rows and columns, with explanations of how the array is filled and the meaning of different values within the array.', 'Mapping through the stage array to render cell components The stage array is mapped through to render individual cell components, with the explanation of how each cell and its type are used for rendering.']}, {'end': 1490.925, 'start': 1283.067, 'title': 'Creating tetrominoes and styling the stage', 'summary': "Covers creating tetromino shapes and colors, including the specific properties of the 'i' tetromino, as well as the initial rendering and future styling of the stage.", 'duration': 207.858, 'highlights': ["The chapter covers creating tetromino shapes and colors, including the specific properties of the 'I' tetromino. Creation of tetrominoes, including the 'I' tetromino shape, and its properties.", 'Discussion about initial rendering and future styling of the stage. Initial rendering of the stage and plans for future styling.']}, {'end': 1916.687, 'start': 1494.088, 'title': 'Creating tetromino shapes in css', 'summary': 'Covers the creation of tetromino shapes in css, including the shapes i, j, l, o, s, t, and z, with their corresponding colors and a function to generate a random tetromino.', 'duration': 422.599, 'highlights': ['The chapter covers the creation of tetromino shapes in CSS The transcript details the process of creating tetromino shapes in CSS, including the shapes I, J, L, O, S, T, and Z.', "Function to generate a random tetromino The chapter includes a function called randomTetromino that generates a random tetromino by selecting a letter from the string 'IJLOSTZ' and retrieving the corresponding tetromino object with its shape and color.", 'Color codes for each tetromino shape The transcript provides RGB color codes for each tetromino shape, such as 80, 227, 230 for the I shape, 223, 173, 36 for the L shape, and 48, 211, 56 for the S shape.']}], 'duration': 1734.343, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU182344.jpg', 'highlights': ['Building React Tetris game, Utilizing React and React Hooks, Creating custom hooks, Using state, useEffect, useCallback, React memo', 'Setting up a Create React app is recommended as it helps in bootstrapping the project without the need to set up webpack and Babel config from scratch. Create React app, Recommended for bootstrapping projects, Avoids setting up webpack and Babel config from scratch', 'The chapter explains the process of creating five different components for a Tetris application The transcript covers the creation of five different components for a Tetris application, namely cell.js, display.js, stage.js, startButton.js, and Tetris.js, which form the core of the application.', 'Setting the stage width and height The stage width is set to 12, and the stage height is set to 20, defining the dimensions of the Tetris game stage.', "The chapter covers creating tetromino shapes and colors, including the specific properties of the 'I' tetromino. Creation of tetrominoes, including the 'I' tetromino shape, and its properties.", 'The chapter covers the creation of tetromino shapes in CSS The transcript details the process of creating tetromino shapes in CSS, including the shapes I, J, L, O, S, T, and Z.', "Function to generate a random tetromino The chapter includes a function called randomTetromino that generates a random tetromino by selecting a letter from the string 'IJLOSTZ' and retrieving the corresponding tetromino object with its shape and color."]}, {'end': 2681.92, 'segs': [{'end': 1944.093, 'src': 'embed', 'start': 1916.687, 'weight': 1, 'content': [{'end': 1923.631, 'text': "we're going to create the styles with style component and after that we're actually going to start to do some heavy coding on the game.", 'start': 1916.687, 'duration': 6.944}, {'end': 1930.724, 'text': "We're going to do some styling now to get this sad look out of this Tetris game.", 'start': 1926.001, 'duration': 4.723}, {'end': 1939.55, 'text': "And if you're not a CSS person, you don't like to style things, you can just copy and paste the styles from the starter files into your project.", 'start': 1931.305, 'duration': 8.245}, {'end': 1944.093, 'text': "But you have to import them into your component, as I'm going to show in this video,", 'start': 1939.99, 'duration': 4.103}], 'summary': 'Creating styles with style component for tetris game, with option to copy and paste starter files for non-css people.', 'duration': 27.406, 'max_score': 1916.687, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1916687.jpg'}, {'end': 2042.295, 'src': 'embed', 'start': 1983.666, 'weight': 0, 'content': [{'end': 1989.45, 'text': "we're going to set our margin to zero and then we are going to import our font.", 'start': 1983.666, 'duration': 5.784}, {'end': 2005.483, 'text': 'so we have a font face and the font family is going to be called pixel and we have a source src with our url and we grab our font from font forward,', 'start': 1989.45, 'duration': 16.033}, {'end': 2012.705, 'text': 'slash pixel, dash, lcd, dash, seven dot, vof.', 'start': 2005.483, 'duration': 7.222}, {'end': 2019.646, 'text': 'we can also set the format to vof like so and we save that one.', 'start': 2012.705, 'duration': 6.941}, {'end': 2023.767, 'text': 'yeah, and we will not see anything happening here right now.', 'start': 2019.646, 'duration': 4.121}, {'end': 2026.531, 'text': "But that's our global styling.", 'start': 2025.111, 'duration': 1.42}, {'end': 2032.913, 'text': "Then we can move up to our components and we're going to style the Tetris component first.", 'start': 2027.371, 'duration': 5.542}, {'end': 2042.295, 'text': 'And what I like to do when I use style component is that I create this folder where I place all of my styling and then I import them into the components.', 'start': 2033.253, 'duration': 9.042}], 'summary': 'Setting margin to zero, importing font, and styling tetris component using style component.', 'duration': 58.629, 'max_score': 1983.666, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1983666.jpg'}, {'end': 2409.006, 'src': 'embed', 'start': 2380.47, 'weight': 3, 'content': [{'end': 2385.153, 'text': 'And by using this inline function, we can grab the props that we send into our style components.', 'start': 2380.47, 'duration': 4.683}, {'end': 2387.995, 'text': 'And we had one prop that is called color.', 'start': 2385.773, 'duration': 2.222}, {'end': 2392.417, 'text': "so we're grabbing that one inside of here.", 'start': 2388.655, 'duration': 3.762}, {'end': 2394.418, 'text': 'all right.', 'start': 2392.417, 'duration': 2.001}, {'end': 2396.479, 'text': "so that's our background.", 'start': 2394.418, 'duration': 2.061}, {'end': 2399.681, 'text': 'we also want to set our border.', 'start': 2396.479, 'duration': 3.202}, {'end': 2403.043, 'text': 'yet again we have a dollar sign and curly braces.', 'start': 2399.681, 'duration': 3.362}, {'end': 2409.006, 'text': "we have our props and then we're going to do a ternary operator here.", 'start': 2403.043, 'duration': 5.963}], 'summary': 'Using inline function to grab props for style components, setting background and border.', 'duration': 28.536, 'max_score': 2380.47, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2380470.jpg'}], 'start': 1916.687, 'title': 'Styling tetris game with style components', 'summary': 'Covers the process of styling the tetris game using style components, including importing global styles and setting up custom fonts. it also explains an alternative for those not comfortable with css. additionally, it covers styling tetris game components, including creating separate folders for styling, importing and using styled components in tetris and cell components, and using props to conditionally modify css properties with style components.', 'chapters': [{'end': 2019.646, 'start': 1916.687, 'title': 'Styling tetris game with style components', 'summary': 'Covers the process of styling the tetris game using style components, including importing global styles and setting up custom fonts, and also provides an alternative for those not comfortable with css.', 'duration': 102.959, 'highlights': ["The chapter demonstrates the creation of global styling using index.css file, including setting margin to zero and importing a custom font called 'pixel'.", 'The tutorial provides an alternative for non-CSS persons to copy and paste the styles from starter files into their project, and import them into the component.', 'The chapter mentions the use of style components for creating styles and the import process for using components from the styles component.']}, {'end': 2681.92, 'start': 2019.646, 'title': 'Styling tetris game components', 'summary': 'Covers the process of styling tetris game components using style components, including creating separate folders for styling, importing and using styled components in tetris and cell components, and using props to conditionally modify css properties with style components.', 'duration': 662.274, 'highlights': ['Creating separate folders for styling and importing styled components into Tetris and cell components The speaker discusses creating a separate folder for styling and importing styled components into Tetris and cell components, which helps in organizing the code and maintaining a clear structure.', 'Using props to conditionally modify CSS properties with style components The speaker demonstrates using props to conditionally modify CSS properties with style components, such as setting background and border colors based on the props sent to the components.', 'Setting background and border colors based on props sent to the components The speaker explains the process of setting the background and border colors based on the props sent to the components, showcasing how the color values are obtained from the props and used to customize the appearance of the components.']}], 'duration': 765.233, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU1916687.jpg', 'highlights': ["The chapter demonstrates the creation of global styling using index.css file, including setting margin to zero and importing a custom font called 'pixel'.", 'The tutorial provides an alternative for non-CSS persons to copy and paste the styles from starter files into their project, and import them into the component.', 'Creating separate folders for styling and importing styled components into Tetris and cell components The speaker discusses creating a separate folder for styling and importing styled components into Tetris and cell components, which helps in organizing the code and maintaining a clear structure.', 'Using props to conditionally modify CSS properties with style components The speaker demonstrates using props to conditionally modify CSS properties with style components, such as setting background and border colors based on the props sent to the components.']}, {'end': 3494.657, 'segs': [{'end': 2744.583, 'src': 'embed', 'start': 2701.693, 'weight': 2, 'content': [{'end': 2710.417, 'text': "all right, then we have our export const styled tetris and that's going to be a style div.", 'start': 2701.693, 'duration': 8.724}, {'end': 2714.52, 'text': 'also type function.', 'start': 2710.417, 'duration': 4.103}, {'end': 2718.023, 'text': 'this is going to be a flex.', 'start': 2714.52, 'duration': 3.503}, {'end': 2724.048, 'text': 'we align items to flex start.', 'start': 2718.023, 'duration': 6.025}, {'end': 2735.818, 'text': 'we set our padding to 40 pixels and we have a margin of zero and auto and a max width of 900 pixels.', 'start': 2724.048, 'duration': 11.77}, {'end': 2741.002, 'text': 'The CSS here is not really optimized.', 'start': 2738.942, 'duration': 2.06}, {'end': 2744.583, 'text': 'You can try to get a better look for yourself if you want to do that.', 'start': 2741.042, 'duration': 3.541}], 'summary': 'Code defines styled tetris as flex div with specific css properties.', 'duration': 42.89, 'max_score': 2701.693, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2701693.jpg'}, {'end': 2880.07, 'src': 'heatmap', 'start': 2768.171, 'weight': 1, 'content': [{'end': 2774.757, 'text': 'So we set our width to 100%, max width of 200 pixels.', 'start': 2768.171, 'duration': 6.586}, {'end': 2783.185, 'text': 'We set our display to block and padding to 0 and 20 pixels, like so.', 'start': 2776.199, 'duration': 6.986}, {'end': 2787.97, 'text': 'And that is going to be our style component for the style Tetris.', 'start': 2783.886, 'duration': 4.084}, {'end': 2792.074, 'text': 'Now we just have to import it up in the component.', 'start': 2789.011, 'duration': 3.063}, {'end': 2798.814, 'text': 'So we can import our styled Tetris wrapper and our styled Tetris.', 'start': 2792.972, 'duration': 5.842}, {'end': 2807.617, 'text': 'And we grab them from dot forward slash styles forward slash styled Tetris.', 'start': 2800.355, 'duration': 7.262}, {'end': 2809.878, 'text': "And no, it shouldn't complain here.", 'start': 2808.177, 'duration': 1.701}, {'end': 2813.017, 'text': 'No All right.', 'start': 2810.318, 'duration': 2.699}, {'end': 2818.318, 'text': 'And as you can see, we are gradually changing this one to something else.', 'start': 2813.557, 'duration': 4.761}, {'end': 2822.979, 'text': 'So we see the space here now, and we see that the cells are just, yeah, these tiny bits now.', 'start': 2818.338, 'duration': 4.641}, {'end': 2825.72, 'text': 'All right.', 'start': 2825.38, 'duration': 0.34}, {'end': 2828.7, 'text': 'Then we can create another style inside our styles folder.', 'start': 2825.76, 'duration': 2.94}, {'end': 2832.841, 'text': "That's called styledstage.js.", 'start': 2829.121, 'duration': 3.72}, {'end': 2836.462, 'text': 'And we create the style first.', 'start': 2834.982, 'duration': 1.48}, {'end': 2840.343, 'text': 'So we import styled from styles.', 'start': 2837.602, 'duration': 2.741}, {'end': 2845.336, 'text': 'style components.', 'start': 2843.234, 'duration': 2.102}, {'end': 2858.246, 'text': "then we export const styled stage and it's equal to styled div and we have back ticks because it's a tagged function and we're going to display a grid.", 'start': 2845.336, 'duration': 12.91}, {'end': 2866.833, 'text': 'for this one we have our grid template rows.', 'start': 2858.246, 'duration': 8.587}, {'end': 2880.07, 'text': "it's going to repeat and we're grabbing from props or props dot height, a comma, and then we're going to do some css calculation.", 'start': 2866.833, 'duration': 13.237}], 'summary': 'Setting width to 100%, max width of 200px, importing styled tetris wrapper and tetris, and creating styled stage with grid template rows.', 'duration': 39.446, 'max_score': 2768.171, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2768171.jpg'}, {'end': 2880.07, 'src': 'embed', 'start': 2843.234, 'weight': 3, 'content': [{'end': 2845.336, 'text': 'style components.', 'start': 2843.234, 'duration': 2.102}, {'end': 2858.246, 'text': "then we export const styled stage and it's equal to styled div and we have back ticks because it's a tagged function and we're going to display a grid.", 'start': 2845.336, 'duration': 12.91}, {'end': 2866.833, 'text': 'for this one we have our grid template rows.', 'start': 2858.246, 'duration': 8.587}, {'end': 2880.07, 'text': "it's going to repeat and we're grabbing from props or props dot height, a comma, and then we're going to do some css calculation.", 'start': 2866.833, 'duration': 13.237}], 'summary': 'Using styled components to create a grid with dynamic height from props.', 'duration': 36.836, 'max_score': 2843.234, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2843234.jpg'}, {'end': 2941.036, 'src': 'embed', 'start': 2911.151, 'weight': 0, 'content': [{'end': 2914.113, 'text': 'then we have our grid template columns.', 'start': 2911.151, 'duration': 2.962}, {'end': 2925.114, 'text': "that's also going to repeat, and from our props yet again We grab our props.width and it's going to be one fragment.", 'start': 2914.113, 'duration': 11.001}, {'end': 2927.602, 'text': 'And of course that one should be there.', 'start': 2925.957, 'duration': 1.645}, {'end': 2935.471, 'text': 'So these calculations is because we want to keep the aspect ratio of our cells.', 'start': 2930.866, 'duration': 4.605}, {'end': 2938.513, 'text': 'We want them to be perfect squares all the time.', 'start': 2935.571, 'duration': 2.942}, {'end': 2941.036, 'text': 'And this is actually kind of tricky to do.', 'start': 2939.014, 'duration': 2.022}], 'summary': 'Calculating grid template columns to maintain perfect square aspect ratio.', 'duration': 29.885, 'max_score': 2911.151, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2911151.jpg'}, {'end': 3058.266, 'src': 'heatmap', 'start': 2962.351, 'weight': 0.947, 'content': [{'end': 2964.932, 'text': 'We have a width of 100%.', 'start': 2962.351, 'duration': 2.581}, {'end': 2966.412, 'text': 'And a max width of 25 viewport width.', 'start': 2964.932, 'duration': 1.48}, {'end': 2969.093, 'text': 'And a background of, say, 111.', 'start': 2966.432, 'duration': 2.661}, {'end': 2969.713, 'text': 'All right.', 'start': 2969.093, 'duration': 0.62}, {'end': 2982.787, 'text': "so that's our style stage.", 'start': 2981.226, 'duration': 1.561}, {'end': 2985.488, 'text': 'we just have to import it into the stage component.', 'start': 2982.787, 'duration': 2.701}, {'end': 2994.313, 'text': "so make sure you're inside the stage component and import styled stage from dot.", 'start': 2985.488, 'duration': 8.825}, {'end': 2996.014, 'text': 'forward slash styles.', 'start': 2994.313, 'duration': 1.701}, {'end': 3000.817, 'text': 'forward slash style stage, all right.', 'start': 2996.014, 'duration': 4.803}, {'end': 3009.142, 'text': 'and then we rename this one to our style stage and we close it with the same,', 'start': 3000.817, 'duration': 8.325}, {'end': 3015.593, 'text': "And we're going to send some props inside of this because we had the width and that one we're grabbing from.", 'start': 3010.526, 'duration': 5.067}, {'end': 3019.679, 'text': 'We are sending in the stage as props to this one.', 'start': 3017.016, 'duration': 2.663}, {'end': 3033.744, 'text': 'So if we grab the stage and the first row, the length, we know the width of our grid and the height, we just grab the stage length like so,', 'start': 3020.621, 'duration': 13.123}, {'end': 3038.406, 'text': 'and that will give us the height from our multi-dimensional array.', 'start': 3033.744, 'duration': 4.662}, {'end': 3047.148, 'text': "all right, we save this one and see what we've got, and as you can see, we have something here, so we're slowly getting there.", 'start': 3038.406, 'duration': 8.742}, {'end': 3052.39, 'text': 'we can actually now also go back into the cell component and we can remove the text here.', 'start': 3047.148, 'duration': 5.242}, {'end': 3058.266, 'text': "we don't need that one, And that's why we can just self-close it like this.", 'start': 3052.39, 'duration': 5.876}], 'summary': 'Styling with 100% width, max 25 viewport width, and background 111. importing and using styled stage, sending width and height as props.', 'duration': 95.915, 'max_score': 2962.351, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2962351.jpg'}, {'end': 3246.163, 'src': 'embed', 'start': 3204.391, 'weight': 4, 'content': [{'end': 3219.967, 'text': 'yeah, some fallback fonts here and the font size of 0.8, rem like so, and then we just have to import and use it in our display component.', 'start': 3204.391, 'duration': 15.576}, {'end': 3230.972, 'text': 'so we import our styled display from dot, forward slash styles, forward slash style display,', 'start': 3219.967, 'duration': 11.005}, {'end': 3243.661, 'text': "and then we change this div to our styled display component and we also had our prop that's called game over.", 'start': 3234.514, 'duration': 9.147}, {'end': 3246.163, 'text': 'so we send that one in like.', 'start': 3243.661, 'duration': 2.502}], 'summary': "Using a font size of 0.8 rem, import and use styled display component with 'game over' prop.", 'duration': 41.772, 'max_score': 3204.391, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU3204391.jpg'}, {'end': 3388.479, 'src': 'embed', 'start': 3357.076, 'weight': 5, 'content': [{'end': 3368.542, 'text': 'So we import styled start button from dot forward slash styles.', 'start': 3357.076, 'duration': 11.466}, {'end': 3378.39, 'text': 'forward slash styled start button and of course we change this one to styled start button.', 'start': 3368.542, 'duration': 9.848}, {'end': 3383.254, 'text': 'we are also going to have an on click handler on this one, so we can type it in now.', 'start': 3378.39, 'duration': 4.864}, {'end': 3388.479, 'text': "so we have the on click and it's going to be a callback, all right.", 'start': 3383.254, 'duration': 5.225}], 'summary': 'Import styled start button, change to styled start button, add on click handler.', 'duration': 31.403, 'max_score': 3357.076, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU3357076.jpg'}], 'start': 2681.92, 'title': 'Styling tetris game components', 'summary': 'Covers styling components like stage, display, and start button in a tetris game using style components and react hooks, optimizing css, creating a responsive grid, and maintaining aspect ratio of grid cells, and creating custom hooks for the game logic.', 'chapters': [{'end': 2969.713, 'start': 2681.92, 'title': 'Styling with style components', 'summary': 'Demonstrates how to use style components to style a tetris game, optimizing css, creating a responsive grid, and maintaining aspect ratio of grid cells.', 'duration': 287.793, 'highlights': ['Creating a responsive grid and maintaining aspect ratio of grid cells The author demonstrates how to create a responsive grid and maintain the aspect ratio of grid cells by using CSS calculations and keeping the cells as perfect squares, providing the width and height calculations.', 'Styling a Tetris game using style components The chapter explains how to style a Tetris game using style components, avoiding inline styling and allowing nesting of styles similar to SAS, with examples of setting padding, display, and width.', 'Optimizing CSS for a Tetris game The author mentions the possibility of optimizing the CSS for a Tetris game to achieve a better look, suggesting improvements in CSS styling and grid design for a more appealing appearance.']}, {'end': 3494.657, 'start': 2981.226, 'title': 'Styling stage, display, and start button', 'summary': 'Covers the process of styling the stage, display, and start button components in a tetris game using styled components, including setting up the grid, creating displays, and adding a start button, while also discussing the use of react hooks and creating custom hooks for the game logic.', 'duration': 513.431, 'highlights': ['Styling Stage Component The chapter focuses on importing and styling the stage component using styled components, setting up the grid, and passing props to determine the width and height of the grid.', "Styling Display Component It covers the creation of a custom display component using styled components, including setting properties like margin, padding, border, and color based on props like 'game over', and importing and implementing the styled display component in the code.", 'Styling Start Button Component The process of styling the start button component using styled components, including setting properties such as margin, padding, border, color, font, and cursor, and importing and implementing the styled start button component with an onClick handler in the code.']}], 'duration': 812.737, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU2681920.jpg', 'highlights': ['Creating a responsive grid and maintaining aspect ratio of grid cells by using CSS calculations and keeping the cells as perfect squares.', 'Styling a Tetris game using style components, avoiding inline styling and allowing nesting of styles similar to SAS.', 'Optimizing CSS for a Tetris game to achieve a better look, suggesting improvements in CSS styling and grid design for a more appealing appearance.', 'Styling Stage Component using styled components, setting up the grid, and passing props to determine the width and height of the grid.', "Styling Display Component, including setting properties like margin, padding, border, and color based on props like 'game over', and importing and implementing the styled display component in the code.", 'Styling Start Button Component, including setting properties such as margin, padding, border, color, font, and cursor, and importing and implementing the styled start button component with an onClick handler in the code.']}, {'end': 5101.968, 'segs': [{'end': 3627.531, 'src': 'embed', 'start': 3583.142, 'weight': 0, 'content': [{'end': 3586.404, 'text': "And that's the way we keep the tetra-minos that has collided.", 'start': 3583.142, 'duration': 3.262}, {'end': 3592.887, 'text': 'i think it will get much more clearer when we actually create the tetromino and how our game loop works,', 'start': 3586.824, 'duration': 6.063}, {'end': 3596.489, 'text': 'because the game loop are going to do a couple of things for us.', 'start': 3592.887, 'duration': 3.602}, {'end': 3604.533, 'text': "the first thing we have to do in our game loop is that we clear the stage and then we check for any merged cells here and we don't clear the merged ones.", 'start': 3596.489, 'duration': 8.044}, {'end': 3606.433, 'text': 'so they are going to stay in the stage.', 'start': 3604.533, 'duration': 1.9}, {'end': 3614.559, 'text': "they're going to stay in the array for a stage and then we're going to check the position of our tetromino and if it hasn't collided,", 'start': 3606.433, 'duration': 8.126}, {'end': 3617.282, 'text': 'we are just going to set it to clear again.', 'start': 3614.559, 'duration': 2.723}, {'end': 3622.106, 'text': "and that means for the next render it's going to be wiped out and it's going to move.", 'start': 3617.282, 'duration': 4.824}, {'end': 3625.69, 'text': "and that's the way we get the illusion of movement here.", 'start': 3622.106, 'duration': 3.584}, {'end': 3627.531, 'text': "or maybe it's not an illusion.", 'start': 3625.69, 'duration': 1.841}], 'summary': 'Game loop clears stage, checks merged cells, and updates tetromino position.', 'duration': 44.389, 'max_score': 3583.142, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU3583142.jpg'}, {'end': 3698.94, 'src': 'embed', 'start': 3666.723, 'weight': 2, 'content': [{'end': 3671.087, 'text': "and if it collides, we don't make the move because then we know that it has collided.", 'start': 3666.723, 'duration': 4.364}, {'end': 3676.573, 'text': 'We always check the game field, the stage one step ahead, before we make the move.', 'start': 3671.607, 'duration': 4.966}, {'end': 3680.637, 'text': 'And that is also going to be much more clear when we actually do this coding.', 'start': 3676.933, 'duration': 3.704}, {'end': 3686.283, 'text': 'I just wanted to explain it shortly for you so you have a rough idea of how this is going to work.', 'start': 3680.917, 'duration': 5.366}, {'end': 3689.367, 'text': "All right, so let's get back to our code.", 'start': 3687.204, 'duration': 2.163}, {'end': 3698.94, 'text': 'We can start in our hooks directory, in our hooks folder, and inside of that folder we create two new files.', 'start': 3691.533, 'duration': 7.407}], 'summary': 'Algorithm checks game field one step ahead to avoid collisions; coding to be clearer.', 'duration': 32.217, 'max_score': 3666.723, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU3666723.jpg'}, {'end': 3998.465, 'src': 'embed', 'start': 3940.265, 'weight': 3, 'content': [{'end': 3945.829, 'text': 'so we grab a random tetromino and the shape of that one and put it in our state for the player,', 'start': 3940.265, 'duration': 5.564}, {'end': 3952.054, 'text': "and then we're going to have a property that's called collided and we set that to false.", 'start': 3945.829, 'duration': 6.225}, {'end': 3957.278, 'text': "so that's our initial state for the player, And now we're actually just going to return the player.", 'start': 3952.054, 'duration': 5.224}, {'end': 3964.242, 'text': "Because we're going to import this custom hook into our Tetris component.", 'start': 3959.879, 'duration': 4.363}, {'end': 3968.344, 'text': "And then we're going to need the player inside of the Tetris component.", 'start': 3964.542, 'duration': 3.802}, {'end': 3971.145, 'text': "I'm going to show you this in a second.", 'start': 3969.364, 'duration': 1.781}, {'end': 3973.526, 'text': 'For now this is it for the use player.', 'start': 3971.445, 'duration': 2.081}, {'end': 3975.167, 'text': "We're going to return to this file.", 'start': 3973.606, 'duration': 1.561}, {'end': 3978.329, 'text': 'And we can now move on to our use stage hook.', 'start': 3975.627, 'duration': 2.702}, {'end': 3980.71, 'text': 'And do almost the same for that one.', 'start': 3978.729, 'duration': 1.981}, {'end': 3984.532, 'text': 'So we import use state.', 'start': 3982.311, 'duration': 2.221}, {'end': 3988.503, 'text': 'from react.', 'start': 3986.343, 'duration': 2.16}, {'end': 3998.465, 'text': 'so we import, create stage from dot dot forward, slash game, help us all right.', 'start': 3988.503, 'duration': 9.962}], 'summary': 'Creating initial state for player and importing custom hook into tetris component', 'duration': 58.2, 'max_score': 3940.265, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU3940265.jpg'}, {'end': 4396.899, 'src': 'embed', 'start': 4371.917, 'weight': 6, 'content': [{'end': 4379.524, 'text': "Okay, let's create the movement for the player and also the stage update so we can see the changes take place on our stage here.", 'start': 4371.917, 'duration': 7.607}, {'end': 4384.528, 'text': "First, we're going to be working in the Tetris.js file, the Tetris component.", 'start': 4380.344, 'duration': 4.184}, {'end': 4389.192, 'text': "And I'm actually going to take back some code we deleted in the last video.", 'start': 4384.988, 'duration': 4.204}, {'end': 4393.235, 'text': 'We are going to use the create stage function in this one also.', 'start': 4389.472, 'duration': 3.763}, {'end': 4395.217, 'text': 'So import it again.', 'start': 4393.916, 'duration': 1.301}, {'end': 4396.899, 'text': 'Sorry for that.', 'start': 4396.238, 'duration': 0.661}], 'summary': 'Developing player movement and stage update in tetris.js, using create stage function.', 'duration': 24.982, 'max_score': 4371.917, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU4371917.jpg'}, {'end': 4452.49, 'src': 'embed', 'start': 4418.53, 'weight': 7, 'content': [{'end': 4427.118, 'text': "we are going to need a function that's called move player and it's going to take in a direction as a parameter.", 'start': 4418.53, 'duration': 8.588}, {'end': 4431.944, 'text': 'For now, we just leave it empty.', 'start': 4430.384, 'duration': 1.56}, {'end': 4435.245, 'text': "Then we're going to need a function that's called StartGame.", 'start': 4432.565, 'duration': 2.68}, {'end': 4440.747, 'text': 'We leave it empty for now.', 'start': 4439.286, 'duration': 1.461}, {'end': 4444.868, 'text': 'We have another one that we call Drop.', 'start': 4443.167, 'duration': 1.701}, {'end': 4449.609, 'text': 'And we leave that one empty.', 'start': 4448.149, 'duration': 1.46}, {'end': 4452.49, 'text': "And we have another one that's called DropPlayer.", 'start': 4450.349, 'duration': 2.141}], 'summary': 'Functions: move player, start game, drop, drop player', 'duration': 33.96, 'max_score': 4418.53, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU4418530.jpg'}, {'end': 4817.826, 'src': 'heatmap', 'start': 4719.964, 'weight': 8, 'content': [{'end': 4734.068, 'text': "we call our function to create a new stage and we reset the player and that's also a function that's going to be in the use player hook and the start game is a callback function also that we're going to have on our start button.", 'start': 4719.964, 'duration': 14.104}, {'end': 4740.59, 'text': 'so we can set an on click handler and call the start game function.', 'start': 4734.068, 'duration': 6.522}, {'end': 4742.453, 'text': "So what we'll do?", 'start': 4741.792, 'duration': 0.661}, {'end': 4747.236, 'text': 'when we press the start game button, we will reset the stage and we will also reset the player.', 'start': 4742.453, 'duration': 4.783}, {'end': 4750.94, 'text': 'And then we have our movePlayer function.', 'start': 4748.678, 'duration': 2.262}, {'end': 4754.703, 'text': 'And that one is going to take care of the left and right movement.', 'start': 4751.6, 'duration': 3.103}, {'end': 4757.165, 'text': 'So we call the updatePlayerPros.', 'start': 4755.043, 'duration': 2.122}, {'end': 4764.411, 'text': 'And we give it the x value of direction and the y value of zero.', 'start': 4759.166, 'duration': 5.245}, {'end': 4774.868, 'text': "because now we're just moving left and right and we're giving it a value here, minus one or one.", 'start': 4766.596, 'duration': 8.272}, {'end': 4777.251, 'text': 'all right, we save that file and it will break.', 'start': 4774.868, 'duration': 2.383}, {'end': 4779.615, 'text': "now, of course, because we haven't created these ones yet.", 'start': 4777.251, 'duration': 2.364}, {'end': 4793.727, 'text': "so we have to create the update player pos function and the reset player function and we're going to place them in our use player custom hook.", 'start': 4784.264, 'duration': 9.463}, {'end': 4805.431, 'text': 'and that means that when we call our use player function here, we also want to get the update player pos and the reset player from that custom hook.', 'start': 4793.727, 'duration': 11.704}, {'end': 4805.872, 'text': 'all right.', 'start': 4805.431, 'duration': 0.441}, {'end': 4810.073, 'text': "so let's move into our use player hook.", 'start': 4805.872, 'duration': 4.201}, {'end': 4814.924, 'text': "so make sure you're in the useplayer.js file and we're going to continue.", 'start': 4810.073, 'duration': 4.851}, {'end': 4815.784, 'text': 'writes on code here.', 'start': 4814.924, 'duration': 0.86}, {'end': 4817.826, 'text': "we're going to create these two functions here.", 'start': 4815.784, 'duration': 2.042}], 'summary': 'Creating functions for stage, player, and movement in game development.', 'duration': 24.099, 'max_score': 4719.964, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU4719964.jpg'}, {'end': 5117.024, 'src': 'heatmap', 'start': 4996.415, 'weight': 9, 'content': [{'end': 4999.597, 'text': 'And this is the way that the tetromino change randomly.', 'start': 4996.415, 'duration': 3.182}, {'end': 5002.579, 'text': 'And we set collided to false.', 'start': 5000.918, 'duration': 1.661}, {'end': 5005.58, 'text': 'Like so.', 'start': 5004.94, 'duration': 0.64}, {'end': 5008.602, 'text': 'We also have to import the useCallback up here.', 'start': 5005.68, 'duration': 2.922}, {'end': 5012.925, 'text': 'And useCallback is a standard React hook.', 'start': 5010.543, 'duration': 2.382}, {'end': 5018.768, 'text': 'And the last thing we have to do for now is also return or update player position.', 'start': 5014.005, 'duration': 4.763}, {'end': 5022.971, 'text': 'Or update player pos and or reset player.', 'start': 5020.209, 'duration': 2.762}, {'end': 5026.078, 'text': 'And this should be it now.', 'start': 5025.017, 'duration': 1.061}, {'end': 5033.004, 'text': "So it's still working, but nothing happens here because we're not drawing anything to the stage now.", 'start': 5027.339, 'duration': 5.665}, {'end': 5036.607, 'text': "And that's what we're going to be doing now.", 'start': 5034.566, 'duration': 2.041}, {'end': 5041.532, 'text': "So let's go into our usestage.js file or usestage custom hook.", 'start': 5036.808, 'duration': 4.724}, {'end': 5048.657, 'text': 'And this one is going to be a little maybe complicated, but I hope we will get through it.', 'start': 5042.816, 'duration': 5.841}, {'end': 5053.838, 'text': "And that's the thing with game making, because as I said, I'm not a game maker.", 'start': 5049.357, 'duration': 4.481}, {'end': 5058.079, 'text': "So yeah, some stuff can be hard to understand when you're not a game maker.", 'start': 5053.898, 'duration': 4.181}, {'end': 5064.821, 'text': "But even if you don't understand everything that's game specific, I hope you will learn some stuff in React.", 'start': 5058.319, 'duration': 6.502}, {'end': 5066.724, 'text': "okay. so let's continue.", 'start': 5065.603, 'duration': 1.121}, {'end': 5073.949, 'text': "in this one we're going to take in our player and reset player as our parameters for this one.", 'start': 5066.724, 'duration': 7.225}, {'end': 5076.21, 'text': 'so add these ones up here.', 'start': 5073.949, 'duration': 2.261}, {'end': 5077.751, 'text': "then we're going to use the hook.", 'start': 5076.21, 'duration': 1.541}, {'end': 5078.932, 'text': "that's called use effect.", 'start': 5077.751, 'duration': 1.181}, {'end': 5089.022, 'text': "that one is for creating side effects with react and it's, yeah, kind of a replacement for the lifecycle methods in the class components.", 'start': 5080.237, 'duration': 8.785}, {'end': 5097.046, 'text': "i won't go into detail with every hook here, so you have to look up that yourself if you don't know how use effect works and what it's for.", 'start': 5089.022, 'duration': 8.024}, {'end': 5101.968, 'text': 'they have an excellent text on the react homepage where you can read about all the hooks.', 'start': 5097.046, 'duration': 4.922}, {'end': 5117.024, 'text': "all right, so we create our use effect and that one is going to have an inline arrow function where we're going to create everything for our effect,", 'start': 5101.968, 'duration': 15.056}], 'summary': 'Creating a custom hook in react for game development', 'duration': 120.609, 'max_score': 4996.415, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU4996415.jpg'}], 'start': 3494.657, 'title': 'Tetris game implementation', 'summary': 'Covers the implementation of tetris game loop and grid logic using a 20x12 array, custom hooks creation in react for managing player and stage states, and player movement with key detection in tetris.js, aiming for smooth animation and collision detection.', 'chapters': [{'end': 3689.367, 'start': 3494.657, 'title': 'Tetris game loop and grid logic', 'summary': 'Discusses the implementation of the tetris game loop using an interval and the representation of the game grid with a 20x12 array, ensuring the movement and collision logic for the tetromino pieces, aiming to achieve smooth game animation and collision detection.', 'duration': 194.71, 'highlights': ['The game loop involves clearing the stage, checking for merged cells, and handling tetromino movement and collision logic using an interval for smooth game animation. Game loop involves clearing the stage, checking for merged cells, and handling tetromino movement and collision logic.', 'The game grid is represented by a 20x12 array, with each cell indicating the presence of a tetromino piece, collision status, and position, ensuring smooth movement and collision detection. Game grid represented by a 20x12 array, with each cell indicating the presence of a tetromino piece, collision status, and position.', 'Collision detection is performed by checking the game field one step ahead before executing the move, ensuring accurate and efficient collision handling for smooth gameplay. Collision detection is performed by checking the game field one step ahead before executing the move.']}, {'end': 4347.817, 'start': 3691.533, 'title': 'Creating custom hooks in react', 'summary': 'Involves creating two custom hooks, useplayer and usestage, for managing player and stage states in a tetris game, utilizing usestate and destructuring in react, and implementing these hooks in the tetris component.', 'duration': 656.284, 'highlights': ['The chapter involves creating two custom hooks, usePlayer and useStage, for managing player and stage states in a Tetris game.', 'It demonstrates the utilization of useState and destructuring in React for managing state and accessing values from arrays.', 'The process involves setting initial states for the player and stage, including position, tetromino, and collision properties.', 'The chapter highlights the implementation of the created custom hooks, usePlayer and useStage, in the Tetris component for utilizing player and stage states.']}, {'end': 5101.968, 'start': 4347.957, 'title': 'Tetris player movement & stage update', 'summary': 'Covers the creation of player movement with keys and stage update in tetris.js, including the addition of functions for movement, game start, dropping, and key press detection, as well as the creation of the updateplayerpos and resetplayer functions in the useplayer custom hook.', 'duration': 754.011, 'highlights': ['Creation of player movement with keys and stage update in Tetris.js The chapter covers the creation of player movement with keys and stage update in Tetris.js, including the addition of functions for movement, game start, dropping, and key press detection.', 'Addition of functions for movement, game start, dropping, and key press detection Functions such as move player, StartGame, Drop, and move are added for movement, game start, dropping, and key press detection.', 'Creation of updatePlayerPos and resetPlayer functions in the usePlayer custom hook The updatePlayerPos and resetPlayer functions are created in the usePlayer custom hook to handle updating player position and resetting the player.', 'Use of useEffect hook for creating side effects and replacing lifecycle methods in class components The use of useEffect hook is mentioned for creating side effects and replacing lifecycle methods in class components.']}], 'duration': 1607.311, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU3494657.jpg', 'highlights': ['Game loop involves clearing the stage, checking for merged cells, and handling tetromino movement and collision logic using an interval for smooth game animation.', 'The game grid is represented by a 20x12 array, with each cell indicating the presence of a tetromino piece, collision status, and position, ensuring smooth movement and collision detection.', 'Collision detection is performed by checking the game field one step ahead before executing the move, ensuring accurate and efficient collision handling for smooth gameplay.', 'The chapter involves creating two custom hooks, usePlayer and useStage, for managing player and stage states in a Tetris game.', 'The process involves setting initial states for the player and stage, including position, tetromino, and collision properties.', 'The chapter highlights the implementation of the created custom hooks, usePlayer and useStage, in the Tetris component for utilizing player and stage states.', 'Creation of player movement with keys and stage update in Tetris.js, including the addition of functions for movement, game start, dropping, and key press detection.', 'Functions such as move player, StartGame, Drop, and move are added for movement, game start, dropping, and key press detection.', 'Creation of updatePlayerPos and resetPlayer functions in the usePlayer custom hook to handle updating player position and resetting the player.', 'Use of useEffect hook for creating side effects and replacing lifecycle methods in class components.']}, {'end': 5865.338, 'segs': [{'end': 5155.798, 'src': 'embed', 'start': 5101.968, 'weight': 0, 'content': [{'end': 5117.024, 'text': "all right, so we create our use effect and that one is going to have an inline arrow function where we're going to create everything for our effect,", 'start': 5101.968, 'duration': 15.056}, {'end': 5118.584, 'text': 'and this is the dependency array.', 'start': 5117.024, 'duration': 1.56}, {'end': 5121.345, 'text': 'for now we can just leave it empty.', 'start': 5118.584, 'duration': 2.761}, {'end': 5123.366, 'text': 'we create another function inside of here.', 'start': 5121.345, 'duration': 2.021}, {'end': 5126.828, 'text': "that's called update stage.", 'start': 5123.366, 'duration': 3.462}, {'end': 5132.008, 'text': "we're going to give it the prev stage, the previous stage below.", 'start': 5126.828, 'duration': 5.18}, {'end': 5135.51, 'text': "here we're going to set the state of the stage with this function.", 'start': 5132.008, 'duration': 3.502}, {'end': 5141.692, 'text': 'so we have the stage state here and we set it with the set stage.', 'start': 5135.51, 'duration': 6.182}, {'end': 5146.234, 'text': 'so set stage and then we have our update function.', 'start': 5141.692, 'duration': 4.542}, {'end': 5149.376, 'text': 'so we grab the previous stage state.', 'start': 5146.234, 'duration': 3.142}, {'end': 5152.577, 'text': "it's easy to be confused here with stage and state.", 'start': 5149.376, 'duration': 3.201}, {'end': 5155.798, 'text': "it's almost the same, saying that.", 'start': 5152.577, 'duration': 3.221}], 'summary': 'Creating useeffect with inline arrow function to update stage state.', 'duration': 53.83, 'max_score': 5101.968, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5101968.jpg'}, {'end': 5211.806, 'src': 'embed', 'start': 5179.219, 'weight': 3, 'content': [{'end': 5183.66, 'text': 'we have to kind of clear it from the previous render.', 'start': 5179.219, 'duration': 4.441}, {'end': 5193.378, 'text': 'so we create the const with a new stage, We take our previous stage, our prev stage, and we map through it, so we get our row.', 'start': 5183.66, 'duration': 9.718}, {'end': 5196.42, 'text': 'And we have an inline function here.', 'start': 5194.519, 'duration': 1.901}, {'end': 5203.542, 'text': 'And we make another map on our row, because this is a multidimensional array, so we have to do two maps here.', 'start': 5197.3, 'duration': 6.242}, {'end': 5211.806, 'text': 'It will probably be a little bit faster if we do this with just four loops, but I think we will be fine here using map.', 'start': 5204.243, 'duration': 7.563}], 'summary': 'Creating a new stage and using map functions for multidimensional arrays.', 'duration': 32.587, 'max_score': 5179.219, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5179219.jpg'}, {'end': 5660.849, 'src': 'heatmap', 'start': 5547.959, 'weight': 0.942, 'content': [{'end': 5554.805, 'text': 'here, inside of the update stage function, we are returning the new stage.', 'start': 5547.959, 'duration': 6.846}, {'end': 5562.874, 'text': "for now, because we're not checking any collisions yet, we're going to return to this one And as you can see here, when I auto-formatted this one,", 'start': 5554.805, 'duration': 8.069}, {'end': 5564.719, 'text': 'it has filled in this itself.', 'start': 5562.874, 'duration': 1.845}, {'end': 5568.387, 'text': 'These are the dependencies that we need for this use effect.', 'start': 5565.46, 'duration': 2.927}, {'end': 5576.657, 'text': 'we have the player.collided, the player.pos.x, the player.pos.y and player.tetromino.', 'start': 5569.455, 'duration': 7.202}, {'end': 5579.477, 'text': "we're using them inside of this use effect,", 'start': 5576.657, 'duration': 2.82}, {'end': 5588.659, 'text': "and that's why we have to specify them as dependencies here and we are going to use the reset player that we wrapped in our use callback later.", 'start': 5579.477, 'duration': 9.182}, {'end': 5593.22, 'text': "so that's why we have wrapped it because we're going to add it as a dependency to this one,", 'start': 5588.659, 'duration': 4.561}, {'end': 5599.915, 'text': "And it's this use effect that will go into an infinity loop if we don't wrap it in a use callback.", 'start': 5594.494, 'duration': 5.421}, {'end': 5602.036, 'text': 'All right, save this one.', 'start': 5600.956, 'duration': 1.08}, {'end': 5606.317, 'text': "And as you can see, we have a tetra minor here now, and that's great.", 'start': 5602.836, 'duration': 3.481}, {'end': 5612.659, 'text': "And if we reload this one, we get a different tetra minor because we have randomized them and that's working great.", 'start': 5606.517, 'duration': 6.142}, {'end': 5615.4, 'text': 'And is this working? No.', 'start': 5612.859, 'duration': 2.541}, {'end': 5617.64, 'text': "Okay, let's check that out.", 'start': 5615.42, 'duration': 2.22}, {'end': 5623.182, 'text': 'In our Tetris.', 'start': 5622.182, 'duration': 1}, {'end': 5626.762, 'text': "All right, I see here it shouldn't be on click.", 'start': 5624.46, 'duration': 2.302}, {'end': 5628.463, 'text': 'It should be callback.', 'start': 5627.482, 'duration': 0.981}, {'end': 5634.507, 'text': "Because if we look in our start button, we have the prop here that's called callback.", 'start': 5629.864, 'duration': 4.643}, {'end': 5639.571, 'text': "So make sure you're in the Tetris component and change this one to callback.", 'start': 5634.687, 'duration': 4.884}, {'end': 5641.692, 'text': 'And I bet it will work now.', 'start': 5640.111, 'duration': 1.581}, {'end': 5644.894, 'text': 'And it does.', 'start': 5644.354, 'duration': 0.54}, {'end': 5650.298, 'text': 'And I think I saw a little bug there.', 'start': 5647.216, 'duration': 3.082}, {'end': 5660.849, 'text': 'Yeah, it disappears, and i think it is.', 'start': 5650.318, 'duration': 10.531}], 'summary': 'Updating stage function, handling dependencies, and fixing bugs in tetris game.', 'duration': 112.89, 'max_score': 5547.959, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5547959.jpg'}, {'end': 5778.976, 'src': 'embed', 'start': 5741.7, 'weight': 4, 'content': [{'end': 5748.404, 'text': "i created this zero here with just a blank little cell here, and that's the one we're going to use for this now.", 'start': 5741.7, 'duration': 6.704}, {'end': 5761.131, 'text': "so if we go back into our use stage now, into our use player, you can see that we are just rendering a random tetromino here, and that's not good.", 'start': 5748.404, 'duration': 12.727}, {'end': 5778.976, 'text': 'if we import our tetrominos also here, then we can just grab the tetromino and we grab the first one in the array tetromino tetrominos and we save it.', 'start': 5761.131, 'duration': 17.845}], 'summary': 'Created a new cell for rendering tetrominoes, importing tetrominos, and saving the first one.', 'duration': 37.276, 'max_score': 5741.7, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5741700.jpg'}, {'end': 5816.248, 'src': 'embed', 'start': 5791.825, 'weight': 1, 'content': [{'end': 5798.971, 'text': 'so if you press left and right and the down button, we can actually move the tetromino now and as you can see,', 'start': 5791.825, 'duration': 7.146}, {'end': 5804.435, 'text': "we have not done any collision detection yet, so it will screw up here, but that's fine for now.", 'start': 5798.971, 'duration': 5.464}, {'end': 5814.106, 'text': "we will fix that later, but at least the controls are working and that's also great.", 'start': 5804.435, 'duration': 9.671}, {'end': 5816.248, 'text': 'so we have something here now.', 'start': 5814.106, 'duration': 2.142}], 'summary': 'Controls for moving the tetromino are implemented, but collision detection is not yet in place.', 'duration': 24.423, 'max_score': 5791.825, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5791825.jpg'}, {'end': 5874.806, 'src': 'embed', 'start': 5844.351, 'weight': 5, 'content': [{'end': 5847.232, 'text': "That's where we're going to place the collision detection function.", 'start': 5844.351, 'duration': 2.881}, {'end': 5850.114, 'text': 'It made sense for me to place it in that file.', 'start': 5847.812, 'duration': 2.302}, {'end': 5854.256, 'text': 'But if you feel that you want to place it somewhere else, you can do that, of course.', 'start': 5850.654, 'duration': 3.602}, {'end': 5858.173, 'text': "But for this tutorial, I'm going to create it here.", 'start': 5855.951, 'duration': 2.222}, {'end': 5861.255, 'text': "So make sure you're in the gamehelpers.js file.", 'start': 5858.253, 'duration': 3.002}, {'end': 5865.338, 'text': 'And we have to think about a few things before we create this function.', 'start': 5862.136, 'duration': 3.202}, {'end': 5874.806, 'text': "One of them is that it's probably better to use for loops, because it will be at least a little bit faster than to use, for example, map or foreach,", 'start': 5865.759, 'duration': 9.047}], 'summary': 'Collision detection function placed in gamehelpers.js for faster performance using for loops', 'duration': 30.455, 'max_score': 5844.351, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5844351.jpg'}], 'start': 5101.968, 'title': 'React use effect and implementing collision detection', 'summary': 'Covers implementing a use effect with an inline arrow function in a react component and emphasizes flushing the stage, using map to iterate over a multidimensional array, and implementing collision detection in a tetris game. it details the process of checking for collisions, updating the game stage, addressing rendering bugs, and making adjustments to the game initialization process.', 'chapters': [{'end': 5225.7, 'start': 5101.968, 'title': 'React use effect and update function', 'summary': 'Covers the implementation of a use effect with an inline arrow function to create and update the stage in a react component, emphasizing the process of flushing the stage and using map to iterate over a multidimensional array.', 'duration': 123.732, 'highlights': ['The chapter explains the process of creating a use effect with an inline arrow function to handle the creation and update of the stage in a React component.', 'It demonstrates the use of the update stage function to set the state of the stage using the set stage function.', 'The transcript delves into the process of flushing the stage and clearing it from the previous render by creating a new stage and iterating over its rows and cells using map.']}, {'end': 5865.338, 'start': 5228.28, 'title': 'Implementing collision detection', 'summary': 'Explains the implementation of collision detection in a tetris game, detailing the process of checking for collisions, updating the game stage, and ensuring proper rendering of tetrominos. it also addresses a bug related to rendering the same tetromino and making adjustments to the game initialization process.', 'duration': 637.058, 'highlights': ['The chapter explains the implementation of collision detection in a Tetris game, detailing the process of checking for collisions, updating the game stage, and ensuring proper rendering of tetrominos.', 'The tutorial addresses a bug related to rendering the same tetromino and making adjustments to the game initialization process.', 'The tutorial also covers the process of creating and placing the collision detection function in the game helpers.js file.']}], 'duration': 763.37, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5101968.jpg', 'highlights': ['The chapter explains the process of creating a use effect with an inline arrow function to handle the creation and update of the stage in a React component.', 'The chapter explains the implementation of collision detection in a Tetris game, detailing the process of checking for collisions, updating the game stage, and ensuring proper rendering of tetrominos.', 'It demonstrates the use of the update stage function to set the state of the stage using the set stage function.', 'The transcript delves into the process of flushing the stage and clearing it from the previous render by creating a new stage and iterating over its rows and cells using map.', 'The tutorial addresses a bug related to rendering the same tetromino and making adjustments to the game initialization process.', 'The tutorial also covers the process of creating and placing the collision detection function in the game helpers.js file.']}, {'end': 7449.429, 'segs': [{'end': 5891.935, 'src': 'embed', 'start': 5865.759, 'weight': 0, 'content': [{'end': 5874.806, 'text': "One of them is that it's probably better to use for loops, because it will be at least a little bit faster than to use, for example, map or foreach,", 'start': 5865.759, 'duration': 9.047}, {'end': 5880.33, 'text': "because we are going to loop through our tetra minor here again and we're going to have two loops for this one also.", 'start': 5874.806, 'duration': 5.524}, {'end': 5885.753, 'text': "So if we use, for example, foreach, We can't break out of that one.", 'start': 5880.931, 'duration': 4.822}, {'end': 5891.935, 'text': "And that's the downside for us because we want to break out of the loop as soon as we collide with anything.", 'start': 5885.893, 'duration': 6.042}], 'summary': 'Using for loops may be faster than map or foreach for looping through tetra minor and breaking out of the loop when colliding.', 'duration': 26.176, 'max_score': 5865.759, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5865759.jpg'}, {'end': 6486.765, 'src': 'heatmap', 'start': 6289.376, 'weight': 0.906, 'content': [{'end': 6298.551, 'text': "so we type in a one here and we check that it isn't clear, Like so.", 'start': 6289.376, 'duration': 9.175}, {'end': 6301.697, 'text': 'And this one should of course be a capital Y.', 'start': 6299.052, 'duration': 2.645}, {'end': 6305.495, 'text': 'So there you have it.', 'start': 6304.775, 'duration': 0.72}, {'end': 6309.838, 'text': "That's everything we need for our kind of simple collision detection.", 'start': 6306.136, 'duration': 3.702}, {'end': 6314.781, 'text': 'I actually almost copy and paste this code from the MethMethMethod tutorial,', 'start': 6310.158, 'duration': 4.623}, {'end': 6319.043, 'text': 'because I think this is a very simple and clever way to check the collision.', 'start': 6314.781, 'duration': 4.262}, {'end': 6326.188, 'text': "Because with this collision detection, we can detect if we're outside the stage and also if we collide with any of the tetraminers.", 'start': 6319.464, 'duration': 6.724}, {'end': 6336.311, 'text': "Because we're looping through the tetraminer that we have in play and check if any of the cells inside of that tetromino collide with any of the cells in the playfield.", 'start': 6326.568, 'duration': 9.743}, {'end': 6345.434, 'text': "and that's how this function can check for everything that we want if we go outside the stage and also if we collide with another tetromino that's merged to the stage.", 'start': 6336.311, 'duration': 9.123}, {'end': 6352.736, 'text': "So we save it and we see that we didn't break anything and we didn't do that and that's good.", 'start': 6347.474, 'duration': 5.262}, {'end': 6358.057, 'text': 'We have to go inside our useStage hook and add a little collision detection here,', 'start': 6353.756, 'duration': 4.301}, {'end': 6373.694, 'text': 'because when we have the new stage here with the new updated position, we then check if we collided like so so we can do a little if statement here.', 'start': 6358.888, 'duration': 14.806}, {'end': 6385.539, 'text': 'if player got collided, then we just reset the player like so and it will need a new dependency here so we can add reset player.', 'start': 6373.694, 'duration': 11.845}, {'end': 6396.523, 'text': 'Because if we collide we just reset the player, we move the player up to the zero Y position and the other one will stay in place where we collided,', 'start': 6386.735, 'duration': 9.788}, {'end': 6398.865, 'text': 'because we merged it into the stage here.', 'start': 6396.523, 'duration': 2.342}, {'end': 6407.232, 'text': 'The last thing we have to do here now is to go into our Tetris component and actually use our check collision function.', 'start': 6399.365, 'duration': 7.867}, {'end': 6410.234, 'text': 'First we have to import it from the game helpers.', 'start': 6408.012, 'duration': 2.222}, {'end': 6413.397, 'text': 'So we have our check collision imported there.', 'start': 6411.035, 'duration': 2.362}, {'end': 6419.612, 'text': 'And we have to check the collision when we move the player and when the player drops.', 'start': 6415.427, 'duration': 4.185}, {'end': 6427.942, 'text': "So inside our movePlayer we create an if statement and if we don't collide,", 'start': 6419.952, 'duration': 7.99}, {'end': 6434.47, 'text': 'we send in the player the stage and the intended position we want to move to.', 'start': 6427.942, 'duration': 6.528}, {'end': 6445.157, 'text': 'So we have an X value of direction and we have the Y set to zero because this MovePlayer function is responsible for moving the player left and right.', 'start': 6435.97, 'duration': 9.187}, {'end': 6450.101, 'text': 'So yeah, I probably should have named it something else.', 'start': 6445.598, 'duration': 4.503}, {'end': 6451.502, 'text': 'Yeah, I realized that.', 'start': 6450.141, 'duration': 1.361}, {'end': 6455.024, 'text': 'can change it to a more descriptive name.', 'start': 6452.683, 'duration': 2.341}, {'end': 6463.548, 'text': "if you want to do that, then we can move this one inside of the if statement, and this means that if we're not colliding with with anything,", 'start': 6455.024, 'duration': 8.524}, {'end': 6465.308, 'text': 'we actually do the move.', 'start': 6463.548, 'duration': 1.76}, {'end': 6468.61, 'text': "otherwise we don't do anything here.", 'start': 6465.308, 'duration': 3.302}, {'end': 6472.771, 'text': 'so we save it and we can see if it works.', 'start': 6468.61, 'duration': 4.161}, {'end': 6479.983, 'text': "we shouldn't be able to go outside the play field to the left and to the right and we can't, and that's great.", 'start': 6472.771, 'duration': 7.212}, {'end': 6486.765, 'text': 'so it will stop the tetra minor there because we are colliding with the sides of the stage.', 'start': 6479.983, 'duration': 6.782}], 'summary': 'Simple collision detection code implemented for tetris game with stage boundaries and tetromino collisions.', 'duration': 197.389, 'max_score': 6289.376, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6289376.jpg'}, {'end': 6345.434, 'src': 'embed', 'start': 6319.464, 'weight': 2, 'content': [{'end': 6326.188, 'text': "Because with this collision detection, we can detect if we're outside the stage and also if we collide with any of the tetraminers.", 'start': 6319.464, 'duration': 6.724}, {'end': 6336.311, 'text': "Because we're looping through the tetraminer that we have in play and check if any of the cells inside of that tetromino collide with any of the cells in the playfield.", 'start': 6326.568, 'duration': 9.743}, {'end': 6345.434, 'text': "and that's how this function can check for everything that we want if we go outside the stage and also if we collide with another tetromino that's merged to the stage.", 'start': 6336.311, 'duration': 9.123}], 'summary': 'Collision detection function checks for stage boundary and tetromino collisions.', 'duration': 25.97, 'max_score': 6319.464, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6319464.jpg'}, {'end': 6410.234, 'src': 'embed', 'start': 6386.735, 'weight': 4, 'content': [{'end': 6396.523, 'text': 'Because if we collide we just reset the player, we move the player up to the zero Y position and the other one will stay in place where we collided,', 'start': 6386.735, 'duration': 9.788}, {'end': 6398.865, 'text': 'because we merged it into the stage here.', 'start': 6396.523, 'duration': 2.342}, {'end': 6407.232, 'text': 'The last thing we have to do here now is to go into our Tetris component and actually use our check collision function.', 'start': 6399.365, 'duration': 7.867}, {'end': 6410.234, 'text': 'First we have to import it from the game helpers.', 'start': 6408.012, 'duration': 2.222}], 'summary': 'Implement reset and collision functions in tetris game', 'duration': 23.499, 'max_score': 6386.735, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6386735.jpg'}, {'end': 6479.983, 'src': 'embed', 'start': 6455.024, 'weight': 3, 'content': [{'end': 6463.548, 'text': "if you want to do that, then we can move this one inside of the if statement, and this means that if we're not colliding with with anything,", 'start': 6455.024, 'duration': 8.524}, {'end': 6465.308, 'text': 'we actually do the move.', 'start': 6463.548, 'duration': 1.76}, {'end': 6468.61, 'text': "otherwise we don't do anything here.", 'start': 6465.308, 'duration': 3.302}, {'end': 6472.771, 'text': 'so we save it and we can see if it works.', 'start': 6468.61, 'duration': 4.161}, {'end': 6479.983, 'text': "we shouldn't be able to go outside the play field to the left and to the right and we can't, and that's great.", 'start': 6472.771, 'duration': 7.212}], 'summary': 'Code checks for collisions and restricts movement within play field, ensuring no overflow.', 'duration': 24.959, 'max_score': 6455.024, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6455024.jpg'}, {'end': 6676.902, 'src': 'heatmap', 'start': 6554.01, 'weight': 5, 'content': [{'end': 6556.372, 'text': "We're just setting the collided to true.", 'start': 6554.01, 'duration': 2.362}, {'end': 6570.998, 'text': "We can also, inside of this else block, create something when the game is over, because if we're colliding and the player.pos.y is less than one,", 'start': 6557.792, 'duration': 13.206}, {'end': 6576.381, 'text': "we know that we're colliding up here somewhere and the game should be set to game over.", 'start': 6570.998, 'duration': 5.383}, {'end': 6594.738, 'text': "so we can console.log gameOver and then we're going to set gameOver to true and set dropTime to null, because we're not dropping anymore.", 'start': 6578.834, 'duration': 15.904}, {'end': 6605.501, 'text': "so we set that to null and also up here in the startGame function we can set gameOver to false because we're starting a new game here,", 'start': 6594.738, 'duration': 10.763}, {'end': 6606.901, 'text': "so it shouldn't be set to true.", 'start': 6605.501, 'duration': 1.4}, {'end': 6609.933, 'text': "All right, we save it and see what we've got.", 'start': 6607.952, 'duration': 1.981}, {'end': 6618.895, 'text': "We're checking here and it's still working with the collision on the sides and if we go down here it should merge into that position in the stage and it does so.", 'start': 6610.513, 'duration': 8.382}, {'end': 6619.515, 'text': "that's great.", 'start': 6618.895, 'duration': 0.62}, {'end': 6627.918, 'text': "And we can see if it will go into game over mode here when we're colliding at the top.", 'start': 6622.336, 'duration': 5.582}, {'end': 6630.042, 'text': 'And it does also.', 'start': 6628.76, 'duration': 1.282}, {'end': 6632.225, 'text': "And that's really, really sweet.", 'start': 6630.082, 'duration': 2.143}, {'end': 6636.692, 'text': 'But now we have a kind of half working game.', 'start': 6632.786, 'duration': 3.906}, {'end': 6641.78, 'text': "It's not dropping because we haven't created the interval and we can't rotate the player.", 'start': 6637.052, 'duration': 4.728}, {'end': 6644.504, 'text': "So that's what we're going to do in the next videos.", 'start': 6641.86, 'duration': 2.644}, {'end': 6653.587, 'text': "In this video we're going to create the rotation for the player and we're mostly going to be in the use player custom hook.", 'start': 6646.983, 'duration': 6.604}, {'end': 6656.63, 'text': "So make sure you're in the use player custom hook.", 'start': 6654.128, 'duration': 2.502}, {'end': 6659.832, 'text': "We're going to create two new functions in this one.", 'start': 6657.31, 'duration': 2.522}, {'end': 6665.115, 'text': "So just below our state here we can create one that's called rotate.", 'start': 6660.912, 'duration': 4.203}, {'end': 6670.519, 'text': 'This one is going to receive a matrix and a direction.', 'start': 6665.936, 'duration': 4.583}, {'end': 6676.902, 'text': 'So the matrix is actually going to be our tetra minor so you can name it to that also if you want.', 'start': 6672.438, 'duration': 4.464}], 'summary': 'Updating game logic to handle collisions and game over, preparing for player rotation and intervals.', 'duration': 122.892, 'max_score': 6554.01, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6554010.jpg'}, {'end': 6690.004, 'src': 'embed', 'start': 6660.912, 'weight': 6, 'content': [{'end': 6665.115, 'text': "So just below our state here we can create one that's called rotate.", 'start': 6660.912, 'duration': 4.203}, {'end': 6670.519, 'text': 'This one is going to receive a matrix and a direction.', 'start': 6665.936, 'duration': 4.583}, {'end': 6676.902, 'text': 'So the matrix is actually going to be our tetra minor so you can name it to that also if you want.', 'start': 6672.438, 'duration': 4.464}, {'end': 6682.326, 'text': "And of course we're going to have an equal sign and an arrow here.", 'start': 6678.503, 'duration': 3.823}, {'end': 6686.21, 'text': "Then we're going to have another function that's called player rotate.", 'start': 6683.227, 'duration': 2.983}, {'end': 6690.004, 'text': 'And we could actually do them in one function.', 'start': 6687.802, 'duration': 2.202}], 'summary': "Creating a 'rotate' function to receive a matrix and direction for tetra minor.", 'duration': 29.092, 'max_score': 6660.912, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6660912.jpg'}, {'end': 7012.488, 'src': 'embed', 'start': 6971.821, 'weight': 7, 'content': [{'end': 6977.325, 'text': 'And grab the tetromino from that one.', 'start': 6971.821, 'duration': 5.504}, {'end': 6982.109, 'text': 'And we use our rotate function.', 'start': 6980.147, 'duration': 1.962}, {'end': 6992.481, 'text': 'and we rotate the cloned player.tetromino and we give it the direction.', 'start': 6984.178, 'duration': 8.303}, {'end': 7005.866, 'text': 'also, and this will rotate the player and we can set the player to the cloned player.', 'start': 6992.481, 'duration': 13.385}, {'end': 7012.488, 'text': "we also need to export our functions here, or actually it's just the player rotate, we need to export.", 'start': 7005.866, 'duration': 6.622}], 'summary': 'Code rotates tetromino and exports player rotate function.', 'duration': 40.667, 'max_score': 6971.821, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU6971821.jpg'}, {'end': 7115.017, 'src': 'embed', 'start': 7082.188, 'weight': 8, 'content': [{'end': 7090.715, 'text': 'I kind of play Tetris with just rotating it with one key, so I choose to not implement two keys for rotating in different directions here.', 'start': 7082.188, 'duration': 8.527}, {'end': 7093.418, 'text': "All right, let's see if this works.", 'start': 7091.656, 'duration': 1.762}, {'end': 7097.121, 'text': "And it does, that's nice.", 'start': 7095.76, 'duration': 1.361}, {'end': 7104.207, 'text': "But if we go to the side here, you can see if we rotate it, it will rotate outside of the stage, and that's no good.", 'start': 7098.082, 'duration': 6.125}, {'end': 7108.791, 'text': 'And it will break it, as you see here.', 'start': 7107.189, 'duration': 1.602}, {'end': 7115.017, 'text': "But it's rotating nicely.", 'start': 7113.476, 'duration': 1.541}], 'summary': 'Implemented single-key rotation in tetris prototype, with some issues rotating outside the stage.', 'duration': 32.829, 'max_score': 7082.188, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7082188.jpg'}, {'end': 7248.159, 'src': 'embed', 'start': 7224.251, 'weight': 1, 'content': [{'end': 7233.794, 'text': "It's going to take the tetra minor when we rotate it and move it right and left and right and left and check if we collide with something.", 'start': 7224.251, 'duration': 9.543}, {'end': 7238.295, 'text': "And that's the clever little function that he came up with in that tutorial.", 'start': 7234.274, 'duration': 4.021}, {'end': 7239.776, 'text': "Let's say we go right.", 'start': 7238.696, 'duration': 1.08}, {'end': 7240.436, 'text': 'It will check.', 'start': 7239.916, 'duration': 0.52}, {'end': 7242.417, 'text': 'Are we colliding? No.', 'start': 7240.716, 'duration': 1.701}, {'end': 7243.637, 'text': 'Then we go left.', 'start': 7242.837, 'duration': 0.8}, {'end': 7245.398, 'text': 'Are we colliding there? No.', 'start': 7244.017, 'duration': 1.381}, {'end': 7248.159, 'text': 'And then it will continue until we collide.', 'start': 7245.958, 'duration': 2.201}], 'summary': 'Tetra minor moves right and left, checking for collisions, a clever function in the tutorial.', 'duration': 23.908, 'max_score': 7224.251, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7224251.jpg'}], 'start': 5865.759, 'title': 'Optimizing game development functions', 'summary': 'Covers optimizing collision detection function for faster performance, implementing collision detection in a tetris game, creating player rotation, and fixing rotation limitation to ensure successful rotation in game development.', 'chapters': [{'end': 6319.043, 'start': 5865.759, 'title': 'Optimizing collision detection function', 'summary': 'Discusses optimizing the collision detection function for a game, highlighting the use of for loops for faster performance and the step-by-step process of checking for collisions and ensuring the tetromino stays within the game area.', 'duration': 453.284, 'highlights': ['Using for loops for faster performance The speaker recommends using for loops over map or foreach for better performance in the collision detection function, as it can be at least a little bit faster.', "Step-by-step process of collision detection The detailed process of collision detection is explained, including checking for actual tetromino cells, verifying movement within game area's height and width, and ensuring the cell is not set to clear.", "Ensuring tetromino stays within game area The function includes checks to ensure the tetromino does not move outside the game area's height and width, and verifies that the intended cell for movement is not set to clear, providing a comprehensive collision detection process."]}, {'end': 6636.692, 'start': 6319.464, 'title': 'Tetris collision detection', 'summary': 'Covers the implementation of collision detection in a tetris game, ensuring the player does not move outside the play field and can detect collisions with other tetrominos, ultimately leading to game-over conditions if necessary.', 'duration': 317.228, 'highlights': ['The collision detection function checks if the player goes outside the stage and collides with other tetrominos, preventing them from moving further. The collision detection function ensures that the player cannot move outside the play field and identifies collisions with other tetrominos, effectively preventing further movement.', "If the player collides, the function resets the player's position, preventing them from moving and merging the tetromino into the stage. In case of a collision, the function resets the player's position, halting movement and merging the tetromino into the stage.", 'The game-over condition is triggered if a collision occurs at the top of the play field, leading to the termination of the game. A collision at the top of the play field triggers the game-over condition, terminating the game.']}, {'end': 7115.017, 'start': 6637.052, 'title': 'Creating player rotation', 'summary': 'Focuses on creating player rotation in the use player custom hook, involving the creation of two new functions for rotating the tetromino and implementing collision detection when rotating the player.', 'duration': 477.965, 'highlights': ["The chapter demonstrates the creation of two new functions, 'rotate' and 'player rotate', for rotating the tetromino and implementing collision detection when rotating the player.", "The 'rotate' function shifts the rows of the matrix to become columns and then reverses the values in the rows to achieve rotation, addressing clockwise and counterclockwise rotations based on the direction input.", "The 'player rotate' function involves creating a deep clone of the player to avoid mutating the state, rotating the cloned player's tetromino using the 'rotate' function, and setting the player to the cloned player.", "The Tetris component is updated to include the 'player rotate' function, allowing for clockwise rotation of the tetromino, with a suggestion to implement counterclockwise rotation as well."]}, {'end': 7449.429, 'start': 7118.921, 'title': 'Fixing rotation limitation', 'summary': 'Discusses a function to prevent rotation of a game piece outside the stage by implementing a back-and-forth movement check, ensuring collision detection and enabling successful rotation, a key concept in game development.', 'duration': 330.508, 'highlights': ["A function is implemented to prevent the rotation of a game piece outside the stage, enhancing the game's mechanics and user experience.", "The function involves a clever back-and-forth movement check to ensure collision detection and enable successful rotation, enhancing the game's functionality.", 'The code involves a while loop to continuously check for collisions during rotation, ensuring smooth and accurate gameplay mechanics.', 'The detailed explanation of the code provides insights into the thought process and logic behind the back-and-forth movement check, aiding in understanding the complex function.', 'The implementation of this function is described as the most advanced in the tutorial, emphasizing its significance in game development and the potential challenges in grasping its complexity.']}], 'duration': 1583.67, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU5865759.jpg', 'highlights': ['Using for loops for faster performance in collision detection', 'Step-by-step process of collision detection explained', 'Ensuring tetromino stays within game area during collision detection', 'Collision detection function prevents player from moving outside play field', "Resetting player's position and merging tetromino on collision", 'Game-over condition triggered by collision at top of play field', "Demonstration of creating 'rotate' and 'player rotate' functions", "Detailed process of rotating tetromino using 'rotate' and 'player rotate' functions", 'Implementation of function to prevent rotation of game piece outside stage', 'Clever back-and-forth movement check for collision detection during rotation', 'Use of while loop for continuous collision check during rotation']}, {'end': 7956.295, 'segs': [{'end': 7533.883, 'src': 'embed', 'start': 7506.17, 'weight': 0, 'content': [{'end': 7509.853, 'text': "and this is how we're going to keep track of all the rows that we have cleared.", 'start': 7506.17, 'duration': 3.683}, {'end': 7517.339, 'text': 'so we use state and give it an initial value of zero.', 'start': 7509.853, 'duration': 7.486}, {'end': 7533.883, 'text': "okay, and the first thing we want to do in this use effect is to set rows cleared to zero and then we're going to create another function here that's called sweep rows.", 'start': 7517.339, 'duration': 16.544}], 'summary': 'Using state to track cleared rows with initial value of zero. creating function sweep rows.', 'duration': 27.713, 'max_score': 7506.17, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7506170.jpg'}, {'end': 7711.094, 'src': 'embed', 'start': 7683.777, 'weight': 3, 'content': [{'end': 7689.16, 'text': 'So with unshift we can add a complete empty row at the beginning of the array.', 'start': 7683.777, 'duration': 5.383}, {'end': 7699.847, 'text': 'So we create a new array from our new stage, zero.length, that will give us the width of the actual playfield.', 'start': 7689.521, 'duration': 10.326}, {'end': 7707.691, 'text': 'And we fill it up with an array of zeros and clear, because these ones are completely fresh.', 'start': 7701.047, 'duration': 6.644}, {'end': 7711.094, 'text': 'So they should be a zero and clear.', 'start': 7709.112, 'duration': 1.982}], 'summary': 'Using unshift to add an empty row to the array for game stage initialization.', 'duration': 27.317, 'max_score': 7683.777, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7683777.jpg'}, {'end': 7767.716, 'src': 'embed', 'start': 7739.084, 'weight': 2, 'content': [{'end': 7741.184, 'text': 'I will go through it again and tell you what it will do.', 'start': 7739.084, 'duration': 2.1}, {'end': 7749.324, 'text': 'We give this function our stage, and we take the complete stage and use the reduce method on this one.', 'start': 7742.219, 'duration': 7.105}, {'end': 7756.388, 'text': 'By using reduce, we can create a new array, so we check if the row contains any zero.', 'start': 7749.864, 'duration': 6.524}, {'end': 7762.252, 'text': "If it does, we know that this row shouldn't be clear because we haven't filled up a complete row.", 'start': 7756.548, 'duration': 5.704}, {'end': 7767.716, 'text': "But if we have filled up a complete row, we first add a row to our row's cleared state.", 'start': 7762.852, 'duration': 4.864}], 'summary': 'Using reduce method to check for complete rows in a stage.', 'duration': 28.632, 'max_score': 7739.084, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7739084.jpg'}, {'end': 7810.778, 'src': 'embed', 'start': 7786.329, 'weight': 1, 'content': [{'end': 7793.613, 'text': 'So this will create the illusion that we remove the row on the stage and move the other ones down that was above that row.', 'start': 7786.329, 'duration': 7.284}, {'end': 7800.769, 'text': "And if we don't have a full row we just return the row as it is in the array and that's the way it works.", 'start': 7794.764, 'duration': 6.005}, {'end': 7804.432, 'text': 'We have to use this function somewhere and we can do it.', 'start': 7801.59, 'duration': 2.842}, {'end': 7810.778, 'text': 'If we know that we collide with something we should do this sweep and see if we also have a full row.', 'start': 7805.053, 'duration': 5.725}], 'summary': 'Function creates illusion of removing rows, moving others down. detects collision and checks for full row.', 'duration': 24.449, 'max_score': 7786.329, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7786329.jpg'}], 'start': 7449.65, 'title': 'Manipulating arrays', 'summary': "Involves creating a function called 'sweep rows' in the use stage custom hook to clear full rows in the tetris game, with the goal of updating the 'rows cleared' state and sweeping the stage based on certain conditions. it also explains how to use the unshift method to add and manipulate elements in an array, demonstrating the process of creating a new array, checking for full rows, and using the sweep rows function to remove full rows from the stage.", 'chapters': [{'end': 7635.029, 'start': 7449.65, 'title': 'Creating a function to sweep rows', 'summary': "Involves creating a function called 'sweep rows' in the use stage custom hook to clear full rows in the tetris game, with the goal of updating the 'rows cleared' state and sweeping the stage based on certain conditions.", 'duration': 185.379, 'highlights': ["Creating a state 'rows cleared' to keep track of cleared rows, initialized with a value of zero A state called 'rows cleared' is created to track cleared rows, starting with an initial value of zero.", "Implementing the 'sweep rows' function to clear full rows based on specific conditions The 'sweep rows' function is implemented to clear full rows based on certain conditions, such as identifying rows without zeros and marking them for clearing.", 'Utilizing the reduce function to iterate through the stage and identify full rows for clearing The reduce function is used to iterate through the stage and identify full rows, enabling the clearing of rows based on specific criteria.']}, {'end': 7956.295, 'start': 7636.024, 'title': 'Updating array with unshift method', 'summary': 'Explains how to use the unshift method to add and manipulate elements in an array, demonstrating the process of creating a new array, checking for full rows, and using the sweep rows function to remove full rows from the stage.', 'duration': 320.271, 'highlights': ['Using unshift method to add a new value to the beginning of the array The speaker explains how the unshift method is used to add a new value to the array at the beginning, demonstrating the process of manipulating the array by adding elements.', 'Creating a new array from the stage and filling it with zeros and clear elements The process of creating a new array from the stage, determining the width of the playfield, and populating it with zeros and clear elements is explained.', 'Demonstrating the process of checking for full rows and removing them using the sweep rows function The speaker explains the process of using the sweep rows function to check for and remove full rows from the stage, creating the illusion of removing rows and moving other elements down.']}], 'duration': 506.645, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7449650.jpg', 'highlights': ["Creating a state 'rows cleared' to keep track of cleared rows, initialized with a value of zero", "Implementing the 'sweep rows' function to clear full rows based on specific conditions", 'Utilizing the reduce function to iterate through the stage and identify full rows for clearing', 'Using unshift method to add a new value to the beginning of the array', 'Creating a new array from the stage and filling it with zeros and clear elements', 'Demonstrating the process of checking for full rows and removing them using the sweep rows function']}, {'end': 9256.358, 'segs': [{'end': 7987.805, 'src': 'embed', 'start': 7956.836, 'weight': 2, 'content': [{'end': 7963.142, 'text': "He has created this use interval for us that we can just use in our game and that's what we're going to do now.", 'start': 7956.836, 'duration': 6.306}, {'end': 7966.685, 'text': 'So back to our app and our code.', 'start': 7964.683, 'duration': 2.002}, {'end': 7969.77, 'text': 'inside of our tetris component.', 'start': 7967.708, 'duration': 2.062}, {'end': 7973.032, 'text': "we're going to be in that component in this video at the beginning.", 'start': 7969.77, 'duration': 3.262}, {'end': 7987.805, 'text': 'here, where we import our custom hooks, we can import our use interval from dot dot forward slash hooks and use interval,', 'start': 7973.032, 'duration': 14.773}], 'summary': 'Developed a custom use interval for game implementation.', 'duration': 30.969, 'max_score': 7956.836, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7956836.jpg'}, {'end': 8099.957, 'src': 'embed', 'start': 8066.613, 'weight': 4, 'content': [{'end': 8068.254, 'text': 'back to the Tetris component.', 'start': 8066.613, 'duration': 1.641}, {'end': 8075.259, 'text': 'we have to do a few more things here to get it up and running, because now our drop time is set to null.', 'start': 8068.254, 'duration': 7.005}, {'end': 8076.52, 'text': 'we set it up here.', 'start': 8075.259, 'duration': 1.261}, {'end': 8083.344, 'text': 'so now the interval is not active, but we have a start button.', 'start': 8078.26, 'duration': 5.084}, {'end': 8090.39, 'text': 'so when we start our game we can set our drop time and we send in 1000.', 'start': 8083.344, 'duration': 7.046}, {'end': 8099.957, 'text': 'that means one second and we save it and then, if we press start game, as you can see,', 'start': 8090.39, 'duration': 9.567}], 'summary': 'Adjusting tetris component drop time to 1 second for game start.', 'duration': 33.344, 'max_score': 8066.613, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU8066613.jpg'}, {'end': 8180.933, 'src': 'embed', 'start': 8142.185, 'weight': 6, 'content': [{'end': 8142.746, 'text': "that's easy.", 'start': 8142.185, 'duration': 0.561}, {'end': 8149.05, 'text': 'we can just set drop time to null and that will make sure that we stop the interval.', 'start': 8142.746, 'duration': 6.304}, {'end': 8154.314, 'text': 'but we also have to activate it again when the player releases the down key.', 'start': 8149.05, 'duration': 5.264}, {'end': 8164.381, 'text': "so we're going to create a new function here that's called key up, and inside of this we're going to take in the key code again.", 'start': 8154.314, 'duration': 10.067}, {'end': 8180.933, 'text': "so we destructure that out from our event and yet again we're going to check if the game is not game over and we can activate the interval again when the player released the down key.", 'start': 8164.381, 'duration': 16.552}], 'summary': 'Set drop time to null to stop interval, activate again on key up', 'duration': 38.748, 'max_score': 8142.185, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU8142185.jpg'}, {'end': 8280.215, 'src': 'embed', 'start': 8237.225, 'weight': 8, 'content': [{'end': 8252.212, 'text': 'because here we can console log interval off and we copy this one and go to our key up console log interval on.', 'start': 8237.225, 'duration': 14.987}, {'end': 8258.23, 'text': "make sure you're showing your console here.", 'start': 8256.03, 'duration': 2.2}, {'end': 8263.951, 'text': 'whoops, i misspelled this one.', 'start': 8258.23, 'duration': 5.721}, {'end': 8266.592, 'text': 'yeah, my formatting here has added this one for us.', 'start': 8263.951, 'duration': 2.641}, {'end': 8267.932, 'text': "yeah, that's nice.", 'start': 8266.592, 'duration': 1.34}, {'end': 8269.653, 'text': 'so i can remove this one.', 'start': 8267.932, 'duration': 1.721}, {'end': 8271.633, 'text': 'it should only be use interval here.', 'start': 8269.653, 'duration': 1.98}, {'end': 8280.215, 'text': 'okay, so we start the game and i press the down button.', 'start': 8271.633, 'duration': 8.582}], 'summary': 'Debugging process to rectify code and execute game commands.', 'duration': 42.99, 'max_score': 8237.225, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU8237225.jpg'}, {'end': 8355.157, 'src': 'embed', 'start': 8329.289, 'weight': 3, 'content': [{'end': 8333.67, 'text': "We're just going to create our custom hook for displaying scores, rows and levels.", 'start': 8329.289, 'duration': 4.381}, {'end': 8339.451, 'text': 'And we are eventually going to import it here in the Tetris component with the other hooks here.', 'start': 8334.29, 'duration': 5.161}, {'end': 8341.633, 'text': 'But we will create it first.', 'start': 8340.092, 'duration': 1.541}, {'end': 8343.414, 'text': 'So we have something to import here.', 'start': 8341.772, 'duration': 1.642}, {'end': 8351.056, 'text': "So inside our hooks folder, create a new file that's called useGameStatus.js.", 'start': 8343.894, 'duration': 7.162}, {'end': 8353.397, 'text': "And we're going to need a few things here.", 'start': 8351.697, 'duration': 1.7}, {'end': 8355.157, 'text': 'So we import useState.', 'start': 8353.496, 'duration': 1.661}], 'summary': 'Creating a custom hook called usegamestatus.js for displaying scores, rows, and levels, and importing it into the tetris component with other hooks.', 'duration': 25.868, 'max_score': 8329.289, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU8329289.jpg'}, {'end': 8471.67, 'src': 'embed', 'start': 8446.871, 'weight': 9, 'content': [{'end': 8456.842, 'text': "that's called line points, and this is going to be an array with 40, 100, 300 and 1200..", 'start': 8446.871, 'duration': 9.971}, {'end': 8459.703, 'text': 'And these are the actual scores.', 'start': 8456.842, 'duration': 2.861}, {'end': 8464.766, 'text': 'I did some googling and found these scores from the original Tetris game.', 'start': 8459.843, 'duration': 4.923}, {'end': 8468.148, 'text': "So we're going to use these to calculate our total score.", 'start': 8465.226, 'duration': 2.922}, {'end': 8471.67, 'text': "I don't know there's probably a lot of different versions,", 'start': 8468.828, 'duration': 2.842}], 'summary': 'Using line points array 40, 100, 300, 1200 from original tetris game to calculate total score.', 'duration': 24.799, 'max_score': 8446.871, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU8446871.jpg'}, {'end': 8879.695, 'src': 'embed', 'start': 8822.476, 'weight': 0, 'content': [{'end': 8825.638, 'text': 'and now we have to use these values inside of our Tetris component.', 'start': 8822.476, 'duration': 3.162}, {'end': 8832.101, 'text': 'First in our drop function we want to change the level depending on how many rows we have cleared.', 'start': 8826.698, 'duration': 5.403}, {'end': 8836.283, 'text': 'And that means we have to have something here that calculates that on every drop.', 'start': 8832.721, 'duration': 3.562}, {'end': 8838.884, 'text': 'So I make a little comment here.', 'start': 8837.444, 'duration': 1.44}, {'end': 8844.968, 'text': 'Increase level when player has cleared 10 rows.', 'start': 8840.205, 'duration': 4.763}, {'end': 8850.841, 'text': "I think that that also is the original Tetris, but I'm not sure.", 'start': 8847.378, 'duration': 3.463}, {'end': 8855.284, 'text': 'When you clear 10 rows, then we go up a level and the speed will increase.', 'start': 8851.381, 'duration': 3.903}, {'end': 8857.826, 'text': 'We create a little if statement here.', 'start': 8856.065, 'duration': 1.761}, {'end': 8864.271, 'text': 'We check if the rows are greater than level plus 1.', 'start': 8858.166, 'duration': 6.105}, {'end': 8872.357, 'text': "That's because the level starts at 0, just as before, times 10.", 'start': 8864.271, 'duration': 8.086}, {'end': 8874.979, 'text': 'We set the level with our previous state.', 'start': 8872.357, 'duration': 2.622}, {'end': 8879.695, 'text': 'and we just have the previous plus one.', 'start': 8876.693, 'duration': 3.002}], 'summary': 'The tetris component increases level and speed when 10 rows are cleared.', 'duration': 57.219, 'max_score': 8822.476, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU8822476.jpg'}, {'end': 9156.074, 'src': 'embed', 'start': 9132.737, 'weight': 1, 'content': [{'end': 9141.139, 'text': "And I actually think that this is a really good example to show you what React Memo does in React, because now it won't affect the cells.", 'start': 9132.737, 'duration': 8.402}, {'end': 9142.839, 'text': "that won't change on that render.", 'start': 9141.139, 'duration': 1.7}, {'end': 9147.42, 'text': 'It will only re-render the cells that change with the tetromino.', 'start': 9143.199, 'duration': 4.221}, {'end': 9149.181, 'text': "And that's good.", 'start': 9148.561, 'duration': 0.62}, {'end': 9154.142, 'text': "So we made quite an optimization here and reduced the re-renders here, and that's good.", 'start': 9149.361, 'duration': 4.781}, {'end': 9156.074, 'text': 'There you have it.', 'start': 9155.353, 'duration': 0.721}], 'summary': 'React memo optimizes rendering, reducing re-renders for improved performance.', 'duration': 23.337, 'max_score': 9132.737, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU9132737.jpg'}, {'end': 9227.975, 'src': 'embed', 'start': 9203.072, 'weight': 7, 'content': [{'end': 9212.346, 'text': 'You will see my pretty face here and you can just go to my channel and make sure you subscribe if you want free coding tips in React and other frontend stuff.', 'start': 9203.072, 'duration': 9.274}, {'end': 9215.851, 'text': 'And I also create paid premium courses.', 'start': 9213.61, 'duration': 2.241}, {'end': 9220.553, 'text': "I'm going to move them to my own platform soon, but for now they're up on Udemy.", 'start': 9216.411, 'duration': 4.142}, {'end': 9227.975, 'text': "And it's a beginner React course and also a course in Gatsby and how to create a Gatsby site with WordPress as a headless CMS.", 'start': 9220.873, 'duration': 7.102}], 'summary': 'Offers free coding tips in react, premium courses, beginner react and gatsby courses available on udemy.', 'duration': 24.903, 'max_score': 9203.072, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU9203072.jpg'}], 'start': 7956.836, 'title': 'Tetris game development', 'summary': "Covers implementing use interval for automatic movement, optimizing game performance, creating a game status hook, calculating scores and level increase, and developing a tetris game using react hooks, providing insights into developer's youtube channel and premium courses.", 'chapters': [{'end': 8066.613, 'start': 7956.836, 'title': 'Implementing use interval for game component', 'summary': 'Demonstrates the implementation of the use interval custom hook to enable automatic movement of the game component, allowing for precise control of the interval timing and functionality.', 'duration': 109.777, 'highlights': ["The use interval custom hook is imported from the 'hooks' directory and utilized to enable autonomous movement of the game component, offering enhanced user experience and interactivity.", 'The use interval function takes an inline function and the specified interval timing as parameters, providing flexibility and control over the automated movement of the game component.', "The 'drop time' state is integrated with the use interval, allowing for precise control and adjustment of the interval timing, enhancing the responsiveness and gameplay experience."]}, {'end': 8304.736, 'start': 8066.613, 'title': 'Tetris game optimization', 'summary': 'Covers optimizing the tetris game by setting up the drop time, creating a new function for key up events, and adding console logging for interval activity, resulting in a smoother gameplay experience.', 'duration': 238.123, 'highlights': ['The drop time is set to 1000 when the game starts, allowing the tetromino to move down every one second.', 'The creation of a new function for key up events ensures that the interval is activated again when the player releases the down key, preventing interference with the keyboard and providing smoother gameplay.', 'Console logging for interval activity is added to track when the interval is turned off and on, ensuring it does not interfere with the keyboard during gameplay.']}, {'end': 8489.282, 'start': 8306.883, 'title': 'Creating game status hook for tetris', 'summary': "Covers the creation of a custom hook usegamestatus.js to display scores, rows, and levels, while explaining the calculation of total score using line points and the parameter 'rows cleared'. it also mentions the importation of the hook into the tetris component.", 'duration': 182.399, 'highlights': ["The chapter covers the creation of a custom hook useGameStatus.js to display scores, rows, and levels, while explaining the calculation of total score using line points and the parameter 'rows cleared'.", 'The line points array, consisting of 40, 100, 300, and 1200, is used to calculate the total score based on the original scores from the Tetris game.', "The useGameStatus.js custom hook requires the 'rows cleared' parameter from the use stage to calculate the score and set the total rows cleared, initialized as zero."]}, {'end': 8922.605, 'start': 8489.282, 'title': 'Tetris score calculation and level increase', 'summary': 'Discusses the creation of a function to calculate the tetris score based on the number of cleared rows and the level, as well as the logic for increasing the level and speed of the game based on the number of cleared rows, with considerations for avoiding infinite loops and hook dependencies.', 'duration': 433.323, 'highlights': ["Creation of function to calculate Tetris score based on cleared rows and level The function 'calc score' is created to calculate the Tetris score based on the number of cleared rows and the level, utilizing a formula found online to determine the score, and updating the score state accordingly.", 'Logic for increasing level and speed of game based on cleared rows The level is increased when the player has cleared 10 rows, with a corresponding increase in speed, and a custom formula is used to adjust the drop time based on the level, while acknowledging the potential for alternative formulas.', "Considerations for avoiding infinite loops and hook dependencies The use of 'useCallback' and specifying dependencies for the 'calc score' function and the use of 'useEffect' to automatically trigger the score calculation based on the 'calc score', 'rows cleared' and 'score', to avoid infinite loops and ensure proper functionality."]}, {'end': 9256.358, 'start': 8922.605, 'title': 'Tetris game with react hooks', 'summary': "Demonstrates the creation of a tetris game using react hooks, optimizing cell renders by implementing react.memo and providing insights into the developer's youtube channel and premium courses.", 'duration': 333.753, 'highlights': ['The chapter demonstrates the creation of a Tetris game using React Hooks. The developer shares the process of creating a Tetris game using React Hooks, providing insights into the game development process.', 'Optimizing cell renders by implementing React.memo. The developer demonstrates the optimization of cell renders by implementing React.memo, reducing the number of re-renders from 240 to only the cells that change with the tetromino.', "Insights into the developer's YouTube channel and premium courses. The developer shares information about their YouTube channel 'WeibenFalk' and their premium courses on Udemy, offering beginner React, Gatsby, and React Redux courses."]}], 'duration': 1299.522, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ZGOaCxX8HIU/pics/ZGOaCxX8HIU7956836.jpg', 'highlights': ['Creation of function to calculate Tetris score based on cleared rows and level', 'Optimizing cell renders by implementing React.memo', "The use interval custom hook is imported from the 'hooks' directory and utilized to enable autonomous movement of the game component", 'The chapter covers the creation of a custom hook useGameStatus.js to display scores, rows, and levels', 'The drop time is set to 1000 when the game starts, allowing the tetromino to move down every one second', 'Logic for increasing level and speed of game based on cleared rows', 'The creation of a new function for key up events ensures that the interval is activated again when the player releases the down key', "Insights into the developer's YouTube channel and premium courses", 'Console logging for interval activity is added to track when the interval is turned off and on', 'The line points array, consisting of 40, 100, 300, and 1200, is used to calculate the total score based on the original scores from the Tetris game']}], 'highlights': ['Creating custom hooks, utilizing state, useEffect, useCallback, and React memo for building a Tetris game with React', 'Setting up a Create React app for bootstrapping projects and avoiding setting up webpack and Babel config from scratch', 'Creating five different components for a Tetris application, including cell.js, display.js, stage.js, startButton.js, and Tetris.js', 'Styling the Tetris game using style components and optimizing CSS for a better look', 'Implementing game loop, collision detection, and creating custom hooks for managing player and stage states', 'Handling collision detection, updating game stage, and creating functions for player movement and key press detection', "Creating a state 'rows cleared' and implementing the 'sweep rows' function to clear full rows based on specific conditions", 'Creating functions to calculate Tetris score, optimizing cell renders, and setting up autonomous movement of the game component', 'Setting drop time, logic for increasing level and speed of game, and handling key up events for game interval activation']}