title
Create a Platformer Game with JavaScript - Full Tutorial

description
Learn how to create a platformer game using vanilla JavaScript. First, learn to organize the code using the Model, View, Controller (MVC) strategy and the principles of Object Oriented Programming (OOP). Then, learn how to program movement, draw a tile map, and detect collision. Finally, see how to animate the sprites, load levels, and collect items. 💻Code and assets: https://github.com/frankarendpoth/frankarendpoth.github.io/tree/master/content/pop-vlog/javascript/2018/006-rabbit-trap 🔗Working example: http://frankpoth.info/content/pop-vlog/javascript/2018/006-rabbit-trap/rabbit-trap.html ⭐️Course Contents ⭐️ ⌨️ (00:00) Part 1: Organization ⌨️ (14:38) Part 2: Movement ⌨️ (51:25) Part 3: Tile Map ⌨️ (1:04:30) Part 4: Tile Based Collision Detection And Response ⌨️ (1:29:08) Part 5: Sprite Animation ⌨️ (1:53:22) Part 5 1/2: Tunneling ⌨️ (2:05:34) Part 6: Loading Levels ⌨️ (1:26:59) Part 7: Collecting Items Tutorial from Poth on Programming. Check out his channel: https://www.youtube.com/channel/UCdS3ojA8RL8t1r18Gj1cl6w -- Learn to code for free and get a developer job: https://www.freecodecamp.org Read hundreds of articles on programming: https://medium.freecodecamp.org

