title
JavaScript Game Development Course for Beginners
description
Learn to make 2D games with HTML, CSS & plain vanilla JavaScript, no frameworks and no libraries! From sprite animation to state management, in this series of projects you will learn everything you need to make your own 2D animated games! We will go step by step explaining each technique on a small standalone codebase and then we will use everything we learned to make a single final game.
✏️ Course by Frank's Laboratory. https://www.youtube.com/c/Frankslaboratory
⭐️ Assets ⭐️
🕹 Project 1: Vanilla JavaScript sprite animation techniques
http://frankslaboratory.co.uk/downloads/shadow_dog.png
🕹 Project 2: Parallax backgrounds with JavaScript
Layers Zip: https://frankslaboratory.co.uk/downloads/backgroundLayers.zip
🕹 Project 3: Enemy movement patterns
Enemies Zip: https://frankslaboratory.co.uk/downloads/enemies.zip
🕹 Project 4: Collision animations from a sprite sheet
http://frankslaboratory.co.uk/downloads/boom.png
🕹 Project 5: Point & shoot game
raven: http://frankslaboratory.co.uk/downloads/raven.png
dust cloud: http://frankslaboratory.co.uk/downloads/boom.png
🕹 Project 6: Enemy variety in JavaScript games
worm: https://frankslaboratory.co.uk/downloads/enemy_worm.png
ghost: https://frankslaboratory.co.uk/downloads/enemy_ghost.png
spider: https://frankslaboratory.co.uk/downloads/enemy_spider.png
🕹 Project 7: Side-scroller game with mobile support
Player: http://frankslaboratory.co.uk/downloads/93/player.png
Background: http://frankslaboratory.co.uk/downloads/93/background_single.png
Enemy: http://frankslaboratory.co.uk/downloads/93/enemy_1.png
🕹 Project 8: State management in JavaScript games
http://frankslaboratory.co.uk/downloads/dog_left_right_white.png
🕹 Project 9: Final endless runner game with all the features
Player: http://frankslaboratory.co.uk/downloads/97/player.png
🕹 City background layers:
Layer 1: https://www.frankslaboratory.co.uk/downloads/97/layer-1.png
Layer 2: https://www.frankslaboratory.co.uk/downloads/97/layer-2.png
Layer 3: https://www.frankslaboratory.co.uk/downloads/97/layer-3.png
Layer 4: https://www.frankslaboratory.co.uk/downloads/97/layer-4.png
Layer 5: https://www.frankslaboratory.co.uk/downloads/97/layer-5.png
🕹 Fire texture:
https://www.frankslaboratory.co.uk/downloads/97/fire.png
🕹 Collision animation:
https://www.frankslaboratory.co.uk/downloads/97/boom.png
🕹 Lives:
https://www.frankslaboratory.co.uk/downloads/97/lives.png
https://www.frankslaboratory.co.uk/downloads/97/heart.png
🕹 Forest background layers:
Layer 1: https://www.frankslaboratory.co.uk/downloads/97/forest/layer-1.png
Layer 2: https://www.frankslaboratory.co.uk/downloads/97/forest/layer-2.png
Layer 3: https://www.frankslaboratory.co.uk/downloads/97/forest/layer-3.png
Layer 4: https://www.frankslaboratory.co.uk/downloads/97/forest/layer-4.png
Layer 5: https://www.frankslaboratory.co.uk/downloads/97/forest/layer-5.png
🕹 18 Enemies:
Big spider: https://www.frankslaboratory.co.uk/downloads/97/enemy_spider_big.png
Bat 1: https://www.frankslaboratory.co.uk/downloads/97/enemy_bat_1.png
Spinner: https://www.frankslaboratory.co.uk/downloads/97/enemy_spinner.png
Small spider: https://www.frankslaboratory.co.uk/downloads/97/enemy_spider.png
Ghost 1: https://www.frankslaboratory.co.uk/downloads/97/enemy_ghost_1.png
Bat 2: https://www.frankslaboratory.co.uk/downloads/97/enemy_bat_2.png
Raven: https://www.frankslaboratory.co.uk/downloads/97/enemy_raven.png
Bat 3: https://www.frankslaboratory.co.uk/downloads/97/enemy_bat_3.png
Ghost 2: https://www.frankslaboratory.co.uk/downloads/97/enemy_ghost_2.png
Fly: https://www.frankslaboratory.co.uk/downloads/97/enemy_fly.png
Ghost 3: https://www.frankslaboratory.co.uk/downloads/97/enemy_ghost_3.png
Ghost 4: https://www.frankslaboratory.co.uk/downloads/97/enemy_ghost_4.png
Hand: https://www.frankslaboratory.co.uk/downloads/97/enemy_hand.png
Plant: https://www.frankslaboratory.co.uk/downloads/97/enemy_plant.png
Worm: https://www.frankslaboratory.co.uk/downloads/97/enemy_worm.png
Walking zombie: https://www.frankslaboratory.co.uk/downloads/97/enemy_zombie.png
Ground zombie: https://www.frankslaboratory.co.uk/downloads/97/enemy_ground_zombie.png
Digger: https://www.frankslaboratory.co.uk/downloads/97/enemy_digger.png
🔗 More art assets: https://bevouliin.com/
⭐️ Contents ⭐️
0:00:00 Intro
0:01:28 Project 1: Vanilla JavaScript sprite animation techniques
0:43:07 Project 2: Parallax backgrounds
1:25:33 Project 3: Enemy movement patterns
2:13:31 Collision detection between rectangles
2:19:23 Collision detection between circles
2:24:14 Project 4: Collision animations from a sprite sheet
2:48:35 Project 5: Point & shoot game
3:50:44 Project 6: Enemy variety
4:45:49 Project 7: Side-scroller game with mobile support
5:54:04 Project 8: State management
7:02:57 Project 9: Final endless runner game with all the features
detail
{'title': 'JavaScript Game Development Course for Beginners', 'heatmap': [{'end': 2775.641, 'start': 2077.12, 'weight': 0.867}], 'summary': 'This javascript game development course covers creating nine game projects using html, css, and javascript, focusing on sprite animation, parallax backgrounds, enemy types, player states, collision detection, and particle effects, providing techniques for intermediate learners to achieve improved animation performance and game mechanics.', 'chapters': [{'end': 91.016, 'segs': [{'end': 24.986, 'src': 'embed', 'start': 0.029, 'weight': 0, 'content': [{'end': 5.112, 'text': 'In this complete game development course, you will learn how to develop a variety of games using JavaScript.', 'start': 0.029, 'duration': 5.083}, {'end': 9.375, 'text': "Frank's courses are top notch and he has a really creative way of presenting things.", 'start': 5.353, 'duration': 4.022}, {'end': 11.397, 'text': 'You are going to love this course.', 'start': 9.956, 'duration': 1.441}, {'end': 12.357, 'text': 'Hi coders.', 'start': 11.877, 'duration': 0.48}, {'end': 18.942, 'text': 'In this class, we will use HTML, CSS, and JavaScript to build nine separate game development projects.', 'start': 12.597, 'duration': 6.345}, {'end': 24.986, 'text': 'I will write and explain all the code from scratch, line by line, using just plain vanilla JavaScript.', 'start': 19.202, 'duration': 5.784}], 'summary': 'Learn game development using javascript with 9 projects in this top-notch course.', 'duration': 24.957, 'max_score': 0.029, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29.jpg'}, {'end': 82.926, 'src': 'embed', 'start': 57.146, 'weight': 1, 'content': [{'end': 61.93, 'text': 'We will write JavaScript code that handles seamless, endlessly scrolling parallax backgrounds.', 'start': 57.146, 'duration': 4.784}, {'end': 68.935, 'text': 'We will learn how to extend JavaScript classes to create a variety of enemy types with different visuals and different behaviors.', 'start': 62.07, 'duration': 6.865}, {'end': 74.259, 'text': 'I will show you how to implement state design pattern to manage player states and special abilities.', 'start': 69.115, 'duration': 5.144}, {'end': 79.903, 'text': 'We will learn how to use collision detection by color, collision between circles and between rectangles.', 'start': 74.519, 'duration': 5.384}, {'end': 82.926, 'text': 'We will add different particle effects and many other things.', 'start': 80.164, 'duration': 2.762}], 'summary': 'Learn to create seamless parallax backgrounds, various enemy types, implement state design pattern, collision detection, and particle effects in javascript.', 'duration': 25.78, 'max_score': 57.146, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c57146.jpg'}], 'start': 0.029, 'title': 'Javascript game development course', 'summary': 'Covers a complete game development course using html, css, and javascript to build nine separate game development projects, led by frank, focusing on sprite animation, parallax backgrounds, enemy types, player states, collision detection, and particle effects.', 'chapters': [{'end': 91.016, 'start': 0.029, 'title': 'Javascript game development course', 'summary': 'Covers a complete game development course using html, css, and javascript to build nine separate game development projects, led by frank, with a focus on sprite animation, parallax backgrounds, enemy types, player states, collision detection, and particle effects.', 'duration': 90.987, 'highlights': ['We will learn how to use collision detection by color, collision between circles and between rectangles, and add different particle effects and many other things.', 'We will write JavaScript code that handles seamless, endlessly scrolling parallax backgrounds and extend JavaScript classes to create a variety of enemy types with different visuals and behaviors.', 'We will implement state design pattern to manage player states and special abilities and learn about sprite animation.', 'The course covers nine separate game development projects using HTML, CSS, and JavaScript, emphasizing individual 2D game development techniques and building a simple mobile game, simple point and shoot game, and a fast-paced 2D side-scroller.']}], 'duration': 90.987, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29.jpg', 'highlights': ['The course covers nine separate game development projects using HTML, CSS, and JavaScript, emphasizing individual 2D game development techniques and building a simple mobile game, simple point and shoot game, and a fast-paced 2D side-scroller.', 'We will implement state design pattern to manage player states and special abilities and learn about sprite animation.', 'We will write JavaScript code that handles seamless, endlessly scrolling parallax backgrounds and extend JavaScript classes to create a variety of enemy types with different visuals and behaviors.', 'We will learn how to use collision detection by color, collision between circles and between rectangles, and add different particle effects and many other things.']}, {'end': 1598.673, 'segs': [{'end': 613.887, 'src': 'embed', 'start': 589.591, 'weight': 7, 'content': [{'end': 596.653, 'text': 'The only difference is they are not used to position and stretch the entire image, but just the area we cut out using these arguments.', 'start': 589.591, 'duration': 7.062}, {'end': 600.294, 'text': 'I comment out line 12, but I will leave it here for reference.', 'start': 597.493, 'duration': 2.801}, {'end': 610.926, 'text': 'And on line 13 I will add source x, source y, source width and source height arguments and I will use them to cut out only one dog at a time.', 'start': 601.764, 'duration': 9.162}, {'end': 613.887, 'text': 'One frame from my large sprite sheet.', 'start': 612.126, 'duration': 1.761}], 'summary': 'Using source x, y, width, and height arguments to cut out one dog from a sprite sheet.', 'duration': 24.296, 'max_score': 589.591, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c589591.jpg'}, {'end': 796.592, 'src': 'embed', 'start': 769.284, 'weight': 4, 'content': [{'end': 772.044, 'text': 'I can also use sprite width and sprite height variables here.', 'start': 769.284, 'duration': 2.76}, {'end': 774.765, 'text': 'And we are drawing the frame at its original size.', 'start': 772.364, 'duration': 2.401}, {'end': 782.186, 'text': 'If you are still not clear what each of these individual arguments passed to draw image method does, feel free to play with it.', 'start': 775.885, 'duration': 6.301}, {'end': 784.266, 'text': 'Change the values and see what happens.', 'start': 782.586, 'duration': 1.68}, {'end': 786.447, 'text': "It's quite straightforward once you get used to it.", 'start': 784.467, 'duration': 1.98}, {'end': 788.888, 'text': "here i'm giving it an image.", 'start': 787.387, 'duration': 1.501}, {'end': 796.592, 'text': 'i want to draw these four values specify a rectangle area to crop out from the original large sprite sheet,', 'start': 788.888, 'duration': 7.704}], 'summary': 'Using sprite width and height variables, drawing frames at original size, and experimenting with draw image method for better understanding.', 'duration': 27.308, 'max_score': 769.284, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c769284.jpg'}, {'end': 941.755, 'src': 'embed', 'start': 906.267, 'weight': 0, 'content': [{'end': 911.209, 'text': 'And now I can swap between animation frames by assigning different values to these variables.', 'start': 906.267, 'duration': 4.942}, {'end': 915.611, 'text': 'frameX cycles through frames of each animation horizontally.', 'start': 911.909, 'duration': 3.702}, {'end': 918.432, 'text': 'frameY swaps between different animations.', 'start': 916.131, 'duration': 2.301}, {'end': 921.093, 'text': 'It travels through my sprite sheet vertically.', 'start': 918.892, 'duration': 2.201}, {'end': 923.724, 'text': "Now let's cover a very simple way.", 'start': 921.963, 'duration': 1.761}, {'end': 931.729, 'text': 'you can animate your sprites and then I will show you proper advanced scalable technique that is suitable for both small and larger game projects.', 'start': 923.724, 'duration': 8.005}, {'end': 933.73, 'text': 'The simple way is this.', 'start': 932.589, 'duration': 1.141}, {'end': 937.432, 'text': 'We know that frameX variable cycles through our sprite sheet horizontally.', 'start': 933.95, 'duration': 3.482}, {'end': 940.334, 'text': 'First row in our sprite sheet is idle animation.', 'start': 937.812, 'duration': 2.522}, {'end': 941.755, 'text': 'It has seven frames.', 'start': 940.714, 'duration': 1.041}], 'summary': 'Swapping animation frames using variables. 7 frames for idle animation.', 'duration': 35.488, 'max_score': 906.267, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c906267.jpg'}, {'end': 1370.154, 'src': 'embed', 'start': 1344.311, 'weight': 2, 'content': [{'end': 1348.636, 'text': 'I want this value to be only integers, whole numbers without decimal points.', 'start': 1344.311, 'duration': 4.325}, {'end': 1353.802, 'text': 'Then I take this entire value and I do remainder operator and six.', 'start': 1349.417, 'duration': 4.385}, {'end': 1359.328, 'text': "Six is here because I'm doing idle animation which has six frames counting from zero.", 'start': 1354.523, 'duration': 4.805}, {'end': 1363.669, 'text': 'This line of code is not the easiest thing to wrap your head around.', 'start': 1360.387, 'duration': 3.282}, {'end': 1365.991, 'text': 'I said this would be slightly more advanced.', 'start': 1363.91, 'duration': 2.081}, {'end': 1368.032, 'text': "Don't worry if you're struggling to read this.", 'start': 1366.411, 'duration': 1.621}, {'end': 1370.154, 'text': 'This is not beginner level JavaScript anymore.', 'start': 1368.052, 'duration': 2.102}], 'summary': 'Code requires integer values, using remainder operator with 6 for idle animation frames.', 'duration': 25.843, 'max_score': 1344.311, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c1344311.jpg'}, {'end': 1452.479, 'src': 'embed', 'start': 1430.222, 'weight': 5, 'content': [{'end': 1439.489, 'text': 'When this is one, one modulus six is one, because one divided by six is zero, and remainder from zero to one is one.', 'start': 1430.222, 'duration': 9.267}, {'end': 1444.273, 'text': 'Basically, this value increases by one every time.', 'start': 1441.01, 'duration': 3.263}, {'end': 1452.479, 'text': 'game frame variable increases by five, slowing or staggering our animation five times, making it five times slower.', 'start': 1444.273, 'duration': 8.206}], 'summary': 'One modulus six is one, game frame variable increases by five, slowing animation five times.', 'duration': 22.257, 'max_score': 1430.222, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c1430222.jpg'}], 'start': 91.317, 'title': 'Javascript game and sprite animation', 'summary': 'Covers javascript game development, canvas animation basics, sprite animation, and optimization techniques, providing intermediate learners with methods for animating sprite sheets, canvas animation basics, sprite animation in javascript, and advanced optimization methods for improved animation performance.', 'chapters': [{'end': 123.369, 'start': 91.317, 'title': 'Javascript game development', 'summary': 'Covers javascript game development for intermediate learners, offering techniques to animate sprite sheets and build a project with downloadable art assets, as well as a quick javascript setup.', 'duration': 32.052, 'highlights': ['The class is for those already comfortable with the basics of JavaScript, including functions, loops, objects, and arrays.', 'The chapter explores two different JavaScript techniques for animating sprite sheets.', 'The project involves building a feature where players can choose different animations from a dropdown.', 'Free art assets are provided for download in the video description, enabling course participants to follow along.', 'A quick JavaScript setup is demonstrated in the class.']}, {'end': 278.813, 'start': 123.729, 'title': 'Canvas animation basics', 'summary': 'Demonstrates the process of animating on canvas, using minimal code and explaining the canvas setup, scaling, and methods for drawing images and sprites.', 'duration': 155.084, 'highlights': ['The chapter demonstrates the process of animating on canvas', 'Explains the canvas setup, scaling, and methods for drawing images and sprites', 'Creates a custom variable called canvas to hold a reference to the HTML canvas element']}, {'end': 1169.556, 'start': 280.302, 'title': 'Javascript sprite animation', 'summary': 'Explains how to create sprite animations in javascript, including initializing an image, drawing on a canvas, and controlling animation frames, with examples of code and quantifiable data provided throughout.', 'duration': 889.254, 'highlights': ['I set player image variable equal to a new image, a built-in image class constructor, to store a sprite sheet image for animation with JavaScript.', 'An animation loop is created using the requestAnimationFrame method, with the ability to clear the canvas and draw shapes, such as rectangles, at specified coordinates.', 'The drawImage method is utilized to manipulate and draw the sprite sheet on the canvas, with explanations of its various versions accepting 3, 5, or 9 arguments, enabling scaling, stretching, and cropping of images.', 'Variables for sprite width and height are calculated and used to precisely crop and draw individual frames from the sprite sheet, and the significance of sourceX and sourceY arguments for cycling through the sprite sheet is detailed.', 'A simple animation technique is demonstrated, cycling through frames horizontally and vertically, and a method to adjust the animation speed using the modulus operator is introduced.']}, {'end': 1598.673, 'start': 1170.116, 'title': 'Sprite animation optimization', 'summary': 'Explains an advanced method for sprite animation optimization, showcasing how to slow down and cycle through animation frames efficiently using stagger frames and advanced mathematics to calculate the position of the frame, with a focus on improving animation performance and eliminating the need to change multiple values when swapping between animations.', 'duration': 428.557, 'highlights': ['The chapter explains an advanced method for sprite animation optimization.', 'The code block on line 20 will run every five frames, slowing down the animation five times.', 'The calculation on line 17 efficiently determines the position of the frame using advanced mathematics.', 'The position variable cycles between 0 and a specific number to optimize frame positioning.', 'The method showcased eliminates the need to change multiple values when swapping between animations.']}], 'duration': 1507.356, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c91317.jpg', 'highlights': ['The chapter explores two different JavaScript techniques for animating sprite sheets.', 'The project involves building a feature where players can choose different animations from a dropdown.', 'The class is for those already comfortable with the basics of JavaScript, including functions, loops, objects, and arrays.', 'The chapter demonstrates the process of animating on canvas', 'Explains the canvas setup, scaling, and methods for drawing images and sprites', 'An animation loop is created using the requestAnimationFrame method, with the ability to clear the canvas and draw shapes, such as rectangles, at specified coordinates.', 'The chapter explains an advanced method for sprite animation optimization.', 'Free art assets are provided for download in the video description, enabling course participants to follow along.', 'A quick JavaScript setup is demonstrated in the class.', 'The code block on line 20 will run every five frames, slowing down the animation five times.']}, {'end': 2928.927, 'segs': [{'end': 1730.384, 'src': 'embed', 'start': 1702.284, 'weight': 10, 'content': [{'end': 1706.589, 'text': 'if we want to use draw method, to cut out this particular frame from the sprite sheet.', 'start': 1702.284, 'duration': 4.305}, {'end': 1713.58, 'text': 'That way we can access any frame we want anytime by directly targeting positions in this array.', 'start': 1707.699, 'duration': 5.881}, {'end': 1724.523, 'text': 'I can just cycle through this location array with a for loop and it will always play the entire animation for me without the need to set up number of frames each animation has each time.', 'start': 1714.22, 'duration': 10.303}, {'end': 1730.384, 'text': 'It will know how many frames that animation has based on the number of objects in this location array.', 'start': 1725.023, 'duration': 5.361}], 'summary': 'Utilize draw method to access frames in array for seamless animation.', 'duration': 28.1, 'max_score': 1702.284, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c1702284.jpg'}, {'end': 1913.679, 'src': 'embed', 'start': 1820.751, 'weight': 0, 'content': [{'end': 1824.674, 'text': 'I could have also given it more properties, but this sprite sheet is not irregular.', 'start': 1820.751, 'duration': 3.923}, {'end': 1830.498, 'text': 'So name and frames properties is all I need to map coordinates for each animation frame.', 'start': 1825.154, 'duration': 5.344}, {'end': 1835.912, 'text': 'I take animation states array and I call built-in array for each method.', 'start': 1831.607, 'duration': 4.305}, {'end': 1841.759, 'text': 'For each method executes provided function once for each array element.', 'start': 1836.413, 'duration': 5.346}, {'end': 1844.302, 'text': 'I will do ES6 syntax here.', 'start': 1842.3, 'duration': 2.002}, {'end': 1846.404, 'text': 'This is so-called arrow function.', 'start': 1844.783, 'duration': 1.621}, {'end': 1850.95, 'text': "It's a simplified syntax to write function expression in JavaScript.", 'start': 1847.085, 'duration': 3.865}, {'end': 1858.657, 'text': 'I can skip function keyword here and I just create brackets where arguments I pass to this callback function go.', 'start': 1852.171, 'duration': 6.486}, {'end': 1867.224, 'text': 'With foreach, the first argument we pass to it is just a variable that will represent each element in the array as we are cycling through it.', 'start': 1859.097, 'duration': 8.127}, {'end': 1868.965, 'text': 'I will call it state.', 'start': 1867.964, 'duration': 1.001}, {'end': 1876.292, 'text': 'As foreach method runs, state will first represent this object, then this object and so on if we add more.', 'start': 1869.486, 'duration': 6.806}, {'end': 1883.256, 'text': "I'm simply saying inside this callback function I'm about to write, refer to these objects as state.", 'start': 1876.972, 'duration': 6.284}, {'end': 1888.42, 'text': 'So this name property can be accessed as state.name, for example.', 'start': 1883.897, 'duration': 4.523}, {'end': 1892.042, 'text': 'I will also pass it a second argument I call index.', 'start': 1888.44, 'duration': 3.602}, {'end': 1895.784, 'text': 'Index is another built-in feature for each array method.', 'start': 1892.622, 'duration': 3.162}, {'end': 1900.147, 'text': 'It simply stores number of each element as we cycle through the array.', 'start': 1896.145, 'duration': 4.002}, {'end': 1904.87, 'text': 'So this first object will have index 0, this will have index 1, and so on.', 'start': 1900.207, 'duration': 4.663}, {'end': 1910.816, 'text': 'I expect you understand basic array manipulation with JavaScript and fundamental methods like foreach,', 'start': 1905.891, 'duration': 4.925}, {'end': 1913.679, 'text': 'but I still wanted to explain in case we have some beginners here.', 'start': 1910.816, 'duration': 2.863}], 'summary': 'Using es6 syntax, the speaker demonstrates array manipulation in javascript, explaining the foreach method and its parameters.', 'duration': 92.928, 'max_score': 1820.751, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c1820751.jpg'}, {'end': 2775.641, 'src': 'heatmap', 'start': 2077.12, 'weight': 0.867, 'content': [{'end': 2086.623, 'text': 'So I am taking sprite animations array from line 14 and I am passing it state.name, which will first refer to idle, then to jump,', 'start': 2077.12, 'duration': 9.503}, {'end': 2089.445, 'text': 'as for each method runs through animation states array.', 'start': 2086.623, 'duration': 2.822}, {'end': 2099.592, 'text': 'I am saying create a new key, new property in sprite animations array, call it idle And its value will be frames from line 27.', 'start': 2089.465, 'duration': 10.127}, {'end': 2108.603, 'text': 'Frames object contains locations array, which I just filled with seven objects that contain X and Y properties for each frame in this animation.', 'start': 2099.592, 'duration': 9.011}, {'end': 2109.764, 'text': "That's it.", 'start': 2109.403, 'duration': 0.361}, {'end': 2113.869, 'text': 'We created the data structure that maps locations in my spreadsheet.', 'start': 2110.144, 'duration': 3.725}, {'end': 2115.451, 'text': 'I can console log it now.', 'start': 2114.409, 'duration': 1.042}, {'end': 2123.546, 'text': 'I can see I made a typo here on line 29.', 'start': 2120.785, 'duration': 2.761}, {'end': 2124.986, 'text': 'You probably noticed it already.', 'start': 2123.546, 'duration': 1.44}, {'end': 2128.287, 'text': 'This should be J, not S.', 'start': 2125.727, 'duration': 2.56}, {'end': 2131.469, 'text': "So now I'm console login animation states from line 15.", 'start': 2128.287, 'duration': 3.182}, {'end': 2132.029, 'text': "That's fine.", 'start': 2131.469, 'duration': 0.56}, {'end': 2138.191, 'text': 'But what I actually want to see is sprite animations array from line 14, which we just created and filled with data.', 'start': 2132.549, 'duration': 5.642}, {'end': 2144.075, 'text': 'You can see that my sprite animations contains two properties called idle and jump.', 'start': 2139.351, 'duration': 4.724}, {'end': 2154.124, 'text': 'If I look inside, each contains location array from line 27 and number of elements in that array corresponds to frames I declared for each animation.', 'start': 2144.996, 'duration': 9.128}, {'end': 2158.216, 'text': 'Each of these values was calculated here on lines 30 and 31.', 'start': 2155.054, 'duration': 3.162}, {'end': 2169.481, 'text': 'You can see that all Y coordinates for idle are zero and for jump animation vertical Y coordinate is 523 as we moved on to the second row in our sprite sheet.', 'start': 2158.216, 'duration': 11.265}, {'end': 2178.468, 'text': 'Now I can replace hardcoded number 6 here on line 40 with length of these locations arrays.', 'start': 2172.881, 'duration': 5.587}, {'end': 2183.595, 'text': 'I access this location array by targeting sprite animations dot log.', 'start': 2179.47, 'duration': 4.125}, {'end': 2185.437, 'text': 'Actually no, I skipped one level.', 'start': 2183.895, 'duration': 1.542}, {'end': 2189.623, 'text': 'I need to specify if I want location array for idle or jump.', 'start': 2185.898, 'duration': 3.725}, {'end': 2194.89, 'text': "Let's just hardcode idle here for a moment and I want length of this array.", 'start': 2190.646, 'duration': 4.244}, {'end': 2199.133, 'text': 'Remember I am just replacing hardcoded number 6 that was here.', 'start': 2195.33, 'duration': 3.803}, {'end': 2200.654, 'text': 'So dot length.', 'start': 2199.653, 'duration': 1.001}, {'end': 2201.715, 'text': "And that's it.", 'start': 2201.215, 'duration': 0.5}, {'end': 2203.116, 'text': "Now it's dynamic.", 'start': 2202.176, 'duration': 0.94}, {'end': 2212.404, 'text': 'I can add animations with 4 or 15 frames per row or however many I want and it will still work with no blank or left out animation frames.', 'start': 2203.677, 'duration': 8.727}, {'end': 2219.55, 'text': 'Here I am accessing sprite animations from line 14, idle, location, dot length.', 'start': 2213.004, 'duration': 6.546}, {'end': 2230.824, 'text': 'Inside animation loop, we are still calculating frames using frameX and frameY variables from lines 10 and 11.', 'start': 2223.621, 'duration': 7.203}, {'end': 2235.706, 'text': "We don't need these anymore because now we have the exact coordinates stored in locations array.", 'start': 2230.824, 'duration': 4.882}, {'end': 2240.31, 'text': 'I delete lines 10 and 11.', 'start': 2236.506, 'duration': 3.804}, {'end': 2247.155, 'text': 'On line 40, I add let keyword in front of frame X and I will declare frame Y variable here.', 'start': 2240.31, 'duration': 6.845}, {'end': 2249.977, 'text': 'Frame Y is just the value we can see here.', 'start': 2247.736, 'duration': 2.241}, {'end': 2254.441, 'text': 'So I can access it by saying sprite animations idle.', 'start': 2250.258, 'duration': 4.183}, {'end': 2264.066, 'text': 'dot location at index position from line 39 dot y.', 'start': 2258.464, 'duration': 5.602}, {'end': 2267.328, 'text': 'i could do the same thing for frame x or i can just leave it as is.', 'start': 2264.066, 'duration': 3.262}, {'end': 2268.648, 'text': 'both will work.', 'start': 2267.328, 'duration': 1.32}, {'end': 2273.49, 'text': "let's replace idle with a jump.", 'start': 2268.648, 'duration': 4.842}, {'end': 2279.973, 'text': "it breaks notice that row 1 with idle animation was working and row 2 doesn't,", 'start': 2273.49, 'duration': 6.483}, {'end': 2284.982, 'text': 'which suggests something is wrong with how we draw vertical position Inside.', 'start': 2279.973, 'duration': 5.009}, {'end': 2289.666, 'text': 'draw image on line 43, I remove sprite width value from source Y argument.', 'start': 2284.982, 'duration': 4.684}, {'end': 2294.35, 'text': "We don't need it anymore as frame Y contains complete already calculated coordinate.", 'start': 2289.786, 'duration': 4.564}, {'end': 2300.655, 'text': 'Now I can go back inside animation states array and I add data for all the remaining animations.', 'start': 2295.371, 'duration': 5.284}, {'end': 2304.278, 'text': "It's important to understand that you can't skip rows here.", 'start': 2301.295, 'duration': 2.983}, {'end': 2312.705, 'text': 'You have to go row by row from top to bottom to match your sprite sheet because vertical Y coordinate is tied to index in for each method.', 'start': 2304.378, 'duration': 8.327}, {'end': 2326.93, 'text': 'I add fall animation with 9 frames, run animation has 9 frames, dizzy 11 frames, sit has only 5 frames, roll 7 frames and so on.', 'start': 2314.085, 'duration': 12.845}, {'end': 2331.412, 'text': 'I also need to make sure there is comma between every object.', 'start': 2328.471, 'duration': 2.941}, {'end': 2340.319, 'text': 'If I try fall, I get blinking.', 'start': 2338.317, 'duration': 2.002}, {'end': 2342.341, 'text': 'There must be an empty frame.', 'start': 2341.1, 'duration': 1.241}, {'end': 2345.343, 'text': 'Fall animation is actually only 7 frames.', 'start': 2343.141, 'duration': 2.202}, {'end': 2351.148, 'text': 'If I put less here, we play only part of animation.', 'start': 2348.366, 'duration': 2.782}, {'end': 2354.952, 'text': 'If I put more here, we get blinking because some frames are empty.', 'start': 2351.569, 'duration': 3.383}, {'end': 2360.517, 'text': 'Run animation works.', 'start': 2359.416, 'duration': 1.101}, {'end': 2363.019, 'text': 'Dizzy works.', 'start': 2362.438, 'duration': 0.581}, {'end': 2366.355, 'text': 'Sit animation works as well.', 'start': 2365.054, 'duration': 1.301}, {'end': 2377.121, 'text': 'You can see sit animation has 5 frames and dizzy animation has 11 frames and I can swap between them easily without having to manually change number of frames like we did before.', 'start': 2367.135, 'duration': 9.986}, {'end': 2380.604, 'text': 'Roll animation works.', 'start': 2379.543, 'duration': 1.061}, {'end': 2382.705, 'text': 'Bite animation works.', 'start': 2381.644, 'duration': 1.061}, {'end': 2384.266, 'text': "Let's go back to idle.", 'start': 2383.185, 'duration': 1.081}, {'end': 2388.408, 'text': 'Putting hardcoded text here like this is not ideal of course.', 'start': 2385.226, 'duration': 3.182}, {'end': 2392.411, 'text': 'I go up to line 10 and I create a variable called player state.', 'start': 2388.989, 'duration': 3.422}, {'end': 2395.851, 'text': 'I set it to run initially.', 'start': 2394.15, 'duration': 1.701}, {'end': 2402.636, 'text': 'Down on line 71 and 73 I replace idle with this new player state variable.', 'start': 2396.632, 'duration': 6.004}, {'end': 2410.642, 'text': 'Now I can swap between animations here on line 10.', 'start': 2403.477, 'duration': 7.165}, {'end': 2414.865, 'text': 'Sit works, jump works, fall works.', 'start': 2410.642, 'duration': 4.223}, {'end': 2421.428, 'text': 'In index.html, I create a new div with a class of controls.', 'start': 2418.226, 'duration': 3.202}, {'end': 2427.552, 'text': 'Inside, there will be a select element with an ID of animations and name animations.', 'start': 2422.008, 'duration': 5.544}, {'end': 2433.836, 'text': 'Label for animations will say choose animation.', 'start': 2431.174, 'duration': 2.662}, {'end': 2445.963, 'text': 'I give it some options that match names we gave to animations in script.js file.', 'start': 2441.4, 'duration': 4.563}, {'end': 2466.151, 'text': 'In style CSS.', 'start': 2465.211, 'duration': 0.94}, {'end': 2481.875, 'text': 'I target controls and I give it position absolute Z index 10, top 50 pixels and transform, translate X minus 50% to center it horizontally.', 'start': 2466.151, 'duration': 15.724}, {'end': 2489.276, 'text': 'I take controls, select and option, and I increase their font size to 25 pixels.', 'start': 2483.255, 'duration': 6.021}, {'end': 2492.977, 'text': 'I can also remove the border around my canvas.', 'start': 2490.796, 'duration': 2.181}, {'end': 2498.556, 'text': 'I want animations to change when I choose different value in this dropdown.', 'start': 2494.733, 'duration': 3.823}, {'end': 2508.344, 'text': 'In Script.js, I take player state from line 10 and I put it up top on line 1.', 'start': 2499.257, 'duration': 9.087}, {'end': 2514.829, 'text': 'I create a constant variable called dropdown and I point it towards this new select element with ID of animations.', 'start': 2508.344, 'duration': 6.485}, {'end': 2523.762, 'text': 'I take drop down and call add event listener on it.', 'start': 2520.839, 'duration': 2.923}, {'end': 2525.924, 'text': 'I will listen for change event.', 'start': 2524.482, 'duration': 1.442}, {'end': 2536.999, 'text': 'Every time its value changes, We will take player state from line one and since we are inside callback function on event listener,', 'start': 2528.085, 'duration': 8.914}, {'end': 2539.02, 'text': 'we have access to event object.', 'start': 2536.999, 'duration': 2.021}, {'end': 2540.66, 'text': "I'm referring to it as E.", 'start': 2539.52, 'duration': 1.14}, {'end': 2543.201, 'text': 'Event object has target property.', 'start': 2540.66, 'duration': 2.541}, {'end': 2550.104, 'text': 'Target is simply referring to an element that was clicked, and it has value property because I have added values myself.', 'start': 2543.662, 'duration': 6.442}, {'end': 2558.087, 'text': 'Whenever any of these option elements in my dropdown is clicked, player state variable will be set to its value attribute.', 'start': 2550.944, 'duration': 7.143}, {'end': 2564.692, 'text': 'Now I can easily swap between different animations in my sprite sheet just by selecting different option in a drop down.', 'start': 2559.042, 'duration': 5.65}, {'end': 2596.966, 'text': 'Parallax scrolling is when background images move past the camera slower than the foreground, creating an illusion of depth in a 2D space.', 'start': 2588.615, 'duration': 8.351}, {'end': 2600.071, 'text': 'This is what my game looks without it.', 'start': 2598.428, 'duration': 1.643}, {'end': 2603.896, 'text': 'And this is what it looks with parallax.', 'start': 2602.033, 'duration': 1.863}, {'end': 2604.977, 'text': 'Which one do you prefer?', 'start': 2604.216, 'duration': 0.761}, {'end': 2611.277, 'text': 'Today we are learning about Vanilla JavaScript game development for beginners and by the end of this video,', 'start': 2605.694, 'duration': 5.583}, {'end': 2618.902, 'text': 'you will have deep understanding about endlessly scrolling backgrounds and how to add parallax effect to your games and websites.', 'start': 2611.277, 'duration': 7.625}, {'end': 2625.846, 'text': 'When we have full control of individual layers, we can match scroll speed to different actions our game character takes.', 'start': 2619.302, 'duration': 6.544}, {'end': 2633.531, 'text': 'For example, my dog character can sit down and the game stops moving or it can do this rolling attack and the game speeds up.', 'start': 2626.226, 'duration': 7.305}, {'end': 2637.694, 'text': 'Art assets for this episode were created by this amazing artist.', 'start': 2634.111, 'duration': 3.583}, {'end': 2639.615, 'text': 'Check out their website for more if you want.', 'start': 2637.874, 'duration': 1.741}, {'end': 2643.577, 'text': 'What is the easiest way to create endlessly scrolling backgrounds?', 'start': 2640.255, 'duration': 3.322}, {'end': 2650.862, 'text': 'How to make different layers move at different speeds to create parallax effect? How to make scroll speed dynamic so we can easily change it?', 'start': 2643.738, 'duration': 7.124}, {'end': 2652.804, 'text': 'We will learn all of that and more.', 'start': 2651.102, 'duration': 1.702}, {'end': 2659.628, 'text': "Let's bring our coding skills one step further today together and have some fun with plain vanilla JavaScript.", 'start': 2653.204, 'duration': 6.424}, {'end': 2661.569, 'text': 'This tutorial is for beginners.', 'start': 2660.068, 'duration': 1.501}, {'end': 2662.19, 'text': "Let's go.", 'start': 2661.85, 'duration': 0.34}, {'end': 2663.391, 'text': 'Click the like, please.', 'start': 2662.69, 'duration': 0.701}, {'end': 2669.407, 'text': 'I create a basic web page markup.', 'start': 2667.506, 'duration': 1.901}, {'end': 2673.37, 'text': 'In document head, I use link tag to include my style CSS file.', 'start': 2669.808, 'duration': 3.562}, {'end': 2675.671, 'text': 'We will use it to position canvas.', 'start': 2674.01, 'duration': 1.661}, {'end': 2679.494, 'text': 'At the bottom of document body, I place my script tag.', 'start': 2676.552, 'duration': 2.942}, {'end': 2684.177, 'text': 'Script.js file will contain all functionality and logic for our project.', 'start': 2679.994, 'duration': 4.183}, {'end': 2689.14, 'text': 'I also create HTML canvas element with an ID of canvas1.', 'start': 2685.138, 'duration': 4.002}, {'end': 2694.024, 'text': 'It will be our main project area, and we will draw on it with JavaScript.', 'start': 2689.921, 'duration': 4.103}, {'end': 2699.213, 'text': 'In style CSS, I take body tag and I set its background to black.', 'start': 2695.228, 'duration': 3.985}, {'end': 2704.72, 'text': 'Canvas will be set to position absolute.', 'start': 2702.737, 'duration': 1.983}, {'end': 2713.901, 'text': 'border 3px solid white, width of 800px, height 700px.', 'start': 2707.577, 'duration': 6.324}, {'end': 2725.547, 'text': 'I do transform translate minus 50% for X axis and minus 50% for Y axis and then I offset top by 50% and left by 50%.', 'start': 2714.701, 'duration': 10.846}, {'end': 2730.73, 'text': 'This will center my canvas in the middle of the page both vertically and horizontally.', 'start': 2725.547, 'duration': 5.183}, {'end': 2741.273, 'text': 'In Script.js, I create a custom variable called canvas, and I point it towards my HTML canvas element by ID canvas1.', 'start': 2733.621, 'duration': 7.652}, {'end': 2751.746, 'text': 'CTX shortcut for context will take this canvas variable from line one and it will call get context built in method on it.', 'start': 2743.942, 'duration': 7.804}, {'end': 2757.189, 'text': 'Get context can only be called on a variable that holds a reference to canvas element.', 'start': 2752.506, 'duration': 4.683}, {'end': 2760.45, 'text': 'And when I pass it argument that says 2D,', 'start': 2757.549, 'duration': 2.901}, {'end': 2767.634, 'text': 'it will create an instance of built in canvas 2D API object that contains all properties and drawing methods we will need today.', 'start': 2760.45, 'duration': 7.184}, {'end': 2775.641, 'text': 'I need to make sure we have the correct scaling, because if you dot set canvas width and height, it will default to 300 times 150 pixels.', 'start': 2768.314, 'duration': 7.327}], 'summary': 'Creating sprite animations array with dynamic frames and parallax effect for game development.', 'duration': 698.521, 'max_score': 2077.12, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c2077120.jpg'}, {'end': 2199.133, 'src': 'embed', 'start': 2144.996, 'weight': 4, 'content': [{'end': 2154.124, 'text': 'If I look inside, each contains location array from line 27 and number of elements in that array corresponds to frames I declared for each animation.', 'start': 2144.996, 'duration': 9.128}, {'end': 2158.216, 'text': 'Each of these values was calculated here on lines 30 and 31.', 'start': 2155.054, 'duration': 3.162}, {'end': 2169.481, 'text': 'You can see that all Y coordinates for idle are zero and for jump animation vertical Y coordinate is 523 as we moved on to the second row in our sprite sheet.', 'start': 2158.216, 'duration': 11.265}, {'end': 2178.468, 'text': 'Now I can replace hardcoded number 6 here on line 40 with length of these locations arrays.', 'start': 2172.881, 'duration': 5.587}, {'end': 2183.595, 'text': 'I access this location array by targeting sprite animations dot log.', 'start': 2179.47, 'duration': 4.125}, {'end': 2185.437, 'text': 'Actually no, I skipped one level.', 'start': 2183.895, 'duration': 1.542}, {'end': 2189.623, 'text': 'I need to specify if I want location array for idle or jump.', 'start': 2185.898, 'duration': 3.725}, {'end': 2194.89, 'text': "Let's just hardcode idle here for a moment and I want length of this array.", 'start': 2190.646, 'duration': 4.244}, {'end': 2199.133, 'text': 'Remember I am just replacing hardcoded number 6 that was here.', 'start': 2195.33, 'duration': 3.803}], 'summary': 'Location arrays contain frame data for sprite animations.', 'duration': 54.137, 'max_score': 2144.996, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c2144996.jpg'}, {'end': 2351.148, 'src': 'embed', 'start': 2314.085, 'weight': 8, 'content': [{'end': 2326.93, 'text': 'I add fall animation with 9 frames, run animation has 9 frames, dizzy 11 frames, sit has only 5 frames, roll 7 frames and so on.', 'start': 2314.085, 'duration': 12.845}, {'end': 2331.412, 'text': 'I also need to make sure there is comma between every object.', 'start': 2328.471, 'duration': 2.941}, {'end': 2340.319, 'text': 'If I try fall, I get blinking.', 'start': 2338.317, 'duration': 2.002}, {'end': 2342.341, 'text': 'There must be an empty frame.', 'start': 2341.1, 'duration': 1.241}, {'end': 2345.343, 'text': 'Fall animation is actually only 7 frames.', 'start': 2343.141, 'duration': 2.202}, {'end': 2351.148, 'text': 'If I put less here, we play only part of animation.', 'start': 2348.366, 'duration': 2.782}], 'summary': 'Animations include fall (7 frames), run (9 frames), dizzy (11 frames), sit (5 frames), and roll (7 frames)', 'duration': 37.063, 'max_score': 2314.085, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c2314085.jpg'}, {'end': 2637.694, 'src': 'embed', 'start': 2611.277, 'weight': 3, 'content': [{'end': 2618.902, 'text': 'you will have deep understanding about endlessly scrolling backgrounds and how to add parallax effect to your games and websites.', 'start': 2611.277, 'duration': 7.625}, {'end': 2625.846, 'text': 'When we have full control of individual layers, we can match scroll speed to different actions our game character takes.', 'start': 2619.302, 'duration': 6.544}, {'end': 2633.531, 'text': 'For example, my dog character can sit down and the game stops moving or it can do this rolling attack and the game speeds up.', 'start': 2626.226, 'duration': 7.305}, {'end': 2637.694, 'text': 'Art assets for this episode were created by this amazing artist.', 'start': 2634.111, 'duration': 3.583}], 'summary': 'Learn to create parallax effect for games and websites with customizable scroll speeds.', 'duration': 26.417, 'max_score': 2611.277, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c2611277.jpg'}, {'end': 2897.953, 'src': 'embed', 'start': 2857.779, 'weight': 7, 'content': [{'end': 2861.48, 'text': 'For commercial projects, you will have to purchase a full license from his website.', 'start': 2857.779, 'duration': 3.701}, {'end': 2867.642, 'text': "This effect will also work with any other image, but maybe you first want to use the same files I'm using,", 'start': 2861.98, 'duration': 5.662}, {'end': 2873.805, 'text': "so that you get the same result and don't have to worry about calculating different width and height or making sure your layers match.", 'start': 2867.642, 'duration': 6.163}, {'end': 2876.806, 'text': "Once you fully understand the code from today's lesson,", 'start': 2874.245, 'duration': 2.561}, {'end': 2881.848, 'text': 'it will be easy to switch the images and adjust values so that the code base works with your own files.', 'start': 2876.806, 'duration': 5.042}, {'end': 2883.748, 'text': 'The images are very large.', 'start': 2882.488, 'duration': 1.26}, {'end': 2889.79, 'text': 'If you experience any lagging or frame drops, making images smaller will significantly improve performance.', 'start': 2884.128, 'duration': 5.662}, {'end': 2897.953, 'text': 'I kept them large on purpose so that we get nice clean visuals, but especially if you are creating a mobile game, these images can be much smaller.', 'start': 2890.271, 'duration': 7.682}], 'summary': 'Purchase full license for commercial projects. images are very large; reducing size improves performance, especially for mobile games.', 'duration': 40.174, 'max_score': 2857.779, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c2857779.jpg'}], 'start': 1599.053, 'title': 'Sprite sheet animation and parallax scrolling', 'summary': 'Covers optimizing sprite sheet animation, altering code variables for animation speed, creating a data structure in javascript for sprite animations, mapping sprite sheet coordinates, implementing parallax scrolling in a vanilla javascript game, and utilizing five layers for seamless parallax effect.', 'chapters': [{'end': 1656.824, 'start': 1599.053, 'title': 'Optimizing sprite sheet animation', 'summary': 'Discusses optimizing sprite sheet animation by altering code variables to control animation speed and ensure correct frame allocation, with a suggestion for further improvement.', 'duration': 57.771, 'highlights': ['Altering the stagger frames variable on line 15 allows for controlling animation speed.', 'Changing the frame y variable on line 11 and ensuring the value on line 17 sets the correct frames per row are crucial for correct frame allocation.', 'Suggests the need for a more optimized code structure for swapping between animations.']}, {'end': 1913.679, 'start': 1658.224, 'title': 'Javascript sprite animations', 'summary': 'Explains how to create a data structure in javascript to hold sprite animation data, utilizing arrays and objects to map coordinates for each animation frame, enabling easy access and manipulation of the animation frames.', 'duration': 255.455, 'highlights': ['The chapter discusses creating a data structure in JavaScript using arrays and objects to hold sprite animation data.', 'It explains how to map coordinates for each animation frame using objects, facilitating easy access and manipulation of frames.', "The use of the built-in array method 'forEach' is demonstrated in the context of cycling through the animation states array and accessing its elements."]}, {'end': 2564.692, 'start': 1914.42, 'title': 'Mapping sprite sheet coordinates', 'summary': 'Discusses the creation of a data structure that maps sprite sheet coordinates for animations, using a for loop to calculate x and y coordinates for each frame, and dynamically updating the animation frames length and swapping between animations using a dropdown.', 'duration': 650.272, 'highlights': ['Creating a data structure to map sprite sheet coordinates', 'Calculating X and Y coordinates for each frame using a for loop', 'Dynamically updating the animation frames length and swapping between animations']}, {'end': 2928.927, 'start': 2588.615, 'title': 'Parallax scrolling in vanilla js game', 'summary': 'Covers the implementation of parallax scrolling in a vanilla javascript game, including creating endlessly scrolling backgrounds and adjusting scroll speed dynamically for game characters, with a focus on using five layers for seamless parallax effect.', 'duration': 340.312, 'highlights': ['The chapter covers the implementation of parallax scrolling in a Vanilla JavaScript game', 'Creating endlessly scrolling backgrounds and adjusting scroll speed dynamically for game characters', 'Using five layers for seamless parallax effect']}], 'duration': 1329.874, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c1599053.jpg', 'highlights': ['Using five layers for seamless parallax effect', 'Creating a data structure to map sprite sheet coordinates', 'Implementing parallax scrolling in a Vanilla JavaScript game', 'Altering the stagger frames variable on line 15 allows for controlling animation speed', 'Changing the frame y variable on line 11 and ensuring the value on line 17 sets the correct frames per row are crucial for correct frame allocation', 'The chapter discusses creating a data structure in JavaScript using arrays and objects to hold sprite animation data', 'Calculating X and Y coordinates for each frame using a for loop', 'Suggests the need for a more optimized code structure for swapping between animations', 'Dynamically updating the animation frames length and swapping between animations', 'Explains how to map coordinates for each animation frame using objects, facilitating easy access and manipulation of frames', 'Creating endlessly scrolling backgrounds and adjusting scroll speed dynamically for game characters', "The use of the built-in array method 'forEach' is demonstrated in the context of cycling through the animation states array and accessing its elements"]}, {'end': 4349.418, 'segs': [{'end': 3465.303, 'src': 'embed', 'start': 3436.087, 'weight': 9, 'content': [{'end': 3443.775, 'text': 'So when X resets, image 1 resets on line 25, or when X2, image 2 resets on line 27,,', 'start': 3436.087, 'duration': 7.688}, {'end': 3449.402, 'text': 'I need to offset the other one by the amount of game speed to account for the fact that for that frame,', 'start': 3443.775, 'duration': 5.627}, {'end': 3452.545, 'text': 'the other image kept moving while the other one was resetting.', 'start': 3449.402, 'duration': 3.143}, {'end': 3465.303, 'text': 'Gap is smaller now, but there is still a gap.', 'start': 3462.881, 'duration': 2.422}], 'summary': 'Images reset at specific lines, offset by game speed to reduce gap.', 'duration': 29.216, 'max_score': 3436.087, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c3436087.jpg'}, {'end': 3557.135, 'src': 'embed', 'start': 3531.713, 'weight': 0, 'content': [{'end': 3537.818, 'text': 'that way, even when gap is somehow created, it auto corrects itself next time around during the next reset.', 'start': 3531.713, 'duration': 6.105}, {'end': 3550.789, 'text': 'I do it by accounting for the current X2 position in my X reset check on line 25 and I account for current X position in my X2 reset check on line 27..', 'start': 3538.579, 'duration': 12.21}, {'end': 3557.135, 'text': 'Keep in mind that when these reset checks happen, X or X2 are small numbers somewhere around zero at that point.', 'start': 3550.789, 'duration': 6.346}], 'summary': 'Auto corrects gaps during reset by accounting for x and x2 positions.', 'duration': 25.422, 'max_score': 3531.713, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c3531713.jpg'}, {'end': 3805.122, 'src': 'embed', 'start': 3778.812, 'weight': 3, 'content': [{'end': 3787.535, 'text': 'It will create one new blank object and it will assign values and properties to that new blank object based on Blueprint inside the constructor.', 'start': 3778.812, 'duration': 8.723}, {'end': 3793.557, 'text': 'Constructor runs only once per object every time JavaScript class is called using the new keyword.', 'start': 3788.115, 'duration': 5.442}, {'end': 3794.638, 'text': 'I will show you in a minute.', 'start': 3793.777, 'duration': 0.861}, {'end': 3797.559, 'text': 'My constructor will expect two arguments.', 'start': 3795.538, 'duration': 2.021}, {'end': 3805.122, 'text': 'Image we want to assign to that layer and speed modifier, because I want each layer to scroll at slightly different speed.', 'start': 3797.999, 'duration': 7.123}], 'summary': 'Javascript constructor assigns values and properties based on blueprint to new object, expecting two arguments for image and speed modifier.', 'duration': 26.31, 'max_score': 3778.812, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c3778812.jpg'}, {'end': 3846.91, 'src': 'embed', 'start': 3819.929, 'weight': 1, 'content': [{'end': 3824.031, 'text': 'Each layer object will have horizontal X coordinate that starts at position zero.', 'start': 3819.929, 'duration': 4.102}, {'end': 3828.975, 'text': 'I say this dot X because my layer class will create many similar objects.', 'start': 3824.671, 'duration': 4.304}, {'end': 3837.722, 'text': "So I'm saying here, on line 20 set X property on this particular object you are creating right now to zero,", 'start': 3829.355, 'duration': 8.367}, {'end': 3842.946, 'text': 'because we are inside a blueprint that will trigger every time we call our class to create an object.', 'start': 3837.722, 'duration': 5.224}, {'end': 3846.91, 'text': 'I will also have a vertical Y coordinate that will be set to zero.', 'start': 3843.707, 'duration': 3.203}], 'summary': 'Each layer object will have x and y coordinates set to zero.', 'duration': 26.981, 'max_score': 3819.929, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c3819929.jpg'}, {'end': 4015.09, 'src': 'embed', 'start': 3987.782, 'weight': 6, 'content': [{'end': 3994.386, 'text': 'To make sure my game speed is dynamic and always reacting to the current value of my global game speed variable from line 10,', 'start': 3987.782, 'duration': 6.604}, {'end': 3996.788, 'text': 'I need to recalculate this dot speed like this', 'start': 3994.386, 'duration': 2.402}, {'end': 4002.893, 'text': "If you want your game to have a constant, never-changing scrolling speed, you don't need to do this line of code.", 'start': 3998.277, 'duration': 4.616}, {'end': 4015.09, 'text': 'Now I just say if this.x from line 20 is less or equal to minus this.width from line 22,, so minus 2, 400 pixels,', 'start': 4004.727, 'duration': 10.363}], 'summary': 'Dynamic game speed reacts to global variable, recalculates dot speed based on position.', 'duration': 27.308, 'max_score': 3987.782, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c3987782.jpg'}, {'end': 4061.032, 'src': 'embed', 'start': 4033.226, 'weight': 7, 'content': [{'end': 4037.031, 'text': 'I copy this entire code block and I do the same thing for this .', 'start': 4033.226, 'duration': 3.805}, {'end': 4041.934, 'text': 'x2 property from line 24.', 'start': 4037.031, 'duration': 4.903}, {'end': 4051.263, 'text': 'So this.x needs to be offset by the current value of x2 and this.x2 needs to be offset by the current value of this.x.', 'start': 4041.934, 'duration': 9.329}, {'end': 4053.204, 'text': 'If they are not resetting,', 'start': 4052.063, 'duration': 1.141}, {'end': 4061.032, 'text': 'I just want my x property to decrease by the amount of this.speed from line 27 to make my background layer move to the left.', 'start': 4053.204, 'duration': 7.828}], 'summary': 'Adjust x and x2 properties to move background layer left by this.speed from line 27.', 'duration': 27.806, 'max_score': 4033.226, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4033226.jpg'}, {'end': 4270.528, 'src': 'embed', 'start': 4246.078, 'weight': 4, 'content': [{'end': 4252.1, 'text': "Now I'm drawing layer 4 and layer 5, but there would be a lot of code repetition if I did it for all 5 layers.", 'start': 4246.078, 'duration': 6.022}, {'end': 4261.424, 'text': 'If I change speed modifier value, I pass the layer class constructor on line 50, you can see their relative speed changes and we have parallax effect.', 'start': 4252.741, 'duration': 8.683}, {'end': 4270.528, 'text': 'Awesome It is because that speed modifier takes game speed and adjusts it by multiplying game speed from line 5 times this modifier value.', 'start': 4261.944, 'duration': 8.584}], 'summary': 'Code repetition in drawing layers 4 and 5; speed modifier affects relative speed for parallax effect.', 'duration': 24.45, 'max_score': 4246.078, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4246078.jpg'}], 'start': 2929.427, 'title': 'Implementing image animation in javascript', 'summary': 'Covers javascript techniques for adding images to a canvas, creating html image elements and animation loops, achieving endlessly scrolling backgrounds and parallax effects, and using javascript classes to manage image layer objects, supporting game development and artistic creation.', 'chapters': [{'end': 2976.683, 'start': 2929.427, 'title': 'Javascript for adding images to canvas', 'summary': 'Discusses adding images to a canvas using javascript, including creating and appending image elements, which can help in making unique games and supporting artists.', 'duration': 47.256, 'highlights': ['Creating a constant variable called background layer one and setting it equal to a new image using the built-in image class constructor, which helps in adding images to the canvas project.', 'Using the appendChild method in JavaScript to insert the image tag into the HTML file, providing a simple way to display images and support game asset creation.', 'Illustrating the functionality of the image constructor as being similar to the document.createElement img, making it easier to handle and manipulate images within the canvas project.']}, {'end': 3340.918, 'start': 2977.243, 'title': 'Creating html image element and animation loop', 'summary': 'Covers creating html image elements, setting up an animation loop with canvas and drawing images to create an endless scrolling effect, using variables like x and game speed to control the movement, and optimizing the process by duplicating and resetting the images.', 'duration': 363.675, 'highlights': ['Setting up animation loop with canvas and drawing images to create an endless scrolling effect', 'Using variables like x and game speed to control the movement of images', 'Optimizing the process by duplicating and resetting the images', 'Creating HTML image elements']}, {'end': 3683.726, 'start': 3341.519, 'title': 'Endlessly scrolling backgrounds and parallax effect', 'summary': 'Explores the concept of endlessly scrolling backgrounds, addressing issues such as gap between images due to independent resetting, the impact of game speed on the gap, and the desire for dynamic game speed. it also introduces the parallax effect and the need for different speeds for layers, emphasizing the goal of achieving synchronization while avoiding code repetition.', 'duration': 342.207, 'highlights': ['The gap between images is caused by independent resetting based on different variables (X and X2), leading to a non-seamless background and potential growth of the gap over time.', "The gap persists due to the game speed of 15 pixels per frame and the resetting of images when their X position is less than -2400, resulting in leftover pixels that can contribute to the gap's growth.", 'The desire for dynamic game speed without limitations, allowing for speed progression and special moves to affect scrolling speed, necessitates synchronization of image positions during resets to achieve seamless scrolling and auto-correction of any created gap.', 'Introduction of the parallax effect involves animating five layers at different speeds while ensuring synchronization to the game speed variable, with the goal of creating a 3D illusion in a 2D space and allowing for proportionate speed changes across all layers.', 'Consideration for clean implementation leads to the decision to remove the X and X2 variables and avoid code repetition while animating the layers at different speeds, highlighting the intention to optimize the process and prepare for subsequent steps.']}, {'end': 4349.418, 'start': 3683.726, 'title': 'Javascript classes for layer objects', 'summary': 'Outlines the creation of javascript classes for image layer objects, explaining the use of constructor method, properties, and methods to create and manage five instances of the layer class, each with different image and speed properties, in order to achieve a parallax effect and dynamic scrolling tied to a global game speed variable.', 'duration': 665.692, 'highlights': ['The chapter emphasizes the use of JavaScript classes to create a blueprint for a layer object, followed by the creation of five instances of the layer class, each with different image and speed properties, in order to efficiently manage multiple similar objects.', 'It explains the constructor method as a mandatory method within a class that triggers itself when the class is called, creating a new object and assigning values and properties based on the class blueprint, with the ability to pass arguments to the constructor to customize the properties of the object.', "The concept of methods within the class, such as the custom 'update' and 'draw' methods, is highlighted as a means to manage and manipulate the properties of the layer objects, enabling dynamic scrolling and redraw of images based on the global game speed variable.", 'The integration of all five layer objects into a single array and the use of the ForEach method to efficiently apply callback functions to each object within the array is explained as a way to avoid code repetition and manage all layer objects simultaneously.']}], 'duration': 1419.991, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c2929427.jpg', 'highlights': ['Using JavaScript classes to efficiently manage multiple similar objects', 'Creating a constant variable for adding images to the canvas project', 'Setting up animation loop with canvas and drawing images for endless scrolling', 'Illustrating the functionality of the image constructor for manipulating images', 'Introduction of the parallax effect for creating a 3D illusion in a 2D space', 'Optimizing the process by duplicating and resetting the images for endless scrolling', 'Using variables like x and game speed to control the movement of images', 'The gap between images is caused by independent resetting based on different variables', 'The desire for dynamic game speed without limitations necessitates synchronization of image positions', 'The concept of methods within the class to manage and manipulate the properties of the layer objects']}, {'end': 6036.183, 'segs': [{'end': 4485.326, 'src': 'embed', 'start': 4450.449, 'weight': 10, 'content': [{'end': 4454.811, 'text': 'Class will be slider, for example, and ID slider as well.', 'start': 4450.449, 'duration': 4.362}, {'end': 4458.132, 'text': 'I put HTML canvas element inside the container.', 'start': 4455.711, 'duration': 2.421}, {'end': 4465.595, 'text': 'Install CSS.', 'start': 4464.714, 'duration': 0.881}, {'end': 4466.515, 'text': 'I take container.', 'start': 4465.695, 'duration': 0.82}, {'end': 4474.063, 'text': 'I give it position absolute width 800px.', 'start': 4468.482, 'duration': 5.581}, {'end': 4477.664, 'text': 'I center it in the middle of the page using transform translate.', 'start': 4474.063, 'duration': 3.601}, {'end': 4481.945, 'text': 'I set canvas to position relative so that it aligns with container.', 'start': 4477.664, 'duration': 4.281}, {'end': 4485.326, 'text': 'I put border on the container so we see where it is.', 'start': 4481.945, 'duration': 3.381}], 'summary': 'Created a slider class with an id, positioned canvas inside a container, and styled with css.', 'duration': 34.877, 'max_score': 4450.449, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4450449.jpg'}, {'end': 4880.582, 'src': 'embed', 'start': 4846.539, 'weight': 1, 'content': [{'end': 4847.039, 'text': 'More like this.', 'start': 4846.539, 'duration': 0.5}, {'end': 4861.085, 'text': 'This second, improved technique uses just one variable to move images horizontally.', 'start': 4856.041, 'duration': 5.044}, {'end': 4870.073, 'text': 'This image is at position this.x and the position of the second image is calculated from that by adding this.x plus this.width.', 'start': 4861.666, 'duration': 8.407}, {'end': 4874.837, 'text': 'The second image is always 2400 pixels to the right of the first image.', 'start': 4870.574, 'duration': 4.263}, {'end': 4880.582, 'text': 'This way, they will always be synchronized since the position of both images is coming from the same variable.', 'start': 4875.338, 'duration': 5.244}], 'summary': 'Improved technique moves images horizontally using one variable, keeping them synchronized.', 'duration': 34.043, 'max_score': 4846.539, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4846539.jpg'}, {'end': 4921.893, 'src': 'embed', 'start': 4891.806, 'weight': 7, 'content': [{'end': 4898.829, 'text': 'Again, the transition, the reset where the images move to the right to start from their original position happens very fast.', 'start': 4891.806, 'duration': 7.023}, {'end': 4900.189, 'text': 'It happens instantly.', 'start': 4899.209, 'duration': 0.98}, {'end': 4905.631, 'text': "So we jump from this to this and that makes it look like it's just one seamless movement.", 'start': 4900.349, 'duration': 5.282}, {'end': 4915.387, 'text': 'We can also calculate position X differently.', 'start': 4913.325, 'duration': 2.062}, {'end': 4921.893, 'text': 'I can create a game frame variable, and I set it to zero.', 'start': 4919.171, 'duration': 2.722}], 'summary': 'Fast transition creates seamless movement with instant reset, using variable for position x.', 'duration': 30.087, 'max_score': 4891.806, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4891806.jpg'}, {'end': 4975.044, 'src': 'embed', 'start': 4941.909, 'weight': 6, 'content': [{'end': 4946.532, 'text': 'I also comment out line 43 and I can replace all of this with just one line of code.', 'start': 4941.909, 'duration': 4.623}, {'end': 4958.693, 'text': 'I say this.x from line 30 is equal to game frame variable we just created and I use remainder operator and this.width from line 32.', 'start': 4948.286, 'duration': 10.407}, {'end': 4965.078, 'text': 'This.width is currently 2, 400 pixels and game frame is endlessly increasing number.', 'start': 4958.693, 'duration': 6.385}, {'end': 4975.044, 'text': 'This calculation will make sure this.x cycles endlessly between zero and the value of this.width between zero and 2, 400 pixels,', 'start': 4965.558, 'duration': 9.486}], 'summary': 'Code optimization achieved by replacing multiple lines with a single line. calculates this.x to cycle endlessly between zero and 2,400 pixels.', 'duration': 33.135, 'max_score': 4941.909, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4941909.jpg'}, {'end': 5103.283, 'src': 'embed', 'start': 5069.619, 'weight': 11, 'content': [{'end': 5071.599, 'text': "I played with it for a while and I couldn't work it out.", 'start': 5069.619, 'duration': 1.98}, {'end': 5077.782, 'text': "Do you see how the background jumps every time I change game speed? Let's comment out these lines so that we can compare it.", 'start': 5071.619, 'duration': 6.163}, {'end': 5084.828, 'text': 'When using the original technique horizontal position transitions smoothly without jumps and that is exactly what I want.', 'start': 5078.342, 'duration': 6.486}, {'end': 5094.976, 'text': 'I need to be able to change my scrolling speed dynamically because I want the scroll speed of my game to change when a character performs special moves like roll or sit.', 'start': 5085.228, 'duration': 9.748}, {'end': 5103.283, 'text': "Let's comment out line 66 since we decided not to use this technique and I also comment out line 6.", 'start': 5095.877, 'duration': 7.406}], 'summary': 'Struggling with background jumps, aiming for smooth transitions and dynamic scrolling speed in game development.', 'duration': 33.664, 'max_score': 5069.619, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5069619.jpg'}, {'end': 5205.64, 'src': 'embed', 'start': 5176.05, 'weight': 8, 'content': [{'end': 5178.851, 'text': 'Art for this episode was made by this amazing artist.', 'start': 5176.05, 'duration': 2.801}, {'end': 5181.011, 'text': 'Go check out his website if you want to see more.', 'start': 5179.231, 'duration': 1.78}, {'end': 5184.472, 'text': 'We will cover four different movement animation techniques.', 'start': 5181.311, 'duration': 3.161}, {'end': 5186.072, 'text': 'And by the end of this video,', 'start': 5184.752, 'duration': 1.32}, {'end': 5194.274, 'text': 'you will have four complete projects and you will be able to introduce a variety of different enemies and movement patterns to your personal JavaScript games.', 'start': 5186.072, 'duration': 8.202}, {'end': 5197.676, 'text': 'Sometimes we tend to make our games too easy and predictable.', 'start': 5194.594, 'duration': 3.082}, {'end': 5201.298, 'text': "Let's give our players some challenge by including different enemy types.", 'start': 5197.836, 'duration': 3.462}, {'end': 5205.64, 'text': 'I create a simple web page markup.', 'start': 5203.999, 'duration': 1.641}], 'summary': 'Learn four movement animation techniques for javascript games with four complete projects and a variety of enemies and movement patterns.', 'duration': 29.59, 'max_score': 5176.05, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5176050.jpg'}, {'end': 5248.543, 'src': 'embed', 'start': 5218.667, 'weight': 9, 'content': [{'end': 5222.57, 'text': 'I also link my script.js file, which will contain all animation logic.', 'start': 5218.667, 'duration': 3.903}, {'end': 5232.094, 'text': 'In the style CSS, I take my canvas element I just created, and I want to give it some border, size, and I want to center it in the middle of the page.', 'start': 5223.51, 'duration': 8.584}, {'end': 5234.416, 'text': 'So border, three pixels, solid black.', 'start': 5232.215, 'duration': 2.201}, {'end': 5241.559, 'text': 'Position absolute, top 50%, left 50%.', 'start': 5235.036, 'duration': 6.523}, {'end': 5247.783, 'text': 'Transform, translate, minus 50%, minus 50%.', 'start': 5241.559, 'duration': 6.224}, {'end': 5248.543, 'text': "Now it's in the middle.", 'start': 5247.783, 'duration': 0.76}], 'summary': 'Css styles canvas with 3px border, centers on page.', 'duration': 29.876, 'max_score': 5218.667, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5218667.jpg'}, {'end': 5301.909, 'src': 'embed', 'start': 5271.119, 'weight': 2, 'content': [{'end': 5277.565, 'text': 'I do it by using getElementById and I pass it id I gave my canvas element, canvas1, like this.', 'start': 5271.119, 'duration': 6.446}, {'end': 5285.251, 'text': 'CTX shortcut for context is equal to canvas.getContext and I pass it 2D.', 'start': 5278.646, 'duration': 6.605}, {'end': 5289.515, 'text': 'We will use a built-in set of 2D drawing methods today.', 'start': 5285.712, 'duration': 3.803}, {'end': 5293.6, 'text': 'Now I can call all these built-in methods from my ctx variable.', 'start': 5290.456, 'duration': 3.144}, {'end': 5301.909, 'text': "If I type ctx dot like this you can see that in VS Code Editor my autocomplete feature doesn't suggest any built-in canvas methods.", 'start': 5294, 'duration': 7.909}], 'summary': 'Using getelementbyid, canvas.getcontext(2d), and built-in 2d drawing methods in javascript.', 'duration': 30.79, 'max_score': 5271.119, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5271119.jpg'}, {'end': 5389.281, 'src': 'embed', 'start': 5363.156, 'weight': 12, 'content': [{'end': 5368.36, 'text': "Before we create many enemies, let's just build one and make it absolutely clear for beginners what's going on.", 'start': 5363.156, 'duration': 5.204}, {'end': 5370.502, 'text': "When we have that, it's easy to scale it up.", 'start': 5368.721, 'duration': 1.781}, {'end': 5375.186, 'text': 'I will create a temporary enemy one variable and I set it equal to JavaScript object.', 'start': 5370.963, 'duration': 4.223}, {'end': 5378.689, 'text': 'I give it X and Y properties and I set them to zero.', 'start': 5375.887, 'duration': 2.802}, {'end': 5383.833, 'text': 'These will represent horizontal and vertical coordinate on canvas where we draw that enemy.', 'start': 5379.27, 'duration': 4.563}, {'end': 5389.281, 'text': 'I will also give it width of 200 pixels and height of 200 pixels, like this.', 'start': 5385.017, 'duration': 4.264}], 'summary': 'Creating a beginner-friendly enemy with x and y properties, 200x200 in size.', 'duration': 26.125, 'max_score': 5363.156, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5363156.jpg'}, {'end': 5479.874, 'src': 'embed', 'start': 5451.828, 'weight': 0, 'content': [{'end': 5453.869, 'text': 'This will create an endless animation loop.', 'start': 5451.828, 'duration': 2.041}, {'end': 5460.834, 'text': 'I also need to delete old paint, previous frames from canvas.', 'start': 5457.132, 'duration': 3.702}, {'end': 5469.02, 'text': 'I do it by using built-in clearRectangle method and I clear canvas from coordinates 0, 0 to canvas with canvas height.', 'start': 5461.495, 'duration': 7.525}, {'end': 5472.723, 'text': 'Now we see only the current animation frame.', 'start': 5470.379, 'duration': 2.344}, {'end': 5479.874, 'text': 'I can also increase vertical Y position by one for every frame, so we get movement towards bottom right like this.', 'start': 5473.584, 'duration': 6.29}], 'summary': 'Creating endless animation loop and clearing canvas for current frame.', 'duration': 28.046, 'max_score': 5451.828, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5451828.jpg'}, {'end': 5672.214, 'src': 'embed', 'start': 5642.934, 'weight': 4, 'content': [{'end': 5644.655, 'text': "Let's adjust its speed, for example.", 'start': 5642.934, 'duration': 1.721}, {'end': 5647.117, 'text': 'Now we can see that there are two of them.', 'start': 5645.536, 'duration': 1.581}, {'end': 5653.621, 'text': "We can control them separately like this, but this wouldn't be very efficient if we had, let's say, 50 or even 500 enemies.", 'start': 5647.517, 'duration': 6.104}, {'end': 5656.483, 'text': 'So how do we make this code better and remove repetition?', 'start': 5654.101, 'duration': 2.382}, {'end': 5665.489, 'text': "First, let's output this code between lines 21 and 24 that handles movement along x and y-axis into a shared class method.", 'start': 5657.003, 'duration': 8.486}, {'end': 5672.214, 'text': 'That way we can write this code only once and it will be available to all objects created by enemy class.', 'start': 5666.109, 'duration': 6.105}], 'summary': 'Optimizing code for managing multiple enemies efficiently by using shared class method.', 'duration': 29.28, 'max_score': 5642.934, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c5642934.jpg'}], 'start': 4349.879, 'title': 'Parallax background and javascript animation', 'summary': 'Demonstrates creating a parallax background with five layers, each moving at different speeds, and implementing a slider to change scroll speed. it also covers javascript animation projects with 4 different movement patterns and object creation and animation using classes.', 'chapters': [{'end': 4664.57, 'start': 4349.879, 'title': 'Parallax background with scroll speed control', 'summary': 'Demonstrates creating a parallax background with five layers, each moving at different speeds relative to a global game speed variable, and also implementing a slider in html to allow users to change the scroll speed, with the maximum value set to 20.', 'duration': 314.691, 'highlights': ['The parallax background consists of five layers moving at different speeds relative to a global game speed variable.', 'Implementing a slider in HTML to allow users to change the scroll speed, with the maximum value set to 20.', 'Connecting the slider to the GameSpeed variable and updating the scroll speed of the layers accordingly.']}, {'end': 5127.348, 'start': 4665.071, 'title': 'Optimizing parallax image positioning', 'summary': 'Discusses optimizing parallax image positioning, replacing separate variables with a single variable to synchronize image positions, resulting in seamless movement and the use of game frame and speed for endless cycling of image positions, but with a disadvantage of jumps when changing game speed.', 'duration': 462.277, 'highlights': ['Using one variable to synchronize image positions resulted in seamless movement', 'Utilizing game frame for endless cycling of image positions', 'Disadvantage of jumps in horizontal position when changing game speed']}, {'end': 5479.874, 'start': 5127.808, 'title': 'Javascript animation tutorial', 'summary': 'Covers the creation of 4 small projects from scratch, including the generation of animated computer-controlled characters and the exploration of 4 different movement animation patterns using vanilla javascript, resulting in the development of four complete projects and the ability to introduce a variety of different enemies and movement patterns to personal javascript games.', 'duration': 352.066, 'highlights': ['Creation of 4 small projects from scratch', 'Generation of animated computer-controlled characters', 'Exploration of 4 different movement animation patterns', 'Introduction of a variety of different enemies and movement patterns']}, {'end': 6036.183, 'start': 5481.015, 'title': 'Javascript object creation and animation', 'summary': 'Explains how to create and animate multiple javascript objects using classes, including defining a template for object creation, using class methods for efficient movement and drawing, and creating and animating multiple objects through an array and for-each loop.', 'duration': 555.168, 'highlights': ['Creating a JavaScript class for generating multiple enemies', 'Utilizing class methods for efficient movement and drawing', 'Creating and animating multiple objects through an array and for-each loop']}], 'duration': 1686.304, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c4349879.jpg', 'highlights': ['Creation of 4 small projects from scratch', 'Introduction of a variety of different enemies and movement patterns', 'Creating a JavaScript class for generating multiple enemies', 'Utilizing class methods for efficient movement and drawing', 'Creating and animating multiple objects through an array and for-each loop', 'The parallax background consists of five layers moving at different speeds relative to a global game speed variable', 'Implementing a slider in HTML to allow users to change the scroll speed, with the maximum value set to 20', 'Connecting the slider to the GameSpeed variable and updating the scroll speed of the layers accordingly', 'Using one variable to synchronize image positions resulted in seamless movement', 'Utilizing game frame for endless cycling of image positions', 'Disadvantage of jumps in horizontal position when changing game speed', 'Generation of animated computer-controlled characters', 'Exploration of 4 different movement animation patterns']}, {'end': 8357.862, 'segs': [{'end': 7005.31, 'src': 'embed', 'start': 6976.561, 'weight': 2, 'content': [{'end': 6978.963, 'text': 'This will randomize the wave shape for each enemy.', 'start': 6976.561, 'duration': 2.402}, {'end': 6981.946, 'text': "Let's set this dot angle to zero for now.", 'start': 6980.004, 'duration': 1.942}, {'end': 6985.789, 'text': 'I reduce the number of enemies on line six.', 'start': 6983.828, 'duration': 1.961}, {'end': 6991.955, 'text': 'As I said, math.sign returns values that cycle periodically between minus one and plus one.', 'start': 6986.59, 'duration': 5.365}, {'end': 6994.786, 'text': 'What if I want to make the curve more prominent?', 'start': 6992.725, 'duration': 2.061}, {'end': 7005.31, 'text': 'I can simply just multiply it times 3 here on line 29 and now we are getting values that cycle between minus 3 and plus 3..', 'start': 6997.447, 'duration': 7.863}], 'summary': 'Randomized wave shape for enemies with reduced count and amplified cycle values.', 'duration': 28.749, 'max_score': 6976.561, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c6976561.jpg'}, {'end': 7492.2, 'src': 'embed', 'start': 7465.883, 'weight': 4, 'content': [{'end': 7469.646, 'text': 'So this technique can be customized to achieve movement pattern you are looking for.', 'start': 7465.883, 'duration': 3.763}, {'end': 7476.374, 'text': 'Maybe your game starts easy but later it becomes more difficult so you need faster enemies.', 'start': 7472.199, 'duration': 4.175}, {'end': 7483.915, 'text': 'If I put 360 here, 360 is divisible by 90.', 'start': 7479.952, 'duration': 3.963}, {'end': 7492.2, 'text': 'If you watch the animation, we will get four horizontal cycles before we get one vertical cycle because 360 divided by 90 is four.', 'start': 7483.915, 'duration': 8.285}], 'summary': 'Customize technique for movement pattern with faster enemies, achieving 4 horizontal cycles before 1 vertical cycle.', 'duration': 26.317, 'max_score': 7465.883, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c7465883.jpg'}, {'end': 7694.848, 'src': 'embed', 'start': 7670.425, 'weight': 1, 'content': [{'end': 7676.808, 'text': 'You can, for example, use it to create automatically moving particle effects and animations for website and many other things.', 'start': 7670.425, 'duration': 6.383}, {'end': 7681.87, 'text': 'Creative coding gives us a lot of opportunities to come up with unique, beautiful stuff.', 'start': 7678.309, 'duration': 3.561}, {'end': 7688.613, 'text': "And that's why we are building these projects together to improve our vanilla JavaScript skills and at the same time to explore what's possible.", 'start': 7682.29, 'duration': 6.323}, {'end': 7691.094, 'text': 'Maybe it will spark new ideas in some of you.', 'start': 7689.013, 'duration': 2.081}, {'end': 7694.848, 'text': 'I know that there are many creative people watching my videos.', 'start': 7692.526, 'duration': 2.322}], 'summary': 'Learn to use creative coding for unique animations and effects in websites, sparking new ideas for creative individuals.', 'duration': 24.423, 'max_score': 7670.425, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c7670425.jpg'}, {'end': 8176.267, 'src': 'embed', 'start': 8148.877, 'weight': 0, 'content': [{'end': 8155.58, 'text': 'Let me show you two different simple algorithms you can use to detect collision between two rectangles, two hitboxes in our games.', 'start': 8148.877, 'duration': 6.703}, {'end': 8159.541, 'text': "Let's say we have rectangle 1 and rectangle 2.", 'start': 8156.1, 'duration': 3.441}, {'end': 8163.583, 'text': 'Both of these objects have x and y coordinates and some width and height.', 'start': 8159.541, 'duration': 4.042}, {'end': 8167.064, 'text': 'The first way I can check if they collide is this.', 'start': 8164.723, 'duration': 2.341}, {'end': 8176.267, 'text': 'I create a simple if statement and I check if horizontal position x of rectangle 1 is less than horizontal position x of rectangle 2,', 'start': 8167.644, 'duration': 8.623}], 'summary': 'Two simple algorithms to detect collision between rectangles in games.', 'duration': 27.39, 'max_score': 8148.877, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c8148877.jpg'}], 'start': 6036.524, 'title': 'Javascript game development', 'summary': 'Covers creating animated enemies, sprite animation, character movement, trigonometry for wavy movement, circular movement using sine and cosine, with a focus on beginner-friendly techniques, and the process of making enemies move in a game using javascript, emphasizing the importance of collision detection and hitboxes.', 'chapters': [{'end': 6192.375, 'start': 6036.524, 'title': 'Creating animated enemies in javascript', 'summary': 'Introduces creating four different animated enemies for javascript games, encouraging support for the artist and focusing on beginner-friendly movement animation techniques, providing free sprites for educational purposes and the option to purchase a full license for commercial use.', 'duration': 155.851, 'highlights': ['The chapter introduces creating four different animated enemies for JavaScript games, focusing on beginner-friendly movement animation techniques.', 'The artist provides free sprites for educational purposes and offers the option to purchase a full license for commercial use.', 'Encourages support for the artist to enable the creation of more game art assets.', 'Demonstrates the process of bringing new images into a JavaScript project and encourages using the same files initially.']}, {'end': 6794.541, 'start': 6192.915, 'title': 'Sprite animation and character movement', 'summary': 'Explains sprite animation and character movement in javascript, covering topics such as cropping sprite frames, animating characters, adjusting animation speed, randomizing movement patterns, and switching sprite sheets.', 'duration': 601.626, 'highlights': ['The chapter explains how to crop out one frame at a time and animate characters by jumping between sprite frames, utilizing the drawImage method and adjusting the width and height of the sprite sheet.', 'The method for slowing down animation is detailed, using the GameFrame variable and conditional logic to control the frequency of animation frames.', 'The process of randomizing animation frequency for characters is explained, involving the creation of a custom FlapSpeed property and the use of math.random to achieve varied animation speeds.', 'The chapter demonstrates how to implement randomized jumpy chaotic movement for characters, utilizing math.random to control horizontal and vertical movement within a specified range.', 'The chapter provides guidance on resetting character positions to create a continuous movement pattern, ensuring characters reappear after moving behind the canvas boundaries.']}, {'end': 7262.69, 'start': 6795.362, 'title': 'Javascript sine wave trigonometry', 'summary': 'Explains how to create wavy movement in javascript animations using sine waves, with examples demonstrating how to manipulate the angle, speed, and curve to produce varied and dynamic enemy movements.', 'duration': 467.328, 'highlights': ['The chapter explains how to create wavy movement in JavaScript animations using sine waves', 'Examples demonstrate how to manipulate the angle, speed, and curve to produce varied and dynamic enemy movements', 'Demonstration of using math.sine and math.cosine built-in JavaScript methods']}, {'end': 7749.775, 'start': 7263.51, 'title': 'Using sine and cosine for circular movement', 'summary': 'Explains how to use sine and cosine functions to create circular movement patterns for game characters, by adjusting angle speed, randomizing radius, and experimenting with the relationship between the sine and cosine values.', 'duration': 486.265, 'highlights': ['Using Math.sine and Math.cosine functions to create periodical horizontal and vertical movement for circular path', 'Randomizing radius for circular movement of characters', 'Adjusting angle speed to control the speed of character movement along the circular path', 'Experimenting with the relationship between sine and cosine values to customize movement patterns']}, {'end': 8357.862, 'start': 7750.395, 'title': 'Javascript game development', 'summary': 'Discusses the process of making enemies move in a game using javascript, including setting random positions, creating individual reset intervals for enemies, and the concept of collision detection, highlighting the importance of hitboxes and simple collision detection algorithms.', 'duration': 607.467, 'highlights': ['The chapter discusses the process of making enemies move in a game using JavaScript, including setting random positions, creating individual reset intervals for enemies, and the concept of collision detection.', 'The chapter explains the importance of hitboxes and simple collision detection algorithms in game development.']}], 'duration': 2321.338, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c6036524.jpg', 'highlights': ['The chapter explains how to create wavy movement in JavaScript animations using sine waves', 'The chapter discusses the process of making enemies move in a game using JavaScript, including setting random positions, creating individual reset intervals for enemies, and the concept of collision detection', 'The chapter introduces creating four different animated enemies for JavaScript games, focusing on beginner-friendly movement animation techniques', 'Using Math.sine and Math.cosine functions to create periodical horizontal and vertical movement for circular path', 'The method for slowing down animation is detailed, using the GameFrame variable and conditional logic to control the frequency of animation frames']}, {'end': 10251.162, 'segs': [{'end': 9312.396, 'src': 'embed', 'start': 9286.568, 'weight': 0, 'content': [{'end': 9294.453, 'text': 'canvas position and I set it equal to canvas from line one and I call get bounding line rectangle built in method on it.', 'start': 9286.568, 'duration': 7.885}, {'end': 9299.816, 'text': 'GetBoundingClientRectangle is a very useful built-in JavaScript method.', 'start': 9295.768, 'duration': 4.048}, {'end': 9306.489, 'text': 'It returns an object, providing information about the size of an element and its position relative to the viewport.', 'start': 9300.076, 'duration': 6.413}, {'end': 9312.396, 'text': 'I can console.log my canvas position variable now and you can see the object here.', 'start': 9307.512, 'duration': 4.884}], 'summary': 'Demonstrates using getboundingclientrect method for canvas positioning.', 'duration': 25.828, 'max_score': 9286.568, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c9286568.jpg'}, {'end': 9390.222, 'src': 'embed', 'start': 9362.901, 'weight': 1, 'content': [{'end': 9368.704, 'text': 'Perfect You can see that rectangle is being drawn towards the right bottom from my mouse cursor.', 'start': 9362.901, 'duration': 5.803}, {'end': 9370.945, 'text': 'This is how rectangles work on canvas.', 'start': 9369.204, 'duration': 1.741}, {'end': 9378.768, 'text': 'If I want my mouse to be exactly in the middle of the rectangle both vertically and horizontally, I need to do one more small tweak here.', 'start': 9371.505, 'duration': 7.263}, {'end': 9381.969, 'text': 'I offset my positions by half of width and height.', 'start': 9379.268, 'duration': 2.701}, {'end': 9390.222, 'text': 'My width and height is 50, so I offset x and y by minus 25.', 'start': 9382.489, 'duration': 7.733}], 'summary': 'Rectangles are drawn on canvas with a mouse, positioned in the middle by offsetting x and y by minus 25.', 'duration': 27.321, 'max_score': 9362.901, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c9362901.jpg'}, {'end': 9825.686, 'src': 'embed', 'start': 9798.651, 'weight': 4, 'content': [{'end': 9806.113, 'text': 'login my array on line 36 in browser console i can see that we are correctly adding and removing objects from the array.', 'start': 9798.651, 'duration': 7.462}, {'end': 9813.662, 'text': 'awesome, We have a solid infrastructure for triggered animation and we can connect this code to collision coordinates, for example,', 'start': 9806.113, 'duration': 7.549}, {'end': 9816.463, 'text': 'and run this animation when two objects collide in our game.', 'start': 9813.662, 'duration': 2.801}, {'end': 9819.644, 'text': 'We can also connect it to different events and user input.', 'start': 9816.963, 'duration': 2.681}, {'end': 9821.065, 'text': "It doesn't have to be a click event.", 'start': 9819.804, 'duration': 1.261}, {'end': 9825.686, 'text': 'To avoid code repetition, I will put this code into a separate custom function.', 'start': 9821.465, 'duration': 4.221}], 'summary': 'Array operations verified; infrastructure set for triggered animation linked to collision coordinates, events, and user input.', 'duration': 27.035, 'max_score': 9798.651, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c9798651.jpg'}, {'end': 10177.435, 'src': 'embed', 'start': 10137.694, 'weight': 2, 'content': [{'end': 10141.677, 'text': 'We will learn how to achieve pixel-perfect collision detection using colors,', 'start': 10137.694, 'duration': 3.983}, {'end': 10148.06, 'text': 'how to use timestamps and delta time to make sure our game runs at the same speed on different machines.', 'start': 10142.017, 'duration': 6.043}, {'end': 10158.785, 'text': 'we will learn about arrays and I will show you how to remove old game objects using array filter method and how to use array sort method to create a correct draw order in a 2D game.', 'start': 10148.06, 'duration': 10.725}, {'end': 10166.709, 'text': 'We will also talk about modern JavaScript syntax and we will learn how to make our animation code cleaner and less repetitive with spread operator.', 'start': 10159.025, 'duration': 7.684}, {'end': 10169.631, 'text': 'I will also share many small tips and tricks as we go along.', 'start': 10166.949, 'duration': 2.682}, {'end': 10176.034, 'text': "Students of today's course will get two premium sprite sheets completely for free, kindly provided by this amazing artist.", 'start': 10169.831, 'duration': 6.203}, {'end': 10177.435, 'text': 'Check out his website for more.', 'start': 10176.234, 'duration': 1.201}], 'summary': 'Learn pixel-perfect collision, timestamps, arrays, and modern js syntax.', 'duration': 39.741, 'max_score': 10137.694, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c10137694.jpg'}], 'start': 8363.427, 'title': 'Javascript game development techniques', 'summary': 'Covers javascript game development techniques including achieving pixel-perfect collision detection, using timestamps and delta time, array manipulation, modern javascript syntax, and building interactive animated projects with html5 canvas.', 'chapters': [{'end': 8860.431, 'start': 8363.427, 'title': 'Collision detection in javascript', 'summary': 'Discusses the importance of collision detection in building particle systems, games, and canvas animations, focusing on techniques for detecting collisions between circles and explaining the algorithm for detecting collisions between two circles with javascript.', 'duration': 497.004, 'highlights': ['The algorithm for detecting collisions between two circles with JavaScript is explained, involving the calculation of the distance between the center points of the circles and the comparison with the sum of their radii.', 'The process of measuring the distance between two points with JavaScript, using a right angle triangle and the Pythagorean theorem, is detailed to calculate the hypotenuse and determine collision.', 'The importance of visual and audio feedback in JavaScript games is emphasized, suggesting the use of collision detection for triggering sound and animation effects.', 'The setup for a simple JavaScript game combining audio and sprite animation using HTML5 canvas is briefly outlined, including the creation of the canvas element and linking of CSS and JavaScript files.']}, {'end': 9133.746, 'start': 8861.718, 'title': 'Sprite sheet animation', 'summary': 'Explains how to calculate the width of a single frame in a sprite sheet, scale the sprite sheet while maintaining aspect ratio, optimize performance by using multiplication instead of division, and use the drawimage method to animate sprite sheets on a canvas.', 'duration': 272.028, 'highlights': ['The sprite sheet width is calculated based on the total width of the sprite sheet and the number of frames, resulting in a width of 200 pixels per frame.', 'The aspect ratio relationship between width and height of the sprite sheet is maintained when scaling to prevent stretching or squishing of the image.', 'Optimizing performance by using multiplication instead of division is recommended in JavaScript due to the higher performance cost of division operations.', 'The drawImage method is utilized to animate the sprite sheet on the canvas by specifying the image, source position, source dimensions, and destination position.']}, {'end': 9405.409, 'start': 9133.986, 'title': 'Drawing rectangles on canvas', 'summary': 'Explains how to draw a simple rectangle on a canvas in response to a mouse click event, offsetting the coordinates to account for page margins and positioning the rectangle under the mouse cursor.', 'duration': 271.423, 'highlights': ['The chapter provides guidance on drawing a simple rectangle on a canvas in response to a mouse click event, using the fillRectangle method with the x, y, width, and height arguments.', 'The chapter demonstrates the utilization of the getBoundingClientRect method to measure the position and size of an element relative to the viewport, providing valuable information for offsetting coordinates and drawing elements at the correct positions.', 'The chapter emphasizes the importance of offsetting the coordinates by half of the width and height to ensure that the mouse cursor is positioned exactly in the middle of the drawn rectangle.']}, {'end': 10003.745, 'start': 9405.409, 'title': 'Custom explosion sprite animation', 'summary': 'Details the implementation of a custom explosion sprite animation in canvas, utilizing an explosion class to create and manage sprite animations triggered by mouse clicks, with a focus on object manipulation, animation loop, and removal of inactive objects from the array.', 'duration': 598.336, 'highlights': ['The chapter details the implementation of a custom explosion sprite animation in canvas, utilizing an explosion class to create and manage sprite animations triggered by mouse clicks.', 'The chapter emphasizes the importance of object manipulation, animation loop, and removal of inactive objects from the array in the implementation of the sprite animation.', 'The chapter demonstrates the use of separate variables to offset and center horizontal and vertical positions, contributing to code cleanliness and readability.']}, {'end': 10251.162, 'start': 10004.345, 'title': 'Javascript game development techniques', 'summary': 'Covers javascript game development techniques including achieving pixel-perfect collision detection, using timestamps and delta time, array manipulation, modern javascript syntax, and building interactive animated projects with html5 canvas.', 'duration': 246.817, 'highlights': ['The chapter covers achieving pixel-perfect collision detection using colors, using timestamps and delta time to ensure consistent game speed, and array manipulation including removing old game objects and creating a correct draw order.', 'The tutorial emphasizes the importance of choosing the right sound and animation speed to enhance the game experience and user satisfaction.', 'The instructor offers additional resources, including premium sprite sheets for students, and encourages viewers to explore more advanced game development techniques.']}], 'duration': 1887.735, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c8363427.jpg', 'highlights': ['Covers achieving pixel-perfect collision detection using colors, timestamps, and delta time', 'Explains algorithm for detecting collisions between circles with JavaScript', 'Demonstrates drawing a simple rectangle on a canvas in response to a mouse click event', 'Details implementation of custom explosion sprite animation in canvas', 'Emphasizes importance of visual and audio feedback in JavaScript games']}, {'end': 11260.873, 'segs': [{'end': 10565.886, 'src': 'embed', 'start': 10535.595, 'weight': 0, 'content': [{'end': 10539.376, 'text': "It's actually very simple but it might take some time to get used to it if you are a beginner.", 'start': 10535.595, 'duration': 3.781}, {'end': 10541.157, 'text': "Let's do it and see how it works.", 'start': 10539.696, 'duration': 1.461}, {'end': 10545.679, 'text': 'What is happening here, we are calling animate using requestAnimationFrame.', 'start': 10541.877, 'duration': 3.802}, {'end': 10556.343, 'text': 'Animate becomes a callback function on requestAnimationFrame method and default JavaScript behavior for callback here is to pass it automatic timestamp as an argument.', 'start': 10546.219, 'duration': 10.124}, {'end': 10558.324, 'text': 'Its value is in milliseconds.', 'start': 10556.883, 'duration': 1.441}, {'end': 10565.886, 'text': "Just so you know where this timestamp will be coming from, it's a default JavaScript behavior when using RequestAnimationFrame.", 'start': 10559.244, 'duration': 6.642}], 'summary': 'Using requestanimationframe for animation, timestamp in milliseconds passed as argument.', 'duration': 30.291, 'max_score': 10535.595, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c10535595.jpg'}, {'end': 10608.063, 'src': 'embed', 'start': 10579.35, 'weight': 1, 'content': [{'end': 10583.491, 'text': 'My goal here is to take time from the current loop, save that value,', 'start': 10579.35, 'duration': 4.141}, {'end': 10589.614, 'text': 'run the loop again with new timestamp value and compare them to see how many milliseconds it took in between frames.', 'start': 10583.491, 'duration': 6.123}, {'end': 10592.075, 'text': 'I will need some helper variables here.', 'start': 10590.434, 'duration': 1.641}, {'end': 10602.219, 'text': 'TimeToNextRaven will be a variable that will accumulate millisecond values between frames until it reaches my interval value and trigger next frame.', 'start': 10593.195, 'duration': 9.024}, {'end': 10604.34, 'text': 'Initially, it will start at zero.', 'start': 10602.499, 'duration': 1.841}, {'end': 10608.063, 'text': 'raven interval will be a value in milliseconds.', 'start': 10605.06, 'duration': 3.003}], 'summary': 'Measure time between frames to trigger next frame with accumulated millisecond values.', 'duration': 28.713, 'max_score': 10579.35, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c10579350.jpg'}, {'end': 10968.434, 'src': 'embed', 'start': 10945.573, 'weight': 2, 'content': [{'end': 10954.08, 'text': "And since I'm console.logging ravens array on line 36, I can see it adds new raven object to the array every 500 milliseconds.", 'start': 10945.573, 'duration': 8.507}, {'end': 10956.983, 'text': 'I remove the console.log.', 'start': 10955.802, 'duration': 1.181}, {'end': 10959.545, 'text': 'We have data for ravens inside the array.', 'start': 10957.223, 'duration': 2.322}, {'end': 10963.749, 'text': 'We just need to cycle through that array, through every single raven object,', 'start': 10959.926, 'duration': 3.823}, {'end': 10968.434, 'text': 'and call their update and draw methods so that we can actually see movement on canvas.', 'start': 10963.749, 'duration': 4.685}], 'summary': 'New raven object added to array every 500ms for movement on canvas.', 'duration': 22.861, 'max_score': 10945.573, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c10945573.jpg'}, {'end': 11107.892, 'src': 'embed', 'start': 11064.608, 'weight': 3, 'content': [{'end': 11073.057, 'text': 'where i created a new array and i used the spread operator to expand my ravens into that new array just so that i can call update and draw on them?', 'start': 11064.608, 'duration': 8.449}, {'end': 11077.882, 'text': 'I could have just called it on ravens array directly without expanding it like this.', 'start': 11073.678, 'duration': 4.204}, {'end': 11085.89, 'text': 'The reason I did that is because when I create particle class in a minute, I can just spread my particles into the same array along with the ravens.', 'start': 11078.183, 'duration': 7.707}, {'end': 11090.195, 'text': 'As long as my particle class will have update and draw methods to call,', 'start': 11086.351, 'duration': 3.844}, {'end': 11095.9, 'text': 'the code will work and I can call all my classes by just expanding more and more arrays in here.', 'start': 11090.195, 'duration': 5.705}, {'end': 11102.346, 'text': 'I can for example also have an array of enemies, obstacles, power-ups and other elements in my game.', 'start': 11096.701, 'duration': 5.645}, {'end': 11107.892, 'text': 'I can spread all of them into a single array and call their update and draw methods all at once.', 'start': 11102.907, 'duration': 4.985}], 'summary': 'Using spread operator to expand arrays for calling update and draw methods efficiently.', 'duration': 43.284, 'max_score': 11064.608, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c11064608.jpg'}], 'start': 10251.342, 'title': 'Javascript animations and timestamp consistency', 'summary': 'Covers creating animated ravens with javascript, managing timestamps for consistent animation, and cycling through an array of objects while ensuring precise intervals and efficient array management.', 'chapters': [{'end': 10464.035, 'start': 10251.342, 'title': 'Creating animated ravens with javascript', 'summary': 'Outlines the process of creating a custom class for animated ravens in javascript, including setting properties and values, creating an animation loop, and clearing the canvas for an endless animation loop.', 'duration': 212.693, 'highlights': ['Creating a custom class for animated ravens in JavaScript', 'Setting properties and values for the raven objects', 'Creating an animation loop and clearing the canvas']}, {'end': 10945.032, 'start': 10464.455, 'title': 'Using timestamps for consistent animation', 'summary': 'Discusses using timestamps to ensure consistent animation across different computer performances, with a focus on triggering periodic events at a precise interval, and the use of timestamps for calculating delta time between frames.', 'duration': 480.577, 'highlights': ["The chapter introduces the concept of using timestamps to trigger periodic events at a consistent interval across different computer performances, ensuring that the animation remains consistent and accurate, regardless of the computer's processing power.", 'The discussion emphasizes the use of timestamps for calculating delta time between frames, ensuring that the animation remains synchronized and accurate, with the example highlighting the use of timestamps to compare the milliseconds elapsed since the last loop and trigger the drawing of the next frame at the precise moment.', 'The transcript covers the practical implementation of using timestamps to calculate delta time and trigger periodic events, providing step-by-step guidance on creating and manipulating variables to achieve this, offering a hands-on demonstration of the concept for practical understanding and application.', 'The chapter also addresses common issues and debugging techniques related to using timestamps, such as identifying and resolving undefined values and ensuring the initial timestamp value is properly set, providing valuable insights for troubleshooting timestamp-related challenges in animation development.']}, {'end': 11260.873, 'start': 10945.573, 'title': 'Managing and cycling through array of objects', 'summary': 'Explains how to manage and cycle through an array of objects, using the spread operator to call update and draw methods, filter out objects that have moved past the left edge of the screen, and reassign the array to remove marked objects.', 'duration': 315.3, 'highlights': ['Using the spread operator to expand the Ravens array into a new array allows calling update and draw methods on all the objects in the array without needing to iterate through each object individually, enhancing efficiency and performance.', "Filtering out objects that have moved past the left edge of the screen by setting a 'marked for deletion' property to true in the update method and using the filter method to create a new array without the marked objects, ensuring efficient management of the array and preventing performance issues.", 'Explanation of using the spread operator and array filter method to manage and cycle through multiple arrays of objects in a game, enabling the code to be clean and easy to read while allowing for the addition of new classes with update and draw methods in a single array.']}], 'duration': 1009.531, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c10251342.jpg', 'highlights': ['Using timestamps for consistent and accurate animation', 'Creating a custom class for animated ravens in JavaScript', 'Managing array of objects efficiently with spread operator and filter method', 'Practical implementation of using timestamps for calculating delta time', 'Clearing the canvas in the animation loop']}, {'end': 14259.639, 'segs': [{'end': 12158.331, 'src': 'embed', 'start': 12115.327, 'weight': 0, 'content': [{'end': 12118.607, 'text': 'We are drawing sprite sheets or raven images on canvas.', 'start': 12115.327, 'duration': 3.28}, {'end': 12124.289, 'text': "In some browsers, you won't be able to call get image data on the same canvas where you draw images.", 'start': 12119.008, 'duration': 5.281}, {'end': 12130.17, 'text': 'It will give you an error that says something like canvas was tainted by cross origin data.', 'start': 12124.789, 'duration': 5.381}, {'end': 12133.89, 'text': 'If you are running your code locally, most likely you see that error.', 'start': 12130.77, 'duration': 3.12}, {'end': 12137.091, 'text': "I'm using local server, so I'm not getting that error right now.", 'start': 12134.35, 'duration': 2.741}, {'end': 12141.535, 'text': "It's a security measure related to cross-origin resource sharing.", 'start': 12137.771, 'duration': 3.764}, {'end': 12149.362, 'text': 'Apparently, there could be viruses hidden in some images and by scanning that image with GetImageData, you could expose yourself to that virus.', 'start': 12141.815, 'duration': 7.547}, {'end': 12155.727, 'text': 'There are many ways to get around this problem and scan canvas without exposing yourself to any potential risks.', 'start': 12149.682, 'duration': 6.045}, {'end': 12158.331, 'text': "In our case it's simple, let me show you.", 'start': 12156.408, 'duration': 1.923}], 'summary': 'Drawing sprite sheets on canvas, avoiding cross-origin errors and risks of exposing to viruses by scanning canvas.', 'duration': 43.004, 'max_score': 12115.327, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c12115327.jpg'}, {'end': 12318.658, 'src': 'embed', 'start': 12293.887, 'weight': 2, 'content': [{'end': 12300.512, 'text': "Now each raven has a random red, green and blue color assigned when it's created by our class constructor,", 'start': 12293.887, 'duration': 6.625}, {'end': 12304.435, 'text': 'and we use these three values to create RGB color for its hitbox.', 'start': 12300.512, 'duration': 3.923}, {'end': 12310.94, 'text': "Hitbox means collision detection area and in our case it's the colored rectangle around each raven.", 'start': 12305.075, 'duration': 5.865}, {'end': 12318.658, 'text': 'We can also do much more complex shapes and still get pixel perfect collision detection but for purposes rectangles are fine.', 'start': 12311.28, 'duration': 7.378}], 'summary': 'Ravens are assigned random rgb colors for hitbox collision detection.', 'duration': 24.771, 'max_score': 12293.887, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c12293887.jpg'}, {'end': 12367.119, 'src': 'embed', 'start': 12333.971, 'weight': 6, 'content': [{'end': 12337.314, 'text': 'We will use these values kinda as a unique password for each raven.', 'start': 12333.971, 'duration': 3.343}, {'end': 12346.661, 'text': 'We click on canvas, get RGB value of that pixel we clicked on using get image data method, and we compare them with this random colors property.', 'start': 12337.674, 'duration': 8.987}, {'end': 12350.044, 'text': 'If they all match, we know we click on this particular raven.', 'start': 12347.201, 'duration': 2.843}, {'end': 12352.205, 'text': 'This technique has one downside.', 'start': 12350.584, 'duration': 1.621}, {'end': 12356.989, 'text': 'There is a very small chance that there will be two identical colors generated next to each other.', 'start': 12352.385, 'duration': 4.604}, {'end': 12367.119, 'text': 'But since we do random number between zero and 255 three times and we only have between 3 and 7 active ravens on the screen at any given time,', 'start': 12357.429, 'duration': 9.69}], 'summary': 'Using rgb values as unique passwords for ravens; chance of identical colors is small due to random generation.', 'duration': 33.148, 'max_score': 12333.971, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c12333971.jpg'}, {'end': 13094.066, 'src': 'embed', 'start': 13061.132, 'weight': 8, 'content': [{'end': 13062.714, 'text': 'animation is complete.', 'start': 13061.132, 'duration': 1.582}, {'end': 13065.057, 'text': 'I set marked for deletion from line 74 to true.', 'start': 13062.714, 'duration': 2.343}, {'end': 13070.434, 'text': 'When I click on Ravens, sound plays and explosion sprites are animated.', 'start': 13066.752, 'duration': 3.682}, {'end': 13073.696, 'text': 'We are making great progress, we just need to polish some details here.', 'start': 13070.614, 'duration': 3.082}, {'end': 13080.559, 'text': 'If I change frame interval on line 73 to 500, you can see it only affects the first frame.', 'start': 13074.436, 'duration': 6.123}, {'end': 13083.16, 'text': 'The rest of animation is playing really fast.', 'start': 13080.939, 'duration': 2.221}, {'end': 13089.063, 'text': 'Oh, it is because I need to reset time since last frame back to zero every time,', 'start': 13084.481, 'duration': 4.582}, {'end': 13094.066, 'text': 'so it can count towards the next frame interval over and over to serve next frames.', 'start': 13089.063, 'duration': 5.003}], 'summary': 'Animation complete with frame interval adjusted to 500 resulting in fast playback initially; reset of time needed for smooth animation.', 'duration': 32.934, 'max_score': 13061.132, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c13061132.jpg'}, {'end': 13256.136, 'src': 'embed', 'start': 13227.781, 'weight': 5, 'content': [{'end': 13235.487, 'text': "It's because these coordinates on line 101 mark top left corner and the text goes towards right and bottom from that point.", 'start': 13227.781, 'duration': 7.706}, {'end': 13238.629, 'text': 'Same as when you are drawing rectangle or image on canvas.', 'start': 13235.647, 'duration': 2.982}, {'end': 13243.533, 'text': "With text it's easy to center by setting text align property to center like this.", 'start': 13239.249, 'duration': 4.284}, {'end': 13247.385, 'text': 'Yes, that worked.', 'start': 13246.584, 'duration': 0.801}, {'end': 13249.948, 'text': 'Same as I did with score, I want to give it shadow.', 'start': 13247.585, 'duration': 2.363}, {'end': 13256.136, 'text': 'I will use this trick where I draw the same text twice with different fill color and I offset it by 5 pixels.', 'start': 13249.968, 'duration': 6.168}], 'summary': 'Explaining text positioning and effects on canvas, using offset and shadow techniques for visual improvement.', 'duration': 28.355, 'max_score': 13227.781, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c13227781.jpg'}], 'start': 11260.873, 'title': 'Implementing sprite animation, collision detection, and game development in javascript', 'summary': 'Covers sprite animation, collision detection, and game development in javascript, including topics such as sprite sheets, canvas image data, raven collision detection, game over conditions, particle effects, and javascript game development tutorial.', 'chapters': [{'end': 12090.826, 'start': 11260.873, 'title': 'Sprite animation & collision detection', 'summary': 'Discusses implementing sprite animation using sprite sheets, including scaling, frame cycling, and delta time for consistent animation speed across different machines. it also covers collision detection using getimagedata method to detect pixel color for interaction with the game environment.', 'duration': 829.953, 'highlights': ['Implementing sprite animation using sprite sheets', 'Utilizing delta time for consistent animation speed', 'Implementing collision detection using GetImageData method']}, {'end': 12438.137, 'start': 12091.266, 'title': 'Canvas image data and collision detection', 'summary': 'Explains the process of scanning canvas elements using get image data, dealing with potential errors related to cross-origin resource sharing, creating unique hitboxes for collision detection, and sorting objects in an array based on size for depth perception in a 2d space.', 'duration': 346.871, 'highlights': ['The chapter explains the process of scanning canvas elements using get image data, addressing potential errors related to cross-origin resource sharing, and creating unique hitboxes for collision detection (e.g., assigning differently colored hitboxes to each raven, using random color values to draw hitboxes, and comparing RGB values for collision detection).', 'The tutorial provides a solution for dealing with potential errors related to cross-origin resource sharing by creating a secondary canvas to draw hitboxes and no images, thereby avoiding tainted canvas error and ensuring secure scanning.', 'The process of sorting objects in an array based on size using the built-in array sort method is described, ensuring the correct draw order in a 2D space for depth perception, and addressing the issue of smaller ravens occasionally being drawn in front of larger ones.', 'The chapter mentions the use of rainbow colors applied to the background with CSS and the application of rainbow colors to the body element, as well as the use of sprite sheets or raven images on canvas.']}, {'end': 12794.221, 'start': 12438.137, 'title': 'Raven collision detection in javascript', 'summary': 'Discusses implementing collision detection between mouse and ravens using javascript, focusing on comparing pixel colors and adding explosion animation and sound effects, resulting in successful collision detection and adding dynamic elements to the game.', 'duration': 356.084, 'highlights': ['Implementing collision detection between mouse and ravens using JavaScript', 'Comparing pixel colors and adding explosion animation and sound effects', 'Successful collision detection and dynamic game elements', 'Use of built-in JavaScript methods for sorting', 'Avoiding tainted canvas error']}, {'end': 13249.948, 'start': 12795.077, 'title': 'Sprite sheet animation and game over condition', 'summary': 'Explains sprite sheet animation implementation for explosions and the creation of a game over condition, with details on time management, animation triggering, and game termination.', 'duration': 454.871, 'highlights': ['The chapter explains the implementation of sprite sheet animation for explosions, utilizing time management and a frame interval of 200 milliseconds, and triggering the animation when the active frame of the explosion is 0, accompanied by playing a sound (lines 9-29).', 'The chapter details the creation of a game over condition, setting the GameOver variable to true when any raven crosses the left edge of the game area, and displaying the game over message with the final score (lines 93-135).', 'The chapter discusses the adjustments made for aligning the explosion animation over the raven sprites, including modifying the destinationY argument in the drawImage method and ensuring its alignment with the raven sprites (lines 78-87).', 'The chapter demonstrates the use of the spread operator to update and draw all ravens and explosions simultaneously and the removal of old explosion objects from the array using the built-in array filter method (lines 106-116).', 'The chapter explains the necessity of resetting the time since the last frame back to zero to ensure the proper counting towards the next frame interval for the explosion animation and the adjustments made to align the explosion animation over the raven sprites (lines 66-71).']}, {'end': 13788.802, 'start': 13249.968, 'title': 'Creating particle effects for game', 'summary': 'Discusses creating particle effects for a game, experimenting with background gradient, and using a code pattern to add particle effects to the game, while detailing the process of creating and animating particle trails behind flying ravens. additionally, it covers optimizing performance by randomizing the drawing of particle trails and adjusting the global alpha property for transparency.', 'duration': 538.834, 'highlights': ['The chapter discusses creating and animating particle trails behind flying ravens, including the process of creating a particle class with properties for x, y, size, and color, and the use of a constructor to initialize particle objects, with the radius, color, and speed of particles being customizable based on the properties of the ravens.', 'The chapter explains the use of the spread operator to expand the contents of the particles array, enabling the update and draw methods to be called for each particle, and the removal of old particles marked for deletion from the particles array to optimize performance.', 'The chapter covers the optimization of performance by randomizing the drawing of particle trails and adjusting the global alpha property for transparency, including the use of the Math.random function to determine the percentage of ravens with particle trails and setting the global alpha property to create a gradual transition from fully visible to transparent particles.']}, {'end': 14259.639, 'start': 13789.603, 'title': 'Javascript game development tutorial', 'summary': 'Discusses developing a javascript game, covering aspects like creating enemy types, subclassing in javascript, and building a game class, with a focus on modular, clean, and easy-to-read code.', 'duration': 470.036, 'highlights': ['The chapter discusses creating enemy types, such as fast flying bats worth extra score points and ravens with trails that are worth more score but also have more lives.', "The chapter explains the use of the 'extends' keyword to create parent and child subclasses, enabling the definition of specific properties and values for each enemy type, enhancing code modularity and readability.", 'The chapter emphasizes the importance of a game class as a wrapper for controlling all movement and animation logic, highlighting the necessity of a constructor, update and draw methods, and the need for a private method for adding new enemies.']}], 'duration': 2998.766, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c11260873.jpg', 'highlights': ['Implementing collision detection between mouse and ravens using JavaScript', 'Creating enemy types, such as fast flying bats worth extra score points', 'The chapter explains the process of scanning canvas elements using get image data', 'The chapter discusses creating and animating particle trails behind flying ravens', 'The chapter explains the use of the spread operator to update and draw all ravens and explosions simultaneously', 'The chapter details the creation of a game over condition, setting the GameOver variable to true when any raven crosses the left edge of the game area', 'The tutorial provides a solution for dealing with potential errors related to cross-origin resource sharing by creating a secondary canvas to draw hitboxes and no images', 'The chapter mentions the use of rainbow colors applied to the background with CSS and the application of rainbow colors to the body element', 'The chapter explains the implementation of sprite sheet animation for explosions, utilizing time management and a frame interval of 200 milliseconds', 'The chapter covers the optimization of performance by randomizing the drawing of particle trails and adjusting the global alpha property for transparency']}, {'end': 17120.311, 'segs': [{'end': 16176.165, 'src': 'embed', 'start': 16148.82, 'weight': 4, 'content': [{'end': 16155.306, 'text': 'The only problem is that math.random returns numbers with decimal points and there is no index 1.5 in this array.', 'start': 16148.82, 'duration': 6.486}, {'end': 16156.687, 'text': "It's easy to fix.", 'start': 16155.846, 'duration': 0.841}, {'end': 16162.412, 'text': 'I will wrap it inside math.floor which will round it down to the closest integer.', 'start': 16157.368, 'duration': 5.044}, {'end': 16165.695, 'text': 'Now I can check if random enemy variable is worm.', 'start': 16162.812, 'duration': 2.883}, {'end': 16169.959, 'text': 'We will push new worm into this.enemies array.', 'start': 16167.156, 'duration': 2.803}, {'end': 16176.165, 'text': 'Else if random enemy is ghost, we will push new ghost.', 'start': 16172.603, 'duration': 3.562}], 'summary': 'Using math.floor to round decimal numbers for array indexing, adding enemies based on random selection.', 'duration': 27.345, 'max_score': 16148.82, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c16148820.jpg'}, {'end': 16768.789, 'src': 'embed', 'start': 16740.274, 'weight': 3, 'content': [{'end': 16746.338, 'text': "I want the spiders to swing up and down from a spider web so let's extend draw method as well and draw it.", 'start': 16740.274, 'duration': 6.064}, {'end': 16757.182, 'text': 'First, I will call draw method from parent class from line 51.', 'start': 16752.699, 'duration': 4.483}, {'end': 16760.583, 'text': 'Here on line 88, I need to pass CTX as an argument.', 'start': 16757.182, 'duration': 3.401}, {'end': 16761.845, 'text': 'I forgot to do that.', 'start': 16760.743, 'duration': 1.102}, {'end': 16764.726, 'text': "We don't want to use global variables inside our classes.", 'start': 16762.105, 'duration': 2.621}, {'end': 16768.789, 'text': 'So on line 114, I pass draw method CTX.', 'start': 16765.206, 'duration': 3.583}], 'summary': 'Updating the draw method to include ctx argument and calling it on line 114.', 'duration': 28.515, 'max_score': 16740.274, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c16740274.jpg'}, {'end': 16940.215, 'src': 'embed', 'start': 16908.442, 'weight': 1, 'content': [{'end': 16911.425, 'text': 'i will call it, for example, this dot frame timer.', 'start': 16908.442, 'duration': 2.983}, {'end': 16912.926, 'text': 'i set it to zero initially.', 'start': 16911.425, 'duration': 1.501}, {'end': 16923.515, 'text': 'I check if this.frameTimer from line 49 is more than frameInterval from line 48..', 'start': 16913.806, 'duration': 9.709}, {'end': 16928.82, 'text': 'If it is I do something, else I increase frameTimer variable by deltaTime.', 'start': 16923.515, 'duration': 5.305}, {'end': 16934.906, 'text': 'Now I just realized we need access to deltaTime here so all this code actually needs to be in the siteUpdate method.', 'start': 16929.541, 'duration': 5.365}, {'end': 16940.215, 'text': 'Here Now I can say frame timer plus equals delta time.', 'start': 16935.726, 'duration': 4.489}], 'summary': 'Code monitors and updates frame timer based on delta time.', 'duration': 31.773, 'max_score': 16908.442, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c16908442.jpg'}, {'end': 16998.741, 'src': 'embed', 'start': 16974.66, 'weight': 0, 'content': [{'end': 16980.945, 'text': 'It will be increasing by delta time and when it reaches frame interval we can move to the next frame in sprite sheet.', 'start': 16974.66, 'duration': 6.285}, {'end': 16987.411, 'text': 'I have to check if current frame x from line 46 is less than max frame from line 47.', 'start': 16981.706, 'duration': 5.705}, {'end': 16990.854, 'text': 'If it is less we increase frame x by 1.', 'start': 16987.411, 'duration': 3.443}, {'end': 16993.656, 'text': 'Else we set frame x back to 0.', 'start': 16990.854, 'duration': 2.802}, {'end': 16998.741, 'text': 'At the same time I set frame timer back to 0 so it can start accumulating delta time again.', 'start': 16993.656, 'duration': 5.085}], 'summary': 'Increment frame x by 1 if less than max frame; reset to 0 otherwise.', 'duration': 24.081, 'max_score': 16974.66, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c16974660.jpg'}], 'start': 14260.279, 'title': 'Game development basics', 'summary': 'Explains creating and manipulating game objects using classes and constructor methods, including the use of delta time to ensure consistent game speed across different computers, with an example of adding enemies at regular intervals and accounting for varying computer speeds.', 'chapters': [{'end': 14480.938, 'start': 14260.279, 'title': 'Optimizing animation for different computers', 'summary': 'Discusses optimizing animation for different computers by explaining the importance of using the load event instead of the dom content loaded event, the process of calculating delta time to ensure consistent animation speed, and the impact of delta time on different computer speeds and screen refresh rates.', 'duration': 220.659, 'highlights': ['The importance of using the load event instead of the DOM content loaded event for loading images from an online server is explained.', 'The process of calculating delta time to ensure consistent animation speed is explained, with emphasis on using the timestamp argument passed by requestAnimationFrame.', 'The impact of delta time on different computer speeds and screen refresh rates is discussed, highlighting the need to adjust animation speed to ensure consistent performance.']}, {'end': 15059.118, 'start': 14481.458, 'title': 'Game development basics', 'summary': 'Explains how to create and manipulate game objects using classes and constructor methods, including the use of delta time to ensure consistent game speed across different computers, with an example of adding enemies at regular intervals and accounting for varying computer speeds.', 'duration': 577.66, 'highlights': ['The chapter focuses on creating and manipulating game objects using classes and constructor methods.', 'The importance of using delta time to ensure consistent game speed across different computers is highlighted.', 'An example of adding enemies at regular intervals is provided, with a demonstration of how to adjust the enemy creation frequency based on delta time.']}, {'end': 15849.199, 'start': 15059.618, 'title': 'Canvas game logic and class inheritance', 'summary': "Discusses passing canvas reference, implementing object deletion, creating child classes using 'extends', and utilizing sprite sheets in a canvas game development, including filtering enemies, implementing class inheritance, and utilizing sprite sheets for animation.", 'duration': 789.581, 'highlights': ["Filtered old enemies using the 'filter' method, reducing the array size from around 20 objects to 10.", "Implemented inheritance by creating a child class 'worm' that extends the parent class 'enemy' to achieve unique behaviors for different enemy types.", 'Utilized sprite sheets to animate and improve the visual appearance of worms in the game.', 'Adjusted movement speed using delta time to ensure consistent movement across different machines.']}, {'end': 16491.882, 'start': 15849.959, 'title': 'Implementing worm and ghost classes', 'summary': 'Explains the implementation of worm and ghost classes in a game, including sorting enemies based on their vertical positions and creating semi-transparent visuals for ghosts, achieving a wavy movement pattern for ghosts, and randomizing the creation of different enemy types.', 'duration': 641.923, 'highlights': ['Sorting enemies by vertical position', 'Creating semi-transparent visuals for ghosts', 'Achieving wavy movement pattern for ghosts', 'Randomizing creation of different enemy types']}, {'end': 17120.311, 'start': 16492.223, 'title': 'Enemy movement and animation', 'summary': 'Discusses the implementation of wavy vertical movement for ghosts, varied movement patterns for different enemy types, and the implementation of sprite animation logic shared across all enemy types.', 'duration': 628.088, 'highlights': ['Ghosts have wavy vertical movement, with the angle being increased by 0.1 per frame, creating a shaking effect.', 'Spiders move up and down with varying speeds and maximum movement ranges, and are drawn with spider webs extending from their position.', 'Sprite animation logic is implemented with frame cycling and delta time accumulation, ensuring consistent movement and animation across different machines.']}], 'duration': 2860.032, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c14260279.jpg', 'highlights': ["Implemented inheritance by creating a child class 'worm' that extends the parent class 'enemy' to achieve unique behaviors for different enemy types.", 'Utilized sprite sheets to animate and improve the visual appearance of worms in the game.', 'An example of adding enemies at regular intervals is provided, with a demonstration of how to adjust the enemy creation frequency based on delta time.', 'The process of calculating delta time to ensure consistent animation speed is explained, with emphasis on using the timestamp argument passed by requestAnimationFrame.', 'The impact of delta time on different computer speeds and screen refresh rates is discussed, highlighting the need to adjust animation speed to ensure consistent performance.']}, {'end': 19463.932, 'segs': [{'end': 17163.437, 'src': 'embed', 'start': 17138.623, 'weight': 1, 'content': [{'end': 17145.367, 'text': 'To learn more fundamental JavaScript techniques on creative coding projects, check out related videos in the video description.', 'start': 17138.623, 'duration': 6.744}, {'end': 17147.833, 'text': "on completing today's course.", 'start': 17146.448, 'duration': 1.385}, {'end': 17149.176, 'text': 'Say hi in the comments.', 'start': 17148.194, 'duration': 0.982}, {'end': 17154.493, 'text': 'Hey coders, so I heard you like making games.', 'start': 17152.352, 'duration': 2.141}, {'end': 17155.193, 'text': 'Me too.', 'start': 17154.813, 'duration': 0.38}, {'end': 17163.437, 'text': 'I think projects like this are great not only for aspiring game developers, but also to learn and improve HTML, CSS, and JavaScript skills.', 'start': 17156.094, 'duration': 7.343}], 'summary': 'Learn fundamental javascript techniques for creative coding projects, with a focus on game development and improving html, css, and javascript skills.', 'duration': 24.814, 'max_score': 17138.623, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17138623.jpg'}, {'end': 17268.075, 'src': 'embed', 'start': 17239.894, 'weight': 0, 'content': [{'end': 17243.718, 'text': 'I will have player image, background image and enemy image here.', 'start': 17239.894, 'duration': 3.824}, {'end': 17247.161, 'text': 'You can download project files in the video description.', 'start': 17244.238, 'duration': 2.923}, {'end': 17251.146, 'text': 'In Style CSS I give my body black background.', 'start': 17248.383, 'duration': 2.763}, {'end': 17255.05, 'text': 'I make canvas blue and I position it in the middle of my web page.', 'start': 17251.626, 'duration': 3.424}, {'end': 17262.448, 'text': 'I also want to hide my image elements because we will draw them with JavaScript on canvas.', 'start': 17257.461, 'duration': 4.987}, {'end': 17264.37, 'text': 'So player image, display none.', 'start': 17262.588, 'duration': 1.782}, {'end': 17268.075, 'text': 'Same goes for background image and enemy image.', 'start': 17265.131, 'duration': 2.944}], 'summary': 'Web page includes player, background, and enemy images, with css styling and canvas positioning.', 'duration': 28.181, 'max_score': 17239.894, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17239894.jpg'}, {'end': 17367.653, 'src': 'embed', 'start': 17339.579, 'weight': 5, 'content': [{'end': 17347.543, 'text': 'I want to make it very clear how we split responsibilities between objects and how these objects interact with each other to create a complete game.', 'start': 17339.579, 'duration': 7.964}, {'end': 17351.245, 'text': "So let's just write all the building blocks we will need today.", 'start': 17348.063, 'duration': 3.182}, {'end': 17360.57, 'text': 'Our game will need input handler class which will apply event listeners to keyboard events and it will hold an array of all currently active keys.', 'start': 17351.705, 'duration': 8.865}, {'end': 17367.653, 'text': 'Player class will react to these keys as they are being pressed, drawing and updating the player.', 'start': 17361.57, 'duration': 6.083}], 'summary': 'Define responsibilities and building blocks for game development, including input handler and player classes.', 'duration': 28.074, 'max_score': 17339.579, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17339579.jpg'}, {'end': 17602.538, 'src': 'embed', 'start': 17572.502, 'weight': 9, 'content': [{'end': 17576.526, 'text': 'you can see, pressing arrow down adds an entry into this dot keys array.', 'start': 17572.502, 'duration': 4.024}, {'end': 17579.663, 'text': "I don't want to have multiple entries for each key.", 'start': 17577.481, 'duration': 2.182}, {'end': 17582.865, 'text': 'Here we can see it added arrow down 4 times.', 'start': 17580.063, 'duration': 2.802}, {'end': 17587.148, 'text': 'I only want to add it if that specific key is not in the array yet.', 'start': 17583.345, 'duration': 3.803}, {'end': 17596.374, 'text': 'So I do second condition here and I say if this.keys indexOf key that was pressed is equal to minus 1.', 'start': 17587.508, 'duration': 8.866}, {'end': 17602.538, 'text': 'With arrays if indexOf is equal to minus 1 it means that element is not present in the array.', 'start': 17596.374, 'duration': 6.164}], 'summary': 'Pressing arrow down adds an entry to dot keys array; added 4 times, only if key is not present.', 'duration': 30.036, 'max_score': 17572.502, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17572502.jpg'}, {'end': 17678.847, 'src': 'embed', 'start': 17653.474, 'weight': 7, 'content': [{'end': 17658.316, 'text': "So here I'm saying when we release a key, if that key is arrow down,", 'start': 17653.474, 'duration': 4.842}, {'end': 17665.379, 'text': 'find index of that key inside this dot keys array and use splice to remove one element from that array.', 'start': 17658.316, 'duration': 7.063}, {'end': 17669.42, 'text': "Now, when I press down arrow key, it's added to the array.", 'start': 17666.059, 'duration': 3.361}, {'end': 17672.221, 'text': "When I release it, it's removed from the array.", 'start': 17669.86, 'duration': 2.361}, {'end': 17676.743, 'text': "Nice Let's also listen for other keys using OR operator.", 'start': 17672.541, 'duration': 4.202}, {'end': 17678.847, 'text': 'I start with arrow up.', 'start': 17677.663, 'duration': 1.184}], 'summary': 'Code allows adding/removing arrow down key from array using splice method. also listens for other keys using or operator.', 'duration': 25.373, 'max_score': 17653.474, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17653474.jpg'}, {'end': 17730.237, 'src': 'embed', 'start': 17703.2, 'weight': 6, 'content': [{'end': 17713.787, 'text': 'In key down if arrow down, up, left or right is pressed and that key is not yet present in this dot keys array we push it into the array.', 'start': 17703.2, 'duration': 10.587}, {'end': 17721.291, 'text': 'In keyup, when any of these four arrows are released, we find index of that key inside this .', 'start': 17714.727, 'duration': 6.564}, {'end': 17724.653, 'text': 'keys array and we use splice method to remove it.', 'start': 17721.291, 'duration': 3.362}, {'end': 17730.237, 'text': 'This keys array now holds information about which arrow keys are currently pressed down.', 'start': 17725.194, 'duration': 5.043}], 'summary': 'Tracks and updates arrow key presses in an array.', 'duration': 27.037, 'max_score': 17703.2, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17703200.jpg'}, {'end': 17948.804, 'src': 'embed', 'start': 17918.5, 'weight': 3, 'content': [{'end': 17922.541, 'text': 'To delete old paint from canvas I use built-in clear rectangle method.', 'start': 17918.5, 'duration': 4.041}, {'end': 17925.742, 'text': 'It will delete entire canvas between each animation loop.', 'start': 17922.841, 'duration': 2.901}, {'end': 17931.664, 'text': 'Perfect, now we have player moving from left to right as we defined in its update method.', 'start': 17926.482, 'duration': 5.182}, {'end': 17935.425, 'text': "Instead of drawing a white rectangle, let's draw player image.", 'start': 17932.264, 'duration': 3.161}, {'end': 17937.746, 'text': 'I call built-in drawImage method.', 'start': 17936.065, 'duration': 1.681}, {'end': 17948.804, 'text': 'I need to bring player sprite sheet into the project so this.image property is document.getElementById and I give it id of player image.', 'start': 17938.655, 'duration': 10.149}], 'summary': 'Utilized built-in methods to delete canvas content and draw player image.', 'duration': 30.304, 'max_score': 17918.5, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17918500.jpg'}, {'end': 19427.539, 'src': 'embed', 'start': 19399.507, 'weight': 2, 'content': [{'end': 19404.151, 'text': 'Else, meaning we are on ground, set max frame to 8 for running animation.', 'start': 19399.507, 'duration': 4.644}, {'end': 19410.804, 'text': 'On line 151 we are adding new enemy to our game in a randomized interval.', 'start': 19406.098, 'duration': 4.706}, {'end': 19416.871, 'text': "When I console.log enemies array I can see it's endlessly growing and adding more and more enemies.", 'start': 19411.284, 'duration': 5.587}, {'end': 19421.497, 'text': 'I actually want to remove enemies that moved off screen from enemies array.', 'start': 19417.412, 'duration': 4.085}, {'end': 19427.539, 'text': 'On enemy class I create a property I call markedForDeletion and I initially set it to false.', 'start': 19422.017, 'duration': 5.522}], 'summary': 'Adjust max frame to 8 for running animation and remove enemies off screen by marking for deletion.', 'duration': 28.032, 'max_score': 19399.507, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c19399507.jpg'}], 'start': 17120.691, 'title': 'Javascript game development basics and input handling', 'summary': 'Covers building a simple animated side-scroll game using javascript, emphasizes extending classes and splitting responsibilities between objects, discusses creating an inputhandler class for key presses, handling keyboard inputs, and creating/managing game enemies.', 'chapters': [{'end': 17405.454, 'start': 17120.691, 'title': 'Javascript game development basics', 'summary': 'Covers the basics of building a simple animated side-scroll game from scratch using plain vanilla javascript with the goal of learning fundamental javascript techniques for game development, emphasizing the importance of extending classes and splitting responsibilities between objects, and aims to help aspiring game developers improve their html, css, and javascript skills.', 'duration': 284.763, 'highlights': ['The importance of extending classes and splitting responsibilities between objects', 'Building a simple animated side-scroll game from scratch using plain vanilla JavaScript', 'Fundamental building blocks of game development with JavaScript', 'Responsible handling of game assets and event listeners in JavaScript']}, {'end': 17754.963, 'start': 17405.995, 'title': 'Game input handling', 'summary': 'Discusses creating an inputhandler class to manage event listeners for tracking multiple key presses, using arrays to keep track of key states, and using event listeners to add and remove keys from the array.', 'duration': 348.968, 'highlights': ['The InputHandler class is created to manage event listeners for tracking multiple key presses, utilizing arrays to keep track of key states, and using event listeners to add and remove keys from the array.', 'The constructor of the InputHandler class initializes a keys property as an empty array to store the currently pressed keys, and event listeners for keyDown and keyUp events are placed inside the constructor to automatically apply the listeners when an instance of the class is created.', 'The eventListener for keyDown event captures the key property from the event object, allowing the addition of the pressed key to the keys array, with a check to prevent multiple entries for the same key.', 'The eventListener for keyUp event removes the released key from the keys array by finding its index and using the splice method, ensuring that the array reflects the currently pressed keys.', 'The keys array holds information about which arrow keys are currently pressed down, enabling the tracking of multiple simultaneous key presses and providing a mechanism for managing keyboard inputs within a game environment.']}, {'end': 18614.465, 'start': 17755.443, 'title': 'Handling keyboard inputs', 'summary': 'Covers handling keyboard inputs in a game, defining player properties, drawing, animating, updating player position, connecting keyboard inputs to player movement, implementing horizontal and vertical boundaries, and creating an endlessly scrolling background.', 'duration': 859.022, 'highlights': ['Defining player properties and methods', 'Connecting keyboard inputs to player movement', 'Implementing vertical movement and boundaries', 'Creating an endlessly scrolling background']}, {'end': 19463.932, 'start': 18615.185, 'title': 'Creating and managing game enemies', 'summary': 'Demonstrates creating and managing game enemies, including setting up enemy class, adding enemies to the game, using timestamps and delta time for periodic events, animating sprite sheets with delta time, and removing off-screen enemies from the array.', 'duration': 848.747, 'highlights': ['The enemy class serves as a blueprint to create enemy objects, with the constructor expecting game width and game height as arguments.', 'Using timestamps and delta time, the chapter explains how to trigger periodic events and add new enemies to the game at regular intervals, ensuring consistent timing across different computer speeds.', 'Animating sprite sheets with delta time allows for controlling the frames per second (FPS) of the sprite animation while maintaining other game elements to update at 60 frames per second.', 'The process of removing off-screen enemies from the enemies array is detailed, ensuring efficient management of active enemies on the screen.']}], 'duration': 2343.241, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c17120691.jpg', 'highlights': ['The importance of extending classes and splitting responsibilities between objects', 'Building a simple animated side-scroll game from scratch using plain vanilla JavaScript', 'Fundamental building blocks of game development with JavaScript', 'Responsible handling of game assets and event listeners in JavaScript', 'The InputHandler class is created to manage event listeners for tracking multiple key presses, utilizing arrays to keep track of key states, and using event listeners to add and remove keys from the array.', 'The constructor of the InputHandler class initializes a keys property as an empty array to store the currently pressed keys, and event listeners for keyDown and keyUp events are placed inside the constructor to automatically apply the listeners when an instance of the class is created.', 'Using timestamps and delta time, the chapter explains how to trigger periodic events and add new enemies to the game at regular intervals, ensuring consistent timing across different computer speeds.', 'The process of removing off-screen enemies from the enemies array is detailed, ensuring efficient management of active enemies on the screen.', 'The eventListener for keyDown event captures the key property from the event object, allowing the addition of the pressed key to the keys array, with a check to prevent multiple entries for the same key.', 'The eventListener for keyUp event removes the released key from the keys array by finding its index and using the splice method, ensuring that the array reflects the currently pressed keys.']}, {'end': 20886.875, 'segs': [{'end': 19676.015, 'src': 'embed', 'start': 19645.902, 'weight': 4, 'content': [{'end': 19650.092, 'text': 'Some of you think that simple collision detection between circles would be enough in this scenario.', 'start': 19645.902, 'duration': 4.19}, {'end': 19654.702, 'text': "Let's try to draw circular hitboxes around our objects to see what it would look like.", 'start': 19650.473, 'duration': 4.229}, {'end': 19663.128, 'text': "It's also easy to offset these circles by a specific pixel value horizontally or vertically in relation to player and enemy object.", 'start': 19656.124, 'duration': 7.004}, {'end': 19666.33, 'text': 'We can also make them smaller or larger if needed.', 'start': 19663.688, 'duration': 2.642}, {'end': 19676.015, 'text': 'I agree with you and I think that using circular collision detection for jumping game like this will get rid of accidental collisions where two corners of rectangles collide.', 'start': 19667.01, 'duration': 9.005}], 'summary': 'Using circular hitboxes with pixel offsets and size adjustments for precise collision detection in jumping game.', 'duration': 30.113, 'max_score': 19645.902, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c19645902.jpg'}, {'end': 20398.413, 'src': 'embed', 'start': 20354.618, 'weight': 0, 'content': [{'end': 20357.7, 'text': 'It will store the initial starting vertical coordinate.', 'start': 20354.618, 'duration': 3.082}, {'end': 20361.802, 'text': 'Maybe I also want the game to only react to longer swipes,', 'start': 20358.16, 'duration': 3.642}, {'end': 20366.945, 'text': "to make sure user actually swipes and the game doesn't accidentally react to simple short taps.", 'start': 20361.802, 'duration': 5.143}, {'end': 20372.846, 'text': 'I will call this property touchThreshold and I set it for example to 30.', 'start': 20367.865, 'duration': 4.981}, {'end': 20379.448, 'text': 'I want the starting touchpoint and the ending touchpoint to be at least 30 pixels apart to trigger the event.', 'start': 20372.846, 'duration': 6.602}, {'end': 20382.949, 'text': 'I could also make the player jump higher here based on how long the swipe is.', 'start': 20379.788, 'duration': 3.161}, {'end': 20386.83, 'text': 'This technique is easy and very powerful if you are designing mobile games.', 'start': 20383.349, 'duration': 3.481}, {'end': 20389.03, 'text': 'I hope you are realizing the potential here.', 'start': 20387.23, 'duration': 1.8}, {'end': 20397.052, 'text': 'In touchStart event I just want to set starting coordinate so this.touchY from line 13 is equal to pageY value from this event.', 'start': 20389.43, 'duration': 7.622}, {'end': 20398.413, 'text': "Let's delete all these.", 'start': 20397.492, 'duration': 0.921}], 'summary': 'Implement touchthreshold property to react to longer swipes, at least 30 pixels apart, in mobile game design.', 'duration': 43.795, 'max_score': 20354.618, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c20354618.jpg'}, {'end': 20523.256, 'src': 'embed', 'start': 20497.23, 'weight': 1, 'content': [{'end': 20501.816, 'text': "Brackets are important, it's easy to make a mistake and even a small thing can break the entire project.", 'start': 20497.23, 'duration': 4.586}, {'end': 20503.197, 'text': "That's programmers life.", 'start': 20502.116, 'duration': 1.081}, {'end': 20505.139, 'text': 'Attention to detail and debugging.', 'start': 20503.417, 'duration': 1.722}, {'end': 20508.503, 'text': 'Perfect, now it gets added only once per value.', 'start': 20505.74, 'duration': 2.763}, {'end': 20511.886, 'text': 'As I said, I will use touchEnd event for cleanup.', 'start': 20509.183, 'duration': 2.703}, {'end': 20516.17, 'text': 'I will use splice method to find swipeUp in keys array and remove it.', 'start': 20512.266, 'duration': 3.904}, {'end': 20518.832, 'text': 'And I do the same thing for swipeDown.', 'start': 20516.91, 'duration': 1.922}, {'end': 20523.256, 'text': 'So in touchStart, I save initial vertical coordinate of touch event.', 'start': 20519.373, 'duration': 3.883}], 'summary': "Importance of brackets for project integrity and programmer's attention to detail and debugging, utilizing touchend event and splice method for cleanup and swipe detection.", 'duration': 26.026, 'max_score': 20497.23, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c20497230.jpg'}], 'start': 19464.333, 'title': 'Game development techniques', 'summary': 'Covers displaying score, collision detection, mobile game development with html, css, and javascript, and touch events with the fullscreen api, providing techniques for incrementing score, implementing collision detection, optimizing for mobile, and utilizing touch events and fullscreen api.', 'chapters': [{'end': 19538.634, 'start': 19464.333, 'title': 'Displaying score in game', 'summary': "Explains how the game displays the score by incrementing it every time an enemy moves off the screen, using a let variable 'score' initially set to 0, and a 'displaystatustext' function to display the score on the canvas, resulting in a range of one to two enemies in the array at any given time.", 'duration': 74.301, 'highlights': ["The game ensures that all elements are tested and checked for their 'marked for deletion' property being false, resulting in a range of one to two enemies in the array at any given time.", "The 'displayStatusText' function is used to display the current score on the canvas, utilizing a let variable 'score' initially set to 0, and incrementing the score by 1 every time an enemy moves off the screen.", "The text displayed on the canvas shows the score, represented by the variable 'score' from line 7, and is called from inside the animation loop, passing the 'ctx' as an argument."]}, {'end': 19882.099, 'start': 19539.175, 'title': 'Collision detection and shadow trick', 'summary': 'Discusses implementing collision detection in a game using techniques such as rectangles, circles, and separating axis theorem, as well as overcoming lag caused by canvas shadow property in firefox by implementing a manual shadow trick.', 'duration': 342.924, 'highlights': ['Implementing collision detection techniques', 'Overcoming lag caused by canvas shadow property in Firefox', 'Calculating collision between player and enemy hitboxes']}, {'end': 20179.927, 'start': 19882.639, 'title': 'Mobile game development with html, css, and javascript', 'summary': 'Covers the process of making a mobile game using html, css, and javascript, including optimizing the game for mobile devices, implementing restart functionality, and handling touch events.', 'duration': 297.288, 'highlights': ['The chapter emphasizes the importance of optimizing a mobile game for various screen sizes and orientations, demonstrating how to use CSS properties to ensure the entire canvas is visible at all times, with specific examples and practical demonstrations.', 'The chapter delves into the implementation of a restart game function, detailing the steps involved such as resetting the player and background positions, as well as resetting the enemies array, score, and game over status, with clear explanations and code examples.', 'The chapter addresses the handling of touch events in the mobile game, indicating that this will be an engaging aspect of the development process, suggesting that practical demonstrations or examples will be provided.']}, {'end': 20886.875, 'start': 20179.927, 'title': 'Touch events and fullscreen api', 'summary': 'Discusses the implementation of touch events to determine swipe direction and length, utilizing touch start, move, and end events, while also demonstrating the use of the fullscreen api to toggle between fullscreen and windowed modes.', 'duration': 706.948, 'highlights': ['The touch events touchStart, touchMove, and touchEnd are used to determine the swipe direction and length, with the touch threshold set at 30 pixels and the ability to trigger game actions based on swipe direction and length.', 'The use of touch events is showcased in a simple game, where swiping up makes the player jump, and swiping down triggers a game restart, with the touch threshold adjusted to impact the functionality based on swipe length.', 'The Fullscreen API is demonstrated, with a button created to toggle between fullscreen and windowed modes, and the implementation of event listeners to adhere to the requirement that fullscreen initiation must be triggered by user-generated events such as click or touch.']}], 'duration': 1422.542, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c19464333.jpg', 'highlights': ['The Fullscreen API is demonstrated, with a button created to toggle between fullscreen and windowed modes, and the implementation of event listeners to adhere to the requirement that fullscreen initiation must be triggered by user-generated events such as click or touch.', 'The touch events touchStart, touchMove, and touchEnd are used to determine the swipe direction and length, with the touch threshold set at 30 pixels and the ability to trigger game actions based on swipe direction and length.', 'The chapter emphasizes the importance of optimizing a mobile game for various screen sizes and orientations, demonstrating how to use CSS properties to ensure the entire canvas is visible at all times, with specific examples and practical demonstrations.', 'The chapter delves into the implementation of a restart game function, detailing the steps involved such as resetting the player and background positions, as well as resetting the enemies array, score, and game over status, with clear explanations and code examples.', "The game ensures that all elements are tested and checked for their 'marked for deletion' property being false, resulting in a range of one to two enemies in the array at any given time."]}, {'end': 22241.969, 'segs': [{'end': 21107.114, 'src': 'embed', 'start': 21082.535, 'weight': 6, 'content': [{'end': 21089.702, 'text': 'And this is the radius of collision area circle we are drawing and that same value is being used in collision detection formula here.', 'start': 21082.535, 'duration': 7.167}, {'end': 21099.711, 'text': 'I can simply offset and resize that collision circle visual in this area and then replicate those changes inside the actual collision detection calculation area here.', 'start': 21090.362, 'duration': 9.349}, {'end': 21101.332, 'text': 'Let me show you what I mean.', 'start': 21100.291, 'duration': 1.041}, {'end': 21107.114, 'text': "What if I want player circle to be smaller? Maybe I don't mind that ears and tail overlap.", 'start': 21102.032, 'duration': 5.082}], 'summary': 'The radius of the collision area circle is being used in collision detection, allowing for visual resizing and replication of changes.', 'duration': 24.579, 'max_score': 21082.535, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c21082535.jpg'}, {'end': 21809.838, 'src': 'embed', 'start': 21716.986, 'weight': 0, 'content': [{'end': 21724.708, 'text': 'Load event will wait for the entire page to be fully loaded and available, including page content such as style sheets, images and so on.', 'start': 21716.986, 'duration': 7.722}, {'end': 21729.009, 'text': 'In the meantime, this text that says load in will be visible.', 'start': 21725.228, 'duration': 3.781}, {'end': 21735.791, 'text': 'so if you add more art assets, user will see this loading screen for however long it takes to load all assets.', 'start': 21729.009, 'duration': 6.782}, {'end': 21737.993, 'text': 'When everything is fully loaded,', 'start': 21736.431, 'duration': 1.562}, {'end': 21748.062, 'text': 'this event listener will run its code and inside I will target this loading text and I will hide it because the page is fully loaded at the point when this code runs.', 'start': 21737.993, 'duration': 10.069}, {'end': 21754.108, 'text': 'I will also set up my canvas, so document.getElementById.', 'start': 21748.943, 'duration': 5.165}, {'end': 21760.514, 'text': 'I instantiate context object, which contains all built-in 2D drawing properties and methods we will need today.', 'start': 21754.108, 'duration': 6.406}, {'end': 21766.362, 'text': 'I set canvas-width to window-inner-width and canvas-height to window-inner-height.', 'start': 21761.255, 'duration': 5.107}, {'end': 21771.069, 'text': 'I can see canvas is now full screen so I make it transparent.', 'start': 21767.284, 'duration': 3.785}, {'end': 21773.172, 'text': "It's time to draw the player.", 'start': 21771.87, 'duration': 1.302}, {'end': 21776.456, 'text': 'In player.js I create a class I call player.', 'start': 21773.612, 'duration': 2.844}, {'end': 21780.499, 'text': 'player always needs to be aware of boundaries of game area,', 'start': 21777.037, 'duration': 3.462}, {'end': 21785.841, 'text': 'since we will be running and jumping around and we need to know when we reach the edges of screen.', 'start': 21780.499, 'duration': 5.342}, {'end': 21794.485, 'text': 'so i will pass it game width and game height from the outside as arguments and i will convert these arguments to class properties like this.', 'start': 21785.841, 'duration': 8.644}, {'end': 21797.467, 'text': 'Today we are learning about state management.', 'start': 21795.245, 'duration': 2.222}, {'end': 21800.069, 'text': 'We will be swapping player between different states.', 'start': 21797.587, 'duration': 2.482}, {'end': 21809.838, 'text': 'This.states will be an array and each position in that array will be one possible player state such as running, jumping, sitting and so on.', 'start': 21800.59, 'duration': 9.248}], 'summary': 'Page fully loads, canvas set up, player class created, state management introduced.', 'duration': 92.852, 'max_score': 21716.986, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c21716986.jpg'}, {'end': 22106.542, 'src': 'embed', 'start': 22062.622, 'weight': 4, 'content': [{'end': 22065.085, 'text': 'Nice, we are drawing player image on canvas.', 'start': 22062.622, 'duration': 2.463}, {'end': 22068.288, 'text': 'What you see on canvas right now is the entire sprite sheet.', 'start': 22065.365, 'duration': 2.923}, {'end': 22069.67, 'text': 'On line 14.', 'start': 22068.849, 'duration': 0.821}, {'end': 22075.76, 'text': 'here we are telling DrawMethod what image to draw and what coordinates to draw it at.', 'start': 22069.67, 'duration': 6.09}, {'end': 22082.45, 'text': 'DrawMethod will just take the entire image at its original size and it places it at these coordinates.', 'start': 22075.76, 'duration': 6.69}, {'end': 22084.032, 'text': 'I can change the coordinates here.', 'start': 22082.45, 'duration': 1.582}, {'end': 22093.437, 'text': 'Built-in canvas draw image method can take three, five or nine arguments, depending on how much control we want to have over the image we are drawing.', 'start': 22084.713, 'duration': 8.724}, {'end': 22094.817, 'text': 'If I give it optional.', 'start': 22093.777, 'duration': 1.04}, {'end': 22098.419, 'text': 'fourth and fifth arguments these stand for width and height,', 'start': 22094.817, 'duration': 3.602}, {'end': 22106.542, 'text': 'and the entire image will be stretched to fill the rectangle defined by these starting coordinates and these ending coordinates.', 'start': 22098.419, 'duration': 8.123}], 'summary': 'Drawing player image on canvas using drawmethod with optional arguments for width and height.', 'duration': 43.92, 'max_score': 22062.622, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c22062622.jpg'}], 'start': 20887.395, 'title': 'Mobile game hitbox adjustments, state design pattern, javascript modules, and sprite animation', 'summary': 'Discusses hitbox adjustments for mobile games, state design pattern for player behavior, javascript modules and live server usage, and sprite animation in javascript, offering insights into collision detection, simplifying code complexity, local server importance, and sprite animation process.', 'chapters': [{'end': 21236.652, 'start': 20887.395, 'title': 'Mobile game hitbox adjustments', 'summary': 'Discusses the need to adjust hitboxes for mobile games to improve performance and prevent unexpected collisions, demonstrating the process and its impact on collision detection.', 'duration': 349.257, 'highlights': ["The hitboxes around player and enemy images don't match the sprite sheet, leading to unexpected collisions, impacting game over scenarios.", 'Performance is crucial for mobile games due to limited computing power, necessitating careful handling of collision detection for improved gameplay.', "The process of adjusting hitboxes involves scaling, resizing, and repositioning them to align more closely with the game's art assets, improving collision predictability and gameplay experience."]}, {'end': 21463.176, 'start': 21236.952, 'title': 'State design pattern in game development', 'summary': 'Introduces the concept of design patterns, specifically focusing on the state design pattern to manage player character behavior in a game, showcasing the benefits of using finite state machine to simplify complex if-else statements and demonstrating how to implement the state design pattern in a side scroll game using native javascript modules.', 'duration': 226.224, 'highlights': ['The chapter introduces the concept of design patterns, specifically focusing on the state design pattern to manage player character behavior in a game.', 'Showcasing the benefits of using finite state machine to simplify complex if-else statements.', 'Demonstrating how to implement the state design pattern in a side scroll game using native javascript modules.']}, {'end': 21882.286, 'start': 21463.436, 'title': 'Javascript modules and live server', 'summary': 'Discusses the usage of javascript modules for splitting programs into separate parts and the necessity of running code through a server, emphasizing the importance of using a local server like live server extension in visual studio code, which automatically reloads the browser window when project files are saved.', 'duration': 418.85, 'highlights': ['The importance of using a local server like Live Server extension in Visual Studio Code, which automatically reloads the browser window when project files are saved, is emphasized, with over 17 million downloads indicating its popularity.', 'JavaScript modules allow the splitting of programs into separate parts that can be imported where needed, with the ability to use import-export keywords to connect data inside, facilitating cleaner and easier-to-navigate projects.', 'The necessity of running code through a server for the import-export keywords to work is highlighted, with the recommendation to install a small plugin to the code editor, such as the Live Server extension in Visual Studio Code.', 'The process of setting up the Live Server extension in Visual Studio Code, including installation, project folder selection, and automatic browser window reload upon file saving, is explained in detail, with a focus on its convenience and usability.', 'The functionality of the load event in JavaScript is described, emphasizing its ability to wait for the entire page and its content to be fully loaded before executing the code, ensuring a seamless user experience.', 'The usage of the load event to ensure that JavaScript waits for all assets to be fully loaded before running, along with the process of hiding the loading text and setting up the canvas, is demonstrated, highlighting the importance of proper asset loading for smooth page rendering.', 'The class creation and functionality of the player in player.js, including awareness of game area boundaries and state management with different player states, is outlined, emphasizing the comprehensive approach to player control and interaction within the game environment.']}, {'end': 22241.969, 'start': 21882.826, 'title': 'Javascript sprite animation', 'summary': 'Covers the encapsulation principle in object-oriented programming, the use of native javascript modules for exporting and importing variables, classes, and functions, and the detailed process of using the drawimage method for sprite animation in javascript, including the manipulation of frame coordinates and the swapping between sprites.', 'duration': 359.143, 'highlights': ['The chapter explains the encapsulation principle in object-oriented programming, where the player class is created as a self-contained class to handle all player functionality, aiding in code organization and easier maintenance.', 'The use of native JavaScript modules for exporting and importing variables, classes, and functions is detailed, including the distinction between named exports and default exports.', 'The detailed process of using the drawImage method for sprite animation in JavaScript is explained, covering the manipulation of frame coordinates and the swapping between sprites to achieve sprite animation.']}], 'duration': 1354.574, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c20887395.jpg', 'highlights': ['The importance of using a local server like Live Server extension in Visual Studio Code, with over 17 million downloads indicating its popularity.', "The process of adjusting hitboxes involves scaling, resizing, and repositioning them to align more closely with the game's art assets, improving collision predictability and gameplay experience.", 'The chapter introduces the concept of design patterns, specifically focusing on the state design pattern to manage player character behavior in a game.', 'The process of setting up the Live Server extension in Visual Studio Code, including installation, project folder selection, and automatic browser window reload upon file saving, is explained in detail, with a focus on its convenience and usability.', 'The usage of the load event to ensure that JavaScript waits for all assets to be fully loaded before running, along with the process of hiding the loading text and setting up the canvas, is demonstrated, highlighting the importance of proper asset loading for smooth page rendering.', 'The detailed process of using the drawImage method for sprite animation in JavaScript is explained, covering the manipulation of frame coordinates and the swapping between sprites to achieve sprite animation.', "The hitboxes around player and enemy images don't match the sprite sheet, leading to unexpected collisions, impacting game over scenarios.", 'The functionality of the load event in JavaScript is described, emphasizing its ability to wait for the entire page and its content to be fully loaded before executing the code, ensuring a seamless user experience.', 'The class creation and functionality of the player in player.js, including awareness of game area boundaries and state management with different player states, is outlined, emphasizing the comprehensive approach to player control and interaction within the game environment.', 'The process of using native JavaScript modules for exporting and importing variables, classes, and functions is detailed, including the distinction between named exports and default exports.', 'The use of native JavaScript modules for exporting and importing variables, classes, and functions is detailed, including the distinction between named exports and default exports.', 'The encapsulation principle in object-oriented programming, where the player class is created as a self-contained class to handle all player functionality, aiding in code organization and easier maintenance.', 'Performance is crucial for mobile games due to limited computing power, necessitating careful handling of collision detection for improved gameplay.', 'JavaScript modules allow the splitting of programs into separate parts that can be imported where needed, with the ability to use import-export keywords to connect data inside, facilitating cleaner and easier-to-navigate projects.']}, {'end': 25350.672, 'segs': [{'end': 23794.7, 'src': 'embed', 'start': 23767.119, 'weight': 4, 'content': [{'end': 23774.664, 'text': 'Both of these objects have their own version of handle input method, so that, as we point current state towards different state objects,', 'start': 23767.119, 'duration': 7.545}, {'end': 23779.207, 'text': 'behavior of player will change, even though we are always calling the same handle input method.', 'start': 23774.664, 'duration': 4.543}, {'end': 23785.972, 'text': "It's important that all our state objects have their own definition of enter method, and handle input method.", 'start': 23779.748, 'duration': 6.224}, {'end': 23794.7, 'text': "I could also created a backup, enter and handle input method on their parent class here in case child class doesn't have methods with these names.", 'start': 23786.573, 'duration': 8.127}], 'summary': 'State objects have unique handle input and enter methods, ensuring player behavior changes when transitioning states.', 'duration': 27.581, 'max_score': 23767.119, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c23767119.jpg'}, {'end': 23848.111, 'src': 'embed', 'start': 23820.581, 'weight': 3, 'content': [{'end': 23828.747, 'text': 'While in standing right state player will ignore all inputs except for pressing of left arrow key which will make it swap to standing left state.', 'start': 23820.581, 'duration': 8.166}, {'end': 23833.369, 'text': 'You might notice that state design pattern has some code repetition,', 'start': 23829.728, 'duration': 3.641}, {'end': 23839.13, 'text': 'but the code is easy to navigate in and if we get a bug it will be limited to a specific state,', 'start': 23833.369, 'duration': 5.761}, {'end': 23842.07, 'text': 'making larger projects much easier to manage and debug.', 'start': 23839.13, 'duration': 2.94}, {'end': 23848.111, 'text': 'If we get some unexpected behavior, we can see what state was our player object in,', 'start': 23842.57, 'duration': 5.541}], 'summary': 'Using state design pattern simplifies code navigation and management, limiting bugs to specific states.', 'duration': 27.53, 'max_score': 23820.581, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c23820581.jpg'}, {'end': 24139.121, 'src': 'embed', 'start': 24112.31, 'weight': 0, 'content': [{'end': 24117.375, 'text': 'I hope you can see now how state pattern limits the number of inputs player reacts in each state.', 'start': 24112.31, 'duration': 5.065}, {'end': 24125.461, 'text': 'We have logic that defines how player behaves while in these two new sitting states, but we have no way to actually enter these sitting states.', 'start': 24118.295, 'duration': 7.166}, {'end': 24133.248, 'text': 'I go inside standInRight class and I say if input is pressed down, we set state to sitInRight.', 'start': 24125.901, 'duration': 7.347}, {'end': 24139.121, 'text': 'If we press down while in standing left class, we set state to sitting left.', 'start': 24135.017, 'duration': 4.104}], 'summary': 'State pattern limits player inputs, enabling sitting states with specific logic.', 'duration': 26.811, 'max_score': 24112.31, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c24112310.jpg'}, {'end': 24874.006, 'src': 'embed', 'start': 24850.291, 'weight': 1, 'content': [{'end': 24857.437, 'text': 'Inside jumping left I check if player on ground is true, and when player gets back on the ground we set its state to standing left.', 'start': 24850.291, 'duration': 7.146}, {'end': 24864.598, 'text': 'In jumping right again we check if player is back on ground and we set it to standing right.', 'start': 24859.594, 'duration': 5.004}, {'end': 24868.561, 'text': 'We are running, standing, sitting and jumping.', 'start': 24865.579, 'duration': 2.982}, {'end': 24870.143, 'text': 'Well done if you followed it this far.', 'start': 24868.682, 'duration': 1.461}, {'end': 24872.505, 'text': "Let's polish this and make it look even better.", 'start': 24870.523, 'duration': 1.982}, {'end': 24874.006, 'text': 'Jumping works this way.', 'start': 24872.965, 'duration': 1.041}], 'summary': 'Code checks player state, transitions on ground, and handles various actions like running, standing, sitting, and jumping.', 'duration': 23.715, 'max_score': 24850.291, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c24850291.jpg'}, {'end': 25120.221, 'src': 'embed', 'start': 25088.724, 'weight': 2, 'content': [{'end': 25089.725, 'text': 'This works really well.', 'start': 25088.724, 'duration': 1.001}, {'end': 25094.229, 'text': 'We created standing, sitting, running, jumping and falling states.', 'start': 25089.865, 'duration': 4.364}, {'end': 25097.492, 'text': 'We are just drawing the first frame in each sprite sheet row.', 'start': 25094.689, 'duration': 2.803}, {'end': 25099.793, 'text': "Let's actually animate the frames horizontally.", 'start': 25097.652, 'duration': 2.141}, {'end': 25104.117, 'text': 'We have frameX property for horizontal navigation within our sprite sheet.', 'start': 25100.354, 'duration': 3.763}, {'end': 25111.323, 'text': 'For every animation frame I check if frameX is less than max frame and I increase frameX by 1.', 'start': 25104.497, 'duration': 6.826}, {'end': 25113.448, 'text': 'I set frame X back to 0.', 'start': 25111.323, 'duration': 2.125}, {'end': 25117.135, 'text': "Some rows have different maximum number of frames, but that's easy to deal with.", 'start': 25113.448, 'duration': 3.687}, {'end': 25120.221, 'text': 'Initially, I set max frame to 5.', 'start': 25117.696, 'duration': 2.525}], 'summary': 'Created multiple sprite sheet states with max frame set to 5.', 'duration': 31.497, 'max_score': 25088.724, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25088724.jpg'}], 'start': 22244.209, 'title': 'Implementing player state patterns', 'summary': 'Covers the creation of an input handler class, state design pattern for player animation, player state management logic, implementing state pattern for player behavior, and animating player movement and states in javascript, demonstrating the use of event listeners, arrow functions, and child classes, allowing the player to react to inputs and switch between different states.', 'chapters': [{'end': 22695.424, 'start': 22244.209, 'title': 'Creating input handler class', 'summary': 'Discusses the creation of an input handler class in javascript, which sets up listeners for specific keys, tracks the last key pressed or released, and demonstrates the use of event listeners and arrow functions in handling keyboard inputs.', 'duration': 451.215, 'highlights': ['The input handler class is created to set up listeners for specific keys and to keep track of the last key pressed or released.', 'The use of event listeners and arrow functions is demonstrated in handling keyboard inputs.', 'The creation of a function to display the last key pressed on the canvas is discussed.']}, {'end': 23047.312, 'start': 22696.045, 'title': 'State design pattern for player animation', 'summary': 'Explains the implementation of the state design pattern for player animation, demonstrating the use of child classes to define different states, handling keyboard inputs, and updating player behavior in response to state changes.', 'duration': 351.267, 'highlights': ['The state design pattern allows objects to change their behavior based on their current state, demonstrated by swapping the player between standing left and standing right states.', 'The use of child classes and inheritance is explained, where multiple child classes extend the parent state class to inherit attributes and methods, allowing for code reuse and avoiding repetition.', "The implementation of the state design pattern involves creating a class for each state, using the 'super' keyword to access and call methods from the parent class, and utilizing the 'this' keyword to reference properties from the parent class."]}, {'end': 23698.84, 'start': 23047.833, 'title': 'Player state management logic', 'summary': 'Explains the implementation of state management pattern in a player class, allowing the player object to react to specific inputs and swap between standing left and standing right states, with the ability to set up and handle input methods for each state.', 'duration': 651.007, 'highlights': ['The player class uses polymorphism to execute different behaviors for the enter and handle input methods depending on the current player state, enabling the object to react to a limited set of inputs for each state.', 'The setState method allows the player to swap between standing left and standing right states by passing the corresponding state number as an argument, facilitating smooth transitions between states.', 'The update method in the player class continuously calls the handle input method from the current state, ensuring that the player can listen for new inputs and change states when necessary during the animation loop.']}, {'end': 24601.684, 'start': 23698.98, 'title': 'Implementing state pattern for player behavior', 'summary': 'Details the implementation of the state pattern for player behavior, covering the handling of different states such as standing, sitting, and running, with a focus on the logic, code structure, and flexibility provided by this approach.', 'duration': 902.704, 'highlights': ['The state pattern is used to manage player behavior, including states such as standing, sitting, and running.', 'Different states are managed by calling the handleInput method from the currentState property, allowing for varied player behaviors.', 'The state design pattern simplifies code navigation and debugging, confining bugs to specific states and easing project management.', 'The state pattern facilitates granular control over player behavior, enabling the creation of multiple abilities, weapons, and special moves.', 'The implementation includes states for sitting and running, with detailed handling of user inputs and state transitions.']}, {'end': 25350.672, 'start': 24602.344, 'title': 'Animating player movement and states', 'summary': "Details the implementation of player movement and states, including setting velocity for vertical and horizontal movement, creating utility methods for checking player's position, switching player states based on conditions, animating sprite sheets, and controlling frame intervals using delta time.", 'duration': 748.328, 'highlights': ["The chapter details the implementation of player movement and states, including setting velocity for vertical and horizontal movement, creating utility methods for checking player's position, switching player states based on conditions, animating sprite sheets, and controlling frame intervals using delta time.", 'The implementation involves setting velocity for vertical movement by adjusting the velocityY property and creating a weight property to simulate gravity, resulting in a smooth jumping curve.', "The creation of a utility method 'onGround' to check if the player is standing on the ground enhances code readability and allows for more readable checks in the code.", 'The chapter covers the implementation of switching player states based on conditions such as checking if the player is on the ground, enabling the player to switch sides while jumping, and transitioning between different states like jumping, standing, running, sitting, and falling.', 'An explanation of animating sprite sheet rows horizontally through the frameX property is provided, along with the adjustment of the max frame value for different animations and the use of delta time to control frame intervals for displaying the next horizontal frame.']}], 'duration': 3106.463, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c22244209.jpg', 'highlights': ['The state pattern is used to manage player behavior, including states such as standing, sitting, and running.', 'The implementation of switching player states based on conditions such as checking if the player is on the ground, enabling the player to switch sides while jumping, and transitioning between different states like jumping, standing, running, sitting, and falling.', "The chapter details the implementation of player movement and states, including setting velocity for vertical and horizontal movement, creating utility methods for checking player's position, switching player states based on conditions, animating sprite sheets, and controlling frame intervals using delta time.", 'The state design pattern allows objects to change their behavior based on their current state, demonstrated by swapping the player between standing left and standing right states.', 'The player class uses polymorphism to execute different behaviors for the enter and handle input methods depending on the current player state, enabling the object to react to a limited set of inputs for each state.']}, {'end': 26233.748, 'segs': [{'end': 25382.752, 'src': 'embed', 'start': 25351.113, 'weight': 0, 'content': [{'end': 25352.453, 'text': 'If I change FPS,', 'start': 25351.113, 'duration': 1.34}, {'end': 25360.758, 'text': 'it affects how fast we serve horizontal sprites while still allowing player to move around at maximum 60 frames per second or whatever your request,', 'start': 25352.453, 'duration': 8.305}, {'end': 25362.92, 'text': 'animation frame can handle on your computer.', 'start': 25360.758, 'duration': 2.162}, {'end': 25366.701, 'text': "If I give it FPS that's higher than my screen's refresh rate.", 'start': 25363.52, 'duration': 3.181}, {'end': 25372.424, 'text': "Request. Animation Frame will automatically cap it, so it won't animate faster past a certain value.", 'start': 25366.701, 'duration': 5.723}, {'end': 25377.106, 'text': "That maximum value of frames per second is limited by your screen's refresh rate.", 'start': 25372.824, 'duration': 4.282}, {'end': 25382.752, 'text': 'Making games with JavaScript is one of my favorite ways to practice coding.', 'start': 25378.686, 'duration': 4.066}], 'summary': 'Adjusting fps affects sprite serving speed, capped by screen refresh rate.', 'duration': 31.639, 'max_score': 25351.113, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25351113.jpg'}, {'end': 25443.621, 'src': 'embed', 'start': 25416.33, 'weight': 1, 'content': [{'end': 25423.017, 'text': 'Come join me and learn how to create your own 2D adventures with HTML, CSS and plain vanilla JavaScript.', 'start': 25416.33, 'duration': 6.687}, {'end': 25425.24, 'text': 'No frameworks and no libraries.', 'start': 25423.378, 'duration': 1.862}, {'end': 25426.802, 'text': 'Click the like if you want more games.', 'start': 25425.38, 'duration': 1.422}, {'end': 25439.84, 'text': 'To keep the code organized and easy to navigate in, I will split JavaScript into multiple files, so-called modules,', 'start': 25433.558, 'duration': 6.282}, {'end': 25443.621, 'text': 'and I will export and import them around the code base as needed.', 'start': 25439.84, 'duration': 3.781}], 'summary': 'Learn to create 2d adventures with html, css, and vanilla javascript, using modular code for organization.', 'duration': 27.291, 'max_score': 25416.33, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25416330.jpg'}, {'end': 25648.173, 'src': 'embed', 'start': 25553.486, 'weight': 2, 'content': [{'end': 25555.867, 'text': "You don't have to use VS Code and Live Server plugin.", 'start': 25553.486, 'duration': 2.381}, {'end': 25559.909, 'text': 'If you know how to create your own local server in a different way, feel free to do that.', 'start': 25555.967, 'duration': 3.942}, {'end': 25564.251, 'text': 'So now I can see my live server is running on port 5501.', 'start': 25560.049, 'duration': 4.202}, {'end': 25567.732, 'text': 'It will reload browser window whenever I save any project file.', 'start': 25564.251, 'duration': 3.481}, {'end': 25571.194, 'text': 'I usually use Ctrl plus S keyboard shortcut to save.', 'start': 25568.093, 'duration': 3.101}, {'end': 25577.076, 'text': 'Sometimes you have to manually reload the browser page for the first time and then it will start doing it automatically.', 'start': 25571.454, 'duration': 5.622}, {'end': 25583.137, 'text': 'In style CSS I reset margin and padding to zero on all elements and I set box size into border box.', 'start': 25577.396, 'duration': 5.741}, {'end': 25588.459, 'text': 'This is so called global reset and we do it to make sure our page looks the same across different browsers.', 'start': 25583.418, 'duration': 5.041}, {'end': 25594.041, 'text': 'Canvas, one will have border five pixels solid black and I center it in the middle of the page.', 'start': 25588.759, 'duration': 5.282}, {'end': 25599.643, 'text': 'so the usual four lines of CSS position absolute top 50%, left 50%.', 'start': 25594.041, 'duration': 5.602}, {'end': 25601.703, 'text': 'transform, translate minus 50%.', 'start': 25599.643, 'duration': 2.06}, {'end': 25603.064, 'text': 'minus 50%.', 'start': 25601.703, 'duration': 1.361}, {'end': 25608.846, 'text': 'I will provide you with game art assets you can use to code along with me and at the end in the experiment sections,', 'start': 25603.064, 'duration': 5.782}, {'end': 25615.169, 'text': 'I will show you how to apply different skins to your game so that you can make it unique, based on your own creative preferences.', 'start': 25608.846, 'duration': 6.323}, {'end': 25620.792, 'text': "Check out this website for more beautiful art assets that are already compatible with today's project.", 'start': 25615.529, 'duration': 5.263}, {'end': 25625.794, 'text': 'Today we will be using images for player, backgrounds, enemies and other things.', 'start': 25621.272, 'duration': 4.522}, {'end': 25633.56, 'text': 'The easiest way to make sure our code runs only after all art assets are loaded is by placing the images inside index.html,', 'start': 25626.454, 'duration': 7.106}, {'end': 25640.126, 'text': 'which we will do in a minute, and we will put all JavaScript inside a callback function on event listener for window load event.', 'start': 25633.56, 'duration': 6.566}, {'end': 25648.173, 'text': 'That way, JavaScript waits for all dependent resources such as style sheets and images to be fully loaded and available before it runs.', 'start': 25640.486, 'duration': 7.687}], 'summary': 'Running live server on port 5501, auto reloads on save, css global reset, canvas styling, game art assets, and ensuring code runs after all assets are loaded.', 'duration': 94.687, 'max_score': 25553.486, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25553486.jpg'}, {'end': 25762.174, 'src': 'embed', 'start': 25733.6, 'weight': 3, 'content': [{'end': 25739.523, 'text': 'If you are a beginner, it will be easier for you if you follow my code exactly and use the sprites and images I provide you.', 'start': 25733.6, 'duration': 5.923}, {'end': 25746.446, 'text': "And only once you have a working project, then you can modify it and add your own art assets and game features if that's what you want to do.", 'start': 25739.723, 'duration': 6.723}, {'end': 25749.768, 'text': 'Inside Player.js, I create a class called Player.', 'start': 25747.066, 'duration': 2.702}, {'end': 25753.49, 'text': 'Its job will be to draw and update our SuperDog character.', 'start': 25750.148, 'duration': 3.342}, {'end': 25756.591, 'text': 'Constructor will take the entire game object as an argument.', 'start': 25753.69, 'duration': 2.901}, {'end': 25762.174, 'text': 'Through it, we will have access to some things we will need such as width and height of the game area and so on.', 'start': 25757.071, 'duration': 5.103}], 'summary': 'Tutorial advises beginners to follow provided code and sprites, then modify for own assets and features.', 'duration': 28.574, 'max_score': 25733.6, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25733600.jpg'}, {'end': 25967.232, 'src': 'embed', 'start': 25941.201, 'weight': 4, 'content': [{'end': 25947.804, 'text': 'It will create one new instance of this class and as a side effect all the code inside the constructor will run.', 'start': 25941.201, 'duration': 6.603}, {'end': 25952.686, 'text': 'We can take advantage of that by putting in any code we want to run at that point.', 'start': 25948.384, 'duration': 4.302}, {'end': 25958.208, 'text': 'When I create an instance of game class I also want to automatically create an instance of player class.', 'start': 25953.246, 'duration': 4.962}, {'end': 25962.67, 'text': "Since I'm importing player class on line 1 I can instantiate it here.", 'start': 25958.708, 'duration': 3.962}, {'end': 25967.232, 'text': 'This.player property on game class will be new player like this.', 'start': 25963.15, 'duration': 4.082}], 'summary': 'Creating a new instance of the game class also triggers the instantiation of the player class.', 'duration': 26.031, 'max_score': 25941.201, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25941201.jpg'}], 'start': 25351.113, 'title': '2d game development with javascript and html5 canvas', 'summary': 'Delves into the impact of fps on game animation, using javascript for 2d game creation, and setting up a local server using vs code and live server plugin. it also covers creating html5 canvas game, including css setup, canvas centering, art asset loading, game and player class creation, and sprite sheet animation.', 'chapters': [{'end': 25571.194, 'start': 25351.113, 'title': '2d game development with javascript', 'summary': 'Explains the impact of frames per second (fps) on game animation, the use of javascript to create a 2d game, and the setup of a local server using vs code and live server plugin for game development.', 'duration': 220.081, 'highlights': ["The maximum value of frames per second is limited by the screen's refresh rate, allowing for smooth animation at a maximum of 60 frames per second (FPS) or the refresh rate of the screen.", 'The chapter details the process of creating a 2D game using HTML, CSS, and plain vanilla JavaScript, without the use of frameworks or libraries.', 'The setup of a local server using VS Code and Live Server plugin is explained, enabling automatic browser window reload upon saving project files.']}, {'end': 26233.748, 'start': 25571.454, 'title': 'Creating html5 canvas game', 'summary': 'Covers setting up a global reset in css, centering canvas, applying different skins to the game, loading art assets, creating a game class, importing and using player class, and animating a game character from a sprite sheet.', 'duration': 662.294, 'highlights': ['Setting up a global reset in CSS', 'Centering the canvas', 'Applying different skins to the game', 'Loading art assets', 'Creating a game class', 'Importing and using player class', 'Animating a game character from a sprite sheet']}], 'duration': 882.635, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c25351113.jpg', 'highlights': ["The maximum value of frames per second is limited by the screen's refresh rate, allowing for smooth animation at a maximum of 60 frames per second (FPS) or the refresh rate of the screen.", 'The chapter details the process of creating a 2D game using HTML, CSS, and plain vanilla JavaScript, without the use of frameworks or libraries.', 'The setup of a local server using VS Code and Live Server plugin is explained, enabling automatic browser window reload upon saving project files.', 'Animating a game character from a sprite sheet', 'Creating a game class', 'Loading art assets', 'Centering the canvas', 'Setting up a global reset in CSS', 'Applying different skins to the game', 'Importing and using player class']}, {'end': 27273.148, 'segs': [{'end': 26261.757, 'src': 'embed', 'start': 26233.748, 'weight': 3, 'content': [{'end': 26240.433, 'text': 'DestinationWidth and DestinationHeight will define where, on destination canvas, we want to draw that cropped out rectangle onto.', 'start': 26233.748, 'duration': 6.685}, {'end': 26244.798, 'text': 'At first I just want to crop out the top left frame in my sprite sheet.', 'start': 26241.053, 'duration': 3.745}, {'end': 26252.407, 'text': 'so I crop from coordinates 0,0 and the area will have a width of 100 pixels and height of 91.3 pixels.', 'start': 26244.798, 'duration': 7.609}, {'end': 26254.49, 'text': "I'm cropping out exactly one frame.", 'start': 26252.627, 'duration': 1.863}, {'end': 26256.492, 'text': "I don't need the red rectangle anymore.", 'start': 26254.73, 'duration': 1.762}, {'end': 26261.757, 'text': 'We are redrawing the same image over and over 60 times per second, but it looks static.', 'start': 26257.153, 'duration': 4.604}], 'summary': 'Cropping a 100x91.3 pixel frame from sprite sheet to redraw 60 times per second.', 'duration': 28.009, 'max_score': 26233.748, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c26233748.jpg'}, {'end': 26294.1, 'src': 'embed', 'start': 26271.906, 'weight': 2, 'content': [{'end': 26279.933, 'text': 'To actually run the code, I need to go to update method on game class and I take this.player from line 13 and I call update on it like this.', 'start': 26271.906, 'duration': 8.027}, {'end': 26284.717, 'text': 'Finally, I call game.update from inside animation loop and we have some motion.', 'start': 26280.273, 'duration': 4.444}, {'end': 26287.678, 'text': 'Congratulations, you are a JavaScript animation master.', 'start': 26284.997, 'duration': 2.681}, {'end': 26290.299, 'text': 'Okay, we can do a bit more with this if you want.', 'start': 26288.558, 'duration': 1.741}, {'end': 26293.04, 'text': 'The dog is leaving a black trail behind.', 'start': 26290.999, 'duration': 2.041}, {'end': 26294.1, 'text': "That's old paint.", 'start': 26293.28, 'duration': 0.82}], 'summary': 'Code update creates motion in animation loop, achieving javascript animation mastery.', 'duration': 22.194, 'max_score': 26271.906, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c26271906.jpg'}, {'end': 26348.423, 'src': 'embed', 'start': 26315.712, 'weight': 4, 'content': [{'end': 26316.653, 'text': "Let's comment this out.", 'start': 26315.712, 'duration': 0.941}, {'end': 26322.177, 'text': 'I want the player to move left and right, jump, and to use superpowers based on keyboard inputs.', 'start': 26317.073, 'duration': 5.104}, {'end': 26325.18, 'text': 'I create a new JavaScript file, a new module.', 'start': 26322.838, 'duration': 2.342}, {'end': 26326.901, 'text': 'I call it input.js.', 'start': 26325.52, 'duration': 1.381}, {'end': 26330.164, 'text': 'Its job will be to capture and keep track of user input.', 'start': 26327.341, 'duration': 2.823}, {'end': 26332.586, 'text': 'Again, I will create a JavaScript class here.', 'start': 26330.464, 'duration': 2.122}, {'end': 26335.469, 'text': 'I will call it for example input handler.', 'start': 26333.266, 'duration': 2.203}, {'end': 26342.617, 'text': 'Inside its constructor I create a property called this.keys and I set it to an empty array at first.', 'start': 26336.229, 'duration': 6.388}, {'end': 26348.423, 'text': 'I will be adding keys that are pressed down into this array and removing the keys that are being released.', 'start': 26342.937, 'duration': 5.486}], 'summary': 'Creating a new javascript module called input.js to capture and track user input for player movement and superpowers.', 'duration': 32.711, 'max_score': 26315.712, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c26315712.jpg'}, {'end': 27064.72, 'src': 'embed', 'start': 27025.082, 'weight': 0, 'content': [{'end': 27030.427, 'text': 'We are building a fast-paced animated side-scroller game with vanilla JavaScript and HTML canvas.', 'start': 27025.082, 'duration': 5.345}, {'end': 27035.671, 'text': 'In the first episode, we created the main game logic, animation loop, and the player.', 'start': 27030.667, 'duration': 5.004}, {'end': 27037.273, 'text': "Let's continue building our game.", 'start': 27035.871, 'duration': 1.402}, {'end': 27043.079, 'text': 'In this class, we will apply state design pattern to our player to make it switch between the states properly.', 'start': 27037.573, 'duration': 5.506}, {'end': 27045.681, 'text': 'We will learn how to control FPS,', 'start': 27043.419, 'duration': 2.262}, {'end': 27053.61, 'text': 'how to animate sprite sheets and how to implement multi-layered seamless backgrounds with scrolling speed that reacts to player movement.', 'start': 27045.681, 'duration': 7.929}, {'end': 27056.052, 'text': 'Part 1 is linked in the video description.', 'start': 27054.13, 'duration': 1.922}, {'end': 27056.433, 'text': "Let's go.", 'start': 27056.132, 'duration': 0.301}, {'end': 27059.555, 'text': 'I like writing my code like this for small simple games.', 'start': 27056.773, 'duration': 2.782}, {'end': 27063.098, 'text': 'As you can see there are quite a lot of if else statements in here already.', 'start': 27059.776, 'duration': 3.322}, {'end': 27064.72, 'text': 'I want to add some special moves.', 'start': 27063.118, 'duration': 1.602}], 'summary': 'Building an animated game with javascript and html canvas, applying state design pattern and implementing multi-layered seamless backgrounds with scrolling speed.', 'duration': 39.638, 'max_score': 27025.082, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c27025082.jpg'}], 'start': 26233.748, 'title': 'Mastering javascript animation and player controls', 'summary': 'Covers javascript animation basics for achieving 60 frames per second, implementing player movement and superpowers, and managing player states in a fast-paced animated side-scroller game.', 'chapters': [{'end': 26315.432, 'start': 26233.748, 'title': 'Javascript animation basics', 'summary': 'Explains how to crop and draw images, implement basic animation, and clear canvas for smooth animation, achieving 60 frames per second and a javascript animation mastery.', 'duration': 81.684, 'highlights': ['To achieve smooth animation, the canvas needs to be cleared for each update, using the builtInClearRectangle method, to show only the current animation frame.', 'In order to animate the player, the X coordinate needs to be increased by one pixel for every animation frame, achieving a frame rate of 60 frames per second.', 'The process of cropping out exactly one frame from the sprite sheet involves using the coordinates 0,0 with a width of 100 pixels and a height of 91.3 pixels.', 'By calling the update method on the game class and game.update from inside the animation loop, the animation is achieved, demonstrating the process of JavaScript animation.', 'The chapter also highlights the need for clearing the canvas to avoid leaving a trail behind and the process of redrawing the same image over and over to achieve animation.']}, {'end': 27005.972, 'start': 26315.712, 'title': 'Implementing player controls and movement', 'summary': 'Details the process of creating a javascript input module to handle player movement and superpowers, including capturing and tracking user input, implementing event listeners for keydown and keyup events, and handling horizontal and vertical movement, resulting in a functional player movement system.', 'duration': 690.26, 'highlights': ['Implementing JavaScript input module for player controls and movement', 'Tracking user input with keys array to enable specific key responses', 'Handling player movement based on user input']}, {'end': 27273.148, 'start': 27006.453, 'title': 'Player states and animation', 'summary': 'Demonstrates the use of state design pattern to manage player states in a fast-paced animated side-scroller game with vanilla javascript and html canvas, including implementing a fireball attack and stopping game scrolling when the player sits down.', 'duration': 266.695, 'highlights': ['The chapter focuses on implementing state design pattern to manage player states in a fast-paced animated side-scroller game with vanilla JavaScript and HTML canvas.', 'The tutorial covers controlling FPS, animating sprite sheets, and implementing multi-layered seamless backgrounds with scrolling speed that reacts to player movement.', 'The chapter emphasizes the importance of structuring code to manage player states separately and explains the creation of a simple enum object to pair values and names of each state for better code readability.']}], 'duration': 1039.4, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c26233748.jpg', 'highlights': ['The tutorial covers controlling FPS, animating sprite sheets, and implementing multi-layered seamless backgrounds with scrolling speed that reacts to player movement.', 'The chapter focuses on implementing state design pattern to manage player states in a fast-paced animated side-scroller game with vanilla JavaScript and HTML canvas.', 'By calling the update method on the game class and game.update from inside the animation loop, the animation is achieved, demonstrating the process of JavaScript animation.', 'The process of cropping out exactly one frame from the sprite sheet involves using the coordinates 0,0 with a width of 100 pixels and a height of 91.3 pixels.', 'Implementing JavaScript input module for player controls and movement']}, {'end': 29222.02, 'segs': [{'end': 27359.561, 'src': 'embed', 'start': 27333.418, 'weight': 0, 'content': [{'end': 27341.107, 'text': 'Player object will have this.states property which will be an array containing individual states such as sitting, running and so on.', 'start': 27333.418, 'duration': 7.689}, {'end': 27348.435, 'text': 'The player can only be in one state at a time so we will have another property here called this.currentState.', 'start': 27341.587, 'duration': 6.848}, {'end': 27354.499, 'text': 'When this.currentState is equal to this.states player is sitting.', 'start': 27349.136, 'duration': 5.363}, {'end': 27359.561, 'text': "When it's this.states the player is in the running state, and so on.", 'start': 27355.059, 'duration': 4.502}], 'summary': "Player object has states property with array of individual states such as sitting, running. currentstate determines player's state.", 'duration': 26.143, 'max_score': 27333.418, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c27333418.jpg'}, {'end': 27425.023, 'src': 'embed', 'start': 27397.378, 'weight': 4, 'content': [{'end': 27403.743, 'text': 'as the player switches from one state to another, we can just keep calling this.currentState.handleInput,', 'start': 27397.378, 'duration': 6.365}, {'end': 27409.468, 'text': 'and we will get different behaviors depending on the current state the player is in at that point in time.', 'start': 27403.743, 'duration': 5.725}, {'end': 27413.191, 'text': 'And this is the entire logic behind state design pattern.', 'start': 27409.849, 'duration': 3.342}, {'end': 27415.073, 'text': "If it's still not clear, don't worry.", 'start': 27413.572, 'duration': 1.501}, {'end': 27418.256, 'text': 'I will go over it today step by step as we write the code.', 'start': 27415.293, 'duration': 2.963}, {'end': 27420.799, 'text': 'It will make more sense if you practice and code with me.', 'start': 27418.416, 'duration': 2.383}, {'end': 27425.023, 'text': 'Inside this.states array I will instantiate each state class.', 'start': 27421.359, 'duration': 3.664}], 'summary': "The state design pattern allows for different behaviors depending on the player's current state, demonstrated through calling this.currentstate.handleinput as the player switches states.", 'duration': 27.645, 'max_score': 27397.378, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c27397378.jpg'}, {'end': 28183.268, 'src': 'embed', 'start': 28158.016, 'weight': 2, 'content': [{'end': 28164.519, 'text': 'I can for example have the dog sprite sheet animate at 10 frames per second while the entire game is still updating at 60 FPS.', 'start': 28158.016, 'duration': 6.503}, {'end': 28169.561, 'text': 'Yes, you can do it by checking animation timestamps and calculating delta time.', 'start': 28165.179, 'duration': 4.382}, {'end': 28170.842, 'text': "It's easy, let me show you.", 'start': 28169.861, 'duration': 0.981}, {'end': 28172.322, 'text': 'I will explain it right now.', 'start': 28170.862, 'duration': 1.46}, {'end': 28174.844, 'text': 'We will need a helper variable here.', 'start': 28173.183, 'duration': 1.661}, {'end': 28179.806, 'text': 'LastTime will hold the value of the timestamp from the previous animation loop.', 'start': 28175.344, 'duration': 4.462}, {'end': 28183.268, 'text': 'RequestAnimationFrame method has two special features.', 'start': 28180.366, 'duration': 2.902}], 'summary': 'Achieve independent sprite sheet animation at 10 fps while game updates at 60 fps using animation timestamps and delta time.', 'duration': 25.252, 'max_score': 28158.016, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c28158016.jpg'}, {'end': 28507.466, 'src': 'embed', 'start': 28479.285, 'weight': 1, 'content': [{'end': 28481.225, 'text': 'We can control these two things separately.', 'start': 28479.285, 'duration': 1.94}, {'end': 28488.747, 'text': 'It would be very bad if controls reacted so slowly, but maybe you have a sprite sheet in your game that was designed for lower FPS.', 'start': 28482.185, 'duration': 6.562}, {'end': 28491.408, 'text': 'Our sprite sheets were designed for speed around 20 FPS.', 'start': 28488.927, 'duration': 2.481}, {'end': 28496.379, 'text': 'Depending on what art assets you are using for your game level.', 'start': 28493.277, 'duration': 3.102}, {'end': 28500.061, 'text': 'you might not want the player to be standing all the way at the bottom of the game area.', 'start': 28496.379, 'duration': 3.682}, {'end': 28502.223, 'text': 'Sometimes you need to adjust this value.', 'start': 28500.502, 'duration': 1.721}, {'end': 28507.466, 'text': 'Today I will give you all art assets to use so I know we will need to create some margin on the bottom.', 'start': 28502.523, 'duration': 4.943}], 'summary': 'Sprite sheets designed for speed around 20 fps, need to adjust player position at bottom for game level art assets.', 'duration': 28.181, 'max_score': 28479.285, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c28479285.jpg'}, {'end': 29050.827, 'src': 'embed', 'start': 29012.292, 'weight': 3, 'content': [{'end': 29014.452, 'text': "I hope this visual makes it clear what's happening.", 'start': 29012.292, 'duration': 2.16}, {'end': 29018.734, 'text': 'And now you know the secret of endlessly scrolling seamless backgrounds.', 'start': 29015.213, 'duration': 3.521}, {'end': 29019.435, 'text': "It's easy.", 'start': 29018.994, 'duration': 0.441}, {'end': 29027.138, 'text': "Let's make them parallax, which means it has multiple layers that move in slightly different speeds to create an illusion of depth, of distance.", 'start': 29019.875, 'duration': 7.263}, {'end': 29034.121, 'text': 'I already brought those images into our project in index HTML, so I just turned them into class properties here.', 'start': 29028.55, 'duration': 5.571}, {'end': 29039.072, 'text': 'I instantiate each layer class with its associated image.', 'start': 29035.524, 'duration': 3.548}, {'end': 29050.827, 'text': 'I put all those layer objects inside this dot background layers array so we can cycle through all of them at once using foreach method.', 'start': 29042.665, 'duration': 8.162}], 'summary': 'Creating parallax backgrounds with multiple layers for illusion of depth and distance.', 'duration': 38.535, 'max_score': 29012.292, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29012292.jpg'}], 'start': 27273.148, 'title': 'Implementing state design pattern in game development', 'summary': 'Explains the application of state design pattern in game development, covering the integration of player states, sprite animation, fps control, and creation of seamless endless background, enhancing user experience and game mechanics.', 'chapters': [{'end': 27435.894, 'start': 27273.148, 'title': 'Applying state design pattern in player object', 'summary': 'Explains the implementation of state design pattern in the player object, including the use of this.states array, this.currentstate property, and the creation of separate classes for each player state, allowing for different behaviors based on the current state.', 'duration': 162.746, 'highlights': ['The player object will have this.states property which will be an array containing individual states such as sitting, running and so on.', 'The player can only be in one state at a time so we will have another property here called this.currentState.', 'Each state class will also have handle update method, which will listen for keyboard inputs, and it will be ready to switch the player to a different state whenever the correct key is pressed.', 'We will have a class for sitting, another class for running, there will be a separate class for every state.', 'It will make more sense if you practice and code with me.']}, {'end': 27668.985, 'start': 27436.855, 'title': 'Sprite animation and player states', 'summary': 'Explains how to set up sprite animation with frame x and frame y, and how to switch player between different states, such as sitting and standing, by defining a method called setstate and handling user input for state switching at 60 times per second.', 'duration': 232.13, 'highlights': ['The player class is set up to handle sprite animation by cycling through frame X and frame Y values to display different animations on the player sprite sheet.', 'The method setState is defined to switch the player between different states, such as sitting and standing, by taking a new state as an argument and setting the currentState accordingly.', 'The handle input method is designed to run 60 times per second, waiting for specific keys to be pressed to switch the player into a different state, such as arrows for movement, and the input value is obtained from the keys array on an instance of the input handler class.']}, {'end': 28077.099, 'start': 27669.525, 'title': 'State design pattern in game development', 'summary': 'Explains the implementation of the state design pattern in a game development context, demonstrating the locking of player object in different states and the corresponding keyboard input reactions, including the creation and functionality of sitting, running, jumping, and falling states, and the integration of these states in the game mechanics.', 'duration': 407.574, 'highlights': ['The chapter explains the implementation of the state design pattern in a game development context.', 'Demonstrating the locking of player object in different states and the corresponding keyboard input reactions.', 'Creation and functionality of sitting, running, jumping, and falling states.', 'Integration of these states in the game mechanics.']}, {'end': 28664.917, 'start': 28078.519, 'title': 'Sprite animation logic and fps control', 'summary': "Covers the implementation of sprite animation logic and fps control, demonstrating the usage of delta time to adjust sprite animation speed and the ability to control fps independently of the game's overall fps. additionally, it addresses organizing code using state design pattern and setting up parallax multilayered background animation.", 'duration': 586.398, 'highlights': ["The chapter covers the implementation of sprite animation logic and FPS control, demonstrating the usage of delta time to adjust sprite animation speed and the ability to control FPS independently of the game's overall FPS.", 'Demonstration of using delta time to calculate the time each frame stays on the screen and passing the delta time value to the player update method.', 'Explanation of organizing code using state design pattern and the ease of keeping track of each state separately.', 'Setting up parallax multilayered background animation with the introduction of Layer and Background classes.']}, {'end': 29222.02, 'start': 28665.237, 'title': 'Creating endless seamless backgrounds', 'summary': 'Explains a small simple trick to create an illusion of endless background in a side scroller game using multiple layers and parallax effect, animating all layers at different speeds, ultimately improving user experience.', 'duration': 556.783, 'highlights': ['The trick to create seamlessly scrolling backgrounds is to draw the same image twice next to each other, creating an illusion of endless background.', 'Animating all layers at different speeds creates a parallax effect, improving user experience.', 'Quick responsive controls contribute to positive user experience.']}], 'duration': 1948.872, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c27273148.jpg', 'highlights': ['Creation and functionality of sitting, running, jumping, and falling states.', 'Integration of player states, sprite animation, and FPS control in game mechanics.', 'Demonstration of sprite animation logic and FPS control using delta time.', 'Setting up parallax multilayered background animation for improved user experience.', 'Explanation of organizing code using state design pattern for better state management.']}, {'end': 30661.411, 'segs': [{'end': 29248.485, 'src': 'embed', 'start': 29222.765, 'weight': 0, 'content': [{'end': 29228.77, 'text': 'We are building a fast-paced animated 2D game with plain vanilla JavaScript and HTML canvas element.', 'start': 29222.765, 'duration': 6.005}, {'end': 29232.012, 'text': 'We applied state design pattern to animate our player.', 'start': 29229.05, 'duration': 2.962}, {'end': 29237.416, 'text': 'We have endlessly scrolling parallax backgrounds where scrolling speed reacts to player movement.', 'start': 29232.292, 'duration': 5.124}, {'end': 29242.52, 'text': 'Today we will learn how to make our game more fun by adding three very different enemy types.', 'start': 29237.937, 'duration': 4.583}, {'end': 29248.485, 'text': 'Are you ready to take our dog for an adventure and help it find its way home while avoiding enemies and creatures of the dark??', 'start': 29242.861, 'duration': 5.624}], 'summary': 'Creating a fast-paced 2d game with javascript and html canvas, featuring state design pattern, parallax backgrounds, and adding three enemy types for more fun.', 'duration': 25.72, 'max_score': 29222.765, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29222765.jpg'}, {'end': 29352.631, 'src': 'embed', 'start': 29306.239, 'weight': 1, 'content': [{'end': 29310.321, 'text': 'and we will extend that parent class into multiple different subclasses.', 'start': 29306.239, 'duration': 4.082}, {'end': 29316.223, 'text': 'Each subclass will have properties and methods that are specific just for that enemy type.', 'start': 29310.601, 'duration': 5.622}, {'end': 29326.634, 'text': 'So enemy is so-called parent class, also called a superclass, and we are using this special extends keyword to create three child classes,', 'start': 29317.668, 'duration': 8.966}, {'end': 29328.135, 'text': 'also called subclasses.', 'start': 29326.634, 'duration': 1.501}, {'end': 29330.377, 'text': "JavaScript actually doesn't have classes.", 'start': 29328.596, 'duration': 1.781}, {'end': 29332.218, 'text': 'This is just syntactical sugar.', 'start': 29330.537, 'duration': 1.681}, {'end': 29335.3, 'text': 'Modern, cleaned, and simplified JavaScript syntax.', 'start': 29332.578, 'duration': 2.722}, {'end': 29340.864, 'text': 'Behind the scenes, this code is just setting up prototype chains using JavaScript inheritance.', 'start': 29335.66, 'duration': 5.204}, {'end': 29344.927, 'text': 'It just looks cleaner and easier to navigate in if you write your code this way.', 'start': 29341.224, 'duration': 3.703}, {'end': 29352.631, 'text': 'So we have a parent enemy class and three child classes called flying enemy, ground enemy and climbing enemy.', 'start': 29345.467, 'duration': 7.164}], 'summary': "Javascript uses 'extends' to create subclasses for enemy types, such as flying, ground, and climbing enemies.", 'duration': 46.392, 'max_score': 29306.239, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29306239.jpg'}, {'end': 29715.529, 'src': 'embed', 'start': 29684.375, 'weight': 4, 'content': [{'end': 29688.499, 'text': 'As I said before we can extend parent class constructor using super keyword.', 'start': 29684.375, 'duration': 4.124}, {'end': 29691.423, 'text': 'We can also extend a method from a parent class.', 'start': 29688.8, 'duration': 2.623}, {'end': 29694.866, 'text': 'In this case I want to have update method on flying enemy type.', 'start': 29691.663, 'duration': 3.203}, {'end': 29704.316, 'text': 'I want it to first run all the code from update method on the parent class and then I want to add a little bit of code that will be specific only for flying enemies.', 'start': 29695.467, 'duration': 8.849}, {'end': 29707.7, 'text': 'Update method will expect delta time as an argument.', 'start': 29705.077, 'duration': 2.623}, {'end': 29715.529, 'text': 'I will call update method on the parent class from line 9 by saying super, referring to its super class dot update,', 'start': 29708.141, 'duration': 7.388}], 'summary': 'Extending parent class constructor and method to update flying enemy type with specific code.', 'duration': 31.154, 'max_score': 29684.375, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29684375.jpg'}, {'end': 30127.886, 'src': 'embed', 'start': 30101.914, 'weight': 3, 'content': [{'end': 30107.738, 'text': 'I can for example randomize their horizontal speed x value so that each enemy flies at a slightly different speed.', 'start': 30101.914, 'duration': 5.824}, {'end': 30112.402, 'text': "Let's try a random value between 1 and 2 pixels per frame.", 'start': 30109.299, 'duration': 3.103}, {'end': 30119.138, 'text': 'I can also randomize their initial X coordinate so that we get even more randomness in their spacing.', 'start': 30113.652, 'duration': 5.486}, {'end': 30127.886, 'text': 'When the player starts running it becomes obvious we need to account for the current game speed when making enemies move.', 'start': 30122.181, 'duration': 5.705}], 'summary': 'Randomize enemy speed and initial position for variety in gameplay.', 'duration': 25.972, 'max_score': 30101.914, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c30101914.jpg'}], 'start': 29222.765, 'title': '2d game development with javascript', 'summary': 'Details the process of adding three different enemy types to a 2d game built with plain vanilla javascript and html canvas, utilizing state design pattern, subclassing for enemy types, extending parent class constructor and method, and implementing specific behaviors for flying and ground enemy types.', 'chapters': [{'end': 29284.549, 'start': 29222.765, 'title': '2d game development with javascript', 'summary': 'Explains the process of adding three different enemy types to a 2d game built with plain vanilla javascript and html canvas. it includes the use of state design pattern for player animation, endlessly scrolling parallax backgrounds, and the creation of a custom javascript class for enemies.', 'duration': 61.784, 'highlights': ['The chapter covers the process of adding three different enemy types to a 2D game built with plain vanilla JavaScript and HTML canvas.', 'It explains the use of state design pattern for player animation and the creation of a custom JavaScript class for enemies.', 'The chapter also includes information about endlessly scrolling parallax backgrounds and sprite sheet navigation for enemy animation.']}, {'end': 29683.735, 'start': 29285.07, 'title': 'Javascript subclassing for enemy types', 'summary': 'Explains javascript subclassing to create different enemy types, utilizing parent and child classes to organize and share properties and methods, and setting up prototype chains. it also details the process of extending classes, utilizing sprite sheets, and implementing superclass constructor and methods for each subclass.', 'duration': 398.665, 'highlights': ['Utilizing JavaScript subclassing to organize and share properties and methods', 'Extending parent class into multiple different subclasses', 'Setting up prototype chains using JavaScript inheritance', 'Utilizing sprite sheets for different enemy types', 'Implementing superclass constructor and methods for each subclass']}, {'end': 30661.411, 'start': 29684.375, 'title': 'Extending enemy types in 2d game development', 'summary': 'Covers extending parent class constructor and method, adding flying and ground enemy types with specific behaviors, and implementing update and draw methods with detailed coding examples.', 'duration': 977.036, 'highlights': ['We extended the update method to include a little bit of code specific to flying enemies, and added flying enemies into the game with a periodic code.', 'We handled the movement and removal of flying enemies based on specific conditions, and resolved issues related to the initial coordinates and speed properties of flying enemies.', 'We added ground enemies into the game, implemented specific behaviors, and controlled their addition based on game speed and random probability.', 'We extended the update and draw methods for climbing enemies, implemented specific climbing behavior, and added spider webs to the drawing.']}], 'duration': 1438.646, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c29222765.jpg', 'highlights': ['The chapter covers the process of adding three different enemy types to a 2D game built with plain vanilla JavaScript and HTML canvas.', 'Utilizing JavaScript subclassing to organize and share properties and methods', 'Extending parent class into multiple different subclasses', 'We added ground enemies into the game, implemented specific behaviors, and controlled their addition based on game speed and random probability.', 'We extended the update method to include a little bit of code specific to flying enemies, and added flying enemies into the game with a periodic code.']}, {'end': 31604.171, 'segs': [{'end': 30726.239, 'src': 'embed', 'start': 30698.974, 'weight': 2, 'content': [{'end': 30703.895, 'text': 'We created a player, we have our game world and we added dangerous creatures of the night.', 'start': 30698.974, 'duration': 4.921}, {'end': 30707.015, 'text': "It's time to add some interactions and special moves.", 'start': 30704.335, 'duration': 2.68}, {'end': 30714.897, 'text': 'Today we will learn an easy way how to handle collision detection and we will resolve collision between player and enemies in two different ways,', 'start': 30707.396, 'duration': 7.501}, {'end': 30716.857, 'text': 'depending on the current player state.', 'start': 30714.897, 'duration': 1.96}, {'end': 30720.778, 'text': 'If the player is rolling enemies are destroyed and we get score points.', 'start': 30717.077, 'duration': 3.701}, {'end': 30723.558, 'text': "In any other state it's the player who receives a hit.", 'start': 30721.018, 'duration': 2.54}, {'end': 30726.239, 'text': 'We will also add dust particles and fire trail.', 'start': 30723.699, 'duration': 2.54}], 'summary': 'Game development: added interactions, resolved collisions, and added visual effects.', 'duration': 27.265, 'max_score': 30698.974, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c30698974.jpg'}, {'end': 30776.138, 'src': 'embed', 'start': 30736.053, 'weight': 3, 'content': [{'end': 30739.298, 'text': "With JavaScript and HTML canvas, it's all the same set of techniques.", 'start': 30736.053, 'duration': 3.245}, {'end': 30743.324, 'text': "Let's go! We have player and enemies in our game.", 'start': 30739.538, 'duration': 3.786}, {'end': 30746.624, 'text': 'We want them to be able to interact in different ways with each other.', 'start': 30743.524, 'duration': 3.1}, {'end': 30748.465, 'text': "Let's apply collision detection.", 'start': 30747.025, 'duration': 1.44}, {'end': 30755.627, 'text': 'First, I want to draw a rectangle around the player and around each enemy to see their collision areas, so-called hitboxes.', 'start': 30748.905, 'duration': 6.722}, {'end': 30759.488, 'text': 'I go to input.js file and I delete these console logs.', 'start': 30756.067, 'duration': 3.421}, {'end': 30762.069, 'text': 'I want our game to have a debug mode.', 'start': 30760.248, 'duration': 1.821}, {'end': 30767.352, 'text': 'When I press letter D on my keyboard, we enable debug mode and collision hitboxes will be drawn.', 'start': 30762.229, 'duration': 5.123}, {'end': 30771.575, 'text': 'When we press D again, we exit debug mode and hitboxes will be hidden.', 'start': 30767.673, 'duration': 3.902}, {'end': 30773.136, 'text': "It's very simple to implement.", 'start': 30771.935, 'duration': 1.201}, {'end': 30776.138, 'text': 'In keydown event, I create an else if statement.', 'start': 30773.576, 'duration': 2.562}], 'summary': 'Using javascript and html canvas, implement collision detection and debug mode in a game.', 'duration': 40.085, 'max_score': 30736.053, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c30736053.jpg'}, {'end': 31144.597, 'src': 'embed', 'start': 31112.133, 'weight': 4, 'content': [{'end': 31115.536, 'text': 'This UI class will have just one method I call for example draw.', 'start': 31112.133, 'duration': 3.403}, {'end': 31120.241, 'text': 'Its job will be to draw all UI elements and game statuses that we need.', 'start': 31115.957, 'duration': 4.284}, {'end': 31122.283, 'text': 'First I declare some basic settings.', 'start': 31120.581, 'duration': 1.702}, {'end': 31128.949, 'text': 'Context.Font will be this.FontSize plus pixels space plus this.FontFamily.', 'start': 31122.583, 'duration': 6.366}, {'end': 31132.833, 'text': 'In this part we will declare code that specific to draw in score.', 'start': 31129.45, 'duration': 3.383}, {'end': 31134.755, 'text': 'Up here some more global settings.', 'start': 31133.274, 'duration': 1.481}, {'end': 31136.417, 'text': 'Text align will be left.', 'start': 31135.255, 'duration': 1.162}, {'end': 31144.597, 'text': 'And fill style for all fonts will be kept on the main game object in case we need to draw fonts from some other modules as well.', 'start': 31137.711, 'duration': 6.886}], 'summary': 'The ui class has one method, draw, to display ui elements and game statuses with specific settings.', 'duration': 32.464, 'max_score': 31112.133, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31112133.jpg'}, {'end': 31249.109, 'src': 'embed', 'start': 31216.672, 'weight': 1, 'content': [{'end': 31219.114, 'text': 'We are keeping our code modular and organized today.', 'start': 31216.672, 'duration': 2.442}, {'end': 31220.655, 'text': "It's easy to expand it later.", 'start': 31219.274, 'duration': 1.381}, {'end': 31223.117, 'text': 'I want to add more player states.', 'start': 31221.616, 'duration': 1.501}, {'end': 31229.32, 'text': 'We will have two different attacks and a separate state that will play dizzy animation when the player gets hit by an enemy.', 'start': 31223.377, 'duration': 5.943}, {'end': 31235.302, 'text': "Let's go ahead and add them up here inside player states.js into our enum object.", 'start': 31229.7, 'duration': 5.602}, {'end': 31240.265, 'text': 'that holds key value pairs and it assigns each state number a more human readable value.', 'start': 31235.302, 'duration': 4.963}, {'end': 31249.109, 'text': 'We will have rolling state with index 4, diving state with index 5 and hit state with index 6 for when the player gets hit.', 'start': 31241.125, 'duration': 7.984}], 'summary': 'Adding two new player attacks and a hit state for a more organized and expandable code.', 'duration': 32.437, 'max_score': 31216.672, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31216672.jpg'}, {'end': 31473.901, 'src': 'embed', 'start': 31450.239, 'weight': 0, 'content': [{'end': 31458.206, 'text': "Dust that comes from the ground at player's feet when it runs on solid ground, blazing fire trail when the player is rolling and diving,", 'start': 31450.239, 'duration': 7.967}, {'end': 31461.729, 'text': 'and a big splash of particles when we dive and stomp into the ground.', 'start': 31458.206, 'duration': 3.523}, {'end': 31465.312, 'text': 'I create a new file I call for example Particles.js.', 'start': 31462.429, 'duration': 2.883}, {'end': 31468.475, 'text': 'Inside we will have the main parent class called particle.', 'start': 31465.712, 'duration': 2.763}, {'end': 31473.901, 'text': 'I will not be exporting it, it will just contain properties and methods shared between all three particle types.', 'start': 31468.836, 'duration': 5.065}], 'summary': 'The game features various particle effects, such as dust, fire trail, and splash, managed within a new file named particles.js.', 'duration': 23.662, 'max_score': 31450.239, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31450239.jpg'}], 'start': 30661.411, 'title': 'Game development: collision detection and interactions', 'summary': 'Covers handling collision detection, adding interactions, enabling debug mode, toggling collision hitboxes, adding special moves and animations, creating hitboxes around enemies, implementing collision detection, adding ui elements, implementing player states, and particle effects for dust, blazing fire trail, and splash, with precise controls and movement for the player.', 'chapters': [{'end': 30848.375, 'start': 30661.411, 'title': 'Game development: collision detection and interactions', 'summary': 'Covers handling collision detection and adding interactions in a game with javascript and html canvas, including enabling debug mode and toggling collision hitboxes, as well as adding special moves and animations for the player and enemies.', 'duration': 186.964, 'highlights': ['The chapter covers handling collision detection and adding interactions in a game with JavaScript and HTML canvas', 'Enabling debug mode and toggling collision hitboxes for player and enemies', 'Adding special moves and unique animations for the player and enemies']}, {'end': 31216.172, 'start': 30848.635, 'title': 'Adding interactions and ui elements', 'summary': 'Details how to create hitboxes around enemies, implement collision detection to handle interactions with the player, and add ui elements to display the score, with the game now having a debug mode toggled by pressing d.', 'duration': 367.537, 'highlights': ['The game now has a debug mode, toggled by pressing D.', 'Implementing collision detection between player and enemies using hitboxes.', 'Adding interactions for player-enemy collisions, enabling destruction of enemies and scoring points.', 'Creation of a UI class to display game statuses and elements, including the score.']}, {'end': 31604.171, 'start': 31216.672, 'title': 'Adding player states and particle effects', 'summary': 'Discusses the addition of new player states including rolling, diving, and hit states with corresponding animations and input handling. it also covers the implementation of particle effects for dust, blazing fire trail, and splash upon diving into the ground in the game, ensuring precise controls and movement for the player.', 'duration': 387.499, 'highlights': ['The chapter discusses the addition of new player states including rolling, diving, and hit states with corresponding animations and input handling.', 'Implementation of particle effects for dust, blazing fire trail, and splash upon diving into the ground in the game, ensuring precise controls and movement for the player.', 'The rolling state is assigned an index of 4, the diving state an index of 5, and the hit state an index of 6, providing clear enumeration of player states.', 'The rolling animation is set to start on row 6 of the sprite sheet, with the player being able to initiate rolling by pressing the enter key and maintaining it as long as the key is pressed down.', 'Allowing the player to start rolling from running, sitting, and jumping states, while ensuring precise controls and quick movement for a better gameplay experience.', "Introduction of three different particle types in the game: dust at the player's feet on solid ground, blazing fire trail during rolling and diving, and a splash of particles upon diving and stomping into the ground."]}], 'duration': 942.76, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c30661411.jpg', 'highlights': ['Implementation of particle effects for dust, blazing fire trail, and splash upon diving into the ground in the game, ensuring precise controls and movement for the player.', 'The chapter discusses the addition of new player states including rolling, diving, and hit states with corresponding animations and input handling.', 'Adding special moves and unique animations for the player and enemies', 'Implementing collision detection between player and enemies using hitboxes.', 'Creation of a UI class to display game statuses and elements, including the score.', 'The game now has a debug mode, toggled by pressing D.']}, {'end': 32973.211, 'segs': [{'end': 31658.949, 'src': 'embed', 'start': 31625.043, 'weight': 4, 'content': [{'end': 31629.787, 'text': 'If I want to handle particles from here this way, I need access to the main game object.', 'start': 31625.043, 'duration': 4.744}, {'end': 31635.212, 'text': 'When I initially built this state management code, I thought I would only need access to the player class,', 'start': 31630.127, 'duration': 5.085}, {'end': 31638.454, 'text': 'but we need to go one level up and access the game object.', 'start': 31635.212, 'duration': 3.242}, {'end': 31642.418, 'text': "This is why it's good to plan your code bases well before you start writing the code.", 'start': 31638.655, 'duration': 3.763}, {'end': 31650.044, 'text': 'I will have to do a little bit of refactoring here to make sure we have access to the main game class from within each individual player state class.', 'start': 31642.778, 'duration': 7.266}, {'end': 31658.949, 'text': 'Here on line 14 I pass the main state parent class a second argument called game and inside I convert it to class property.', 'start': 31650.805, 'duration': 8.144}], 'summary': 'Refactoring needed to access main game object for particle handling.', 'duration': 33.906, 'max_score': 31625.043, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31625043.jpg'}, {'end': 31764.643, 'src': 'embed', 'start': 31729.138, 'weight': 1, 'content': [{'end': 31735.879, 'text': 'Then I select 1, 2, 3, 4, 5, 6, and I need this.game.player here in all these places.', 'start': 31729.138, 'duration': 6.741}, {'end': 31739.66, 'text': 'I do the same in jumping class, refactoring.', 'start': 31737.2, 'duration': 2.46}, {'end': 31741.601, 'text': 'Sorry, I should have planned this part better.', 'start': 31739.98, 'duration': 1.621}, {'end': 31742.481, 'text': 'We are almost done.', 'start': 31741.681, 'duration': 0.8}, {'end': 31748.102, 'text': 'I replace all nine occurrences of this.player here with this.game.player.', 'start': 31743.521, 'duration': 4.581}, {'end': 31753.853, 'text': "Falling class doesn't have much code so this one is easy.", 'start': 31751.471, 'duration': 2.382}, {'end': 31764.643, 'text': 'And rolling class is the last one we need to refactor.', 'start': 31753.873, 'duration': 10.77}], 'summary': 'Refactored 9 occurrences of this.player with this.game.player, nearly completing the task.', 'duration': 35.505, 'max_score': 31729.138, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31729138.jpg'}, {'end': 31900.698, 'src': 'embed', 'start': 31871.105, 'weight': 3, 'content': [{'end': 31871.966, 'text': 'So I create it here.', 'start': 31871.105, 'duration': 0.861}, {'end': 31875.348, 'text': 'These two particles will be an empty array at first.', 'start': 31872.927, 'duration': 2.421}, {'end': 31877.77, 'text': 'Back to PlayerStates.js.', 'start': 31876.349, 'duration': 1.421}, {'end': 31880.23, 'text': 'I only want to add dust when the player is running.', 'start': 31877.77, 'duration': 2.46}, {'end': 31884.992, 'text': 'so inside HandleInput method, on running state that runs 60 times per second.', 'start': 31880.23, 'duration': 4.762}, {'end': 31888.514, 'text': 'I will be pushing one new particle in every time it runs.', 'start': 31884.992, 'duration': 3.522}, {'end': 31893.455, 'text': 'This.game.particles.push and I pass it new dust.', 'start': 31889.394, 'duration': 4.061}, {'end': 31895.656, 'text': 'On line 14 in Particles.js.', 'start': 31893.815, 'duration': 1.841}, {'end': 31900.698, 'text': 'I can see that dust class constructor expects game x and y as arguments.', 'start': 31895.656, 'duration': 5.042}], 'summary': 'A program creates and adds dust particles while the player is running, with 60 particles added per second.', 'duration': 29.593, 'max_score': 31871.105, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31871105.jpg'}, {'end': 32586.622, 'src': 'embed', 'start': 32558.081, 'weight': 0, 'content': [{'end': 32561.643, 'text': 'In the next part we will make our game look and feel better by adding more animation.', 'start': 32558.081, 'duration': 3.562}, {'end': 32565.825, 'text': 'It will help the player to get more visual feedback to the events happening in the game.', 'start': 32562.043, 'duration': 3.782}, {'end': 32566.625, 'text': "I'll see you there.", 'start': 32566.145, 'duration': 0.48}, {'end': 32573.546, 'text': 'Hey creative coders! In this episode we will finalize player abilities and particle effects.', 'start': 32568.68, 'duration': 4.866}, {'end': 32580.374, 'text': 'We will animate collisions with a special sprite sheet and we will add win and lose condition based on game timer.', 'start': 32573.866, 'duration': 6.508}, {'end': 32582.837, 'text': 'We will also clean up some loose ends in our code.', 'start': 32580.394, 'duration': 2.443}, {'end': 32586.622, 'text': "Let's finish the base game and then we can talk about some optional bonus features.", 'start': 32582.937, 'duration': 3.685}], 'summary': 'Enhance game with animations, player abilities, and win/lose conditions based on timer.', 'duration': 28.541, 'max_score': 32558.081, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c32558081.jpg'}, {'end': 32625.246, 'src': 'embed', 'start': 32592.743, 'weight': 2, 'content': [{'end': 32595.265, 'text': "Player can only enter this state when it's in the air.", 'start': 32592.743, 'duration': 2.522}, {'end': 32599.367, 'text': "It's a perfect use case for state design pattern we have here in our codebase.", 'start': 32595.505, 'duration': 3.862}, {'end': 32603.769, 'text': 'When the player is running on the ground and we press down arrow key it sits down.', 'start': 32599.567, 'duration': 4.202}, {'end': 32608.952, 'text': 'When the player is up in the air we press down arrow key it will do a crushing dive attack from above.', 'start': 32604.009, 'duration': 4.943}, {'end': 32613.355, 'text': 'I copied the entire code block with rolling state class and I call it diveIn.', 'start': 32609.432, 'duration': 3.923}, {'end': 32618.46, 'text': 'I also pass a string that says diveIn in all caps to super class constructor.', 'start': 32614.016, 'duration': 4.444}, {'end': 32625.246, 'text': 'All the values inside enter method will stay the same because diveIn uses the same sprite animation row as rolling.', 'start': 32618.92, 'duration': 6.326}], 'summary': 'Player can perform a crushing dive attack when in air, using state design pattern.', 'duration': 32.503, 'max_score': 32592.743, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c32592743.jpg'}], 'start': 31605.032, 'title': 'Refactoring and optimizing game state and particle effects', 'summary': 'Discusses refactoring state management code for game object access, implementing particles, optimizing particle removal, and adding particle effects to the game, resulting in improved code structure and efficient performance.', 'chapters': [{'end': 31688.474, 'start': 31605.032, 'title': 'Refactoring state management for game object access', 'summary': 'Discusses refactoring the state management code to ensure access to the main game object, emphasizing the importance of planning code bases and making necessary adjustments to control particles and player states.', 'duration': 83.442, 'highlights': ["It's important to plan code bases well before writing the code, as demonstrated by the need to refactor the state management code to access the main game object.", 'The state design pattern is used to control particles closely tied to player states, highlighting the significance of adjusting the code to ensure access to the game object.', 'Refactoring involves passing the main game class as an argument to individual player state classes, allowing access to the player object through the game object.']}, {'end': 31939.377, 'start': 31689.115, 'title': 'Refactoring code and implementing particles', 'summary': "Covers the process of refactoring code to replace instances of 'this.player' with 'this.game.player', adding particles to the game, and cleaning up console logs, resulting in improved code structure and debugging capabilities.", 'duration': 250.262, 'highlights': ["Refactor code to replace instances of 'this.player' with 'this.game.player', affecting nine occurrences in various classes.", 'Add dust particles to the game by pushing new particles in the running state, running 60 times per second.', 'Clean up console logs and organize code for better debugging capabilities.']}, {'end': 32557.801, 'start': 31943.092, 'title': 'Optimizing particle removal and fire trail animation', 'summary': 'Discusses optimizing particle removal, creating a fire trail animation, and setting a maximum limit of 200 particles to ensure efficient performance.', 'duration': 614.709, 'highlights': ['Setting maximum limit of 200 particles', 'Implementing unshift method for particle addition', 'Using slice method to limit particle array length']}, {'end': 32973.211, 'start': 32558.081, 'title': 'Player abilities and particle effects', 'summary': 'Covers finalizing player abilities and adding particle effects to the game, including creating a diving state for a crushing meteor attack, implementing splash particles upon hitting the ground, and addressing issues with player movement and particle animation.', 'duration': 415.13, 'highlights': ['The chapter covers finalizing player abilities and adding particle effects to the game, including creating a diving state for a crushing meteor attack, implementing splash particles upon hitting the ground, and addressing issues with player movement and particle animation.', "The player's abilities are enhanced with the addition of a new diving state for a crushing meteor attack, triggered when the player is in the air and presses the down arrow key, providing a more dynamic gameplay experience.", "The implementation of splash particles upon hitting the ground adds visual impact to the game, with the creation of 30 particles forming a powerful visual effect, enhancing the player's special move.", 'The chapter also addresses issues with player movement, ensuring the player cannot get stuck below ground level, and fine-tuning the animation and movement of the splash particles to create a more polished game experience.']}], 'duration': 1368.179, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c31605032.jpg', 'highlights': ['The chapter covers finalizing player abilities and adding particle effects to the game, including creating a diving state for a crushing meteor attack, implementing splash particles upon hitting the ground, and addressing issues with player movement and particle animation.', "Refactor code to replace instances of 'this.player' with 'this.game.player', affecting nine occurrences in various classes.", "The player's abilities are enhanced with the addition of a new diving state for a crushing meteor attack, triggered when the player is in the air and presses the down arrow key, providing a more dynamic gameplay experience.", 'Add dust particles to the game by pushing new particles in the running state, running 60 times per second.', 'The state design pattern is used to control particles closely tied to player states, highlighting the significance of adjusting the code to ensure access to the game object.']}, {'end': 34629.35, 'segs': [{'end': 33188.002, 'src': 'embed', 'start': 33160.514, 'weight': 1, 'content': [{'end': 33163.976, 'text': 'When the player collides with an enemy, I want to run this sprite animation.', 'start': 33160.514, 'duration': 3.462}, {'end': 33166.117, 'text': "Let's handle that logic in a separate module.", 'start': 33164.196, 'duration': 1.921}, {'end': 33169.057, 'text': 'I will call it for example collision animation js.', 'start': 33166.536, 'duration': 2.521}, {'end': 33170.557, 'text': 'You know how we do this by now.', 'start': 33169.237, 'duration': 1.32}, {'end': 33173.578, 'text': 'There will be a class called collision animation.', 'start': 33171.417, 'duration': 2.161}, {'end': 33177.599, 'text': 'Constructor will expect game object reference and x and y positions.', 'start': 33173.839, 'duration': 3.76}, {'end': 33180.72, 'text': 'We convert game into class property as usual.', 'start': 33178.1, 'duration': 2.62}, {'end': 33183.741, 'text': 'You can download the image in the video description.', 'start': 33181.58, 'duration': 2.161}, {'end': 33188.002, 'text': 'I place it in my assets folder and I link it here in index.html.', 'start': 33184.18, 'duration': 3.822}], 'summary': 'Create a collision animation module with game object reference and x, y positions.', 'duration': 27.488, 'max_score': 33160.514, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c33160514.jpg'}, {'end': 33457.153, 'src': 'embed', 'start': 33426.612, 'weight': 4, 'content': [{'end': 33428.553, 'text': 'Collision animations are running very fast.', 'start': 33426.612, 'duration': 1.941}, {'end': 33432.297, 'text': 'We can control their FPS frames per second using delta time.', 'start': 33428.754, 'duration': 3.543}, {'end': 33439.803, 'text': 'Delta time is the difference in milliseconds between the timestamp from this animation frame and the timestamp from the previous frame.', 'start': 33432.637, 'duration': 7.166}, {'end': 33442.165, 'text': 'It will be passed as an argument up here.', 'start': 33440.223, 'duration': 1.942}, {'end': 33444.506, 'text': 'We will need three helper properties.', 'start': 33442.845, 'duration': 1.661}, {'end': 33446.849, 'text': 'FPS will define frames per second.', 'start': 33444.947, 'duration': 1.902}, {'end': 33453.15, 'text': 'Frame interval will be the amount of milliseconds that need to pass before we serve the next animation frame.', 'start': 33447.468, 'duration': 5.682}, {'end': 33457.153, 'text': 'It will be 1 second divided by FPS.', 'start': 33453.532, 'duration': 3.621}], 'summary': 'Collision animations run fast; fps controls with delta time.', 'duration': 30.541, 'max_score': 33426.612, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c33426612.jpg'}, {'end': 33591.088, 'src': 'embed', 'start': 33567.224, 'weight': 5, 'content': [{'end': 33573.731, 'text': 'If time from line 33 is more than max time from line 34, we set game over to true.', 'start': 33567.224, 'duration': 6.507}, {'end': 33578.661, 'text': 'We need to declare this game over property up here.', 'start': 33576.26, 'duration': 2.401}, {'end': 33585.145, 'text': 'When the game over is true I want to display a scoreboard, a custom message and I want the game to stop animating.', 'start': 33579.262, 'duration': 5.883}, {'end': 33591.088, 'text': 'Down here in animation loop I say only request the next animation frame if game over is false.', 'start': 33585.545, 'duration': 5.543}], 'summary': 'Set game over to true if time from line 33 exceeds max time from line 34, then display scoreboard and stop animating.', 'duration': 23.864, 'max_score': 33567.224, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c33567224.jpg'}, {'end': 33729.443, 'src': 'embed', 'start': 33699.295, 'weight': 2, 'content': [{'end': 33700.996, 'text': 'Nice, so this is our winning message.', 'start': 33699.295, 'duration': 1.701}, {'end': 33704.777, 'text': 'I want this message to display if score is more than 5 for example.', 'start': 33701.416, 'duration': 3.361}, {'end': 33706.577, 'text': 'This is just for testing purposes.', 'start': 33705.037, 'duration': 1.54}, {'end': 33713.939, 'text': 'When we have the whole game working, you can tune it and you can set game time and the score required to win the game to different value,', 'start': 33706.957, 'duration': 6.982}, {'end': 33716.06, 'text': 'depending on how difficult you want your game to be.', 'start': 33713.939, 'duration': 2.121}, {'end': 33719.761, 'text': 'If game score is more than 5, we display this message.', 'start': 33716.92, 'duration': 2.841}, {'end': 33725.782, 'text': 'Else, meaning game over is true and game score is less than 5, we display a different message.', 'start': 33720.421, 'duration': 5.361}, {'end': 33729.443, 'text': 'I will say love at first bite, I like to keep the Halloween theme.', 'start': 33726.322, 'duration': 3.121}], 'summary': 'Winning message displayed if score is more than 5; options to set game difficulty and winning conditions.', 'duration': 30.148, 'max_score': 33699.295, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c33699295.jpg'}, {'end': 33921.143, 'src': 'embed', 'start': 33893.487, 'weight': 0, 'content': [{'end': 33898.35, 'text': 'This is a final episode where we quickly implement some of the bonus features I showed in the previews.', 'start': 33893.487, 'duration': 4.863}, {'end': 33901.191, 'text': 'We will improve visuals and clean up our code.', 'start': 33898.67, 'duration': 2.521}, {'end': 33905.734, 'text': 'I will start by quickly changing background images just to keep things interesting.', 'start': 33901.812, 'duration': 3.922}, {'end': 33913.719, 'text': 'You can download the forest background layers in the video description and I just replaced them in the assets folder overriding the city images.', 'start': 33906.114, 'duration': 7.605}, {'end': 33916.94, 'text': 'I backed the old images up somewhere else on my computer.', 'start': 33914.119, 'duration': 2.821}, {'end': 33921.143, 'text': 'You can also go to background.js and adjust speeds of individual layers.', 'start': 33917.301, 'duration': 3.842}], 'summary': 'Implementing bonus features, improving visuals, and adjusting background speeds.', 'duration': 27.656, 'max_score': 33893.487, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c33893487.jpg'}, {'end': 34159.668, 'src': 'embed', 'start': 34130.46, 'weight': 3, 'content': [{'end': 34134.961, 'text': 'Perfect I want score numbers to fly from enemies as we defeat them.', 'start': 34130.46, 'duration': 4.501}, {'end': 34137.962, 'text': 'This can also be used for other floating messages in our game.', 'start': 34135.381, 'duration': 2.581}, {'end': 34140.643, 'text': 'I create a new file called FloatingMessages.js.', 'start': 34138.462, 'duration': 2.181}, {'end': 34146.736, 'text': 'I create a custom class I call for example FloatingMessage and I export it.', 'start': 34142.512, 'duration': 4.224}, {'end': 34153.822, 'text': 'Constructor will expect value of the floating text starting x and y position and target x and y position.', 'start': 34147.216, 'duration': 6.606}, {'end': 34159.668, 'text': 'Text with this value will float from this position to this position and then it will disappear.', 'start': 34154.403, 'duration': 5.265}], 'summary': 'Creating a custom class floatingmessage in floatingmessages.js to display floating messages with specific animations and disappearance', 'duration': 29.208, 'max_score': 34130.46, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c34130460.jpg'}], 'start': 32973.571, 'title': 'Game development techniques', 'summary': 'Covers player state management, collision animation logic, bonus feature implementation, and game optimization in game development, including details on enemy collision handling, sprite sheet setup, bonus feature impact on frame rate, and game difficulty settings.', 'chapters': [{'end': 33159.894, 'start': 32973.571, 'title': 'Player state management and enemy collision handling', 'summary': "Covers the implementation of player state management, including the creation of a 'hit' state triggered by enemy collisions, and the handling of score points and enemy deletion upon collision, with specific states offering invulnerability and score increments.", 'duration': 186.323, 'highlights': ["The player state 'hit' is created to trigger a 'dizzy' animation upon enemy collision, and the game stops moving during this state to emphasize the collision, with no score points awarded for the hit.", "Upon collision detection, if the player is in the 'rolling' or 'diving' state, the enemy is destroyed and the player's score increases by 1, while in other states, the player enters the 'hit' state without gaining any score points.", "The implementation ensures that specific player states ('rolling' and 'diving') provide invulnerability and score increments upon collision with enemies, while the 'hit' state emphasizes the collision without awarding any score points."]}, {'end': 33768.359, 'start': 33160.514, 'title': 'Collision animation logic for game', 'summary': 'Explains the process of handling collision animations in a game, including setting up the sprite sheet, controlling animation speed, managing game over conditions, and displaying winning/losing messages based on the game score.', 'duration': 607.845, 'highlights': ['Handling Collision Animation Logic', 'Controlling Animation Speed', 'Managing Game Over Conditions']}, {'end': 34130.22, 'start': 33769.315, 'title': 'Implementing bonus features', 'summary': 'Discusses implementing bonus features, optimizing performance, and making visual improvements in a game development project, along with demonstrating the impact on frame rate and providing specific coding examples. it also covers changing background images, adjusting background layer speeds, and updating font styles. additionally, it involves adding a display for player lives and handling collisions with enemies, resulting in a game over screen.', 'duration': 360.905, 'highlights': ['Implementing bonus features, optimizing performance, and making visual improvements in a game development project.', 'Demonstrating the impact on frame rate and providing specific coding examples.', 'Changing background images, adjusting background layer speeds, and updating font styles.', 'Adding a display for player lives and handling collisions with enemies, resulting in a game over screen.']}, {'end': 34629.35, 'start': 34130.46, 'title': 'Floating messages and game optimization', 'summary': 'Discusses implementing floating messages for score points, optimizing game performance by using filter method instead of splice, and setting game difficulty with a winning score of 40 within 30 seconds.', 'duration': 498.89, 'highlights': ['Implementing Floating Messages for Score Points', 'Optimizing Game Performance with Filter Method', 'Setting Game Difficulty and Winning Condition']}], 'duration': 1655.779, 'thumbnail': 'https://coursnap.oss-ap-southeast-1.aliyuncs.com/video-capture/GFO_txvwK_c/pics/GFO_txvwK_c32973571.jpg', 'highlights': ['Implementing bonus features, optimizing performance, and making visual improvements in a game development project.', 'Handling Collision Animation Logic', 'Setting Game Difficulty and Winning Condition', 'Implementing Floating Messages for Score Points', 'Controlling Animation Speed', 'Managing Game Over Conditions', 'Demonstrating the impact on frame rate and providing specific coding examples.']}], 'highlights': ['The course covers nine separate game development projects using HTML, CSS, and JavaScript, emphasizing individual 2D game development techniques and building a simple mobile game, simple point and shoot game, and a fast-paced 2D side-scroller.', 'Using five layers for seamless parallax effect', 'Creation of 4 small projects from scratch', 'Using JavaScript classes to efficiently manage multiple similar objects', 'Covers achieving pixel-perfect collision detection using colors, timestamps, and delta time', "Implemented inheritance by creating a child class 'worm' that extends the parent class 'enemy' to achieve unique behaviors for different enemy types.", 'The Fullscreen API is demonstrated, with a button created to toggle between fullscreen and windowed modes, and the implementation of event listeners to adhere to the requirement that fullscreen initiation must be triggered by user-generated events such as click or touch.', 'The importance of using a local server like Live Server extension in Visual Studio Code, with over 17 million downloads indicating its popularity.', 'The state pattern is used to manage player behavior, including states such as standing, sitting, and running.', "The maximum value of frames per second is limited by the screen's refresh rate, allowing for smooth animation at a maximum of 60 frames per second (FPS) or the refresh rate of the screen.", 'The tutorial covers controlling FPS, animating sprite sheets, and implementing multi-layered seamless backgrounds with scrolling speed that reacts to player movement.', 'Creation and functionality of sitting, running, jumping, and falling states.', 'The chapter covers the process of adding three different enemy types to a 2D game built with plain vanilla JavaScript and HTML canvas.', 'Implementation of particle effects for dust, blazing fire trail, and splash upon diving into the ground in the game, ensuring precise controls and movement for the player.', 'The chapter covers finalizing player abilities and adding particle effects to the game, including creating a diving state for a crushing meteor attack, implementing splash particles upon hitting the ground, and addressing issues with player movement and particle animation.', 'Implementing bonus features, optimizing performance, and making visual improvements in a game development project.']}