title
Multiplayer Snake Game | JavaScript & Socket.io

description
In this video we will create a multiplayer snake game using socket.io Hungry Turtle Code YouTube Channel: https://www.youtube.com/channel/UC7Vxnf06GP6w42Lg3TQLXSw Code: https://github.com/HungryTurtleCode/multiplayerSnake Timestamps: 0:07 - Adrian's Intro 1:05 - Setting up HTML 2:25 - Setting up the canvas 7:00 - Painting the snake 12:24 - Setting up the socketio server 14:15 - Connecting to socketio from frontend 18:10 - Moving game state to the server 19:58 - Adding a game loop 32:31 - Debugging game loop issue 33:45 - Controlling the snake 39:05 - WORKING SNAKE GAME!! 40:50 - Home screen for multiplayer game 45:12 - Handling new game on the server 53:30 - Adding ability for second player to join the game 1:01:30 - Handling join game error states 1:03:44 - Modify game mechanics for two players 1:11:48 - Testing the game 1:12:35 - Debugging errors 1:15:15 - Working multiplayer game 1:15:21 - Outro

detail
{'title': 'Multiplayer Snake Game | JavaScript & Socket.io', 'heatmap': [{'end': 940.623, 'start': 749.457, 'weight': 0.761}], 'summary': 'Learn to create a multiplayer snake game with socket.io, covering game setup, canvas and colors initialization, real-time server configuration, game state management, player control, room creation, and multiplayer updates for a fully functional two-player game.', 'chapters': [{'end': 263.15, 'segs': [{'end': 50.571, 'src': 'embed', 'start': 23.799, 'weight': 1, 'content': [{'end': 29.742, 'text': "So before we build anything, I just want to quickly show you what we're going to build so that you know you need to stick around to watch it.", 'start': 23.799, 'duration': 5.943}, {'end': 32.143, 'text': 'So we can see two browsers in front of us.', 'start': 30.162, 'duration': 1.981}, {'end': 35.184, 'text': "And on one of them, I'll click Create New Game.", 'start': 32.683, 'duration': 2.501}, {'end': 37.665, 'text': "and we're shown our game code.", 'start': 36.084, 'duration': 1.581}, {'end': 46.049, 'text': "We can copy that game code into the other browser, click Join Game, and we're immediately playing Snake multiplayer.", 'start': 38.285, 'duration': 7.764}, {'end': 50.571, 'text': "Obviously we lose here because we can't control two browsers at once with one keyboard.", 'start': 46.689, 'duration': 3.882}], 'summary': 'Demonstrating multiplayer snake game with two browsers and game code sharing.', 'duration': 26.772, 'max_score': 23.799, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs23799.jpg'}, {'end': 263.15, 'src': 'embed', 'start': 209.49, 'weight': 0, 'content': [{'end': 213.952, 'text': 'Now to complete the setup, we just want to paint the canvas in the color that we want.', 'start': 209.49, 'duration': 4.462}, {'end': 222.476, 'text': "So to do that, I'll just go up here, and I'll create a BG color constant, and I'll set that equal to the color that we want.", 'start': 214.432, 'duration': 8.044}, {'end': 230.082, 'text': "So in this case, I'm gonna use the color 231F20, which is just a nice off black color.", 'start': 222.777, 'duration': 7.305}, {'end': 235.866, 'text': "And while we're at it with our colors, I'll just create a snake color.", 'start': 231.823, 'duration': 4.043}, {'end': 240.136, 'text': "And I'll set that to see to see to see to.", 'start': 237.435, 'duration': 2.701}, {'end': 248.2, 'text': "And I'll also create a food color, which is going to be six six nine one six.", 'start': 240.957, 'duration': 7.243}, {'end': 258.224, 'text': "So with those out of the way, we'll come back down into our initialization and we'll set the fill style equal to the BG color.", 'start': 249.38, 'duration': 8.844}, {'end': 263.15, 'text': "and then we'll fill rect, which will just create a rectangle.", 'start': 259.668, 'duration': 3.482}], 'summary': 'Set up canvas with background color 231f20, snake color cccccc, and food color 66916.', 'duration': 53.66, 'max_score': 209.49, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs209490.jpg'}], 'start': 7.093, 'title': 'Creating a multiplayer snake game with socket.io', 'summary': 'Demonstrates building a multiplayer snake game using socket.io, allowing players to create and join games using unique game codes. it also covers setting up the game screen using bootstrap classes and initializing canvas and colors in javascript for a snake game.', 'chapters': [{'end': 90.435, 'start': 7.093, 'title': 'Creating multiplayer snake game with socket.io', 'summary': 'Demonstrates building a multiplayer snake game using socket.io, allowing players to create and join games using unique game codes.', 'duration': 83.342, 'highlights': ["We're building a multiplayer Snake game using Socket.io, showcasing how players can create and join games using unique game codes.", 'The game allows players to create a new game, receive a unique game code, and join the game using the code, enabling immediate multiplayer gameplay.', "The tutorial emphasizes focusing on the back end and game mechanics rather than HTML, demonstrating the development of the game's functionality."]}, {'end': 263.15, 'start': 90.915, 'title': 'Setting up game screen with bootstrap and javascript', 'summary': 'Covers setting up the game screen using bootstrap classes, creating canvas elements, importing socket.io, and initializing canvas and colors in javascript for a snake game.', 'duration': 172.235, 'highlights': ['Setting up the game screen using Bootstrap classes and creating canvas elements with specific dimensions and colors.', 'Importing socket.io from a CDN and focusing on initializing canvas and colors in the JavaScript file.', 'Using JavaScript to grab and initialize the gameScreen div and canvas elements, setting canvas dimensions, and defining background, snake, and food colors.']}], 'duration': 256.057, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs7093.jpg', 'highlights': ['The game allows players to create a new game, receive a unique game code, and join the game using the code, enabling immediate multiplayer gameplay.', 'Setting up the game screen using Bootstrap classes and creating canvas elements with specific dimensions and colors.', "We're building a multiplayer Snake game using Socket.io, showcasing how players can create and join games using unique game codes.", 'Importing socket.io from a CDN and focusing on initializing canvas and colors in the JavaScript file.']}, {'end': 685.838, 'segs': [{'end': 361.095, 'src': 'embed', 'start': 330.657, 'weight': 4, 'content': [{'end': 333.96, 'text': "But anyway, so now we've got that, we wanna boot up our browser.", 'start': 330.657, 'duration': 3.303}, {'end': 337.082, 'text': "But to make life easier, I'm gonna use a tool called Live Server.", 'start': 334, 'duration': 3.082}, {'end': 341.746, 'text': "So we'll just open up another terminal, and I'll run mpx live server.", 'start': 337.162, 'duration': 4.584}, {'end': 350.772, 'text': 'And mpx is just a tool that ships with Node that allows us to run libraries from NPM without having to install them directly.', 'start': 342.306, 'duration': 8.466}, {'end': 355.991, 'text': "So we'll boot that up and that should open up our browser as it does here.", 'start': 351.687, 'duration': 4.304}, {'end': 361.095, 'text': 'And we have a nice centered black slightly off black canvas.', 'start': 356.311, 'duration': 4.784}], 'summary': 'Using live server tool to open browser and display canvas.', 'duration': 30.438, 'max_score': 330.657, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs330657.jpg'}, {'end': 437.863, 'src': 'embed', 'start': 394.562, 'weight': 0, 'content': [{'end': 399.466, 'text': 'the server pushes that state into the browser and the browser simply paints it onto the canvas.', 'start': 394.562, 'duration': 4.904}, {'end': 406.272, 'text': "But before we create that server, I'm just going to define a quick game state object in our front,", 'start': 399.966, 'duration': 6.306}, {'end': 409.395, 'text': 'end JavaScript and then create the function that paints that.', 'start': 406.272, 'duration': 3.123}, {'end': 416.001, 'text': "And then, once that's working, we can pull that onto the server, get it working single player with the server,", 'start': 409.655, 'duration': 6.346}, {'end': 419.545, 'text': 'and then we introduce the second player and everything should work.', 'start': 416.001, 'duration': 3.544}, {'end': 423.368, 'text': "So we'll head back into our front end JavaScript.", 'start': 420.125, 'duration': 3.243}, {'end': 428.093, 'text': "And I'm just going to paste in our game state object,", 'start': 424.349, 'duration': 3.744}, {'end': 437.863, 'text': 'and what we have here is a player object that has a position which has an X Y coordinate velocity, that has an X and Y component,', 'start': 428.093, 'duration': 9.77}], 'summary': 'Creating a game state object with player position and velocity, integrating with server for multiplayer functionality.', 'duration': 43.301, 'max_score': 394.562, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs394562.jpg'}, {'end': 507.488, 'src': 'embed', 'start': 479.774, 'weight': 2, 'content': [{'end': 489.1, 'text': "So we come down here to the bottom and we'll create a new function and we'll call it paint game and that paint game will accept our state object.", 'start': 479.774, 'duration': 9.326}, {'end': 492.483, 'text': "Like we did before, we're going to need to fill in the background.", 'start': 489.861, 'duration': 2.622}, {'end': 504.127, 'text': "So we'll say the fill style equals the background color and we'll fill rect fill in our rectangle, just like we did before,", 'start': 493.484, 'duration': 10.643}, {'end': 507.488, 'text': 'at zero zero canvas width and canvas height.', 'start': 504.127, 'duration': 3.361}], 'summary': "Creating a new function 'paint game' to fill the background with the specified color.", 'duration': 27.714, 'max_score': 479.774, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs479774.jpg'}, {'end': 618.87, 'src': 'embed', 'start': 590.171, 'weight': 1, 'content': [{'end': 594.714, 'text': 'And then we want the width and height of the square to just be that size.', 'start': 590.171, 'duration': 4.543}, {'end': 597.976, 'text': "So we'll give the other parameters size and size.", 'start': 595.434, 'duration': 2.542}, {'end': 600.998, 'text': 'So now we have the background drawn in and the food drawn in.', 'start': 598.336, 'duration': 2.662}, {'end': 606.782, 'text': "I'll call another function, which I'll define shortly, called paint player.", 'start': 601.979, 'duration': 4.803}, {'end': 610.905, 'text': "And into paint player, I'll pass in state.player.", 'start': 606.802, 'duration': 4.103}, {'end': 614.907, 'text': 'And that is the object that represents the snake for the current player.', 'start': 611.485, 'duration': 3.422}, {'end': 618.87, 'text': "And I'll also pass in size and snake color.", 'start': 615.207, 'duration': 3.663}], 'summary': 'Drawing a background and food, then painting the snake player.', 'duration': 28.699, 'max_score': 590.171, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs590171.jpg'}], 'start': 263.57, 'title': 'Initializing canvas and creating snake game', 'summary': 'Covers initializing a canvas and adding a key event listener, with details on filling the canvas, adding a key down event listener, and the importance of calling the initialization function. it also discusses setting up the development environment using live server, creating a game state object with player and food details, and defining functions to paint the game state onto the canvas, while addressing the coordination between pixel space and game space.', 'chapters': [{'end': 329.455, 'start': 263.57, 'title': 'Canvas initialization and key event listener', 'summary': 'Covers initializing a canvas and adding a key event listener, with details on filling the canvas, adding a key down event listener, and the importance of calling the initialization function.', 'duration': 65.885, 'highlights': ["The chapter emphasizes the process of initializing a canvas and filling it with a specific color, providing clear instructions on setting the rectangle's dimensions and painting the canvas black.", 'It explains the addition of a key down event listener and the function called key down, highlighting the use of the event key code property to represent the pressed key numerically.', "The importance of calling the initialization function is stressed, with a relatable mention of the common debugging issue where the function is not called and its impact on the program's functionality."]}, {'end': 685.838, 'start': 330.657, 'title': 'Creating single player snake game', 'summary': 'Discusses setting up the development environment using live server, creating a game state object with player and food details, and defining functions to paint the game state onto the canvas, while also addressing the coordination between pixel space and game space.', 'duration': 355.181, 'highlights': ['Setting up the development environment using Live Server for easier browser booting and using mpx tool to run libraries from NPM without direct installation. Using Live Server and mpx tool to streamline browser booting and library execution.', "Defining a game state object in front-end JavaScript with player position, velocity, snake segments, food position, and grid size, which represents the game world's coordinate system with 20 squares. Creating a game state object with player and food details, and specifying the game world's coordinate system.", 'Creating a function to paint the game state onto the canvas, including filling the background, painting the food, and defining the coordination between pixel space and game space. Implementing a function to paint the game state on the canvas, handling background filling, food painting, and coordination between pixel space and game space.']}], 'duration': 422.268, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs263570.jpg', 'highlights': ["The chapter emphasizes initializing a canvas and filling it with a specific color, providing clear instructions on setting the rectangle's dimensions and painting the canvas black.", "Defining a game state object in front-end JavaScript with player position, velocity, snake segments, food position, and grid size, representing the game world's coordinate system with 20 squares.", 'Creating a function to paint the game state onto the canvas, including filling the background, painting the food, and defining the coordination between pixel space and game space.', 'Explaining the addition of a key down event listener and the function called key down, highlighting the use of the event key code property to represent the pressed key numerically.', 'Setting up the development environment using Live Server for easier browser booting and using mpx tool to run libraries from NPM without direct installation.']}, {'end': 1326.972, 'segs': [{'end': 940.623, 'src': 'heatmap', 'start': 749.457, 'weight': 0.761, 'content': [{'end': 751.779, 'text': 'As you can see, we have that server.js file.', 'start': 749.457, 'duration': 2.322}, {'end': 755.922, 'text': "And I'm just going to yarn add socket.io.", 'start': 752.279, 'duration': 3.643}, {'end': 758.404, 'text': "Because we're going to need the socket.io library.", 'start': 755.942, 'duration': 2.462}, {'end': 759.565, 'text': 'We ls there.', 'start': 758.784, 'duration': 0.781}, {'end': 763.688, 'text': 'We have now a package.json, a yarn lock file, and the node modules.', 'start': 759.665, 'duration': 4.023}, {'end': 768.162, 'text': "So we're good to go from there and we can start creating the server.", 'start': 765.06, 'duration': 3.102}, {'end': 771.924, 'text': 'So the first thing I need to do is import socket IO.', 'start': 768.342, 'duration': 3.582}, {'end': 783.25, 'text': "We'll set that equal to a variable called IO and then that imports a function and we just immediately want to call that to get hold of the socket IO object.", 'start': 772.504, 'duration': 10.746}, {'end': 787.592, 'text': 'And then with that we can say IO.on connection.', 'start': 783.63, 'duration': 3.962}, {'end': 793.034, 'text': "And we'll give it a function to call, just give it an inline arrow function.", 'start': 788.473, 'duration': 4.561}, {'end': 795.615, 'text': 'And that gives us a client object.', 'start': 793.494, 'duration': 2.121}, {'end': 800.997, 'text': "And that client object is what's going to allow us to communicate back to the client that's just connected.", 'start': 795.675, 'duration': 5.322}, {'end': 805.659, 'text': "As soon as a client connects, we'll just send them back a message.", 'start': 801.277, 'duration': 4.382}, {'end': 811.481, 'text': "we'll just send back an object with the key of data that has hello world as the value.", 'start': 805.659, 'duration': 5.822}, {'end': 817.214, 'text': 'And then finally we have to listen on port 3000.', 'start': 813.373, 'duration': 3.841}, {'end': 819.914, 'text': 'And with that we have a basic SocketIO server.', 'start': 817.214, 'duration': 2.7}, {'end': 825.495, 'text': "So we'll go back into our third terminal and we'll run npx nodemon,", 'start': 820.374, 'duration': 5.121}, {'end': 830.376, 'text': 'which is going to give us auto-refreshing of our server when we make changes to the server code,', 'start': 825.495, 'duration': 4.881}, {'end': 833.177, 'text': "so we don't have to keep killing the server and restarting it.", 'start': 830.376, 'duration': 2.801}, {'end': 836.437, 'text': "And we'll run the server.js file.", 'start': 833.977, 'duration': 2.46}, {'end': 841.238, 'text': "And we'll just let that boot up and we're off to the races.", 'start': 837.677, 'duration': 3.561}, {'end': 844.064, 'text': 'Now back into our code.', 'start': 842.403, 'duration': 1.661}, {'end': 852.352, 'text': "we can now configure the front end to connect to the back end and hopefully as soon as we connect we'll get an init message with the data hello world.", 'start': 844.064, 'duration': 8.288}, {'end': 859.118, 'text': "We'll go back into our front end and, if you remember, back to our HTML.", 'start': 854.994, 'duration': 4.124}, {'end': 867.305, 'text': 'we already have the socket IO library in our HTML, so we can just use it immediately using the global IO object.', 'start': 859.118, 'duration': 8.187}, {'end': 870.198, 'text': "we'll say const.", 'start': 868.917, 'duration': 1.281}, {'end': 876.081, 'text': 'socket equals io and what this takes is the url to connect to.', 'start': 870.198, 'duration': 5.883}, {'end': 887.787, 'text': "so we want to connect to http localhost port 3000 and then from here we'll say socket.on and we want to listen to the init events,", 'start': 876.081, 'duration': 11.706}, {'end': 893.69, 'text': "because that's what we defined in our server, and we'll call a function called handle init.", 'start': 887.787, 'duration': 5.903}, {'end': 911.776, 'text': "then we'll come down to the bottom and we'll create that function called handle init and that's going to accept a message and we're just going to console log out that message for now.", 'start': 895.103, 'duration': 16.673}, {'end': 919.492, 'text': 'So if we go back to the browser and open up the Chrome DevTools, we just quickly refresh.', 'start': 912.95, 'duration': 6.542}, {'end': 925.494, 'text': 'We can see data hello world logged out from index line 82.', 'start': 919.972, 'duration': 5.522}, {'end': 928.775, 'text': 'And that is, of course, coming from here, line 82.', 'start': 925.494, 'duration': 3.281}, {'end': 934.599, 'text': 'So we have communication with our server and that gives us the baseline to start building out the game.', 'start': 928.775, 'duration': 5.824}, {'end': 940.623, 'text': "So right now we're manually calling our paint game function inside our front end JavaScript.", 'start': 934.899, 'duration': 5.724}], 'summary': "Setting up a socketio server to communicate with the client and initializing the connection to receive 'hello world' data.", 'duration': 191.166, 'max_score': 749.457, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs749457.jpg'}, {'end': 793.034, 'src': 'embed', 'start': 765.06, 'weight': 2, 'content': [{'end': 768.162, 'text': "So we're good to go from there and we can start creating the server.", 'start': 765.06, 'duration': 3.102}, {'end': 771.924, 'text': 'So the first thing I need to do is import socket IO.', 'start': 768.342, 'duration': 3.582}, {'end': 783.25, 'text': "We'll set that equal to a variable called IO and then that imports a function and we just immediately want to call that to get hold of the socket IO object.", 'start': 772.504, 'duration': 10.746}, {'end': 787.592, 'text': 'And then with that we can say IO.on connection.', 'start': 783.63, 'duration': 3.962}, {'end': 793.034, 'text': "And we'll give it a function to call, just give it an inline arrow function.", 'start': 788.473, 'duration': 4.561}], 'summary': 'Preparing to create the server with socket io for handling connections.', 'duration': 27.974, 'max_score': 765.06, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs765060.jpg'}, {'end': 887.787, 'src': 'embed', 'start': 859.118, 'weight': 0, 'content': [{'end': 867.305, 'text': 'we already have the socket IO library in our HTML, so we can just use it immediately using the global IO object.', 'start': 859.118, 'duration': 8.187}, {'end': 870.198, 'text': "we'll say const.", 'start': 868.917, 'duration': 1.281}, {'end': 876.081, 'text': 'socket equals io and what this takes is the url to connect to.', 'start': 870.198, 'duration': 5.883}, {'end': 887.787, 'text': "so we want to connect to http localhost port 3000 and then from here we'll say socket.on and we want to listen to the init events,", 'start': 876.081, 'duration': 11.706}], 'summary': 'Using socket io library to connect to http localhost port 3000 and listen to init events.', 'duration': 28.669, 'max_score': 859.118, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs859118.jpg'}], 'start': 686.779, 'title': 'Setting up real-time game server', 'summary': 'Explains setting up a socketio server for a snake game, including front-end and server folder creation, socket.io library installation, and real-time communication between server and browser to handle game state updates and define game mechanics with a focus on server logic and game mechanics.', 'chapters': [{'end': 887.787, 'start': 686.779, 'title': 'Setting up socketio server for snake game', 'summary': 'Discusses setting up a socketio server for a snake game, including creating front-end and server folders, installing the socket.io library, and establishing communication between front-end and back-end, with a focus on initiating a basic socketio server on port 3000 and configuring the front end to connect to the back end.', 'duration': 201.008, 'highlights': ['The chapter discusses setting up a SocketIO server for a Snake game, including creating front-end and server folders, installing the socket.io library, and establishing communication between front-end and back-end, with a focus on initiating a basic SocketIO server on port 3000 and configuring the front end to connect to the back end.', 'The next step is to pull the state out of the front end, put it onto the back end, and then update the state for every frame of the game.', 'Creating a new front end folder and moving existing files into that folder, as well as creating a server folder for server code organization.', 'Importing the socket IO library, setting up the SocketIO server, and establishing communication between the front end and back end.', 'Running npx nodemon for auto-refreshing the server when making changes to the server code, and running the server.js file to initiate the server.']}, {'end': 1326.972, 'start': 887.787, 'title': 'Real-time game server setup', 'summary': 'Explains setting up real-time communication between the server and browser, handling game state updates, and defining game mechanics with frame rate and grid size constants, aiming to achieve a baseline for building a game, with a focus on server logic and game mechanics.', 'duration': 439.185, 'highlights': ['Setting up real-time communication between server and browser Explaining the process of establishing real-time communication for server and browser, enabling prompt updates and interactions.', "Defining game mechanics with frame rate and grid size constants Describing the establishment of game mechanics by defining constants for frame rate and grid size, crucial for the game's functioning and interaction.", 'Creating game state and initiating game loop function for frame updates Detailing the creation of game state and implementation of a game loop function to update the game frame by frame, ensuring a dynamic game experience.']}], 'duration': 640.193, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs686779.jpg', 'highlights': ['Setting up a SocketIO server for a Snake game, including creating front-end and server folders, installing the socket.io library, and establishing communication between front-end and back-end.', 'Establishing real-time communication for server and browser, enabling prompt updates and interactions.', 'Creating game state and initiating game loop function for frame updates.', 'Initiating a basic SocketIO server on port 3000 and configuring the front end to connect to the back end.', 'Defining game mechanics by setting constants for frame rate and grid size.']}, {'end': 2146.277, 'segs': [{'end': 1417.606, 'src': 'embed', 'start': 1363.942, 'weight': 1, 'content': [{'end': 1366.903, 'text': "So we'll do that inside our game.js file.", 'start': 1363.942, 'duration': 2.961}, {'end': 1369.924, 'text': "We'll create a new function.", 'start': 1368.444, 'duration': 1.48}, {'end': 1376.606, 'text': "We'll call it game loop and we accept the state of the world in there.", 'start': 1370.124, 'duration': 6.482}, {'end': 1380.588, 'text': "Before we forget I'll export that out.", 'start': 1377.147, 'duration': 3.441}, {'end': 1392.105, 'text': "and I'll also hop into here in our server and I also want to import that because I know I will forget to do that if I don't do it immediately.", 'start': 1381.84, 'duration': 10.265}, {'end': 1394.266, 'text': "So we've got that game loop.", 'start': 1393.186, 'duration': 1.08}, {'end': 1398.532, 'text': 'so now we need give ourselves some space.', 'start': 1394.266, 'duration': 4.266}, {'end': 1401.354, 'text': 'we need our functionality for the game loop.', 'start': 1398.532, 'duration': 2.822}, {'end': 1409.16, 'text': "and if you've seen the video on my hunger turtle code channel where i speed coded snake, some of this code might look familiar, but if not,", 'start': 1401.354, 'duration': 7.806}, {'end': 1411.281, 'text': "i'm just going to explain through it anyway.", 'start': 1409.16, 'duration': 2.121}, {'end': 1415.244, 'text': "so just to be defensive, i'm just going to check if not state.", 'start': 1411.281, 'duration': 3.963}, {'end': 1417.606, 'text': "so if we're not given a state, we don't want to do anything.", 'start': 1415.244, 'duration': 2.362}], 'summary': 'Creating a game loop function in game.js and importing it into the server.', 'duration': 53.664, 'max_score': 1363.942, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs1363942.jpg'}, {'end': 1553.813, 'src': 'embed', 'start': 1524.4, 'weight': 4, 'content': [{'end': 1531.608, 'text': "So right now we're only making the single player version, but to look ahead to when we have two players.", 'start': 1524.4, 'duration': 7.208}, {'end': 1537.695, 'text': 'I said earlier that we want this game loop function to return an integer that represents the player that won.', 'start': 1531.608, 'duration': 6.087}, {'end': 1545.409, 'text': "So we'll return 2 from here, because if player 1 has gone off the edge of the canvas, then player 2 wins the game.", 'start': 1538.746, 'duration': 6.663}, {'end': 1553.813, 'text': "And now, if we've made it past this conditional, it means we're still within the confines of the canvas and we want to make sure.", 'start': 1545.849, 'duration': 7.964}], 'summary': 'Developing a single-player game loop returning 2 if player 1 goes off canvas.', 'duration': 29.413, 'max_score': 1524.4, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs1524400.jpg'}, {'end': 1727.871, 'src': 'embed', 'start': 1695.274, 'weight': 5, 'content': [{'end': 1700.097, 'text': "We'll do that by looping through each cell of player1.snake.", 'start': 1695.274, 'duration': 4.823}, {'end': 1710.765, 'text': "And we'll have a very similar conditional to what we had before, where we'll say if cell dot x equals player one,", 'start': 1702.159, 'duration': 8.606}, {'end': 1716.689, 'text': 'dot position dot x and cell dot y equals player one.', 'start': 1710.765, 'duration': 5.924}, {'end': 1727.871, 'text': "position.y. that means one of the cells in the body of the snake is overlapping with the head of the snake, which means it's bumped into itself,", 'start': 1717.942, 'duration': 9.929}], 'summary': 'Using conditional statements to detect snake self-collision in game programming.', 'duration': 32.597, 'max_score': 1695.274, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs1695274.jpg'}, {'end': 1884.487, 'src': 'embed', 'start': 1853.43, 'weight': 0, 'content': [{'end': 1855.453, 'text': "We'll remove that semicolon that we don't need.", 'start': 1853.43, 'duration': 2.023}, {'end': 1857.317, 'text': "We'll duplicate that for y.", 'start': 1855.854, 'duration': 1.463}, {'end': 1861.764, 'text': 'So now we have a food object with an x and y coordinate randomly on our grid.', 'start': 1857.317, 'duration': 4.447}, {'end': 1866.472, 'text': "And then we'll say state.food equals that new food object.", 'start': 1862.706, 'duration': 3.766}, {'end': 1876.665, 'text': "And we would think we're done, but there's actually one small thing we need to think about, which is we never want to place a food on top of a snake.", 'start': 1867.523, 'duration': 9.142}, {'end': 1884.487, 'text': "So to make sure that we don't do that, we need to verify that the random food we've just created isn't actually part of any snake.", 'start': 1877.005, 'duration': 7.482}], 'summary': 'Programming logic for placing food objects on grid without overlapping snakes.', 'duration': 31.057, 'max_score': 1853.43, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs1853430.jpg'}], 'start': 1327.692, 'title': 'Game state and loop function', 'summary': "Covers emitting game state, creating game loop function, updating player positions, checking for winning conditions, handling movements, collisions, placing food on grid, and controlling snake's direction.", 'chapters': [{'end': 1545.409, 'start': 1327.692, 'title': 'Emitting game state and creating game loop function', 'summary': "Outlines the process of emitting a game state, including json stringification, emitting 'game over' when there's a winner, and clearing the game loop interval. additionally, it covers the creation of a game loop function that updates player positions based on velocity and checks for winning conditions, aiming to return an integer representing the winning player.", 'duration': 217.717, 'highlights': ["The chapter outlines the process of emitting a game state, including JSON stringification, emitting 'game over' when there's a winner, and clearing the game loop interval.", 'It covers the creation of a game loop function that updates player positions based on velocity and checks for winning conditions, aiming to return an integer representing the winning player.']}, {'end': 2146.277, 'start': 1545.849, 'title': 'Game loop and snake movement', 'summary': "Details the game loop function, which handles movements, checking for collisions, and placing food on the grid, as well as the key down event listener for controlling the snake's direction.", 'duration': 600.428, 'highlights': ["The game loop function determines if the snake has eaten the food, increases the snake's size, updates its position, and places new food on the grid. The game loop function checks if the snake has eaten the food by comparing the coordinates of the snake's head with the food's coordinates. If true, it increases the snake's size and updates its position. It then places new food on the grid.", "The process of moving the snake involves pushing the new position onto the array and removing the last item to keep the snake the same length while moving it forward. To move the snake, the new position is pushed onto the array and the last item is removed to maintain the snake's length while moving it forward.", "The random food function is defined to generate a new food object with random x and y coordinates on the grid, ensuring it's not placed on top of the snake. The random food function generates a new food object with random x and y coordinates on the grid, ensuring it's not placed on top of the snake by recursively calling itself until a valid position is found.", "The key down event listener sends the key code back to the server to update the snake's velocity and direction. The key down event listener sends the key code back to the server to update the snake's velocity and direction, allowing control over the snake's movement."]}], 'duration': 818.585, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs1327692.jpg', 'highlights': ["The chapter outlines the process of emitting a game state, including JSON stringification, emitting 'game over' when there's a winner, and clearing the game loop interval.", "The game loop function determines if the snake has eaten the food, increases the snake's size, updates its position, and places new food on the grid.", 'The process of moving the snake involves pushing the new position onto the array and removing the last item to keep the snake the same length while moving it forward.', "The random food function is defined to generate a new food object with random x and y coordinates on the grid, ensuring it's not placed on top of the snake.", "The key down event listener sends the key code back to the server to update the snake's velocity and direction, allowing control over the snake's movement.", 'It covers the creation of a game loop function that updates player positions based on velocity and checks for winning conditions, aiming to return an integer representing the winning player.']}, {'end': 3071.703, 'segs': [{'end': 2351.22, 'src': 'embed', 'start': 2317.231, 'weight': 2, 'content': [{'end': 2325.698, 'text': 'So state is undefined inside game JS line 77.', 'start': 2317.231, 'duration': 8.467}, {'end': 2327.479, 'text': 'So state is undefined here.', 'start': 2325.698, 'duration': 1.781}, {'end': 2331.482, 'text': 'So where we call random food, there we go.', 'start': 2328.38, 'duration': 3.102}, {'end': 2332.663, 'text': "There's our issue.", 'start': 2331.502, 'duration': 1.161}, {'end': 2337.226, 'text': "We called random food, but we didn't pass it in the state that we needed.", 'start': 2333.824, 'duration': 3.402}, {'end': 2342.03, 'text': "So we'll just give it there and we'll just check it once again.", 'start': 2337.246, 'duration': 4.784}, {'end': 2351.22, 'text': 'make sure that we can in fact eat the food and we can, and we get one bigger and everything is all good.', 'start': 2344.116, 'duration': 7.104}], 'summary': 'Issue with undefined state in game js line 77 resolved by passing in required state for random food. food can now be eaten and player size increases by one.', 'duration': 33.989, 'max_score': 2317.231, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs2317231.jpg'}, {'end': 2744.221, 'src': 'embed', 'start': 2712.177, 'weight': 0, 'content': [{'end': 2713.578, 'text': "So we'll jump into our server.", 'start': 2712.177, 'duration': 1.401}, {'end': 2716.481, 'text': "So here we're listening for the key down event.", 'start': 2714.52, 'duration': 1.961}, {'end': 2729.228, 'text': "So we'll copy that and we'll specify the new game events and we'll call a new function called handle new game and we'll define that here handle new game.", 'start': 2716.861, 'duration': 12.367}, {'end': 2737.034, 'text': 'So when you create a new game, what we actually want to do on the server is create a new socket IO room.', 'start': 2731.069, 'duration': 5.965}, {'end': 2744.221, 'text': "And then when another player enters the game by clicking join game in the UI, they're entering the game code.", 'start': 2737.295, 'duration': 6.926}], 'summary': 'Creating new game events and socket io room for player interaction.', 'duration': 32.044, 'max_score': 2712.177, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs2712177.jpg'}, {'end': 2798.902, 'src': 'embed', 'start': 2774.488, 'weight': 1, 'content': [{'end': 2780.75, 'text': 'And as an argument to make ID, we want to pass in the length of the ID that we want to generate.', 'start': 2774.488, 'duration': 6.262}, {'end': 2783.612, 'text': 'So in this case, we want to generate a five character ID.', 'start': 2781.051, 'duration': 2.561}, {'end': 2785.152, 'text': "So we'll pass in the number five.", 'start': 2783.732, 'duration': 1.42}, {'end': 2787.213, 'text': 'And now we also need to think about state.', 'start': 2785.372, 'duration': 1.841}, {'end': 2790.794, 'text': 'So we have this state equals create game state above.', 'start': 2787.633, 'duration': 3.161}, {'end': 2794.696, 'text': "And what that's doing is creating a state as soon as the player connects.", 'start': 2791.074, 'duration': 3.622}, {'end': 2798.902, 'text': 'But we want multiple rooms where many people can play on the server.', 'start': 2795.416, 'duration': 3.486}], 'summary': 'Generating a 5-character id and creating multiple game rooms for player connections.', 'duration': 24.414, 'max_score': 2774.488, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs2774488.jpg'}], 'start': 2146.997, 'title': 'Snake game development', 'summary': 'Covers converting key code to velocity, enabling successful snake control, developing a single-player game with server control, and implementing multiplayer features including room creation and global state management.', 'chapters': [{'end': 2351.22, 'start': 2146.997, 'title': 'Converting key code to velocity', 'summary': 'Discusses converting key code presses into velocity using a defined function getupdatedvelocity, including the use of switch statements to handle different key codes, resulting in the successful control of the snake in the browser.', 'duration': 204.223, 'highlights': ['The function getUpdatedVelocity is defined to convert key code presses into velocity, allowing control of the snake. The getUpdatedVelocity function is defined to convert key code presses into velocity, enabling control of the snake in the browser.', 'The switch statement is used to handle different key codes, such as 37, 38, 39, and 40, representing the arrow keys on the keyboard. A switch statement is used to handle different key codes, including 37, 38, 39, and 40, which represent the arrow keys on the keyboard.', 'Issues with undefined state and function not being imported are resolved, resulting in successful control of the snake in the browser. The issues with undefined state and function not being imported are resolved, leading to the successful control of the snake in the browser.']}, {'end': 2794.696, 'start': 2351.22, 'title': 'Multiplayer snake game development', 'summary': 'Covers the development of a single-player snake game where the server controls the state and sends it to the front end, and the front end repaints on every frame. it also discusses the implementation of a multiplayer version with a home screen for creating or joining games.', 'duration': 443.476, 'highlights': ['The chapter covers the development of a single-player snake game where the server controls the state and sends it to the front end, and the front end repaints on every frame. The server controls the state and sends it to the front end, and the front end repaints on every frame.', 'The implementation of a multiplayer version with a home screen for creating or joining games is discussed. Discusses the implementation of a multiplayer version with a home screen for creating or joining games.']}, {'end': 3071.703, 'start': 2795.416, 'title': 'Managing global state and room creation', 'summary': 'Discusses creating a global state object to hold the state of all possible rooms, implementing a client rooms lookup table for user ids, and defining functions for creating game states and generating random food.', 'duration': 276.287, 'highlights': ['The chapter discusses creating a global state object to hold the state of all possible rooms, which allows multiple users to play on the server (e.g., state equals an empty object).', 'It explains the implementation of a client rooms lookup table that maps user IDs to room names for convenient lookups (e.g., client rooms object mapping client ID to a room name).', 'The transcript details the modification of the create game state function to add the state object as a child of the room name in the global state object and the implementation of a function for generating random food for new game states.', 'It demonstrates the definition of a new init game function in the game.js file for creating game states and generating random food, and the use of socket IO to connect clients to specific rooms and assign player numbers.', 'It also covers the purpose of the init event in sending the player number back to the client for tracking the current player in the game and the definition of the make ID function for generating random IDs.']}], 'duration': 924.706, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs2146997.jpg', 'highlights': ['The chapter covers the development of a single-player snake game where the server controls the state and sends it to the front end, and the front end repaints on every frame.', 'The implementation of a multiplayer version with a home screen for creating or joining games is discussed.', 'The chapter discusses creating a global state object to hold the state of all possible rooms, which allows multiple users to play on the server (e.g., state equals an empty object).']}, {'end': 3351.494, 'segs': [{'end': 3127.426, 'src': 'embed', 'start': 3097.133, 'weight': 2, 'content': [{'end': 3106.077, 'text': "We want this player number to be global, so I'm just going to initialize it up at the top here where we have our canvas and context initialization.", 'start': 3097.133, 'duration': 8.944}, {'end': 3110.198, 'text': "I'll just initialize player number and I won't set it to anything,", 'start': 3106.197, 'duration': 4.001}, {'end': 3114.5, 'text': "because we're going to set it when that init event comes back with the correct player number.", 'start': 3110.198, 'duration': 4.302}, {'end': 3127.426, 'text': "So we've also just sent back the game code event from the server and what we want to do with that on the front end is take that game code and display it to the user so they know what to send to their friend when they want to play snake against them.", 'start': 3114.98, 'duration': 12.446}], 'summary': 'Initializing global player number and displaying game code to user.', 'duration': 30.293, 'max_score': 3097.133, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3097133.jpg'}, {'end': 3188.696, 'src': 'embed', 'start': 3127.666, 'weight': 0, 'content': [{'end': 3137.691, 'text': "So we'll hop into our HTML and we'll come down to our canvas area and just above our canvas we'll paste in another piece of HTML and just give us a bit of space there.", 'start': 3127.666, 'duration': 10.025}, {'end': 3145.658, 'text': "But this is just a simple heading that has a span with the ID of game code display that currently doesn't have anything in it.", 'start': 3138.012, 'duration': 7.646}, {'end': 3150.863, 'text': "But we're going to hook into that from our JavaScript and insert the correct game code into that span.", 'start': 3145.939, 'duration': 4.924}, {'end': 3168.708, 'text': 'So back into our JavaScript const game code display equals document dot get elements by ID game code display and then up to our socket events.', 'start': 3151.884, 'duration': 16.824}, {'end': 3175.992, 'text': 'And instead of game over, we want to listen on the game code and handle game code function.', 'start': 3169.588, 'duration': 6.404}, {'end': 3181.276, 'text': "We'll come right down to the bottom and we'll define the handle game code.", 'start': 3176.432, 'duration': 4.844}, {'end': 3185.633, 'text': 'function here.', 'start': 3184.912, 'duration': 0.721}, {'end': 3188.696, 'text': "And that's going to accept a game code.", 'start': 3186.313, 'duration': 2.383}], 'summary': 'Adding html and javascript to display and handle game code in canvas area.', 'duration': 61.03, 'max_score': 3127.666, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3127666.jpg'}, {'end': 3268.656, 'src': 'embed', 'start': 3214.329, 'weight': 1, 'content': [{'end': 3218.993, 'text': "where we're grabbing the value of the input and sending the join game event back to the server.", 'start': 3214.329, 'duration': 4.664}, {'end': 3232.335, 'text': "So let's jump into the server and we'll create a new event and that will be join game and we'll call a function called handle join game.", 'start': 3219.854, 'duration': 12.481}, {'end': 3236.002, 'text': "We'll create that here.", 'start': 3232.355, 'duration': 3.647}, {'end': 3242.616, 'text': 'And this takes a game code for the game that you want to join.', 'start': 3239.534, 'duration': 3.082}, {'end': 3246.059, 'text': 'So now a few things need to happen for you to join a game.', 'start': 3242.997, 'duration': 3.062}, {'end': 3251.303, 'text': 'The game needs to exist in the first place and there has to be another player waiting to play you.', 'start': 3246.299, 'duration': 5.004}, {'end': 3261.471, 'text': "So we're going to leverage the power of socket IO rooms and we're going to grab hold of the room and we'll do that by saying IO dot sockets,", 'start': 3251.984, 'duration': 9.487}, {'end': 3263.973, 'text': 'dot adapter dot rooms.', 'start': 3261.471, 'duration': 2.502}, {'end': 3266.515, 'text': "And then that's an object.", 'start': 3265.034, 'duration': 1.481}, {'end': 3268.656, 'text': 'And then we can look into the object.', 'start': 3266.815, 'duration': 1.841}], 'summary': "Creating a new event 'join game' and handling game code to join a game leveraging socket io rooms.", 'duration': 54.327, 'max_score': 3214.329, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3214329.jpg'}], 'start': 3071.963, 'title': 'Front end event handling', 'summary': 'Focuses on handling the init event, initializing a global player number variable, and displaying the game code for player two to join using javascript and socket.io rooms.', 'chapters': [{'end': 3114.5, 'start': 3071.963, 'title': 'Handling init event in front end', 'summary': 'Focuses on handling the init event in the front end, initializing a global player number variable, and correctly assigning the player number received from the init event.', 'duration': 42.537, 'highlights': ['Initializing a global player number variable at the top of the front end code for later assignment. (Player number initialization at the top)', 'Handling the init event to correctly assign the player number received, which is essential for game functionality. (Handling the init event)']}, {'end': 3351.494, 'start': 3114.98, 'title': 'Displaying game code and joining the game', 'summary': 'Explains how to display the game code to the user and enable player number two to join the game, utilizing javascript and socket.io rooms to manage the process.', 'duration': 236.514, 'highlights': ['Creating a function to handle game code and displaying it to the user A function is created to handle the game code and display it to the user, ensuring the correct game code is inserted into the designated span.', 'Enabling player number two to join the game through server-side and front-end handling The server and front-end are set up to allow player number two to join the game, involving the creation of a new event and the implementation of a join game function.', 'Utilizing Socket.IO rooms to manage the game joining process The power of Socket.IO rooms is leveraged to manage the game joining process, including checking for the existence of the game and the presence of another player to join.']}], 'duration': 279.531, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3071963.jpg', 'highlights': ['Handling the init event', 'Initializing a global player number variable at the top', 'Utilizing Socket.IO rooms to manage the game joining process', 'Enabling player number two to join the game through server-side and front-end handling', 'Creating a function to handle game code and displaying it to the user']}, {'end': 3727.355, 'segs': [{'end': 3529.802, 'src': 'embed', 'start': 3480.291, 'weight': 0, 'content': [{'end': 3486.201, 'text': 'because we can get hold of the socket IO global rooms objects and emit to all players in that room.', 'start': 3480.291, 'duration': 5.91}, {'end': 3493.693, 'text': "And now that we've changed the call signature of this start game interval, we need to go down and find that function down here.", 'start': 3486.321, 'duration': 7.372}, {'end': 3497.746, 'text': "and it's just going to accept a room name.", 'start': 3495.325, 'duration': 2.421}, {'end': 3502.088, 'text': 'And then the state here, instead of being the state passed in.', 'start': 3498.406, 'duration': 3.682}, {'end': 3509.431, 'text': 'we can grab the global state and then just access the room name, which gives us the state of that current room.', 'start': 3502.088, 'duration': 7.343}, {'end': 3515.453, 'text': 'And then down here in the conditionals, we were emitting to just the client that we were passing in.', 'start': 3509.611, 'duration': 5.842}, {'end': 3517.754, 'text': 'But now we want to emit to the whole room.', 'start': 3515.954, 'duration': 1.8}, {'end': 3529.802, 'text': "So let's create new functions where we emit game state and we specify the room name we're emitting to, and we give it the state to emit,", 'start': 3519.175, 'duration': 10.627}], 'summary': 'Modifying game interval to emit to all players in the room.', 'duration': 49.511, 'max_score': 3480.291, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3480291.jpg'}, {'end': 3594.944, 'src': 'embed', 'start': 3558.737, 'weight': 1, 'content': [{'end': 3560.198, 'text': "And now we'll come further down.", 'start': 3558.737, 'duration': 1.461}, {'end': 3565.223, 'text': "And we'll create emit game state.", 'start': 3560.218, 'duration': 5.005}, {'end': 3572.629, 'text': 'And that takes the room name and state.', 'start': 3567.465, 'duration': 5.164}, {'end': 3576.112, 'text': "And here's where we use the socket IO room magic.", 'start': 3573.33, 'duration': 2.782}, {'end': 3581.217, 'text': 'So we do io dot socket dot in room name.', 'start': 3576.533, 'duration': 4.684}, {'end': 3586.115, 'text': "dot emit and then it's just a regular emit.", 'start': 3582.591, 'duration': 3.524}, {'end': 3594.944, 'text': 'So we want to emit game state and we will json dot stringify the state.', 'start': 3586.575, 'duration': 8.369}], 'summary': 'The emit game state function sends room name and state using socket io, and then stringifies the state.', 'duration': 36.207, 'max_score': 3558.737, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3558737.jpg'}], 'start': 3352.834, 'title': 'Game room logic and multiplayer updates', 'summary': 'Covers the logic for joining a game room based on client count and updates made to the game logic to support multiple players, including changes in game interval, emitting game state and game over to all clients, and handling new events on the front end.', 'chapters': [{'end': 3405.526, 'start': 3352.834, 'title': 'Game room joining logic', 'summary': 'Discusses the logic for joining a game room based on the number of clients, emitting different messages based on the conditions of zero, one, or more than one player.', 'duration': 52.692, 'highlights': ['The logic explains the different scenarios for joining a game room based on the number of clients, with specific actions and messages emitted for each condition.', "The code specifies that if there are zero clients, an 'unknown game' message is emitted, and if there are more than one client, a 'too many players' message is emitted.", 'If there is exactly one player waiting, the logic allows for joining the game.']}, {'end': 3727.355, 'start': 3405.766, 'title': 'Updating game logic for multiple players', 'summary': 'Explains the updates made to the game logic to accommodate multiple players, including changes in the start game interval, emitting game state and game over to all clients in the room, and handling new events on the front end.', 'duration': 321.589, 'highlights': ['The start game interval is modified to start only when a second player has joined the game, as opposed to starting immediately upon any player connecting to the server.', 'The function to emit game state now uses the socket IO room magic to emit to all clients in the specified room, allowing for scalability to accommodate an arbitrary number of clients.', "New events 'unknown game' and 'too many players' are handled on the front end, ensuring proper handling of these scenarios during gameplay.", 'The chapter also discusses the need to update the game loop to handle two players, indicating the ongoing development and refinement of the game logic.']}], 'duration': 374.521, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3352834.jpg', 'highlights': ['The logic explains the different scenarios for joining a game room based on the number of clients, with specific actions and messages emitted for each condition.', 'The start game interval is modified to start only when a second player has joined the game, as opposed to starting immediately upon any player connecting to the server.', 'The function to emit game state now uses the socket IO room magic to emit to all clients in the specified room, allowing for scalability to accommodate an arbitrary number of clients.']}, {'end': 4683.472, 'segs': [{'end': 3754.684, 'src': 'embed', 'start': 3727.355, 'weight': 2, 'content': [{'end': 3732.177, 'text': 'we just want to reset the UI back to what it would look like when you first refresh the page.', 'start': 3727.355, 'duration': 4.822}, {'end': 3736.259, 'text': "So we'll create a function called reset that does exactly that.", 'start': 3732.757, 'duration': 3.502}, {'end': 3742.502, 'text': "And then just for ease right now, we'll just alert out unknown game code.", 'start': 3737.019, 'duration': 5.483}, {'end': 3749.423, 'text': "Of course, when we're flashing this out as a proper game that you're going to deploy and people are going to use,", 'start': 3744.082, 'duration': 5.341}, {'end': 3751.323, 'text': 'you want to handle this a bit more gracefully.', 'start': 3749.423, 'duration': 1.9}, {'end': 3754.684, 'text': "But for the sake of this tutorial, we'll just use the alert.", 'start': 3751.983, 'duration': 2.701}], 'summary': 'Create a reset function to restore ui to default state, and temporarily alert unknown game code.', 'duration': 27.329, 'max_score': 3727.355, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3727355.jpg'}, {'end': 3923.712, 'src': 'embed', 'start': 3848.355, 'weight': 0, 'content': [{'end': 3855.898, 'text': "So now we have a second player and I'll just change the properties of each of these players so that they start off at different positions on the canvas.", 'start': 3848.355, 'duration': 7.543}, {'end': 3866.664, 'text': "And because in our initGame function we're always assigning a random food to the game state,", 'start': 3860.017, 'duration': 6.647}, {'end': 3869.788, 'text': 'we can set the food object to just an empty object to start.', 'start': 3866.664, 'duration': 3.124}, {'end': 3876.235, 'text': 'So now coming down into our game loop, we can define the game loop code for multiple players.', 'start': 3870.148, 'duration': 6.087}, {'end': 3889.024, 'text': "So we have Player1 is State.Player but now it's going to be State.Player's index 0 and Player2 is going to be State.Player's index 1.", 'start': 3877.156, 'duration': 11.868}, {'end': 3895.688, 'text': "And now we want to copy all of this code that's handling Player1 and handle the same stuff for Player2.", 'start': 3889.024, 'duration': 6.664}, {'end': 3903.213, 'text': "So we'll copy this conditional and we'll change Player1 to Player2 in all of these cases.", 'start': 3895.728, 'duration': 7.485}, {'end': 3915.826, 'text': 'And then instead of returning two, we return one because remember this game loop function returns the number of the player that won the game.', 'start': 3906.078, 'duration': 9.748}, {'end': 3920.289, 'text': 'So in this case, player two has went off the edge of the canvas.', 'start': 3916.586, 'duration': 3.703}, {'end': 3921.95, 'text': 'So player one wins.', 'start': 3920.81, 'duration': 1.14}, {'end': 3923.712, 'text': 'So we return the number one.', 'start': 3922.471, 'duration': 1.241}], 'summary': 'Updating game code to handle two players, assigning different starting positions, and determining the winner based on canvas boundaries.', 'duration': 75.357, 'max_score': 3848.355, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3848355.jpg'}, {'end': 4023.374, 'src': 'embed', 'start': 3973.356, 'weight': 8, 'content': [{'end': 3978.822, 'text': "And again, we need to change this two to a one because we're returning the winning player number.", 'start': 3973.356, 'duration': 5.466}, {'end': 3983.495, 'text': 'And with that, we have the game loop handling two players.', 'start': 3979.892, 'duration': 3.603}, {'end': 3986.698, 'text': 'And our random food function also needs to change now.', 'start': 3983.815, 'duration': 2.883}, {'end': 3991.722, 'text': "We were just checking if the food landed on one snake, but now there's two snakes in the game.", 'start': 3987.178, 'duration': 4.544}, {'end': 3998.427, 'text': 'So we need to check if cell is on player state.players zero,', 'start': 3992.322, 'duration': 6.105}, {'end': 4006.654, 'text': "and then we'll copy all of that and loop through all of the cells in snake for player index one.", 'start': 3998.427, 'duration': 8.227}, {'end': 4010.859, 'text': 'Other than that the logic is exactly the same.', 'start': 4008.737, 'duration': 2.122}, {'end': 4016.506, 'text': "And now there's one more place on the server where we're going to need to handle the fact that there's two players,", 'start': 4011.6, 'duration': 4.906}, {'end': 4019.549, 'text': "and that's in our key down function in our server file.", 'start': 4016.506, 'duration': 3.043}, {'end': 4023.374, 'text': 'So if we scroll down we can find that key down.', 'start': 4020.711, 'duration': 2.663}], 'summary': 'The game now handles two players, requiring changes in various functions and server file.', 'duration': 50.018, 'max_score': 3973.356, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3973356.jpg'}, {'end': 4143.073, 'src': 'embed', 'start': 4114.698, 'weight': 10, 'content': [{'end': 4120.399, 'text': 'So we need to take one away to get us into index zero so that we can correctly index that array.', 'start': 4114.698, 'duration': 5.701}, {'end': 4128.267, 'text': 'And now we have the player that we need to update.velocity equals velocity and remove this old call.', 'start': 4121.724, 'duration': 6.543}, {'end': 4133.649, 'text': 'And with that our server fully handles the two player game.', 'start': 4128.867, 'duration': 4.782}, {'end': 4136.51, 'text': 'But our front end is still a bit lagging.', 'start': 4134.368, 'duration': 2.142}, {'end': 4143.073, 'text': 'So if we hop back into our front end code and find our paint game function.', 'start': 4137.27, 'duration': 5.803}], 'summary': 'Optimizing server for two-player game, front end needs improvement', 'duration': 28.375, 'max_score': 4114.698, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs4114698.jpg'}, {'end': 4679.574, 'src': 'embed', 'start': 4654.697, 'weight': 1, 'content': [{'end': 4664.604, 'text': "and I'm sure will continue to drive it even higher in the future as he starts to expand the platform into being more of a community-driven platform and not just Brad's channel.", 'start': 4654.697, 'duration': 9.907}, {'end': 4673.229, 'text': 'So, if you want to see anything more from me, I run a YouTube channel called Hungry Turtle Code, as well as the website HungryTurtleCode.com,', 'start': 4665.144, 'duration': 8.085}, {'end': 4679.574, 'text': 'where I post write-ups for all of these videos in depth, if you prefer reading instead of watching videos.', 'start': 4673.229, 'duration': 6.345}], 'summary': 'Hungry turtle code offers in-depth content on youtube and website.', 'duration': 24.877, 'max_score': 4654.697, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs4654697.jpg'}], 'start': 3727.355, 'title': 'Multiplayer snake game development', 'summary': 'Covers resetting ui, handling game conditions, modifying a single-player game for two players, debugging game code, and building a multiplayer snake game using socket io, resulting in a fully functional two-player game with suggestions for future improvements.', 'chapters': [{'end': 3825.724, 'start': 3727.355, 'title': 'Resetting ui and handling game conditions', 'summary': 'Discusses creating a reset function to revert the ui to its initial state, including handling too many players and unknown game codes through alerts, and modifying the server to support game mechanics for two players.', 'duration': 98.369, 'highlights': ['The chapter emphasizes creating a reset function to revert the UI to its initial state, including resetting player number to null, game code input value to an empty string, game code display inner text to nothing, setting initial screen display to block, and game screen display to none.', 'The tutorial suggests handling too many players and unknown game codes through alerts for the sake of simplicity, with the intention of implementing more graceful handling in a proper deployment.']}, {'end': 4308.512, 'start': 3826.224, 'title': 'Multiplayer game development', 'summary': 'Explains the process of modifying a single-player game to handle two players, including updating game state, game loop, random food function, server handling, front-end display, and event handling, resulting in a fully functional two-player game.', 'duration': 482.288, 'highlights': ['The game loop is modified to handle two players by updating player references and handling game outcomes. The game loop code is adjusted to define Player1 and Player2 references, with modifications made to handle game outcomes for both players, resulting in a functional two-player game.', "The random food function is updated to account for two players by checking if the food is on either player's snake. The random food function is modified to check if the food is on either player's snake by looping through all the cells in the snake for each player, ensuring fair distribution of food for both players.", 'The server handling is updated to manage two players by assigning player updates to specific game rooms. The server handling is adjusted to update player state within specific game rooms, ensuring that player updates are correctly assigned to individual game instances, facilitating the management of two-player games.', 'The front-end display is modified to paint both players and differentiate them with distinct colors. The front-end display is enhanced to paint both players by calling the paint player function for each player and differentiating them with distinct colors, improving the visual representation of the two-player game.', 'The event handling is updated to emit win/lose messages to the respective players upon game over. The event handling is adjusted to emit win/lose messages to the winning and losing players upon game over, providing a clear indication of the game outcome for each player and enhancing the overall game experience.']}, {'end': 4498.515, 'start': 4308.512, 'title': 'Debugging game code', 'summary': 'Details the process of debugging game code, encountering errors such as import failures and incorrect element ids, and resolving issues related to game over conditions and player positions.', 'duration': 190.003, 'highlights': ['The game code encounters import failures and element ID errors, leading to immediate failure and error messages in the browser.', 'Debugging focuses on the game loop code to address issues with game over conditions and player position updates.', 'Game over conditions are successfully resolved, leading to correct error messages and win/lose outcomes in the game.']}, {'end': 4683.472, 'start': 4500.816, 'title': 'Building multiplayer snake game with socket io', 'summary': 'Demonstrates creating a multiplayer snake game using socket io, highlighting the architecture and providing suggestions for future improvements, such as adding new features and expanding player capacity.', 'duration': 182.656, 'highlights': ['Creating a multiplayer snake game using socket IO The tutorial demonstrates the development of a multiplayer snake game using socket IO, showcasing the practical application of canvas and socket IO for game development.', 'Suggesting future improvements for the game The speaker encourages viewers to enhance the game by adding new features such as rematch or restart options, as well as expanding the player capacity to accommodate more than two players.', 'Emphasizing the importance of creativity and continuous learning in programming The speaker stresses the significance of setting targets, experimenting with new ideas, and building on existing platforms to foster creativity and enhance programming skills, providing a solid foundation for learning and growth.']}], 'duration': 956.117, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/ppcBIHv_ZPs/pics/ppcBIHv_ZPs3727355.jpg', 'highlights': ['The server handling is updated to manage two players by assigning player updates to specific game rooms. The server handling is adjusted to update player state within specific game rooms, ensuring that player updates are correctly assigned to individual game instances, facilitating the management of two-player games.', 'The front-end display is modified to paint both players and differentiate them with distinct colors. The front-end display is enhanced to paint both players by calling the paint player function for each player and differentiating them with distinct colors, improving the visual representation of the two-player game.', 'The event handling is updated to emit win/lose messages to the respective players upon game over. The event handling is adjusted to emit win/lose messages to the winning and losing players upon game over, providing a clear indication of the game outcome for each player and enhancing the overall game experience.', 'The game loop is modified to handle two players by updating player references and handling game outcomes. The game loop code is adjusted to define Player1 and Player2 references, with modifications made to handle game outcomes for both players, resulting in a functional two-player game.', "The random food function is updated to account for two players by checking if the food is on either player's snake. The random food function is modified to check if the food is on either player's snake by looping through all the cells in the snake for each player, ensuring fair distribution of food for both players.", 'The chapter emphasizes creating a reset function to revert the UI to its initial state, including resetting player number to null, game code input value to an empty string, game code display inner text to nothing, setting initial screen display to block, and game screen display to none.', 'Debugging focuses on the game loop code to address issues with game over conditions and player position updates.', 'Game over conditions are successfully resolved, leading to correct error messages and win/lose outcomes in the game.', 'The tutorial demonstrates the development of a multiplayer snake game using socket IO, showcasing the practical application of canvas and socket IO for game development.', 'The speaker encourages viewers to enhance the game by adding new features such as rematch or restart options, as well as expanding the player capacity to accommodate more than two players.', 'The speaker stresses the significance of setting targets, experimenting with new ideas, and building on existing platforms to foster creativity and enhance programming skills, providing a solid foundation for learning and growth.']}], 'highlights': ['The game allows players to create a new game, receive a unique game code, and join the game using the code, enabling immediate multiplayer gameplay.', 'Setting up the game screen using Bootstrap classes and creating canvas elements with specific dimensions and colors.', "The chapter emphasizes initializing a canvas and filling it with a specific color, providing clear instructions on setting the rectangle's dimensions and painting the canvas black.", "Defining a game state object in front-end JavaScript with player position, velocity, snake segments, food position, and grid size, representing the game world's coordinate system with 20 squares.", 'Setting up a SocketIO server for a Snake game, including creating front-end and server folders, installing the socket.io library, and establishing communication between front-end and back-end.', "The chapter outlines the process of emitting a game state, including JSON stringification, emitting 'game over' when there's a winner, and clearing the game loop interval.", 'The chapter covers the development of a single-player snake game where the server controls the state and sends it to the front end, and the front end repaints on every frame.', 'Handling the init event', 'The logic explains the different scenarios for joining a game room based on the number of clients, with specific actions and messages emitted for each condition.', 'The server handling is updated to manage two players by assigning player updates to specific game rooms. The server handling is adjusted to update player state within specific game rooms, ensuring that player updates are correctly assigned to individual game instances, facilitating the management of two-player games.', 'The front-end display is modified to paint both players and differentiate them with distinct colors. The front-end display is enhanced to paint both players by calling the paint player function for each player and differentiating them with distinct colors, improving the visual representation of the two-player game.', 'The event handling is updated to emit win/lose messages to the respective players upon game over. The event handling is adjusted to emit win/lose messages to the winning and losing players upon game over, providing a clear indication of the game outcome for each player and enhancing the overall game experience.', 'The game loop is modified to handle two players by updating player references and handling game outcomes. The game loop code is adjusted to define Player1 and Player2 references, with modifications made to handle game outcomes for both players, resulting in a functional two-player game.', "The random food function is updated to account for two players by checking if the food is on either player's snake. The random food function is modified to check if the food is on either player's snake by looping through all the cells in the snake for each player, ensuring fair distribution of food for both players.", 'The chapter emphasizes creating a reset function to revert the UI to its initial state, including resetting player number to null, game code input value to an empty string, game code display inner text to nothing, setting initial screen display to block, and game screen display to none.', 'The tutorial demonstrates the development of a multiplayer snake game using socket IO, showcasing the practical application of canvas and socket IO for game development.', 'The speaker encourages viewers to enhance the game by adding new features such as rematch or restart options, as well as expanding the player capacity to accommodate more than two players.', 'The speaker stresses the significance of setting targets, experimenting with new ideas, and building on existing platforms to foster creativity and enhance programming skills, providing a solid foundation for learning and growth.']}