detail
{'title': 'Create a Platformer Game with JavaScript - Full Tutorial', 'heatmap': [{'end': 982.087, 'start': 778.15, 'weight': 0.726}, {'end': 9768.777, 'start': 9675.163, 'weight': 1}], 'summary': 'Learn to build rabbit trap platforming game with javascript, covering topics like tile-based collision detection, mvc architecture, sprite animation, canvas drawing, tile-based collision implementation, sprite animation basics, frame adjustment, json data loading, and game development essentials.', 'chapters': [{'end': 67.709, 'segs': [{'end': 54.21, 'src': 'embed', 'start': 0.329, 'weight': 0, 'content': [{'end': 1.43, 'text': 'Hey guys, my name is Frank.', 'start': 0.329, 'duration': 1.101}, {'end': 5.294, 'text': "I'm starting a series on how to program a tile-based platforming game called Rabbit Trap.", 'start': 1.51, 'duration': 3.784}, {'end': 12.941, 'text': 'It will feature tile-based collision detection and response, scrolling maps, loading levels, sprite animation, and interactive game objects.', 'start': 5.374, 'duration': 7.567}, {'end': 17.205, 'text': "In this first part of the series, I'll be talking about how to build a strong foundation for the game.", 'start': 13.442, 'duration': 3.763}, {'end': 24.813, 'text': "The concepts I'm going to explain are strongly rooted in object-oriented programming and can be used in any program to improve organization and modularity.", 'start': 17.646, 'duration': 7.167}, {'end': 27.819, 'text': 'This might seem boring, but if you use this approach,', 'start': 25.413, 'duration': 2.406}, {'end': 33.674, 'text': 'it can save you hours of editing and frustration and leave you more time to focus on fun stuff like level design and graphics.', 'start': 27.819, 'duration': 5.855}, {'end': 34.776, 'text': 'so be sure to watch this video.', 'start': 33.674, 'duration': 1.102}, {'end': 49.468, 'text': "In this video I'm going to talk about the model view controller approach to organizing a program and how the different components of this example work together in the main.js file.", 'start': 40.746, 'duration': 8.722}, {'end': 54.21, 'text': "Then I'm going to talk about how this structure increases maintainability and modularity.", 'start': 50.108, 'duration': 4.102}], 'summary': 'Frank starts a series on programming rabbit trap game, featuring tile-based collision, scrolling maps, and more, emphasizing the benefits of the object-oriented approach.', 'duration': 53.881, 'max_score': 0.329, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA329.jpg'}], 'start': 0.329, 'title': 'Building rabbit trap game', 'summary': 'Introduces a series on programming a tile-based platforming game called rabbit trap, covering topics such as tile-based collision detection, scrolling maps, loading levels, sprite animation, and interactive game objects.', 'chapters': [{'end': 67.709, 'start': 0.329, 'title': 'Rabbit trap: building a tile-based platforming game', 'summary': 'Introduces a series on programming a tile-based platforming game called rabbit trap, covering topics such as tile-based collision detection, scrolling maps, loading levels, sprite animation, and interactive game objects, emphasizing the importance of a strong foundational approach rooted in object-oriented programming and the model view controller design for improving organization and modularity.', 'duration': 67.38, 'highlights': ['The series focuses on programming a tile-based platforming game called Rabbit Trap, including features like tile-based collision detection, scrolling maps, loading levels, sprite animation, and interactive game objects.', 'The foundational concepts are rooted in object-oriented programming and can save hours of editing and frustration, allowing more time for fun activities like level design and graphics.', 'The chapter emphasizes the importance of a strong foundational approach rooted in object-oriented programming and the model view controller design for improving organization and modularity.']}], 'duration': 67.38, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA329.jpg', 'highlights': ['The series focuses on programming a tile-based platforming game called Rabbit Trap, including features like tile-based collision detection, scrolling maps, loading levels, sprite animation, and interactive game objects.', 'The chapter emphasizes the importance of a strong foundational approach rooted in object-oriented programming and the model view controller design for improving organization and modularity.', 'The foundational concepts are rooted in object-oriented programming and can save hours of editing and frustration, allowing more time for fun activities like level design and graphics.']}, {'end': 916.657, 'segs': [{'end': 121.799, 'src': 'embed', 'start': 86.605, 'weight': 0, 'content': [{'end': 90.929, 'text': "And each one of these handles its own business, and it's totally separate from the other.", 'start': 86.605, 'duration': 4.324}, {'end': 97.195, 'text': "So I'm not going to run into any issues with having references to the game logic inside of the display.", 'start': 91.33, 'duration': 5.865}, {'end': 100.979, 'text': "I'm not going to have the controller logic reference inside of the game.", 'start': 97.596, 'duration': 3.383}, {'end': 109.327, 'text': "I'm going to have all these different components interact with each other through their public methods inside of the main JS file context.", 'start': 101.459, 'duration': 7.868}, {'end': 114.157, 'text': 'And by the way, each one of these classes is defined in its own individual file.', 'start': 110.236, 'duration': 3.921}, {'end': 121.239, 'text': "You don't need to have your own individual files, but it makes it a lot easier to just use these different things in other applications,", 'start': 114.517, 'duration': 6.722}, {'end': 121.799, 'text': 'if I choose to.', 'start': 121.239, 'duration': 0.56}], 'summary': 'Each component is separate, with public methods in main js file context.', 'duration': 35.194, 'max_score': 86.605, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA86605.jpg'}, {'end': 174.149, 'src': 'embed', 'start': 146.134, 'weight': 1, 'content': [{'end': 151.401, 'text': "green and blue channels inside of a color value to change these different colors that you're seeing on the screen.", 'start': 146.134, 'duration': 5.267}, {'end': 160.554, 'text': 'And then it will talk to the display class, which governs things like the canvas and resizing the canvas when the screen resizes and rendering.', 'start': 152.262, 'duration': 8.292}, {'end': 167.324, 'text': 'And the game will hand a color value to the display and the display will render it on every frame.', 'start': 160.574, 'duration': 6.75}, {'end': 170.703, 'text': 'And the engine takes care of frames.', 'start': 168.96, 'duration': 1.743}, {'end': 174.149, 'text': "As for the controller, I didn't really have anything cool to do with the controller for this example.", 'start': 170.803, 'duration': 3.346}], 'summary': 'The game engine handles frames, while the display class governs canvas resizing and rendering color values on every frame.', 'duration': 28.015, 'max_score': 146.134, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA146134.jpg'}, {'end': 516.008, 'src': 'embed', 'start': 491.372, 'weight': 2, 'content': [{'end': 500.839, 'text': 'So using the MVC approach or just separating out the different components of your game into logical groups is a really great way to keep your code maintainable and modular.', 'start': 491.372, 'duration': 9.467}, {'end': 503.921, 'text': "And I'm going to get into why in the next part of this video.", 'start': 500.919, 'duration': 3.002}, {'end': 512.263, 'text': 'So now I want to talk about how this approach makes things more modular and more easy to maintain.', 'start': 507.336, 'duration': 4.927}, {'end': 516.008, 'text': "So obviously right off the bat, it's a lot more organized.", 'start': 512.383, 'duration': 3.625}], 'summary': 'Using mvc approach organizes game components for maintainability and modularity.', 'duration': 24.636, 'max_score': 491.372, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA491372.jpg'}], 'start': 67.709, 'title': 'Mvc in game development', 'summary': 'Explains the model view controller architecture, with game logic in the game class, display logic in the display class, and controller logic in the controller class, emphasizing the benefits of mvc in organizing game components for clean code, maintainability, and modularity.', 'chapters': [{'end': 170.703, 'start': 67.709, 'title': 'Model view controller architecture', 'summary': 'Explains the model view controller architecture, with game logic in the game class, display logic in the display class, and controller logic in the controller class, each handling its own business and interacting through public methods. the game class controls color value, the display class governs canvas, and the engine takes care of frames.', 'duration': 102.994, 'highlights': ['Each component (game logic, display logic, and controller logic) is stored in separate classes and handles its own business, ensuring there are no issues with cross-referencing.', 'All components interact through their public methods inside the main JS file context, promoting modularity and reusability across different applications.', 'The game class controls the color value by incrementing the red, green, and blue channels to change the colors on the screen, while the display class governs canvas-related operations and rendering.', 'The engine is stored in its own file for potential use in other applications, promoting ease of reuse and modularity.']}, {'end': 916.657, 'start': 170.803, 'title': 'Organizing game components with mvc', 'summary': 'Demonstrates the importance of organizing game components using the mvc approach, focusing on clean code, maintainability, and modularity, leading to better organization, easy maintainability, and improved modularity', 'duration': 745.854, 'highlights': ['Using the MVC approach to separate game components into logical groups improves maintainability and modularity', 'Separating components into their own classes and files makes code more organized and maintainable', 'Utilizing public methods for component communication enhances maintainability and code organization']}], 'duration': 848.948, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA67709.jpg', 'highlights': ['Each component (game logic, display logic, and controller logic) is stored in separate classes and handles its own business, ensuring there are no issues with cross-referencing.', 'The game class controls the color value by incrementing the red, green, and blue channels to change the colors on the screen, while the display class governs canvas-related operations and rendering.', 'Using the MVC approach to separate game components into logical groups improves maintainability and modularity', 'All components interact through their public methods inside the main JS file context, promoting modularity and reusability across different applications.']}, {'end': 2025.574, 'segs': [{'end': 961.163, 'src': 'embed', 'start': 918.797, 'weight': 2, 'content': [{'end': 925.501, 'text': 'first thing i want to talk about is what this example actually does and how this program has changed since part one.', 'start': 918.797, 'duration': 6.704}, {'end': 933.825, 'text': 'so all this example does is allow me to place a square, which represents my player, on the screen and use the keyboard to make him jump up and down.', 'start': 925.501, 'duration': 8.324}, {'end': 938.227, 'text': 'i also added some stuff in for collision detection and to make it look nice.', 'start': 933.825, 'duration': 4.402}, {'end': 943.09, 'text': 'so he changes color on every jump And he leaves a trail.', 'start': 938.227, 'duration': 4.863}, {'end': 946.632, 'text': "The reason he's leaving a trail is just because I'm filling the background.", 'start': 943.13, 'duration': 3.502}, {'end': 953.816, 'text': "I'm redrawing the background on every frame of animation with a slightly transparent background.", 'start': 946.692, 'duration': 7.124}, {'end': 955.437, 'text': "So that's the reason I'm getting that trail.", 'start': 953.916, 'duration': 1.521}, {'end': 958.199, 'text': 'If I was drawing just a plain opaque background.', 'start': 955.497, 'duration': 2.702}, {'end': 959.36, 'text': 'or opaque.', 'start': 958.519, 'duration': 0.841}, {'end': 961.163, 'text': 'i guess some people pronounce it that way.', 'start': 959.36, 'duration': 1.803}], 'summary': 'Program allows player to jump, change color, and leave a trail on screen.', 'duration': 42.366, 'max_score': 918.797, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA918797.jpg'}, {'end': 1037.662, 'src': 'embed', 'start': 1001.378, 'weight': 4, 'content': [{'end': 1002.259, 'text': 'That has a part one.', 'start': 1001.378, 'duration': 0.881}, {'end': 1005.073, 'text': "So that's my naming convention that I'm using.", 'start': 1003.311, 'duration': 1.762}, {'end': 1010.519, 'text': 'Really the only thing that I changed majorly, besides the code that went into making the example work,', 'start': 1005.654, 'duration': 4.865}, {'end': 1016.366, 'text': 'was I took the event listeners out of the display and the controller classes.', 'start': 1010.519, 'duration': 5.847}, {'end': 1024.354, 'text': 'So the key down up actual event handler function I hand into the event at event listener method in my main function.', 'start': 1016.806, 'duration': 7.548}, {'end': 1025.935, 'text': 'js file.', 'start': 1024.935, 'duration': 1}, {'end': 1029.217, 'text': "i'm actually defining those inside of my main file now.", 'start': 1025.935, 'duration': 3.282}, {'end': 1037.662, 'text': 'so this would be one that i moved out the key down up event listener and the resize event listener or actually event handlers.', 'start': 1029.217, 'duration': 8.445}], 'summary': 'Key event listeners moved to main function.js file.', 'duration': 36.284, 'max_score': 1001.378, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA1001378.jpg'}, {'end': 1261.038, 'src': 'embed', 'start': 1228.2, 'weight': 5, 'content': [{'end': 1229.86, 'text': 'The player is going to be defined here.', 'start': 1228.2, 'duration': 1.66}, {'end': 1233.882, 'text': "Later on, I'm going to define other objects that are going to be in-game objects.", 'start': 1230.1, 'duration': 3.782}, {'end': 1235.362, 'text': "They're going to be defined here.", 'start': 1234.322, 'duration': 1.04}, {'end': 1240.645, 'text': 'The world boundaries, so the height and width of our level are going to be defined here.', 'start': 1235.743, 'duration': 4.902}, {'end': 1246.168, 'text': "If I were to change this, let's say I want to make the height something like 200 and have a really tall screen.", 'start': 1240.705, 'duration': 5.463}, {'end': 1254.514, 'text': 'If I do that and come here and refresh the screen, now you can see that I have a really, really tall game world, and that looks kind of stupid.', 'start': 1246.208, 'duration': 8.306}, {'end': 1261.038, 'text': "So we're going to change it back, save, refresh, and now I'm back to my normal size.", 'start': 1254.574, 'duration': 6.464}], 'summary': 'Defining player and game objects, adjusting world boundaries, and refreshing screen for changes.', 'duration': 32.838, 'max_score': 1228.2, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA1228200.jpg'}, {'end': 1402.211, 'src': 'embed', 'start': 1374.622, 'weight': 6, 'content': [{'end': 1378.446, 'text': 'it just governs everything to do with the world, the dimensions, the player,', 'start': 1374.622, 'duration': 3.824}, {'end': 1389.355, 'text': "the colors that you're seeing in there and also in our game class we have added or i have added rather the player, and it's a simple class.", 'start': 1378.446, 'duration': 10.909}, {'end': 1396.068, 'text': "it's of using dot syntax to kind of add this player class to the game class.", 'start': 1389.355, 'duration': 6.713}, {'end': 1400.73, 'text': "And that's kind of just a way to keep things organized and almost like namespace in there.", 'start': 1396.508, 'duration': 4.222}, {'end': 1402.211, 'text': "It's not real namespacing.", 'start': 1400.77, 'duration': 1.441}], 'summary': 'The player class was added to the game class using dot syntax for organization.', 'duration': 27.589, 'max_score': 1374.622, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA1374622.jpg'}, {'end': 1689.475, 'src': 'embed', 'start': 1655.685, 'weight': 0, 'content': [{'end': 1657.687, 'text': "And that's going to give me these nice,", 'start': 1655.685, 'duration': 2.002}, {'end': 1663.531, 'text': "cool physics and take care of all my numbers and player position and velocity and whether or not he's colliding.", 'start': 1657.687, 'duration': 5.844}, {'end': 1667.275, 'text': "And that's going to take care of all of the physics logic in my game.", 'start': 1663.571, 'duration': 3.704}, {'end': 1668.816, 'text': "It's also going to change the player color.", 'start': 1667.295, 'duration': 1.521}, {'end': 1672.374, 'text': 'all right.', 'start': 1672.114, 'duration': 0.26}, {'end': 1681.105, 'text': 'so now i just talked about what actually makes the game logic work, and that is of course the game class itself, storing the game o2 file.', 'start': 1672.374, 'duration': 8.731}, {'end': 1689.475, 'text': "so now i have to talk about how i'm getting keyboard input and relaying that to the game class so we can actually take that input and do something with it.", 'start': 1681.105, 'duration': 8.37}], 'summary': 'Game logic handles physics, player position, velocity, collision, and input processing for game class.', 'duration': 33.79, 'max_score': 1655.685, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA1655685.jpg'}, {'end': 1767.757, 'src': 'embed', 'start': 1735.028, 'weight': 7, 'content': [{'end': 1738.692, 'text': 'Now, active is gonna hold the virtual state of our button.', 'start': 1735.028, 'duration': 3.664}, {'end': 1742.996, 'text': "So I'll get into that in a little bit, because it has to do with jumping.", 'start': 1739.292, 'duration': 3.704}, {'end': 1747.661, 'text': 'And down is going to refer to the physical state of our button on the keyboard.', 'start': 1743.657, 'duration': 4.004}, {'end': 1752.626, 'text': 'So if I physically press the up key down, down is going to be true.', 'start': 1747.701, 'duration': 4.925}, {'end': 1756.129, 'text': "And if I hold that key down, it's going to remain true.", 'start': 1753.146, 'duration': 2.983}, {'end': 1761.335, 'text': "The active value, however, is going to depend more on my actual game's logic.", 'start': 1756.57, 'duration': 4.765}, {'end': 1767.757, 'text': "So just remember, keep in mind that down refers to the physical state of the button on my keyboard, and that's what that is going to track.", 'start': 1761.795, 'duration': 5.962}], 'summary': "Virtual state of button is tracked by 'active' and physical state by 'down'.", 'duration': 32.729, 'max_score': 1735.028, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA1735028.jpg'}, {'end': 1935.77, 'src': 'embed', 'start': 1911.625, 'weight': 1, 'content': [{'end': 1924.735, 'text': 'this controller class just gets keyboard input and then we relay that input to the game component right here in the main.js file inside of its update function,', 'start': 1911.625, 'duration': 13.11}, {'end': 1931.084, 'text': "which is called on every frame of animation managed by our engine, which I'm going to talk about later on in this video.", 'start': 1924.735, 'duration': 6.349}, {'end': 1935.77, 'text': 'So really simply, just checks to see if the left, right, and up keys are active.', 'start': 1931.124, 'duration': 4.646}], 'summary': 'The controller class relays keyboard input to the game component in main.js, checking for left, right, and up keys.', 'duration': 24.145, 'max_score': 1911.625, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA1911625.jpg'}], 'start': 918.797, 'title': 'Game development and logic', 'summary': 'Delves into a game development example, including placing a player, keyboard controls, collision detection, and creating a trail effect. it also covers changes since part one, moving event listeners, defining game world and player, and organizing classes. additionally, it details processing keyboard input and implementing game logic through the controller and game class, using button input objects with dual virtual and physical button state trackers.', 'chapters': [{'end': 976.703, 'start': 918.797, 'title': 'Game development example', 'summary': 'Discusses a game development example that involves placing a player on the screen, enabling keyboard controls for jumping, implementing collision detection, and creating a trail effect with a slightly transparent background.', 'duration': 57.906, 'highlights': ['The example allows placing a square representing the player on the screen and using keyboard controls for movement, with added features for collision detection and visual appeal.', 'The player changes color on every jump and leaves a trail due to redrawing the background with a slightly transparent effect, aiding in visualizing each frame of animation.']}, {'end': 1629.897, 'start': 976.703, 'title': 'Game development part 2', 'summary': 'Discusses the changes made since part one, including moving event listeners to the main file, defining the game world and player, and organizing classes using dot syntax, with a focus on self-contained object functions and interactions.', 'duration': 653.194, 'highlights': ['Event listeners moved to main file', 'Defining game world and player', 'Organizing classes using dot syntax']}, {'end': 2025.574, 'start': 1630.878, 'title': 'Game logic and keyboard input processing', 'summary': 'Details the process of processing keyboard input and implementing game logic through the controller and game class, using button input objects with dual virtual and physical button state trackers to prevent continuous jumping.', 'duration': 394.696, 'highlights': ['The game class drives the game logic, including physics, player position, and velocity, and color changes.', 'The controller class processes keyboard input and relays it to the game object to trigger player movements such as left, right, and jumping.', 'The button input class tracks both virtual and physical states of the keyboard buttons to prevent continuous jumping by updating the active and down values accordingly.']}], 'duration': 1106.777, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA918797.jpg', 'highlights': ['The game class drives game logic, including physics, player position, and color changes.', 'The controller class processes keyboard input and triggers player movements.', 'The example allows placing a player on the screen and using keyboard controls for movement.', 'The player changes color on every jump and leaves a trail for visual appeal.', 'Event listeners moved to main file for improved organization.', 'Defining game world and player for better structuring.', 'Organizing classes using dot syntax for enhanced readability.', 'The button input class tracks virtual and physical states of keyboard buttons.']}, {'end': 3194.89, 'segs': [{'end': 2077.155, 'src': 'embed', 'start': 2046.687, 'weight': 3, 'content': [{'end': 2053.728, 'text': "So how we're drawing the player object and the world itself to this canvas element is with the display class.", 'start': 2046.687, 'duration': 7.041}, {'end': 2058.17, 'text': 'So inside of the display class, I just define a buffer and a context of my canvas.', 'start': 2053.748, 'duration': 4.422}, {'end': 2063.731, 'text': 'So these are two 2D rendering contexts, canvas rendering contexts.', 'start': 2058.19, 'duration': 5.541}, {'end': 2069.272, 'text': 'context is the rendering context of the on-screen canvas that you see on screen.', 'start': 2065.231, 'duration': 4.041}, {'end': 2077.155, 'text': 'buffer is just an off-screen canvas that is going to be sized perfectly to match our world height and width.', 'start': 2069.272, 'duration': 7.883}], 'summary': 'Drawing player object and world to canvas using display class and 2d rendering contexts.', 'duration': 30.468, 'max_score': 2046.687, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA2046687.jpg'}, {'end': 2530.712, 'src': 'embed', 'start': 2498.627, 'weight': 2, 'content': [{'end': 2503.152, 'text': "Somewhere around here, I'm going to change over from a max height situation to a max width situation.", 'start': 2498.627, 'duration': 4.525}, {'end': 2508.818, 'text': 'And now you can see my display canvas gradually getting smaller in height.', 'start': 2503.932, 'duration': 4.886}, {'end': 2510.655, 'text': "So that's pretty cool.", 'start': 2509.693, 'duration': 0.962}, {'end': 2511.757, 'text': "That's the display function.", 'start': 2510.675, 'duration': 1.082}, {'end': 2521.376, 'text': 'Takes care of resizing the canvas and maintaining that nice aspect ratio so our game can scale nicely across many different devices.', 'start': 2512.138, 'duration': 9.238}, {'end': 2530.712, 'text': "Alright, so now I'm going to do a brief run through of my fixed time step game engine.", 'start': 2524.79, 'duration': 5.922}], 'summary': 'Demonstrating the transition from max height to max width, scaling the game for different devices.', 'duration': 32.085, 'max_score': 2498.627, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA2498627.jpg'}, {'end': 2621.183, 'src': 'embed', 'start': 2594.974, 'weight': 0, 'content': [{'end': 2602.038, 'text': "And they're basically just going to update my game logic and render the changed game state to the screen.", 'start': 2594.974, 'duration': 7.064}, {'end': 2607.335, 'text': "Let's hop back inside of the engine and talk about this game loop some more.", 'start': 2603.353, 'duration': 3.982}, {'end': 2615.34, 'text': "All right, so we've got our time step, and that's going to be, in this case, about 33.33 milliseconds.", 'start': 2607.956, 'duration': 7.384}, {'end': 2621.183, 'text': "And so every 33.33 milliseconds, I'm going to call the update and render function that I passed in.", 'start': 2616.02, 'duration': 5.163}], 'summary': 'The game loop updates and renders game state every 33.33 milliseconds.', 'duration': 26.209, 'max_score': 2594.974, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA2594974.jpg'}, {'end': 2915.988, 'src': 'embed', 'start': 2891.475, 'weight': 1, 'content': [{'end': 2898.057, 'text': "we're going to update our game at whatever rate we want it to update until we have caught up with however much time has passed.", 'start': 2891.475, 'duration': 6.582}, {'end': 2904.499, 'text': "And that's a really great functionality of fixed time step game loops, and it's a great reason to add them in to any game that you're writing.", 'start': 2898.097, 'duration': 6.402}, {'end': 2908.482, 'text': 'so now, down here we have the updated flag.', 'start': 2905.519, 'duration': 2.963}, {'end': 2915.988, 'text': 'basically we turn that flag on, we set it to true anytime we do an update and then, if it is true, if we have updated,', 'start': 2908.482, 'duration': 7.506}], 'summary': 'Game can update at any rate using fixed time step loops, a great functionality to add.', 'duration': 24.513, 'max_score': 2891.475, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA2891475.jpg'}], 'start': 2025.574, 'title': 'Game development essentials', 'summary': 'Covers drawing and resizing canvas for game, utilizing a fixed time step game loop with a value of 33.33 milliseconds, and implementing it across multiple devices, emphasizing the importance of maintaining consistent game updates.', 'chapters': [{'end': 2521.376, 'start': 2025.574, 'title': 'Drawing and resizing canvas for game', 'summary': 'Explains how to draw the player object and the world to the canvas using the display class, including resizing functionality for maintaining aspect ratio, with the key points being: defining player and world objects, getting user input, drawing on and off-screen canvases, and resizing canvas for maintaining aspect ratio.', 'duration': 495.802, 'highlights': ['The display class defines a buffer and a context for the canvas, with the buffer being an off-screen canvas sized to match the world height and width.', 'The fill method in the display class fills the off-screen buffer with color, which is then rendered to the on-screen display canvas.', 'The drawRectangle method in the display class draws a rectangle to the off-screen buffer, ensuring that the x and y positions are rounded down to prevent rendering on half pixels.', 'The resize function in the display class is responsible for scaling the on-screen canvas and maintaining the aspect ratio of the game world to the final display canvas.']}, {'end': 2957.43, 'start': 2524.79, 'title': 'Fixed time step game loop', 'summary': 'Discusses implementing a fixed time step game loop, with key points including a time step value of 33.33 milliseconds, the process of accumulating and utilizing time, and the benefits of ensuring consistent game updates across devices.', 'duration': 432.64, 'highlights': ['The game engine uses a fixed time step of 33.33 milliseconds to update and render the game, maintaining consistent performance across devices.', 'Accumulated time is utilized to account for variations in the time step, ensuring that the game logic and rendering are synchronized with the fixed time step.', "The fixed time step game loop provides the benefit of ensuring consistent game updates regardless of the device's speed, enhancing the overall performance and user experience.", "The 'updated' flag is utilized to determine whether an update has occurred, ensuring that rendering only takes place when the game state has changed, thus optimizing CPU and GPU usage."]}, {'end': 3194.89, 'start': 2958.482, 'title': 'Implementing a fixed time step game loop', 'summary': 'Explains the implementation of a fixed time step game loop to handle updating the game at a consistent rate across multiple devices, while also discussing the use of arrow functions to maintain the correct reference to the engine object instead of the window object.', 'duration': 236.408, 'highlights': ['The chapter explains the implementation of a fixed time step game loop, ensuring consistent game updates across devices.', 'The usage of arrow functions is discussed to maintain the correct reference to the engine object instead of the window object.', 'The video demonstrates the addition of a tile map and changes in the world size, character appearance, and physics code in part three compared to part two.', 'The changes occurred in the display, game, and main files, utilizing the controller class from part two and the engine class from part one.']}], 'duration': 1169.316, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA2025574.jpg', 'highlights': ['The game engine uses a fixed time step of 33.33 milliseconds to update and render the game, maintaining consistent performance across devices.', "The fixed time step game loop provides the benefit of ensuring consistent game updates regardless of the device's speed, enhancing the overall performance and user experience.", 'The resize function in the display class is responsible for scaling the on-screen canvas and maintaining the aspect ratio of the game world to the final display canvas.', 'The display class defines a buffer and a context for the canvas, with the buffer being an off-screen canvas sized to match the world height and width.']}, {'end': 5346.847, 'segs': [{'end': 3940.064, 'src': 'embed', 'start': 3914.398, 'weight': 1, 'content': [{'end': 3918.78, 'text': 'Basically, I have pixel perfect, tile-based collision detection and response,', 'start': 3914.398, 'duration': 4.382}, {'end': 3924.346, 'text': 'And everything looks and works the way you would expect it to in a tile-based platforming game.', 'start': 3919.44, 'duration': 4.906}, {'end': 3929.452, 'text': "So now that you know what the example is all about, let's take a look at what's changed in the code.", 'start': 3924.426, 'duration': 5.026}, {'end': 3935.8, 'text': 'So the only two files that have changed since part three are the game file, which holds the game class, and the display file,', 'start': 3929.572, 'duration': 6.228}, {'end': 3937.241, 'text': 'which holds the display class.', 'start': 3935.8, 'duration': 1.441}, {'end': 3940.064, 'text': 'Display had a minor change since part three.', 'start': 3937.942, 'duration': 2.122}], 'summary': 'Achieved pixel perfect, tile-based collision detection in game code and display class, with minor changes made.', 'duration': 25.666, 'max_score': 3914.398, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA3914398.jpg'}, {'end': 4632.914, 'src': 'embed', 'start': 4606.758, 'weight': 2, 'content': [{'end': 4612.982, 'text': 'Interesting, so I can take my narrow phase functions and I can tweak them a little bit inside of my routing function,', 'start': 4606.758, 'duration': 6.224}, {'end': 4618.165, 'text': "and that's gonna give me the ability to create a whole bunch of different tile types, however I want.", 'start': 4612.982, 'duration': 5.183}, {'end': 4623.428, 'text': 'So all the different shapes are gonna be defined basically inside of the routing function,', 'start': 4618.225, 'duration': 5.203}, {'end': 4629.592, 'text': 'and all it really does is gets the tile value and links it to a certain set of narrow phase functions.', 'start': 4623.428, 'duration': 6.164}, {'end': 4632.914, 'text': "Let's take a look at, let's see what I got here.", 'start': 4629.632, 'duration': 3.282}], 'summary': 'Narrow phase functions can be tweaked to create various tile types inside the routing function.', 'duration': 26.156, 'max_score': 4606.758, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA4606758.jpg'}, {'end': 4850.022, 'src': 'embed', 'start': 4826.464, 'weight': 0, 'content': [{'end': 4835.346, 'text': 'and, awesomely enough, with these four functions we can do collision, detection and response with all of the different tile types,', 'start': 4826.464, 'duration': 8.882}, {'end': 4837.747, 'text': 'basically any tile that has four sides.', 'start': 4835.346, 'duration': 2.401}, {'end': 4845.538, 'text': 'we can take these four functions and combine them to get all kinds of different combinations up to 15 combinations,', 'start': 4837.747, 'duration': 7.791}, {'end': 4850.022, 'text': 'which is as many combinations as you can have with a four sided tile.', 'start': 4845.538, 'duration': 4.484}], 'summary': 'Four functions allow up to 15 combinations for collision detection and response with four-sided tiles.', 'duration': 23.558, 'max_score': 4826.464, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA4826464.jpg'}, {'end': 4966.493, 'src': 'embed', 'start': 4940.251, 'weight': 3, 'content': [{'end': 4947.153, 'text': "it's gonna hand the information to the routing function and the routing function is gonna call collide platform top.", 'start': 4940.251, 'duration': 6.902}, {'end': 4957.09, 'text': 'Now collide platform top without doing this check on the last position that the bottom of the player was in the last frame of animation.', 'start': 4948.007, 'duration': 9.083}, {'end': 4966.493, 'text': "without that, it's just gonna check to see is the bottom of the player greater than the tile top and if it is, set it to the top of the tile.", 'start': 4957.09, 'duration': 9.403}], 'summary': 'Routing function calls collide platform top to check player position and adjust accordingly.', 'duration': 26.242, 'max_score': 4940.251, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA4940251.jpg'}, {'end': 5122.228, 'src': 'embed', 'start': 5097.334, 'weight': 4, 'content': [{'end': 5102.539, 'text': "Collide platform right and collide platform bottom don't have this problem and it has to do with rounding.", 'start': 5097.334, 'duration': 5.205}, {'end': 5105.662, 'text': "So let's just comment this out and see what happens.", 'start': 5103.019, 'duration': 2.643}, {'end': 5109.165, 'text': "But first I'm gonna show you the desired functionality.", 'start': 5105.702, 'duration': 3.463}, {'end': 5115.606, 'text': "So right now I'm colliding with the left side of these two tiles and it's calling collide platform left to do that collision resolution.", 'start': 5109.565, 'duration': 6.041}, {'end': 5120.927, 'text': "So as you can see, I can jump up and down and it's as you would expect, I'm jumping up and falling down.", 'start': 5116.466, 'duration': 4.461}, {'end': 5122.228, 'text': 'Nothing is broken yet.', 'start': 5121.307, 'duration': 0.921}], 'summary': 'Issue with collision platforms resolved, desired functionality demonstrated.', 'duration': 24.894, 'max_score': 5097.334, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5097334.jpg'}], 'start': 3197.892, 'title': 'Implementing tile-based collision in javascript game development', 'summary': 'Covers loading sprite sheet images, creating tile map arrays, and implementing tile-based collision detection and response, with insights into changes made in the code, broad phase and narrow phase collision methods, and handling up to 15 combinations for four-sided tiles, emphasizing smooth collision resolution and glitch prevention.', 'chapters': [{'end': 3365.908, 'start': 3197.892, 'title': 'Loading sprite sheet image into javascript', 'summary': 'Discusses the process of defining a tile sheet class, loading a png image into javascript, and ensuring the image is fully loaded before starting the game engine, with key points including defining tile size and number of columns, setting the image source, and handling the load event.', 'duration': 168.016, 'highlights': ['The chapter discusses the process of defining a tile sheet class, loading a PNG image into JavaScript, and ensuring the image is fully loaded before starting the game engine, with key points including defining tile size and number of columns, setting the image source, and handling the load event.', 'The tile sheet class is defined to contain the image, tile size (set to 16 pixels), and the number of columns in the tile sheet image (8 in this case).', "The image source of the tile sheet object in the display class is set to 'rabbit-trap.png' to start loading the image into the tile sheet object.", 'Upon the image being fully loaded, the event listener for the load event triggers actions including resizing the canvas to fit the browser window and starting the game engine.']}, {'end': 4035.502, 'start': 3366.528, 'title': 'Sprite sheet image and tile map', 'summary': 'Explains the process of loading a sprite sheet image into javascript, creating a tilemap array, and drawing tiles to the display canvas, emphasizing the correlation between tile map values and the images on the screen, as well as providing insights into the changes made in the code since part three, including minor adjustments in the display file and significant additions in the game file to implement pixel-perfect, tile-based collision detection and response.', 'duration': 668.974, 'highlights': ['The chapter explains the process of loading a sprite sheet image into JavaScript and creating a tilemap array, emphasizing the correlation between tile map values and the images on the screen, with an example of values corresponding to locations inside the tile sheet graphic and the map, providing a clear understanding of the connection between these values and the visual representation on the map.', 'The chapter provides insights into the changes made in the code since part three, including minor adjustments in the display file and significant additions in the game file to implement pixel-perfect, tile-based collision detection and response, involving the addition of the Collider function, collision map, and the Collider class for broad phase collision detection and response as well as the routing function and narrow phase collision methods.', 'The chapter also discusses the drawMap function inside the display class, which loops through every single value in the map, subtracting one from it to ensure the appropriate position to cut out of the tile sheet image and draw it into the buffer, ultimately illustrating how to draw all the tiles to the game screen and encouraging the audience to build these basic components into their own application.']}, {'end': 4604.911, 'start': 4035.502, 'title': 'Tile-based collision detection', 'summary': "Discusses the implementation of tile-based collision detection and response, covering broad phase, routing function, and narrow phase, with a focus on collision map values, broad phase collision method, and routing function's switch statement for different collision types.", 'duration': 569.409, 'highlights': ['The routing function determines which narrow phase functions to call based on the value of the collision tile, enabling adjustments like changing the height of collision tiles for specific cases.', 'The broad phase function checks for collision with boundaries of the world and different corners of the player character, and converts physical XY positions to one-dimensional index of row and column values in the collision map.', 'The chapter introduces the components of tile-based collision detection and response, including broad phase, routing function, and narrow phase, all centered around a collision map containing various collision tile values.']}, {'end': 4850.022, 'start': 4606.758, 'title': 'Tile-based collision system', 'summary': 'Discusses how to manipulate narrow phase functions within a routing function to create various tile types, and explains the collision detection and response process using the example of a 13 tile, with the ability to handle up to 15 combinations for four-sided tiles.', 'duration': 243.264, 'highlights': ['The routing function allows for the creation of various tile types by manipulating narrow phase functions, with the capability to define different shapes and link them to specific tile values.', 'Detailed explanation of collision handling for a 13 tile, including the specific methods called for collision with different sides, and the usage of if statements to manage collision checks.', 'Switching to a switch statement for the tile-based collision system is highlighted as a much faster alternative to using an array and object references.', 'The four functions within the collider classes prototype enable collision detection and response for all types of four-sided tiles, offering up to 15 combinations for handling different tile types.']}, {'end': 5346.847, 'start': 4853.049, 'title': 'Narrow phase collision explanation', 'summary': "Explains the implementation of narrow phase collision detection in a game development project, covering the functionality of detecting collision with the top, left, and right sides of a tile, and the process of keeping track of the player's previous and current positions to ensure smooth collision resolution and prevent glitchy responses.", 'duration': 493.798, 'highlights': ["The function 'collide platform top' checks if the bottom of the player character is greater than the tile top and also verifies if the bottom of the player from the last frame of animation is above the tile top, ensuring smooth collision resolution.", "The concept of subtracting a small value from the bottom of the object in the 'collide platform left' function is explained, demonstrating how it prevents the player character from being stuck inside the tile space and ensures the desired collision resolution.", "The importance of tracking the player's old and current positions to calculate trajectory and improve collision resolution is emphasized, highlighting its role in preventing glitchy responses and enabling smooth animation."]}], 'duration': 2148.955, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA3197892.jpg', 'highlights': ['The four functions within the collider classes prototype enable collision detection and response for all types of four-sided tiles, offering up to 15 combinations for handling different tile types.', 'The chapter provides insights into the changes made in the code since part three, including minor adjustments in the display file and significant additions in the game file to implement pixel-perfect, tile-based collision detection and response, involving the addition of the Collider function, collision map, and the Collider class for broad phase collision detection and response as well as the routing function and narrow phase collision methods.', 'The routing function allows for the creation of various tile types by manipulating narrow phase functions, with the capability to define different shapes and link them to specific tile values.', "The function 'collide platform top' checks if the bottom of the player character is greater than the tile top and also verifies if the bottom of the player from the last frame of animation is above the tile top, ensuring smooth collision resolution.", "The concept of subtracting a small value from the bottom of the object in the 'collide platform left' function is explained, demonstrating how it prevents the player character from being stuck inside the tile space and ensures the desired collision resolution."]}, {'end': 6359.671, 'segs': [{'end': 5405.225, 'src': 'embed', 'start': 5379.294, 'weight': 0, 'content': [{'end': 5383.417, 'text': 'Now I am working with this animated rabbit, and he looks a lot better.', 'start': 5379.294, 'duration': 4.123}, {'end': 5389.221, 'text': "It's starting to look a lot more like a game that you can actually play just minus power ups and items and stuff like that.", 'start': 5383.457, 'duration': 5.764}, {'end': 5396.116, 'text': "So Basically not much has changed other than I've added an animator class that does the sprite animation.", 'start': 5389.301, 'duration': 6.815}, {'end': 5399.119, 'text': "And I've also tweaked his physics for jumping and stuff like that a little bit.", 'start': 5396.336, 'duration': 2.783}, {'end': 5401.501, 'text': "But that's pretty common sense stuff.", 'start': 5399.159, 'duration': 2.342}, {'end': 5405.225, 'text': "Kind of know how to do that if you're already to this point in the tutorial series.", 'start': 5402.182, 'duration': 3.043}], 'summary': 'Improved animated rabbit for game with sprite animation and physics tweaks.', 'duration': 25.931, 'max_score': 5379.294, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5379294.jpg'}, {'end': 5448.235, 'src': 'embed', 'start': 5419.879, 'weight': 5, 'content': [{'end': 5424.384, 'text': "take a look at the source code that I've linked in the video description at the top of each file that has changed.", 'start': 5419.879, 'duration': 4.505}, {'end': 5428.188, 'text': "And for part five, it's just these three, the game, the display, and the main files.", 'start': 5424.424, 'duration': 3.764}, {'end': 5430.671, 'text': 'For each file that has changes in it,', 'start': 5428.629, 'duration': 2.042}, {'end': 5437.56, 'text': "I've added a bulleted list in the comments at the top of each file that outlines what exactly has changed specifically in the code.", 'start': 5430.671, 'duration': 6.889}, {'end': 5442.387, 'text': "so if you want to find out what's changed, take a look at the source code and take a look at these comments.", 'start': 5437.56, 'duration': 4.827}, {'end': 5448.235, 'text': "but in this video i'm just going to focus on the animator class and how to get this dude animated on the screen.", 'start': 5442.387, 'duration': 5.848}], 'summary': 'Video explains changes in 3 files and focuses on animating the character.', 'duration': 28.356, 'max_score': 5419.879, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5419879.jpg'}, {'end': 5482.917, 'src': 'embed', 'start': 5455.102, 'weight': 1, 'content': [{'end': 5457.603, 'text': 'So this here is my sprite sheet image.', 'start': 5455.102, 'duration': 2.501}, {'end': 5461.746, 'text': "It's a PNG, has all my tile graphics in it, has my sprite images in it.", 'start': 5457.643, 'duration': 4.103}, {'end': 5469.19, 'text': 'Now each sprite animation is just a compilation of these different unique images.', 'start': 5462.126, 'duration': 7.064}, {'end': 5478.616, 'text': 'So each image can be considered just a square that you would cut out of this bigger image and then put on the screen in quick succession to give yourself an animation.', 'start': 5469.691, 'duration': 8.925}, {'end': 5482.917, 'text': "so, for instance, right now my player character isn't doing anything, he's just sitting still.", 'start': 5478.616, 'duration': 4.301}], 'summary': 'Sprite sheet contains png tile and sprite graphics for animations.', 'duration': 27.815, 'max_score': 5455.102, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5455102.jpg'}, {'end': 5731.612, 'src': 'embed', 'start': 5702.313, 'weight': 4, 'content': [{'end': 5706.476, 'text': "Now we're actually going to have to define what those animations are.", 'start': 5702.313, 'duration': 4.163}, {'end': 5711.04, 'text': "The animation itself is going to be defined by the object that's using it.", 'start': 5706.716, 'duration': 4.324}, {'end': 5717.425, 'text': 'The animation for this rabbit or for the player is going to live inside of the player class.', 'start': 5711.48, 'duration': 5.945}, {'end': 5718.866, 'text': 'Every unique animation.', 'start': 5717.685, 'duration': 1.181}, {'end': 5724.171, 'text': 'the idle frames, the walking left and right frames, the jump frames.', 'start': 5718.866, 'duration': 5.305}, {'end': 5731.612, 'text': 'Those are all gonna be stored inside of the player class, inside of its prototype.', 'start': 5725.424, 'duration': 6.188}], 'summary': 'Defining unique animations for player class with idle, walking, and jump frames.', 'duration': 29.299, 'max_score': 5702.313, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5702313.jpg'}, {'end': 5848.388, 'src': 'embed', 'start': 5820.154, 'weight': 2, 'content': [{'end': 5822.335, 'text': 'frame rate dependent animation class.', 'start': 5820.154, 'duration': 2.181}, {'end': 5831.541, 'text': 'so what that means is the rate of frames that you see for each animation is going to be totally dependent on the game engines frame rate.', 'start': 5822.335, 'duration': 9.206}, {'end': 5834.523, 'text': "so if you don't want that kind of functionality, this probably isn't for you.", 'start': 5831.541, 'duration': 2.982}, {'end': 5840.807, 'text': "but if you're just going to run your game consistently at 30 frames per second across all devices, this is probably what you want to do,", 'start': 5834.523, 'duration': 6.284}, {'end': 5843.189, 'text': "and for html5 games that's a pretty good bet.", 'start': 5840.807, 'duration': 2.382}, {'end': 5845.45, 'text': 'so this will probably work for you.', 'start': 5843.189, 'duration': 2.261}, {'end': 5848.388, 'text': 'so I define a couple different values in here.', 'start': 5845.45, 'duration': 2.938}], 'summary': 'Frame rate dependent animation class for consistent 30 fps across devices.', 'duration': 28.234, 'max_score': 5820.154, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5820154.jpg'}, {'end': 5919.836, 'src': 'embed', 'start': 5887.252, 'weight': 6, 'content': [{'end': 5892.676, 'text': 'Those values, of course, correspond to our different frames that we use to cut the animation image out of the sprite sheet.', 'start': 5887.252, 'duration': 5.424}, {'end': 5899.882, 'text': 'Frame index is just going to be where we are or where the playhead is, so to speak, inside of that frame set array.', 'start': 5893.477, 'duration': 6.405}, {'end': 5906.887, 'text': "frame value is going to be the value of whatever index we're in inside of our frame set.", 'start': 5900.763, 'duration': 6.124}, {'end': 5910.73, 'text': 'So for idle left, remember that was value zero, the value was zero.', 'start': 5906.927, 'duration': 3.803}, {'end': 5919.836, 'text': 'So for that particular animation, it would be at index zero inside of the frame set and the value would also be zero for the idle left image.', 'start': 5911.43, 'duration': 8.406}], 'summary': 'Explanation of frame index and value in animation image sprite sheet.', 'duration': 32.584, 'max_score': 5887.252, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5887252.jpg'}, {'end': 5966.012, 'src': 'embed', 'start': 5936.947, 'weight': 7, 'content': [{'end': 5939.149, 'text': "Pretty simply, I'm going to just explain that as we go.", 'start': 5936.947, 'duration': 2.202}, {'end': 5941.931, 'text': "I'm going to come down to the loop function.", 'start': 5939.169, 'duration': 2.762}, {'end': 5943.852, 'text': 'All it does is.', 'start': 5943.252, 'duration': 0.6}, {'end': 5951.02, 'text': 'it just changes the playhead position every so many frames that pass in our game loop.', 'start': 5945.956, 'duration': 5.064}, {'end': 5958.566, 'text': 'So count is gonna increase one time on every cycle of our game loop until it reaches the delay that we specify.', 'start': 5951.06, 'duration': 7.506}, {'end': 5966.012, 'text': "So for the walking left and right animations, I've defined a delay of five inside of the player class.", 'start': 5958.646, 'duration': 7.366}], 'summary': 'The loop function changes playhead position every few frames, with a delay of five for walking animations in the player class.', 'duration': 29.065, 'max_score': 5936.947, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5936947.jpg'}, {'end': 6140.41, 'src': 'embed', 'start': 6110.54, 'weight': 8, 'content': [{'end': 6113.541, 'text': 'the change frame set function inside of the animator class.', 'start': 6110.54, 'duration': 3.001}, {'end': 6117.742, 'text': "And basically what this does is it just changes what frame set we're using.", 'start': 6114.141, 'duration': 3.601}, {'end': 6122.144, 'text': "So whenever I press left, On the keyboard, I'm going to call change frame set.", 'start': 6117.782, 'duration': 4.362}, {'end': 6125.505, 'text': "It's just going to change the frame set to the left animation,", 'start': 6122.164, 'duration': 3.341}, {'end': 6129.986, 'text': 'which is that array inside of the player class that defines which frames to use for the left animation.', 'start': 6125.505, 'duration': 4.481}, {'end': 6133.928, 'text': "When I press right, it's going to call change frame set.", 'start': 6131.487, 'duration': 2.441}, {'end': 6137.429, 'text': "I'm going to hand in the player's right movement animation.", 'start': 6133.948, 'duration': 3.481}, {'end': 6140.41, 'text': "If I jump to the left, I'm going to call change frame set.", 'start': 6137.869, 'duration': 2.541}], 'summary': 'The change frame set function in the animator class switches frame sets based on player movement.', 'duration': 29.87, 'max_score': 6110.54, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6110540.jpg'}, {'end': 6198.331, 'src': 'embed', 'start': 6169.767, 'weight': 9, 'content': [{'end': 6173.528, 'text': 'Basically, this is just called on every frame, and it just calls the corresponding method.', 'start': 6169.767, 'duration': 3.761}, {'end': 6174.789, 'text': "It's pretty simple.", 'start': 6174.128, 'duration': 0.661}, {'end': 6182.844, 'text': "So now that we know how we're animating our frames, let's actually take a look at the render function, which lives inside of the main file.", 'start': 6175.72, 'duration': 7.124}, {'end': 6189.767, 'text': "And we're gonna take a look at how we actually use that frame information to cut our image out of the sprite sheet itself.", 'start': 6183.304, 'duration': 6.463}, {'end': 6192.629, 'text': 'So the first thing we do.', 'start': 6190.708, 'duration': 1.921}, {'end': 6198.331, 'text': "we're actually gonna have to jump to another section of the code real quick, because I'm using an assets manager to load my tile set image.", 'start': 6192.629, 'duration': 5.702}], 'summary': 'Code calls method on each frame, renders and cuts image from sprite sheet.', 'duration': 28.564, 'max_score': 6169.767, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6169767.jpg'}], 'start': 5347.987, 'title': 'Sprite animation basics', 'summary': 'Explains the basics of sprite animation, including sprite sheet workings, character animation process, and classes involved, featuring an animated rabbit, source code changes, and frame rate-dependent animation class with focus on frame index, value, and set.', 'chapters': [{'end': 5437.56, 'start': 5347.987, 'title': 'Adding sprite animation to game', 'summary': 'Discusses adding sprite animation to the game, featuring the use of an animator class and an animated rabbit, with minor tweaks in physics, and providing source code changes.', 'duration': 89.573, 'highlights': ["The addition of an animator class for sprite animation and an animated rabbit improves the game's visual appeal.", "Minor tweaks in physics for jumping and other movements have been made to improve the game's dynamics.", 'Source code changes are available for reference, with specific outlines of the modifications in the game, display, and main files.']}, {'end': 5796.807, 'start': 5437.56, 'title': 'Sprite animation basics', 'summary': 'Explains the basics of sprite animation, including how sprite sheets work, the process of animating a character using different images from the sprite sheet, and the classes and objects involved in defining and using animations.', 'duration': 359.247, 'highlights': ['The process of animating a character using different images from the sprite sheet', 'The classes and objects involved in defining and using animations', 'How sprite sheets work']}, {'end': 6359.671, 'start': 5797.267, 'title': 'Animator class and frame animation', 'summary': 'Discusses the animator class, a frame rate-dependent animation class used for animating sprite sheet images, with a focus on how the frame index, frame value, and frame set are utilized to loop through the animation and how the render function is used to cut images out of the sprite sheet.', 'duration': 562.404, 'highlights': ["The animator class is frame rate dependent, with the rate of frames for each animation being totally dependent on the game engine's frame rate.", 'The frame set consists of different frame sets or animation arrays that are defined inside the player, and the frame index indicates the position inside the frame set array.', 'The loop function changes the playhead position every specified number of frames and uses the delay to control the animation cycle.', 'The change frame set function in the animator class is used to switch between different frame sets for animations based on user input, such as pressing left or right on the keyboard.', 'The render function, located in the main file, is responsible for using the frame information to cut the image out of the sprite sheet.']}], 'duration': 1011.684, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA5347987.jpg', 'highlights': ["The addition of an animator class for sprite animation and an animated rabbit improves the game's visual appeal.", 'The process of animating a character using different images from the sprite sheet', "The animator class is frame rate dependent, with the rate of frames for each animation being totally dependent on the game engine's frame rate.", "Minor tweaks in physics for jumping and other movements have been made to improve the game's dynamics.", 'The classes and objects involved in defining and using animations', 'Source code changes are available for reference, with specific outlines of the modifications in the game, display, and main files.', 'The frame set consists of different frame sets or animation arrays that are defined inside the player, and the frame index indicates the position inside the frame set array.', 'The loop function changes the playhead position every specified number of frames and uses the delay to control the animation cycle.', 'The change frame set function in the animator class is used to switch between different frame sets for animations based on user input, such as pressing left or right on the keyboard.', 'The render function, located in the main file, is responsible for using the frame information to cut the image out of the sprite sheet.']}, {'end': 7533.651, 'segs': [{'end': 6381.682, 'src': 'embed', 'start': 6361.272, 'weight': 1, 'content': [{'end': 6376.82, 'text': 'this code basically what it does is it just repositions the frame a little bit to center it on the players position so we can more easily move him around the screen without that pixel perfect collision that makes his hitbox seem a lot larger than it needs to be.', 'start': 6361.272, 'duration': 15.548}, {'end': 6381.682, 'text': 'so all this does it gets his exposition, it adds the center,', 'start': 6376.82, 'duration': 4.862}], 'summary': 'Code repositions frame to center on player, improving movement and hitbox accuracy.', 'duration': 20.41, 'max_score': 6361.272, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6361272.jpg'}, {'end': 6461.257, 'src': 'embed', 'start': 6428.162, 'weight': 2, 'content': [{'end': 6429.623, 'text': 'And that does not look quite right.', 'start': 6428.162, 'duration': 1.461}, {'end': 6431.944, 'text': "So that's why I have that offset position.", 'start': 6429.663, 'duration': 2.281}, {'end': 6439.126, 'text': 'All it does is add a slight offset when I draw the frame to the screen to make him appear in the appropriate location.', 'start': 6432.024, 'duration': 7.102}, {'end': 6440.625, 'text': "So that's it.", 'start': 6440.185, 'duration': 0.44}, {'end': 6441.546, 'text': "That's all that does.", 'start': 6440.665, 'duration': 0.881}, {'end': 6442.746, 'text': "You don't need this stuff.", 'start': 6441.686, 'duration': 1.06}, {'end': 6446.208, 'text': "Like I said, I'm using a frame-based approach.", 'start': 6442.967, 'duration': 3.241}, {'end': 6452.832, 'text': 'You could easily use a tile-based approach, where you have all your graphics inside of one big grid, kind of like the tiles are,', 'start': 6446.228, 'duration': 6.604}, {'end': 6456.194, 'text': 'instead of having them all close together and cutting them out specifically.', 'start': 6452.832, 'duration': 3.362}, {'end': 6461.257, 'text': "The reason I do this is because if I were to add, let's say my rabbit has a sword.", 'start': 6456.614, 'duration': 4.643}], 'summary': 'Using an offset position when drawing frames to the screen for a frame-based approach, instead of a tile-based approach.', 'duration': 33.095, 'max_score': 6428.162, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6428162.jpg'}, {'end': 6767.878, 'src': 'embed', 'start': 6742.183, 'weight': 0, 'content': [{'end': 6748.128, 'text': 'So basically, the update animation function is fired on every frame after you do collision detection with the player in the world.', 'start': 6742.183, 'duration': 5.945}, {'end': 6751.611, 'text': "And it just determines what way he's moving.", 'start': 6748.768, 'duration': 2.843}, {'end': 6754.513, 'text': "And depending on what direction he's moving, it runs a certain animation.", 'start': 6751.871, 'duration': 2.642}, {'end': 6757.17, 'text': 'now. this is actually really important.', 'start': 6755.669, 'duration': 1.501}, {'end': 6763.935, 'text': "it's more important than you think, not necessarily for the player, because you can have fine control over the player,", 'start': 6757.17, 'duration': 6.765}, {'end': 6767.878, 'text': 'but for non-player characters who move on their own.', 'start': 6763.935, 'duration': 3.943}], 'summary': "The update animation function is crucial for non-player characters' movement.", 'duration': 25.695, 'max_score': 6742.183, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6742183.jpg'}, {'end': 6888.009, 'src': 'embed', 'start': 6856.988, 'weight': 3, 'content': [{'end': 6862.272, 'text': "So, in order to show you guys better what's actually happening, first I'm going to explain what tunneling is,", 'start': 6856.988, 'duration': 5.284}, {'end': 6865.934, 'text': "just using my mouse pointer as an example, and then I'm going to show you in slow motion.", 'start': 6862.272, 'duration': 3.662}, {'end': 6867.375, 'text': 'when I slow this game down,', 'start': 6865.934, 'duration': 1.441}, {'end': 6872.819, 'text': "I'm going to show you what's actually happening with the player and why tunneling is happening in this particular instance.", 'start': 6867.375, 'duration': 5.444}, {'end': 6880.284, 'text': 'So tunneling is when the object moves too far in one frame to actually collide with a collision shape.', 'start': 6873.579, 'duration': 6.705}, {'end': 6888.009, 'text': "So let's say that this tile is going to be my collision shape and the mouse pointer is going to be my object.", 'start': 6880.344, 'duration': 7.665}], 'summary': 'Tunneling occurs when an object moves too far in one frame to collide with a collision shape.', 'duration': 31.021, 'max_score': 6856.988, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6856988.jpg'}, {'end': 7544.234, 'src': 'embed', 'start': 7516.109, 'weight': 4, 'content': [{'end': 7518.17, 'text': "Jump really far, really fast, because there's no friction.", 'start': 7516.109, 'duration': 2.061}, {'end': 7522.2, 'text': "So I don't want that, but that's basically how you fix tunneling.", 'start': 7519.858, 'duration': 2.342}, {'end': 7528.946, 'text': 'You just basically have to clamp your velocity to a certain speed and to get the jump height that you want.', 'start': 7522.22, 'duration': 6.726}, {'end': 7533.651, 'text': "you just mess with friction and gravity and that's going to do it for tunneling.", 'start': 7528.946, 'duration': 4.705}, {'end': 7541.532, 'text': "I'm going to show you how to create level data files using JSON, how to load level data and use it to populate the game world and, finally,", 'start': 7535.006, 'duration': 6.526}, {'end': 7544.234, 'text': 'how to trigger subsequent level loads by colliding with doors.', 'start': 7541.532, 'duration': 2.702}], 'summary': 'Tunneling fix: clamp velocity, adjust friction and gravity. also covers creating and using json level data files.', 'duration': 28.125, 'max_score': 7516.109, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA7516109.jpg'}], 'start': 6361.272, 'title': 'Frame adjustment and animation update', 'summary': 'Covers repositioning frames, utilizing offsets for appearance adjustment, update animation function, and addressing tunneling in tile-based physics for collision detection, with examples.', 'chapters': [{'end': 6487.378, 'start': 6361.272, 'title': 'Frame repositioning and offset exposition', 'summary': "Explains the process of repositioning the frame to center it on the player's position, utilizing offsets to adjust the appearance on the screen and emphasizing the flexibility of this approach in accommodating varying sprite sizes and animations.", 'duration': 126.106, 'highlights': ["Repositioning the frame to center it on the player's position", 'Utilizing offset exposition for adjusting frame appearance', 'Flexibility in accommodating varying sprite sizes and animations']}, {'end': 6800.25, 'start': 6489.952, 'title': 'Animation update function', 'summary': "Explains the update animation function in the player class, which determines the player's animation based on direction and velocity, allowing for gradual stopping and automation of animation for non-player characters.", 'duration': 310.298, 'highlights': ["The update animation function in the player class determines the player's animation based on direction and velocity, allowing for gradual stopping (velocity less than -0.1 pixels) and automation of animation for non-player characters.", 'This function is fired on every frame after collision detection and is crucial for non-player characters, as it automates the process of setting the animation based on movement direction and velocity.']}, {'end': 7533.651, 'start': 6802.11, 'title': 'Addressing tunneling in tile based physics', 'summary': 'Discusses the issue of tunneling in tile-based physics engines, explaining its occurrence, its impact on collision detection, and proposing a solution through clamping velocity and adjusting gravity and friction to prevent tunneling, demonstrated with examples.', 'duration': 731.541, 'highlights': ['Tunneling occurs when an object moves too far in one frame to collide with a collision shape, with the example illustrating that moving more than one tile space or 16 pixels in one frame leads to tunneling.', "Demonstrates the impact of tunneling through slow-motion visualization, showcasing how the player character's movement causes tunneling by exceeding the collision boundaries, with the solution involving clamping the movement velocity to prevent tunneling.", 'Explains the solution to prevent tunneling by clamping the movement velocity to avoid exceeding one tile space and adjusting gravity and friction to achieve the desired jump height, with a comparison between the impact of different velocities and smoothness of movement.']}], 'duration': 1172.379, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA6361272.jpg', 'highlights': ['The update animation function automates animation for non-player characters', "Repositioning the frame to center it on the player's position", 'Utilizing offset for adjusting frame appearance', 'Demonstrates the impact of tunneling through slow-motion visualization', 'Clamping movement velocity to prevent tunneling']}, {'end': 8401.226, 'segs': [{'end': 7564.689, 'src': 'embed', 'start': 7535.006, 'weight': 0, 'content': [{'end': 7541.532, 'text': "I'm going to show you how to create level data files using JSON, how to load level data and use it to populate the game world and, finally,", 'start': 7535.006, 'duration': 6.526}, {'end': 7544.234, 'text': 'how to trigger subsequent level loads by colliding with doors.', 'start': 7541.532, 'duration': 2.702}, {'end': 7549.579, 'text': "Let's take a look at what has changed since part five and part five and a half.", 'start': 7545.255, 'duration': 4.324}, {'end': 7553.042, 'text': 'So this is part six and everything is basically the same.', 'start': 7550.26, 'duration': 2.782}, {'end': 7558.145, 'text': 'I did make quite a few changes, but most of those changes pertain to loading different levels.', 'start': 7553.922, 'duration': 4.223}, {'end': 7564.689, 'text': "so when I jump up into this area here and walk off the side of the screen, it's actually going to load a different level, as you just saw.", 'start': 7558.145, 'duration': 6.544}], 'summary': 'Tutorial on creating level data files using json and triggering level loads by colliding with doors.', 'duration': 29.683, 'max_score': 7535.006, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA7535006.jpg'}, {'end': 7729.918, 'src': 'embed', 'start': 7699.811, 'weight': 2, 'content': [{'end': 7702.434, 'text': 'So like I said, this is zone 00.', 'start': 7699.811, 'duration': 2.623}, {'end': 7713.277, 'text': "So when I load zone 00, this just tells my world object that it's zone ID 00.", 'start': 7702.434, 'duration': 10.843}, {'end': 7718.644, 'text': "Now let's take a look at zone 2, and we'll just take a look at zone 2's code really quick,", 'start': 7713.277, 'duration': 5.367}, {'end': 7721.988, 'text': 'just so you get it in your head that this is what the format is.', 'start': 7718.644, 'duration': 3.344}, {'end': 7723.93, 'text': "So here's my doors array.", 'start': 7722.769, 'duration': 1.161}, {'end': 7726.013, 'text': 'Zone 2 has two doors.', 'start': 7724.211, 'duration': 1.802}, {'end': 7729.918, 'text': "There's a door right here to go back into zone 0, or actually it's zone 1.", 'start': 7726.033, 'duration': 3.885}], 'summary': 'Zone 00 has 1 door, zone 2 has 2 doors.', 'duration': 30.107, 'max_score': 7699.811, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA7699811.jpg'}, {'end': 7794.252, 'src': 'embed', 'start': 7771.51, 'weight': 1, 'content': [{'end': 7780.78, 'text': "because it's so similar to JavaScript already and you have the built-in JSON.parse method to parse this information into usable JavaScript objects.", 'start': 7771.51, 'duration': 9.27}, {'end': 7784.865, 'text': "So now that you know how to write the level data, let's get on to the next part of the video.", 'start': 7781.201, 'duration': 3.664}, {'end': 7794.252, 'text': 'okay. so now that we know how to define our level data, we need to figure out a way to load it, and the best way to load it is with xml http request.', 'start': 7785.962, 'duration': 8.29}], 'summary': 'Javascript has a built-in json.parse method for parsing information, and the best way to load level data is with xml http request.', 'duration': 22.742, 'max_score': 7771.51, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA7771510.jpg'}, {'end': 8334.718, 'src': 'embed', 'start': 8307.165, 'weight': 3, 'content': [{'end': 8312.63, 'text': 'if i run into a door, the first thing that happens is i stop the engine.', 'start': 8307.165, 'duration': 5.465}, {'end': 8320.559, 'text': 'i then make a request with request json to whatever zone that door brings you to.', 'start': 8312.63, 'duration': 7.929}, {'end': 8326.475, 'text': "so if i come up here into my zone00.json, We're in zone 00..", 'start': 8320.559, 'duration': 5.916}, {'end': 8333.538, 'text': 'The destination zone for this specific door, located at an X of 192,, which is about there, and a Y of 64,, which is about there,', 'start': 8326.475, 'duration': 7.063}, {'end': 8334.718, 'text': 'has a width and height of 16..', 'start': 8333.538, 'duration': 1.18}], 'summary': 'When encountering a door, engine stops, request sent to zone00.json, with destination at x: 192, y: 64, and dimensions 16x16.', 'duration': 27.553, 'max_score': 8307.165, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8307165.jpg'}], 'start': 7535.006, 'title': 'Loading and parsing json data for javascript game', 'summary': 'Covers creating level data files using json, loading level data, using it to populate the game world, and triggering subsequent level loads by colliding with doors. it also discusses the process of loading and parsing json data for a javascript game, including defining the initial level, setting up the level data, and loading levels dynamically when walking into a door.', 'chapters': [{'end': 7749.293, 'start': 7535.006, 'title': 'Creating level data with json', 'summary': 'Covers creating level data files using json, loading level data, using it to populate the game world, and triggering subsequent level loads by colliding with doors. it demonstrates the process of loading different levels, defining doors, and the structure of level files, such as zone 00 and zone 2.', 'duration': 214.287, 'highlights': ['The chapter covers creating level data files using JSON, loading level data, using it to populate the game world, and triggering subsequent level loads by colliding with doors.', 'It demonstrates the process of loading different levels and defining doors.', 'The structure of level files, such as zone 00 and zone 2, is explained, including the doors array, maps information, and level ID.']}, {'end': 8401.226, 'start': 7750.563, 'title': 'Loading and parsing json data for javascript game', 'summary': 'Discusses the process of loading and parsing json data for a javascript game, including using xml http request to load json files, defining the initial level, setting up the level data, and loading levels dynamically when walking into a door.', 'duration': 650.663, 'highlights': ['The process of loading and parsing JSON data for a JavaScript game involves using XML HTTP request to load JSON files, defining the initial level, setting up the level data, and loading levels dynamically when walking into a door.', 'The requestJSON function is used to load the JSON file by creating an XML HTTP request, processing the request, and using JSON.parse method to turn the response text into a JavaScript object.', 'The game.world.setup function is responsible for putting all the information from the zone file into the game.world object, which is used on every frame of animation to perform actions in the game.', 'The process of loading a level on the fly when walking into a door involves stopping the engine, making a request with requestJSON to the destination zone specified by the door, and loading the specified zone when the player collides with the door.']}], 'duration': 866.22, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA7535006.jpg', 'highlights': ['The chapter covers creating level data files using JSON, loading level data, and triggering subsequent level loads by colliding with doors.', 'The process of loading and parsing JSON data for a JavaScript game involves using XML HTTP request to load JSON files and defining the initial level.', 'The structure of level files, such as zone 00 and zone 2, is explained, including the doors array, maps information, and level ID.', 'The process of loading a level on the fly when walking into a door involves stopping the engine, making a request with requestJSON to the destination zone specified by the door, and loading the specified zone when the player collides with the door.']}, {'end': 9770.558, 'segs': [{'end': 8434.124, 'src': 'embed', 'start': 8402.179, 'weight': 0, 'content': [{'end': 8409.821, 'text': "We're just going to call game.world.setup, and it's going to get all the information out of the level file and put it on the screen basically.", 'start': 8402.179, 'duration': 7.642}, {'end': 8418.043, 'text': "So there is one difference this time, however, because now we're going to have to use some information from a specific door.", 'start': 8410.601, 'duration': 7.442}, {'end': 8422.625, 'text': 'So let me go back inside the game.world.setup function real quick.', 'start': 8418.523, 'duration': 4.102}, {'end': 8424.285, 'text': "I'm going to scroll up to it.", 'start': 8422.645, 'duration': 1.64}, {'end': 8434.124, 'text': 'right here, game.world.setup, and we check for the case that we are colliding with the door.', 'start': 8426.314, 'duration': 7.81}], 'summary': 'Using game.world.setup to display level file information and handle door collision.', 'duration': 31.945, 'max_score': 8402.179, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8402179.jpg'}, {'end': 8506.882, 'src': 'embed', 'start': 8469.389, 'weight': 1, 'content': [{'end': 8477.229, 'text': "The only difference is when you walk into a specific door, you reposition the player according to that door's destination X and destination Y.", 'start': 8469.389, 'duration': 7.84}, {'end': 8483.361, 'text': "So stay tuned for the next part where I'm going to talk about the door class specifically, the collision, and all that kind of good stuff.", 'start': 8477.229, 'duration': 6.132}, {'end': 8487.907, 'text': 'Now I wanna take a look at what a door actually is.', 'start': 8484.744, 'duration': 3.163}, {'end': 8493.672, 'text': "So if I zoom in here, I'm gonna look at what a door is inside of my zone00.json file.", 'start': 8488.007, 'duration': 5.665}, {'end': 8497.395, 'text': "I've got an X position and a Y position, a width and a height.", 'start': 8494.232, 'duration': 3.163}, {'end': 8504.161, 'text': 'So basically my door is just a rectangular region on the screen somewhere that the player object can collide with.', 'start': 8497.435, 'duration': 6.726}, {'end': 8506.882, 'text': 'Then I also have a destination zone.', 'start': 8504.841, 'duration': 2.041}], 'summary': 'The door in the game is defined by x, y, width, height, and a destination zone.', 'duration': 37.493, 'max_score': 8469.389, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8469389.jpg'}, {'end': 8558.952, 'src': 'embed', 'start': 8529.719, 'weight': 2, 'content': [{'end': 8530.519, 'text': 'Same thing for X.', 'start': 8529.719, 'duration': 0.8}, {'end': 8534.78, 'text': "If I have a negative 1, the destination X position isn't going to be used.", 'start': 8530.519, 'duration': 4.261}, {'end': 8537.401, 'text': "The player's X position is going to remain the same.", 'start': 8534.8, 'duration': 2.601}, {'end': 8543.322, 'text': 'We can see this functionality over here if I fall into this world.', 'start': 8537.801, 'duration': 5.521}, {'end': 8546.563, 'text': "I'm not being repositioned on the Y axis.", 'start': 8544.102, 'duration': 2.461}, {'end': 8551.645, 'text': "or on the x-axis rather, because I don't need to be.", 'start': 8548.362, 'duration': 3.283}, {'end': 8558.952, 'text': 'I just want to fall right through and naturally have my player end up where he has to be based on where he was in the previous level.', 'start': 8551.865, 'duration': 7.087}], 'summary': "Player's x position remains same, regardless of negative 1 destination x position.", 'duration': 29.233, 'max_score': 8529.719, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8529719.jpg'}, {'end': 8663.647, 'src': 'embed', 'start': 8637.309, 'weight': 3, 'content': [{'end': 8643.774, 'text': "then I'm going to set the destination x, y and zone to whatever those are from the door object that we hand in.", 'start': 8637.309, 'duration': 6.465}, {'end': 8647.877, 'text': "And that's just going to be whatever is defined inside of the zone file.", 'start': 8643.794, 'duration': 4.083}, {'end': 8663.647, 'text': "Then inside of the prototype I have a function called collide object and that's just gonna test to see if the object's center points are inside of the rectangular region of the door.", 'start': 8649.844, 'duration': 13.803}], 'summary': 'Setting destination and zone based on door object parameters, testing object collision.', 'duration': 26.338, 'max_score': 8637.309, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8637309.jpg'}, {'end': 8739.017, 'src': 'embed', 'start': 8710.903, 'weight': 4, 'content': [{'end': 8714.524, 'text': "I'm going to test to see if the door is colliding with the player object.", 'start': 8710.903, 'duration': 3.621}, {'end': 8720.186, 'text': "And if it is, I'm just going to set the world's door property equal to that door.", 'start': 8714.924, 'duration': 5.262}, {'end': 8729.33, 'text': "And then, just like in the last part, we're going to go into the update function for our main game loop, game loop,", 'start': 8720.626, 'duration': 8.704}, {'end': 8735.014, 'text': "and inside of that we're going to have a an if statement that just checks to see is game.world.door defined,", 'start': 8729.33, 'duration': 5.684}, {'end': 8739.017, 'text': "and the only time it's defined is right after we collide with the door.", 'start': 8735.014, 'duration': 4.003}], 'summary': 'Testing door collision with player object, updating game loop.', 'duration': 28.114, 'max_score': 8710.903, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8710903.jpg'}, {'end': 8846.85, 'src': 'embed', 'start': 8818.633, 'weight': 6, 'content': [{'end': 8822.756, 'text': "I'm going to show you how I define the carrot and grass objects in the level data file,", 'start': 8818.633, 'duration': 4.123}, {'end': 8827.28, 'text': 'their respective classes and the basic collision detection used to collide with the carrot objects.', 'start': 8822.756, 'duration': 4.524}, {'end': 8835.226, 'text': "The first thing I'm going to talk about is what this example program is all about and where the carrot and grass objects are defined,", 'start': 8827.964, 'duration': 7.262}, {'end': 8841.608, 'text': 'because since the last installment of this series, I have since added carrot objects and grass objects.', 'start': 8835.226, 'duration': 6.382}, {'end': 8846.85, 'text': "You can see that I'm running into the carrot objects and when I collide with their hitbox I collect a carrot.", 'start': 8841.648, 'duration': 5.202}], 'summary': 'Defining carrot and grass objects, showing collision detection and collecting carrots.', 'duration': 28.217, 'max_score': 8818.633, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8818633.jpg'}, {'end': 8969.374, 'src': 'embed', 'start': 8919.872, 'weight': 7, 'content': [{'end': 8928.701, 'text': "my first grass tile is at x position 2, y position 7, and that's going to be this grass object right here.", 'start': 8919.872, 'duration': 8.829}, {'end': 8929.562, 'text': 'so pretty simple.', 'start': 8928.701, 'duration': 0.861}, {'end': 8934.168, 'text': "so when i load my level up, i'm going to actually have to loop through these arrays here,", 'start': 8929.562, 'duration': 4.606}, {'end': 8941.255, 'text': 'get the x and y tile positions from them and then create an object from that x and y tile position.', 'start': 8934.168, 'duration': 7.087}, {'end': 8944.737, 'text': "And if I am looping through the carrots array, I'll create a carrots object.", 'start': 8941.595, 'duration': 3.142}, {'end': 8947.739, 'text': "If I'm looping through the grass array, I'll create a grass object.", 'start': 8945.218, 'duration': 2.521}, {'end': 8953.243, 'text': "So let's go in and check out the setup function of the game.world object.", 'start': 8947.779, 'duration': 5.464}, {'end': 8956.085, 'text': 'the setup function just runs.', 'start': 8954.244, 'duration': 1.841}, {'end': 8957.867, 'text': 'i come over here and refresh my screen.', 'start': 8956.085, 'duration': 1.782}, {'end': 8961.489, 'text': 'the setup function runs right after the level data is loaded.', 'start': 8957.867, 'duration': 3.622}, {'end': 8969.374, 'text': 'so right after i load this level data and i get access to it with json.parse, i then call the setup function.', 'start': 8961.489, 'duration': 7.885}], 'summary': 'Loop through arrays to create objects from x and y tile positions.', 'duration': 49.502, 'max_score': 8919.872, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8919872.jpg'}, {'end': 9507.891, 'src': 'embed', 'start': 9481.241, 'weight': 8, 'content': [{'end': 9485.703, 'text': 'save, come down here and look at how we actually use these.', 'start': 9481.241, 'duration': 4.462}, {'end': 9491.204, 'text': "so math that cosine and math that sine are what's going to give us that circular motion.", 'start': 9485.703, 'duration': 5.501}, {'end': 9495.806, 'text': 'And we just plug in position x and position y into cosine and sine.', 'start': 9491.824, 'duration': 3.982}, {'end': 9504.709, 'text': "And over here, we have a multiplier of two, that's going to control the distance that the carrot sways on the x axis.", 'start': 9496.446, 'duration': 8.263}, {'end': 9507.891, 'text': 'So if I come over here and refresh to get things back to normal,', 'start': 9505.25, 'duration': 2.641}], 'summary': 'Using cosine and sine for circular motion, with a multiplier of two for x-axis control.', 'duration': 26.65, 'max_score': 9481.241, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA9481241.jpg'}, {'end': 9768.777, 'src': 'heatmap', 'start': 9675.163, 'weight': 1, 'content': [{'end': 9679.326, 'text': "and we start up, we update the player's position,", 'start': 9675.163, 'duration': 4.163}, {'end': 9685.109, 'text': "we collide the player with the game world to get the tile collision going and then we're gonna start colliding with carrots.", 'start': 9679.326, 'duration': 5.783}, {'end': 9693.214, 'text': "So we have a carrots array that's gonna hold all of our carrot objects that we created inside of game.world.setup.", 'start': 9685.349, 'duration': 7.865}, {'end': 9696.075, 'text': "We're gonna loop through all of those carrot objects.", 'start': 9693.574, 'duration': 2.501}, {'end': 9700.658, 'text': 'so just these guys here and we are going to update the carrots position.', 'start': 9696.075, 'duration': 4.583}, {'end': 9707.48, 'text': "we're gonna animate the carrot And then we're going to say is the caret colliding with the player with the cloud object function?", 'start': 9700.658, 'duration': 6.822}, {'end': 9714.802, 'text': "If that function returns, true, we're going to splice that specific caret out of the carets array.", 'start': 9708.26, 'duration': 6.542}, {'end': 9718.823, 'text': "And we're going to just remove it completely.", 'start': 9716.103, 'duration': 2.72}, {'end': 9721.164, 'text': "And we're going to add one to caret count.", 'start': 9719.103, 'duration': 2.061}, {'end': 9722.729, 'text': "It's as simple as that.", 'start': 9721.809, 'duration': 0.92}, {'end': 9725.891, 'text': "We're just going to test for collision between the player and the carrot.", 'start': 9723.23, 'duration': 2.661}, {'end': 9729.253, 'text': "If collision occurs, we're going to just remove the carrot.", 'start': 9726.591, 'duration': 2.662}, {'end': 9730.754, 'text': 'The carrot object is totally gone.', 'start': 9729.313, 'duration': 1.441}, {'end': 9734.555, 'text': 'It will be garbage collected later on, assuming that I removed all references to it.', 'start': 9730.794, 'duration': 3.761}, {'end': 9735.736, 'text': 'I think I have.', 'start': 9735.196, 'duration': 0.54}, {'end': 9741.119, 'text': "Then what's going to happen is I'm going to increase carrot count by one.", 'start': 9736.677, 'duration': 4.442}, {'end': 9748.072, 'text': "And carat count is what we're using to update this P elements inner HTML right here.", 'start': 9742.29, 'duration': 5.782}, {'end': 9751.813, 'text': 'So where does that happen? That happens inside of the main JS file.', 'start': 9748.132, 'duration': 3.681}, {'end': 9755.514, 'text': 'If I come down to the render function, I have a P element.', 'start': 9752.593, 'duration': 2.921}, {'end': 9757.054, 'text': "It's referenced with the P variable.", 'start': 9755.554, 'duration': 1.5}, {'end': 9764.616, 'text': 'And I just set its inner HTML to equal carats plus game.world.carat count on every frame.', 'start': 9757.774, 'duration': 6.842}, {'end': 9765.957, 'text': "And that's it.", 'start': 9765.456, 'duration': 0.501}, {'end': 9767.777, 'text': 'So I hope you guys learned something.', 'start': 9766.677, 'duration': 1.1}, {'end': 9768.777, 'text': 'I hope you enjoyed the video.', 'start': 9767.797, 'duration': 0.98}], 'summary': 'Updating player position, colliding with game world, and animating carrots for collision detection with player.', 'duration': 93.614, 'max_score': 9675.163, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA9675163.jpg'}], 'start': 8402.179, 'title': 'Game development', 'summary': 'Covers game development topics such as setting up door positions and destinations, defining door objects, loading levels, level data objects, collision detection, and the creation and functionality of grass and carrot objects in game development.', 'chapters': [{'end': 8587.11, 'start': 8402.179, 'title': 'Game door positioning', 'summary': 'Explains the process of setting up door positions and destinations for player repositioning in a game using a specific door, with details on the door class and collision code.', 'duration': 184.931, 'highlights': ["The game.world.setup function retrieves information from the level file and displays it on the screen, involving repositioning the player based on the specific door's destination X and Y values, simplifying the process of loading a new level.", "The door class in the zone00.json file contains information about the door's position, dimensions, and destination zone, as well as the destination X and Y for the player, providing a clear understanding of the door's functionality.", "Use of negative 1 for destination X or Y indicates that the player's position remains unchanged in that specific axis when transitioning through the door, ensuring seamless continuity in the player's movement between different levels."]}, {'end': 8817.292, 'start': 8587.17, 'title': 'Defining door objects and loading levels', 'summary': 'Outlines the process of defining door objects and loading levels in a game, including the use of the collide object function, the role of the world update function, and the setup function for setting player coordinates, with specific emphasis on the use of prototype and inheritance.', 'duration': 230.122, 'highlights': ["The collide object function tests if the object's center points are inside the rectangular region of the door, determining collisions with doors.", "The world update function loops through and tests for collisions with each door in the world, setting the world's door property if a collision is detected.", "The setup function checks if a door is defined and sets the player's coordinates based on the door object, facilitating level loading and player positioning.", 'Defining door objects involves inheritance from the object class, with specific functions for determining the sides of a rectangle, contributing to efficient collision detection.', 'The destination x position for certain doors is set to negative one, ensuring specific player character positioning for seamless level transitions.']}, {'end': 9090.811, 'start': 8818.633, 'title': 'Level data objects and collision detection', 'summary': 'Discusses defining carrot and grass objects in the level data file, their collision detection, and the setup function for creating game objects, using arrays to define x and y tile positions, and setting up game graphics.', 'duration': 272.178, 'highlights': ['The chapter discusses defining carrot and grass objects in the level data file.', 'The setup function is used to create game objects and set up graphics and collision map for the level.', 'Using arrays to define X and Y tile positions for creating game objects.']}, {'end': 9770.558, 'start': 9092.432, 'title': 'Grass and carrot objects in game development', 'summary': 'Discusses the creation and functionality of grass and carrot objects, including their animation, position, collision detection, and removal upon collision with the player object, as well as the impact of parameters on their movement and animation.', 'duration': 678.126, 'highlights': ['The creation and functionality of grass and carrot objects', 'Inheritance and attributes of the grass and carrot classes', 'Impact of randomization on carrot movement', 'Utilization of cosine and sine functions for circular motion', 'Collision detection and removal of collided carrot objects']}], 'duration': 1368.379, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/w-OKdSHRlfA/pics/w-OKdSHRlfA8402179.jpg', 'highlights': ["The game.world.setup function simplifies loading a new level by repositioning the player based on door's destination.", "The door class in zone00.json provides clear information about the door's position, dimensions, and destination.", "Use of negative 1 for destination X or Y ensures seamless continuity in player's movement between levels.", "The collide object function tests if the object's center points are inside the rectangular region of the door.", "The world update function sets the world's door property if a collision with a door is detected.", 'Defining door objects involves inheritance from the object class, contributing to efficient collision detection.', 'The chapter discusses defining carrot and grass objects in the level data file.', 'The setup function is used to create game objects and set up graphics and collision map for the level.', 'Utilization of cosine and sine functions for circular motion in grass and carrot objects.', 'Using arrays to define X and Y tile positions for creating game objects.']}], 'highlights': ['The series focuses on programming a tile-based platforming game called Rabbit Trap, including features like tile-based collision detection, scrolling maps, loading levels, sprite animation, and interactive game objects.', 'The game engine uses a fixed time step of 33.33 milliseconds to update and render the game, maintaining consistent performance across devices.', 'The chapter covers creating level data files using JSON, loading level data, and triggering subsequent level loads by colliding with doors.', 'Each component (game logic, display logic, and controller logic) is stored in separate classes and handles its own business, ensuring there are no issues with cross-referencing.', 'The four functions within the collider classes prototype enable collision detection and response for all types of four-sided tiles, offering up to 15 combinations for handling different tile types.']}