1 00:00:00,000 --> 00:00:16,290 2 00:00:16,290 --> 00:00:19,560 SPEAKER 1: All right, welcome to GD 50, lecture 7. 3 00:00:19,560 --> 00:00:22,950 This week we'll be talking about one of my favorite franchises of all time, 4 00:00:22,950 --> 00:00:24,870 a core part of my childhood-- 5 00:00:24,870 --> 00:00:27,850 Pokemon as shown by the Poke Ball on the screen there. 6 00:00:27,850 --> 00:00:32,280 So back in 1997 I think it was, the first Pokemon 7 00:00:32,280 --> 00:00:34,004 game was released, Red and Blue. 8 00:00:34,004 --> 00:00:36,420 I believe it was released a year earlier in Japan where it 9 00:00:36,420 --> 00:00:39,661 was released as Red, Blue, and Green. 10 00:00:39,661 --> 00:00:42,160 And the overall goal of the game was fairly straightforward. 11 00:00:42,160 --> 00:00:43,284 You were a Pokemon trainer. 12 00:00:43,284 --> 00:00:47,250 Your goal was to go out into the world and try and capture 13 00:00:47,250 --> 00:00:51,900 any number of 151 different types of these creatures called 14 00:00:51,900 --> 00:00:56,460 Pokemon that were based on a whole bunch of different types of creatures. 15 00:00:56,460 --> 00:01:00,170 Shown in the screenshot here, there's a Weepinbell fighting and Geodude. 16 00:01:00,170 --> 00:01:03,270 A Geodude was a rock type, Weepinbeel was a grass type. 17 00:01:03,270 --> 00:01:05,280 You had different types of Pokemon. 18 00:01:05,280 --> 00:01:08,340 When they fight each other, some types were better than other types, 19 00:01:08,340 --> 00:01:12,572 like this sort of very large rock, paper, scissors relationship. 20 00:01:12,572 --> 00:01:14,280 And it was just a very addicting formula. 21 00:01:14,280 --> 00:01:17,100 You'd have a team of these creatures that you had caught and raised 22 00:01:17,100 --> 00:01:20,670 and battled, and you'd fight other trainers. 23 00:01:20,670 --> 00:01:23,490 And the awesome part of this was you could go 24 00:01:23,490 --> 00:01:25,440 and you could actually fight your friends, 25 00:01:25,440 --> 00:01:28,200 or trade Pokemon with your friends that they had caught. 26 00:01:28,200 --> 00:01:30,200 And you would often share stories back and forth 27 00:01:30,200 --> 00:01:32,991 about the different rare creatures that you would have encountered, 28 00:01:32,991 --> 00:01:34,170 and all sorts of things. 29 00:01:34,170 --> 00:01:37,170 You'd have a customized party that was sort of a part of you. 30 00:01:37,170 --> 00:01:38,700 And so this is Pokemon Red. 31 00:01:38,700 --> 00:01:40,160 The series has evolved over time. 32 00:01:40,160 --> 00:01:43,368 This is a screenshot of Gold and Silver, which was released a couple of years 33 00:01:43,368 --> 00:01:45,150 afterwards for the Gameboy Color. 34 00:01:45,150 --> 00:01:48,120 Again, this was released for the regular Gameboy. 35 00:01:48,120 --> 00:01:51,180 Gold and Silver introduced a bunch of new features including breeding, 36 00:01:51,180 --> 00:01:53,310 and a day, night cycle, and a lot of other things 37 00:01:53,310 --> 00:01:55,310 that became part of the core series. 38 00:01:55,310 --> 00:01:58,500 Here is Ruby and Sapphire, which was for the Gameboy Advance 39 00:01:58,500 --> 00:02:01,500 and got a significant graphical update, but the core formula 40 00:02:01,500 --> 00:02:03,330 stayed much the same. 41 00:02:03,330 --> 00:02:08,130 Here is Diamond and Pearl, which is for the DS, which 42 00:02:08,130 --> 00:02:11,730 it made use of two screens, as seen on the top and bottom there. 43 00:02:11,730 --> 00:02:14,460 Here is Black and White, which was another step forward 44 00:02:14,460 --> 00:02:18,060 in that it introduced three dimensional graphics for the over world, 45 00:02:18,060 --> 00:02:21,960 so you could actually see some sort of 3D for the first time in the franchise. 46 00:02:21,960 --> 00:02:26,230 And then more recently, we've seen for the 3DS, games like X and Y, 47 00:02:26,230 --> 00:02:29,940 which is shown here, and Omega Sapphire, Alpha Ruby-- 48 00:02:29,940 --> 00:02:33,990 Alpha Sapphire and Omega Ruby, and Moon and Sun. 49 00:02:33,990 --> 00:02:37,680 And so this is a great illustration of why 50 00:02:37,680 --> 00:02:41,700 the RPG genre of video games, role playing game, 51 00:02:41,700 --> 00:02:44,880 even though it's sort of its own unique take on the formula. 52 00:02:44,880 --> 00:02:47,760 But it allows us to, we can sort of dissect this and take a look 53 00:02:47,760 --> 00:02:51,210 at what makes an RPG and what makes a Pokemon game altogether 54 00:02:51,210 --> 00:02:52,860 for a nice cool demonstration. 55 00:02:52,860 --> 00:02:54,943 So today, we'll be talking about a few new things. 56 00:02:54,943 --> 00:02:58,800 We'll be doing things a lot differently in this lecture example 57 00:02:58,800 --> 00:03:03,060 relative to other examples, because we're transitioning away from the state 58 00:03:03,060 --> 00:03:07,500 machine and talking about a construct called the state stack, which 59 00:03:07,500 --> 00:03:10,800 is effectively a more advanced version of the state machine. 60 00:03:10,800 --> 00:03:15,420 Whereas before, we had a state machine that was in one state at a time, 61 00:03:15,420 --> 00:03:19,560 whereby we could be in the play state or the start state or what 62 00:03:19,560 --> 00:03:22,290 not, we can now actually have multiple states 63 00:03:22,290 --> 00:03:25,920 that exist in parallel that are on a stack of data structure, which you've 64 00:03:25,920 --> 00:03:29,110 seen in CS 50 if you've taken, where we can have, 65 00:03:29,110 --> 00:03:32,070 for example, the field state, the play state at the very bottom, 66 00:03:32,070 --> 00:03:36,180 which is always there, and then we can push states onto the stack 67 00:03:36,180 --> 00:03:39,120 as we need to for example, a dialog state 68 00:03:39,120 --> 00:03:41,410 so that we can actually display some dialog, 69 00:03:41,410 --> 00:03:44,940 some text to the screen without getting rid of the play state 70 00:03:44,940 --> 00:03:46,720 that we had there before. 71 00:03:46,720 --> 00:03:50,220 It allows us to render multiple things at the same time, 72 00:03:50,220 --> 00:03:52,530 and then also return back to prior states, 73 00:03:52,530 --> 00:03:55,060 rather than completely create new states every time 74 00:03:55,060 --> 00:03:57,040 we want to make a transition. 75 00:03:57,040 --> 00:03:58,860 We'll be talking about turn based systems. 76 00:03:58,860 --> 00:04:02,970 So an RPGs like Pokemon and others, there 77 00:04:02,970 --> 00:04:06,210 are often battle systems that are usually 78 00:04:06,210 --> 00:04:09,090 turn based in this particular genre where you're fighting-- you have 79 00:04:09,090 --> 00:04:11,605 one team or one character fighting against against one other team or one 80 00:04:11,605 --> 00:04:13,980 other character, and you take turns fighting each other. 81 00:04:13,980 --> 00:04:16,846 And you have an indefinite amount of time to make your decision 82 00:04:16,846 --> 00:04:18,720 and then form some sort of strategy as to how 83 00:04:18,720 --> 00:04:20,490 you want to approach the problem. 84 00:04:20,490 --> 00:04:23,340 We'll be taking a look at a very primitive turn based system, 85 00:04:23,340 --> 00:04:26,610 but a fully functional one today. 86 00:04:26,610 --> 00:04:32,250 Another huge aspect of this genre is graphical user interfaces or GUIs 87 00:04:32,250 --> 00:04:33,510 as they're shortened. 88 00:04:33,510 --> 00:04:37,740 Things like panels, and scroll bars, and text boxes, and menus, all 89 00:04:37,740 --> 00:04:42,270 sorts of these things that allow us to get a more visual sort of look 90 00:04:42,270 --> 00:04:46,680 at our data, and allow us to navigate a much more complex game ecosystem more 91 00:04:46,680 --> 00:04:47,670 efficiently. 92 00:04:47,670 --> 00:04:50,820 And to tie it all together, RPG mechanics at large, 93 00:04:50,820 --> 00:04:53,700 we'll be looking at things like leveling up and experience 94 00:04:53,700 --> 00:04:57,720 and how to calculate the damage that one party does to the other party 95 00:04:57,720 --> 00:04:59,810 throughout the course of a battle. 96 00:04:59,810 --> 00:05:04,170 And so it will be a fairly complicated set of examples, 97 00:05:04,170 --> 00:05:08,580 but fairly illustrative of the genre as a whole. 98 00:05:08,580 --> 00:05:11,790 So I'd like to demonstrate sort of the example that I put together. 99 00:05:11,790 --> 00:05:15,040 If I could get a volunteer from the audience to come up and take a look. 100 00:05:15,040 --> 00:05:18,120 Tony that'd be awesome, thank you so much. 101 00:05:18,120 --> 00:05:23,850 So this is my simple but fully featured, more or less, demonstration of Pokemon. 102 00:05:23,850 --> 00:05:27,760 So if you want to enter or return. 103 00:05:27,760 --> 00:05:29,630 So this is a-- 104 00:05:29,630 --> 00:05:30,930 so here we have a-- 105 00:05:30,930 --> 00:05:35,040 we can see right off the bat, we have a text box and a play state 106 00:05:35,040 --> 00:05:36,340 like we did before. 107 00:05:36,340 --> 00:05:41,034 So this text box is actually a state that's layered above the place. 108 00:05:41,034 --> 00:05:43,950 So you can see it has some instructions about, if you want to press P, 109 00:05:43,950 --> 00:05:45,120 you can heal your Pokemon. 110 00:05:45,120 --> 00:05:46,730 You can press Enter to dismiss. 111 00:05:46,730 --> 00:05:47,880 So if you go ahead and press Enter, you'll 112 00:05:47,880 --> 00:05:49,620 be able to actually move around now. 113 00:05:49,620 --> 00:05:52,500 And so something to note is before, input was actually 114 00:05:52,500 --> 00:05:57,060 halted while the dialogue was on the top of the screen for the play state. 115 00:05:57,060 --> 00:06:01,110 You're actually not allowed to access or update this bottom state, 116 00:06:01,110 --> 00:06:05,220 because the state stack is only allowing input to the top state. 117 00:06:05,220 --> 00:06:09,990 And so I have limited the play here just to this box, 118 00:06:09,990 --> 00:06:13,830 but if we walk in the tall grass down here, in Pokemon, 119 00:06:13,830 --> 00:06:15,630 in order to actually initiate an encounter 120 00:06:15,630 --> 00:06:19,554 with another Pokemon or another wild Pokemon, you walk in the grass. 121 00:06:19,554 --> 00:06:20,970 So here we've walked in the grass. 122 00:06:20,970 --> 00:06:25,500 There's a random chance for this to happen, there's a 1 in 10 chance 123 00:06:25,500 --> 00:06:26,370 basically. 124 00:06:26,370 --> 00:06:28,310 So it's saying that a wild Bamboon appeared. 125 00:06:28,310 --> 00:06:29,550 So a wild creature appeared. 126 00:06:29,550 --> 00:06:32,550 He's level 5, we're level 5, should be a fairly even battle. 127 00:06:32,550 --> 00:06:34,982 So you can press Enter, and it will say go 128 00:06:34,982 --> 00:06:37,440 the name of your Pokemon, which is an Aardart in this case, 129 00:06:37,440 --> 00:06:39,410 and it's randomly allocated at the moment. 130 00:06:39,410 --> 00:06:41,160 So go ahead and press Enter one more time. 131 00:06:41,160 --> 00:06:43,360 Now we can see on the bottom right, we have a menu. 132 00:06:43,360 --> 00:06:46,290 So we can fight or we can run, so those two choices. 133 00:06:46,290 --> 00:06:47,686 So we can go ahead and fight. 134 00:06:47,686 --> 00:06:49,560 So we fight, whichever Pokemon has the higher 135 00:06:49,560 --> 00:06:51,900 speed will go first and do damage. 136 00:06:51,900 --> 00:06:55,287 We obviously, do a lot more damage, but he's a little bit faster, 137 00:06:55,287 --> 00:06:56,370 so he's going to go first. 138 00:06:56,370 --> 00:06:57,453 So we fight one more time. 139 00:06:57,453 --> 00:07:00,130 140 00:07:00,130 --> 00:07:03,050 We should be able to knock him out. 141 00:07:03,050 --> 00:07:06,252 So as soon as we do, we get a victory message, we get a victory song. 142 00:07:06,252 --> 00:07:08,460 If we press Enter, we'll actually get some experience 143 00:07:08,460 --> 00:07:10,320 for defeating that enemy. 144 00:07:10,320 --> 00:07:12,837 So we've got quite a bit of experience, we got 65 XP. 145 00:07:12,837 --> 00:07:15,420 In that bottom bar, we can see we have all these GUI elements, 146 00:07:15,420 --> 00:07:19,380 we've got a panel here, we have text boxes, we have progress bars, 147 00:07:19,380 --> 00:07:24,360 all these pieces are coming together to give us sort of this turn based system. 148 00:07:24,360 --> 00:07:27,420 And so after this, we may level up just to demonstrate 149 00:07:27,420 --> 00:07:31,803 leveling, which is part of the RPG mechanic side of this game. 150 00:07:31,803 --> 00:07:34,960 So we have to press this one more time. 151 00:07:34,960 --> 00:07:35,770 We did, perfectly. 152 00:07:35,770 --> 00:07:36,970 So they leveled up. 153 00:07:36,970 --> 00:07:44,300 And so now we're level 6, so we can see the 6 changed above our progress bars. 154 00:07:44,300 --> 00:07:46,300 So now will be a little bit stronger every time. 155 00:07:46,300 --> 00:07:49,258 And the stats aren't shown here, it's actually a part of the assignment 156 00:07:49,258 --> 00:07:52,630 is to create a menu that will actually show you how you leveled up, 157 00:07:52,630 --> 00:07:54,550 what stats actually increased. 158 00:07:54,550 --> 00:07:57,400 But underneath the hood, behind the scenes, 159 00:07:57,400 --> 00:07:59,680 you actually are getting stat increases. 160 00:07:59,680 --> 00:08:03,250 And so here we can see that if we our HP goes all the way down to zero, 161 00:08:03,250 --> 00:08:04,090 we faint. 162 00:08:04,090 --> 00:08:06,730 And when we faint, the screen instead of fading to white 163 00:08:06,730 --> 00:08:09,063 will actually fade to black to illustrate the difference 164 00:08:09,063 --> 00:08:11,040 between the two transitions. 165 00:08:11,040 --> 00:08:13,760 And so that we can keep playing indefinitely, 166 00:08:13,760 --> 00:08:16,360 the game will restore your Pokemon back to full health. 167 00:08:16,360 --> 00:08:18,274 And so this will go on forever. 168 00:08:18,274 --> 00:08:20,440 This is effectively what the simulator is, it's just 169 00:08:20,440 --> 00:08:22,480 a simple series of infinite battles. 170 00:08:22,480 --> 00:08:24,450 There are random Pokemon in the grass. 171 00:08:24,450 --> 00:08:27,880 There's five total that you can fight. 172 00:08:27,880 --> 00:08:30,172 But all the core pieces of what make the game are here. 173 00:08:30,172 --> 00:08:31,879 So actually, let's illustrate running too 174 00:08:31,879 --> 00:08:34,850 if you wouldn't mind, just so that we can see if there is a difference. 175 00:08:34,850 --> 00:08:37,710 So we can actually flee, and then battle we'll get cut short there. 176 00:08:37,710 --> 00:08:39,880 We won't get any XP, we won't faint, but we still 177 00:08:39,880 --> 00:08:41,419 get taken back to the play state. 178 00:08:41,419 --> 00:08:43,090 So that's all for the Pokemon demo. 179 00:08:43,090 --> 00:08:45,925 Thanks so much Tony for coming up to demo it. 180 00:08:45,925 --> 00:08:53,427 Well, there's a lot of pieces involved here, but as we will see, 181 00:08:53,427 --> 00:08:56,260 once we have a lot of these sort of foundational pieces implemented, 182 00:08:56,260 --> 00:09:00,040 it's not too difficult to start layering more and more of these 183 00:09:00,040 --> 00:09:02,860 onto the game to make it even more rich. 184 00:09:02,860 --> 00:09:05,562 In fact, the assignment is to-- 185 00:09:05,562 --> 00:09:08,020 and we'll see this at the end, I'll recap this at the end-- 186 00:09:08,020 --> 00:09:12,040 but the assignments goal is for you to implement a menu-- 187 00:09:12,040 --> 00:09:16,300 similar to the menu that we saw where fight and run were shown-- 188 00:09:16,300 --> 00:09:19,330 that will show you what your current stat is for each of your stats, 189 00:09:19,330 --> 00:09:22,080 there's attack, defense, speed, and your HP. 190 00:09:22,080 --> 00:09:25,960 It will show you what your stat is before leveling, the amount 191 00:09:25,960 --> 00:09:28,400 that it will increase by, and then the final amount, 192 00:09:28,400 --> 00:09:31,570 which is sort of similar to how the actual Pokemon games work, 193 00:09:31,570 --> 00:09:35,230 so you can see rather than just seeing, oh I increased my level from 5 to 6, 194 00:09:35,230 --> 00:09:38,692 6 to 7, you can see, oh, my strength increased from 12 to 14. 195 00:09:38,692 --> 00:09:41,650 I'm a little bit stronger, I'm going to do more damage on the next play 196 00:09:41,650 --> 00:09:43,240 through. 197 00:09:43,240 --> 00:09:47,080 So our goal here, we're going to take a look at the field state, the play 198 00:09:47,080 --> 00:09:49,190 state, and the battle state. 199 00:09:49,190 --> 00:09:53,370 And there's a common dichotomy in most of these sorts of games, 200 00:09:53,370 --> 00:09:55,930 be it Final Fantasy, or Dragon Quest, or Pokemon 201 00:09:55,930 --> 00:09:58,710 where there is a field, where you are walking around, 202 00:09:58,710 --> 00:10:02,440 you're character interacting with a game world with NPCs, going through towns, 203 00:10:02,440 --> 00:10:03,650 and what have you. 204 00:10:03,650 --> 00:10:05,844 And then a battle mode, sort of a battle state 205 00:10:05,844 --> 00:10:08,260 where you're actually fighting against some sort of enemy, 206 00:10:08,260 --> 00:10:11,060 or a series of enemies, a party or a single creature. 207 00:10:11,060 --> 00:10:14,080 And so we've implemented simple versions of both of these to illustrate 208 00:10:14,080 --> 00:10:17,770 and also the transitions between them. 209 00:10:17,770 --> 00:10:21,100 Before we start, I want to make another sort of plug 210 00:10:21,100 --> 00:10:26,050 for this howtomakeanrpg.com, this book, I actually learned a lot from this 211 00:10:26,050 --> 00:10:28,510 and about using LUA in the context of game development. 212 00:10:28,510 --> 00:10:30,926 And I pitched this I think in one of the earlier lectures, 213 00:10:30,926 --> 00:10:34,570 but if you want a deeper dive into a lot of these constructs, 214 00:10:34,570 --> 00:10:38,320 and to sort of get a sense for how you might do something like cut scenes, 215 00:10:38,320 --> 00:10:42,162 or more complicated battle layouts, and a lot more like-- 216 00:10:42,162 --> 00:10:44,620 it goes into a lot of detail about a lot of awesome things, 217 00:10:44,620 --> 00:10:45,620 definitely check it out. 218 00:10:45,620 --> 00:10:49,060 It's not free, but if you're interested in this genre, which I am, 219 00:10:49,060 --> 00:10:50,880 it's definitely worthwhile. 220 00:10:50,880 --> 00:10:53,350 Here's what the sprite sheets look like that we'll be 221 00:10:53,350 --> 00:10:55,750 using for this sort of demonstration. 222 00:10:55,750 --> 00:10:58,586 The Pokemon aside, which are individual textures. 223 00:10:58,586 --> 00:11:00,460 Here we're using a simple sprite sheet, which 224 00:11:00,460 --> 00:11:03,280 just has a bunch of tiles, most of which we did not use. 225 00:11:03,280 --> 00:11:08,620 Note that the bush, the tall grass is not on any sort of background. 226 00:11:08,620 --> 00:11:13,030 And therefore, we need to layer, basically 227 00:11:13,030 --> 00:11:17,260 have two separate tile maps as opposed to one, which we didn't do last time. 228 00:11:17,260 --> 00:11:22,180 And we were reusing the sprite sheet that we used in the Zelda lecture. 229 00:11:22,180 --> 00:11:24,970 Before, we used it for all the enemies, the skeletons, ghosts, 230 00:11:24,970 --> 00:11:26,090 and slimes, et cetera. 231 00:11:26,090 --> 00:11:28,750 But now we're actually using it for the PCs that it contains. 232 00:11:28,750 --> 00:11:34,060 Specifically, just the male NPC here, which is our main character. 233 00:11:34,060 --> 00:11:37,870 The foundational class that we're using in this lecture 234 00:11:37,870 --> 00:11:42,130 that sort of everything else revolves around and makes this work 235 00:11:42,130 --> 00:11:44,170 is the state stack. 236 00:11:44,170 --> 00:11:49,560 And so before, what we had was a state machine, right, 237 00:11:49,560 --> 00:11:51,530 where we were in one state at a time. 238 00:11:51,530 --> 00:11:55,090 So you can almost think of it like, we have a box here, 239 00:11:55,090 --> 00:11:57,190 and it just has one socket. 240 00:11:57,190 --> 00:11:59,710 And then we're always looking at this one socket, 241 00:11:59,710 --> 00:12:02,350 whether it's the play state, or the battle state, 242 00:12:02,350 --> 00:12:05,500 or a transition of some kind. 243 00:12:05,500 --> 00:12:08,710 And now we're transitioning into the idea of, instead, 244 00:12:08,710 --> 00:12:14,740 of just one state that we can only see at once, we'll make it a stack. 245 00:12:14,740 --> 00:12:18,640 And so what we can do with this is, rather than just having one, 246 00:12:18,640 --> 00:12:22,150 we can therefore render multiple states at a time, right? 247 00:12:22,150 --> 00:12:27,460 So let's say this is like the field, right, or the play state. 248 00:12:27,460 --> 00:12:31,540 And then maybe this is like a dialogue, or something, right? 249 00:12:31,540 --> 00:12:34,680 Like we saw before in the field, we had a text box. 250 00:12:34,680 --> 00:12:37,460 We can actually layer things on top of each other. 251 00:12:37,460 --> 00:12:42,670 And then maybe this is like a fade out, right, or a fade in. 252 00:12:42,670 --> 00:12:45,520 So we start with the play state maybe, and we're walking around, 253 00:12:45,520 --> 00:12:47,320 and we interact with in NPC. 254 00:12:47,320 --> 00:12:50,590 Rather than transition the play state to a dialog state, 255 00:12:50,590 --> 00:12:55,360 which would, in our previous model, completely eliminate the play state, 256 00:12:55,360 --> 00:12:58,960 because there's only one state that could be active at a time. 257 00:12:58,960 --> 00:13:02,290 Now we just render, however many states we have in our stack, 258 00:13:02,290 --> 00:13:05,660 we just render them sequentially based on the order that they were popped in. 259 00:13:05,660 --> 00:13:09,610 We would rendered this first, we basically render from the bottom up. 260 00:13:09,610 --> 00:13:12,130 Render the play state, then the dialogue, then the fade in. 261 00:13:12,130 --> 00:13:15,421 And this will have the effect of doing a whole bunch of different things, which 262 00:13:15,421 --> 00:13:17,410 we'll see in the distro. 263 00:13:17,410 --> 00:13:21,430 But we only really ever need to update one state at a time, 264 00:13:21,430 --> 00:13:26,620 right, because if we have the play state active and the dialog state active 265 00:13:26,620 --> 00:13:29,950 and the fade in state active, in this order, as a stack, 266 00:13:29,950 --> 00:13:33,886 right, we were pushing the operation for pushing for getting something 267 00:13:33,886 --> 00:13:36,010 onto the stack is called a push, and getting it off 268 00:13:36,010 --> 00:13:38,140 is called a pop if unfamiliar. 269 00:13:38,140 --> 00:13:41,530 If we're pushing all of these states on, then usually, 270 00:13:41,530 --> 00:13:44,654 we only need to update whatever's on top, right? 271 00:13:44,654 --> 00:13:46,570 If there's no fade in for example, and we only 272 00:13:46,570 --> 00:13:49,300 have a dialog state active, or a dialogue and a place 273 00:13:49,300 --> 00:13:53,110 state in that order top to bottom, then we usually 274 00:13:53,110 --> 00:13:55,782 don't want him update what's going on in the play state. 275 00:13:55,782 --> 00:13:58,240 We're only concerned with the dialogue that's taking place. 276 00:13:58,240 --> 00:14:00,050 We only want that to take input. 277 00:14:00,050 --> 00:14:02,050 And when we press Spacebar, Enter, or whatever 278 00:14:02,050 --> 00:14:06,340 button clears that dialog state, we pop it off, right, 279 00:14:06,340 --> 00:14:08,070 and then we're back to the play state. 280 00:14:08,070 --> 00:14:10,810 Then we're just updating the play state. 281 00:14:10,810 --> 00:14:14,649 And so being able to update just what's on top while 282 00:14:14,649 --> 00:14:16,690 being able to render everything that's on bottom. 283 00:14:16,690 --> 00:14:18,760 And this doesn't hold true for all game formulas, 284 00:14:18,760 --> 00:14:22,640 there's certainly some games where you can have a dialogue and a play state 285 00:14:22,640 --> 00:14:28,050 both get updated, but that's still using a state stack of sorts, 286 00:14:28,050 --> 00:14:31,780 you're just then updating things in a top down way. 287 00:14:31,780 --> 00:14:35,530 But this allows us to do all kinds of things like transitions, 288 00:14:35,530 --> 00:14:38,440 and preserving-- like for example, the fact that we have a play state 289 00:14:38,440 --> 00:14:40,840 and we can pop a battle state on top of that, 290 00:14:40,840 --> 00:14:43,270 where we don't see the play state underneath it, 291 00:14:43,270 --> 00:14:45,577 we only see the battle state, and that's all updating. 292 00:14:45,577 --> 00:14:47,410 But it is we pop the battle state off, we're 293 00:14:47,410 --> 00:14:49,510 right back where we just were in the play state. 294 00:14:49,510 --> 00:14:53,860 It's preserved its state, for lack of a better word, from before. 295 00:14:53,860 --> 00:14:58,750 And this is something that this model affords us comfortably. 296 00:14:58,750 --> 00:15:01,120 And so that's sort of the foundational class that's 297 00:15:01,120 --> 00:15:03,190 implemented in this distro, which will allow 298 00:15:03,190 --> 00:15:06,080 us to do all kinds of awesome things. 299 00:15:06,080 --> 00:15:09,580 So let's go ahead and take a look at what that looks like. 300 00:15:09,580 --> 00:15:11,500 I have state stack open here. 301 00:15:11,500 --> 00:15:15,460 So state stack has just a set of states here. 302 00:15:15,460 --> 00:15:18,430 303 00:15:18,430 --> 00:15:20,530 And then whenever we want to insert a state, 304 00:15:20,530 --> 00:15:23,540 it's going to be at the end of the state stack. 305 00:15:23,540 --> 00:15:25,450 So it's going to be whatever the last-- 306 00:15:25,450 --> 00:15:28,990 so if we're looking at it as a series of states in a table, 307 00:15:28,990 --> 00:15:31,870 it'll be whatever the last index is in the table. 308 00:15:31,870 --> 00:15:35,530 That will be our, the top of our stack. 309 00:15:35,530 --> 00:15:38,440 And you can implement this either way in reverse if you wanted to. 310 00:15:38,440 --> 00:15:44,890 It's just easier, because you can just do a simple table.remove to get rid 311 00:15:44,890 --> 00:15:45,490 of the-- 312 00:15:45,490 --> 00:15:48,100 313 00:15:48,100 --> 00:15:52,420 table.remove on that table to get rid of the last state 314 00:15:52,420 --> 00:15:54,280 without having to shift back everything. 315 00:15:54,280 --> 00:15:57,940 So if we did it starting at index one, you'd have to shift everything back. 316 00:15:57,940 --> 00:16:00,940 And it would also be a little bit weird, because you would start at one, 317 00:16:00,940 --> 00:16:03,070 and then things would go left. 318 00:16:03,070 --> 00:16:07,690 But basically, in order to update whatever our end state is, 319 00:16:07,690 --> 00:16:13,870 we just do at #self.states, which will be however large our state stack is, 320 00:16:13,870 --> 00:16:16,570 we just call update on that state. 321 00:16:16,570 --> 00:16:19,420 And then process AI is here, although we're not using it. 322 00:16:19,420 --> 00:16:21,640 But if you had AI, it would be the same thing 323 00:16:21,640 --> 00:16:26,950 as basically an update for artificial intelligence for your state. 324 00:16:26,950 --> 00:16:29,500 Rather than rendering just one state at a time, 325 00:16:29,500 --> 00:16:32,140 we iterate through all of our states here 326 00:16:32,140 --> 00:16:35,140 using ipairs, which will iterate through them numerically 327 00:16:35,140 --> 00:16:38,230 starting at one going to the end. 328 00:16:38,230 --> 00:16:41,410 So we call for istate, and ipairs of self.state, render it, 329 00:16:41,410 --> 00:16:47,260 so that will render everything back to front, or bottom to top, 330 00:16:47,260 --> 00:16:49,060 and allow us to get this layered look where 331 00:16:49,060 --> 00:16:51,268 we have a play state going on underneath for example, 332 00:16:51,268 --> 00:16:54,230 and then a dialogue on top. 333 00:16:54,230 --> 00:16:56,230 Or we have a battle state going at the very top, 334 00:16:56,230 --> 00:16:59,410 and maybe that battle state itself pushes a dialogue 335 00:16:59,410 --> 00:17:02,230 state to the top of the stack, or a bunch of other states, 336 00:17:02,230 --> 00:17:05,410 a transition, whatever you would like. 337 00:17:05,410 --> 00:17:08,290 To clear it, we just reset the table to an empty table. 338 00:17:08,290 --> 00:17:12,010 To push a state, we just do an insert on that state, and then 339 00:17:12,010 --> 00:17:14,680 we call enter on that state. 340 00:17:14,680 --> 00:17:19,240 As we did before, sort of similarly with state machine, when we changed a state, 341 00:17:19,240 --> 00:17:21,369 we would call enter on it and exit, but now we're 342 00:17:21,369 --> 00:17:23,050 just calling enter when we push. 343 00:17:23,050 --> 00:17:26,470 And then to pop, all we do is call exit on whatever 344 00:17:26,470 --> 00:17:30,460 the last state is in our state stack, and then just 345 00:17:30,460 --> 00:17:32,650 call table.remove on self.states. 346 00:17:32,650 --> 00:17:36,790 And by default, when you call table.remove on a table, just a table 347 00:17:36,790 --> 00:17:40,930 with no other arguments, it'll remove whatever 348 00:17:40,930 --> 00:17:43,165 the last index is of that table. 349 00:17:43,165 --> 00:17:44,100 Does that makes sense? 350 00:17:44,100 --> 00:17:46,558 Anybody have any questions as to how the state stack works? 351 00:17:46,558 --> 00:17:49,300 352 00:17:49,300 --> 00:17:51,650 All right, awesome. 353 00:17:51,650 --> 00:17:56,700 So let's take a look then at the start state. 354 00:17:56,700 --> 00:17:59,980 So this is the start date. 355 00:17:59,980 --> 00:18:03,850 356 00:18:03,850 --> 00:18:06,250 Fairly simple, we just have a couple of text labels, 357 00:18:06,250 --> 00:18:10,690 and then we have just a randomly assigned sprite going left to right. 358 00:18:10,690 --> 00:18:14,724 How do we think we're achieving the movement? 359 00:18:14,724 --> 00:18:17,230 Yep, timer.tween, and then we're just drawing 360 00:18:17,230 --> 00:18:19,840 an ellipse, right, pretty simple. 361 00:18:19,840 --> 00:18:24,830 And then when we press Enter, note the transition. 362 00:18:24,830 --> 00:18:31,140 Notice that there's a fade to white, and then fade to transparent. 363 00:18:31,140 --> 00:18:34,850 And so if we recall from when we looked at match three, how do we do this, 364 00:18:34,850 --> 00:18:36,792 do we remember? 365 00:18:36,792 --> 00:18:40,110 AUDIENCE: [INAUDIBLE] 366 00:18:40,110 --> 00:18:42,480 367 00:18:42,480 --> 00:18:44,930 SPEAKER 1: Exactly, and the rectangle was stored where? 368 00:18:44,930 --> 00:18:50,090 369 00:18:50,090 --> 00:18:52,510 Sorry, to repeat for the camera, we had a rectangle 370 00:18:52,510 --> 00:18:56,380 that filled the entire screen, and we just tween the transparency for it, 371 00:18:56,380 --> 00:18:57,710 which is true. 372 00:18:57,710 --> 00:19:01,120 The rectangle there before though was stored 373 00:19:01,120 --> 00:19:04,570 in whatever state was active at the time, which was like the start date, 374 00:19:04,570 --> 00:19:08,710 or the I think begin game state was the name. 375 00:19:08,710 --> 00:19:13,450 The actual state that wasn't necessarily relevant at the transition. 376 00:19:13,450 --> 00:19:18,130 But using a state stack, we can actually decouple this idea. 377 00:19:18,130 --> 00:19:21,580 We can take the concept of a transition, and because imagine 378 00:19:21,580 --> 00:19:24,567 if we wanted to make a transition between every single state 379 00:19:24,567 --> 00:19:25,900 that existed in our game, right? 380 00:19:25,900 --> 00:19:28,233 If we wanted to transition from the battle to the field, 381 00:19:28,233 --> 00:19:33,340 or the field to the battle, or whatever else we might want, like the start 382 00:19:33,340 --> 00:19:36,820 to the field, we would need a rectangle in every single one 383 00:19:36,820 --> 00:19:39,580 of those that has an opacity that we're keeping track of. 384 00:19:39,580 --> 00:19:44,500 And that's not necessarily germane to the purpose of that state, right? 385 00:19:44,500 --> 00:19:47,380 So because we now have a state stack, we can actually 386 00:19:47,380 --> 00:19:52,870 abstract out this idea of a transition, and turn it into its own state. 387 00:19:52,870 --> 00:19:56,230 We can have a transition state. 388 00:19:56,230 --> 00:19:59,470 And recall that since we're just layering everything 389 00:19:59,470 --> 00:20:03,130 [? off ?] all these states, and we're rendering them sequentially, 390 00:20:03,130 --> 00:20:07,840 having a state that possesses it's own for example, opacity rectangle, 391 00:20:07,840 --> 00:20:12,080 we can just layer that, push that onto the stack, and render that, 392 00:20:12,080 --> 00:20:16,160 and it'll give us the illusion of having this transition. 393 00:20:16,160 --> 00:20:19,000 But we don't need to actually have it be part of the state 394 00:20:19,000 --> 00:20:21,380 that we're trying to transition out of and into. 395 00:20:21,380 --> 00:20:23,720 Does that make sense? 396 00:20:23,720 --> 00:20:27,469 So let's take a look, for example, at the-- 397 00:20:27,469 --> 00:20:29,260 let's take a look at the start state first, 398 00:20:29,260 --> 00:20:32,920 just so we can see where that actually gets kicked off. 399 00:20:32,920 --> 00:20:36,160 So the start state, we kick off some music, we have a sprite, 400 00:20:36,160 --> 00:20:37,210 and a sprite x and y. 401 00:20:37,210 --> 00:20:40,570 These are values that are relevant to the sprite that's moving, actually, 402 00:20:40,570 --> 00:20:43,089 we only have one sprite ever moving left to right. 403 00:20:43,089 --> 00:20:45,380 It just gets teleported to the right edge of the screen 404 00:20:45,380 --> 00:20:47,620 as soon as it gets taken to one edge. 405 00:20:47,620 --> 00:20:51,340 So we only have one sprite, one x and y. 406 00:20:51,340 --> 00:20:53,440 And then every three seconds as we see here, 407 00:20:53,440 --> 00:20:59,890 we have a callback function that will tween the sprites x to negative 64 408 00:20:59,890 --> 00:21:03,370 over 0.2 seconds, so really quickly. 409 00:21:03,370 --> 00:21:06,190 And then on finish, teleport it to the right. 410 00:21:06,190 --> 00:21:08,380 And then do the same exact thing, but tween it 411 00:21:08,380 --> 00:21:11,170 to the center over 0.2 seconds. 412 00:21:11,170 --> 00:21:18,190 And then as soon as we press Enter or Return, note this here, 413 00:21:18,190 --> 00:21:22,960 we have gStateStack, not a gStateMachine anymore, 414 00:21:22,960 --> 00:21:27,490 and we're pushing on to it a fade in state, 415 00:21:27,490 --> 00:21:32,170 which takes an RGB, a duration, and a callback function. 416 00:21:32,170 --> 00:21:38,080 Now if you look at main.lua, this is relevant, 417 00:21:38,080 --> 00:21:42,790 because now we no longer have a state machine, right? 418 00:21:42,790 --> 00:21:45,670 We previously had a global state machine, gStateMachine. 419 00:21:45,670 --> 00:21:49,450 We would give it a list of indexes into functions, anonymous functions. 420 00:21:49,450 --> 00:21:53,150 Those would return the instantiation of a state. 421 00:21:53,150 --> 00:21:55,885 And then when we called change, the state machine will 422 00:21:55,885 --> 00:22:00,820 index into its list of states, and call that anonymous function, 423 00:22:00,820 --> 00:22:04,090 which would have the result of changing the state to some state 424 00:22:04,090 --> 00:22:07,000 that we've implemented as a class, right? 425 00:22:07,000 --> 00:22:09,190 Now we just create a state stack and we just 426 00:22:09,190 --> 00:22:14,320 push a new start state onto the class. 427 00:22:14,320 --> 00:22:18,220 And so what this will do is effectively the same thing, only now 428 00:22:18,220 --> 00:22:23,101 we can layer things onto the start state, right, or play state, 429 00:22:23,101 --> 00:22:25,850 or whatever we want to, and we're not going to ever get rid of it. 430 00:22:25,850 --> 00:22:28,250 I mean, we can get rid of it, but we don't have to. 431 00:22:28,250 --> 00:22:32,680 For the play state, especially, we want that to pretty much never get 432 00:22:32,680 --> 00:22:35,260 popped off the stack, because that's going 433 00:22:35,260 --> 00:22:36,960 to preserve all of our information. 434 00:22:36,960 --> 00:22:40,210 We're going to default back to that to store all of our character information, 435 00:22:40,210 --> 00:22:43,210 our Pokemon information, whatever else we might 436 00:22:43,210 --> 00:22:46,690 want to add onto this shell of a game in inventory, 437 00:22:46,690 --> 00:22:49,360 et cetera, a world state at large. 438 00:22:49,360 --> 00:22:53,140 We want to preserve that and keep that consistent across all of our battle 439 00:22:53,140 --> 00:22:54,580 states and so forth. 440 00:22:54,580 --> 00:22:58,060 And the battle states will just pull information from that world, 441 00:22:58,060 --> 00:23:01,840 from that play state, and construct a battle as needed. 442 00:23:01,840 --> 00:23:04,570 Does that makes sense? 443 00:23:04,570 --> 00:23:08,590 OK, so here we're effectively, the only real changes we've made to main 444 00:23:08,590 --> 00:23:11,790 are no longer a state machine, now we have a state stack, 445 00:23:11,790 --> 00:23:14,230 going to push start state, that start state 446 00:23:14,230 --> 00:23:18,790 has some behavior just like any other state that we've implemented before. 447 00:23:18,790 --> 00:23:22,570 448 00:23:22,570 --> 00:23:29,560 And what I was about to get into before was here on line 36 of the start state, 449 00:23:29,560 --> 00:23:32,540 we're pushing another state onto the stack. 450 00:23:32,540 --> 00:23:36,951 So there's already a start state, and it's from within the start state itself 451 00:23:36,951 --> 00:23:37,450 actually. 452 00:23:37,450 --> 00:23:40,279 453 00:23:40,279 --> 00:23:42,820 We're going to take that stack, which is just one level deep, 454 00:23:42,820 --> 00:23:44,560 and then we're going to make it two levels deep now. 455 00:23:44,560 --> 00:23:46,360 So now we're going to add a fade in state. 456 00:23:46,360 --> 00:23:49,270 And the fade in state as we can see, takes in an RGB. 457 00:23:49,270 --> 00:23:52,160 Does anybody have a guess as to what the RGB is relevant for? 458 00:23:52,160 --> 00:23:55,046 459 00:23:55,046 --> 00:23:58,425 AUDIENCE: [INAUDIBLE] 460 00:23:58,425 --> 00:24:00,800 SPEAKER 1: To whether you want to fade in black or white? 461 00:24:00,800 --> 00:24:02,035 Yes, any color. 462 00:24:02,035 --> 00:24:04,660 We can make this, we can make it a fade to red if we wanted to, 463 00:24:04,660 --> 00:24:06,350 or fade to blue. 464 00:24:06,350 --> 00:24:10,490 But we don't have to create two separate classes for a fade in white, 465 00:24:10,490 --> 00:24:13,850 fade in black, fade out black, fade out white. 466 00:24:13,850 --> 00:24:16,760 We can just give it a color. 467 00:24:16,760 --> 00:24:20,360 And then I mean, we could even go a level further with this, 468 00:24:20,360 --> 00:24:23,960 and make it take in an opacity as well, so that we don't need a fade in state, 469 00:24:23,960 --> 00:24:26,690 or a fade out state, we just need a fade state, right? 470 00:24:26,690 --> 00:24:30,110 And the fade state will determine, based on whatever 471 00:24:30,110 --> 00:24:37,654 last opacity parameter we give it, the right way to fade in and out. 472 00:24:37,654 --> 00:24:40,070 But in this case, the difference between the fade in state 473 00:24:40,070 --> 00:24:44,090 and the fade out state is one knows to go to 0, one knows to go to 255. 474 00:24:44,090 --> 00:24:46,700 That's really the only key difference. 475 00:24:46,700 --> 00:24:51,830 And then this 1, the duration, right, we need to tell it how long to fade. 476 00:24:51,830 --> 00:24:55,610 And then this last bit here is a function. 477 00:24:55,610 --> 00:24:59,960 We're giving it an anonymous function, this is a callback function, 478 00:24:59,960 --> 00:25:06,650 because the fade in state by nature is an asynchronous state. 479 00:25:06,650 --> 00:25:08,480 It does its behavior over time. 480 00:25:08,480 --> 00:25:10,940 So we need a way, we need to tell it, OK, 481 00:25:10,940 --> 00:25:14,360 when you finished doing what you're doing, call this bit of code 482 00:25:14,360 --> 00:25:19,010 here, so that we can do something not immediately, 483 00:25:19,010 --> 00:25:22,250 we can sort of defer its execution till later. 484 00:25:22,250 --> 00:25:26,910 And this is something that we'll see common throughout this lecture, 485 00:25:26,910 --> 00:25:29,870 because we have this implemented also in like dialogue for example, 486 00:25:29,870 --> 00:25:34,910 because we don't know when the user is going to press Spacebar on the dialog 487 00:25:34,910 --> 00:25:36,630 state and clear the window. 488 00:25:36,630 --> 00:25:39,320 But what if we want that window, the clearing of that dialog 489 00:25:39,320 --> 00:25:41,690 to trigger some sort of event, right? 490 00:25:41,690 --> 00:25:44,830 For example, if they press Enter when they're in the battle, 491 00:25:44,830 --> 00:25:46,534 we want it to go to the next action. 492 00:25:46,534 --> 00:25:48,700 We don't necessarily know when it's going to happen, 493 00:25:48,700 --> 00:25:54,770 so we'll just pass in an anonymous function to that dialogue state 494 00:25:54,770 --> 00:25:59,760 that the class will call whenever the close function is called on that dialog 495 00:25:59,760 --> 00:26:00,260 state. 496 00:26:00,260 --> 00:26:03,170 It says, when closed, execute this anonymous function. 497 00:26:03,170 --> 00:26:06,320 And then that anonymous function can do whatever you want to do. 498 00:26:06,320 --> 00:26:09,170 It could pop another other several states onto the stack. 499 00:26:09,170 --> 00:26:12,057 But this is what allows us to chain asynchronous behavior. 500 00:26:12,057 --> 00:26:12,890 That's the key here. 501 00:26:12,890 --> 00:26:15,650 502 00:26:15,650 --> 00:26:18,800 So this anonymous function-- so we'll take a look now actually 503 00:26:18,800 --> 00:26:23,340 at the fade in state, just so we can see what this looks like. 504 00:26:23,340 --> 00:26:26,360 So we see here, fade in state, right, takes in the color. 505 00:26:26,360 --> 00:26:30,560 We saw before, that will be the color we fade to. 506 00:26:30,560 --> 00:26:34,580 The length of time that it'll take us to actually perform the transition. 507 00:26:34,580 --> 00:26:46,390 And what are we using for the transition do we think, timer.tween, right? 508 00:26:46,390 --> 00:26:51,890 So most everything that we'll do actually 509 00:26:51,890 --> 00:26:55,150 throughout the course of this lecture that has asynchronous behavior, 510 00:26:55,150 --> 00:26:57,420 we can implement it with timer, which is nice. 511 00:26:57,420 --> 00:27:01,600 It allows us to fairly succinctly and declaratively tell 512 00:27:01,600 --> 00:27:04,670 right out what exactly we want to have happen over time. 513 00:27:04,670 --> 00:27:07,930 In this case, we're going to tween over the course of time 514 00:27:07,930 --> 00:27:11,840 the opacity of our self to 255. 515 00:27:11,840 --> 00:27:15,627 So the fade in is going to fade into the full color of whatever we 516 00:27:15,627 --> 00:27:16,210 have given it. 517 00:27:16,210 --> 00:27:22,180 So it's going to go from 0, which is shown here by default, to 255. 518 00:27:22,180 --> 00:27:27,550 And then as soon as we finish that tween, 519 00:27:27,550 --> 00:27:32,740 that is when we pop the fade in state. 520 00:27:32,740 --> 00:27:35,920 We're going to pop ourselves off the state effectively, off the stack 521 00:27:35,920 --> 00:27:37,840 effectively. 522 00:27:37,840 --> 00:27:41,150 And then here, we're calling on fade complete. 523 00:27:41,150 --> 00:27:43,210 And that's where the anonymous function is. 524 00:27:43,210 --> 00:27:45,430 On fade complete is passed in here. 525 00:27:45,430 --> 00:27:52,630 So by putting that function into the finish function of the tween operation, 526 00:27:52,630 --> 00:27:58,710 we've allowed ourselves to defer that function that we've written up in the-- 527 00:27:58,710 --> 00:28:01,120 it's in the start state. 528 00:28:01,120 --> 00:28:04,750 We defer the execution of this function until after that tween operation 529 00:28:04,750 --> 00:28:05,700 takes place. 530 00:28:05,700 --> 00:28:08,220 Does that make sense? 531 00:28:08,220 --> 00:28:09,764 OK, awesome. 532 00:28:09,764 --> 00:28:11,180 And that's effectively what it is. 533 00:28:11,180 --> 00:28:13,970 And that's a common theme that we'll see if you're looking through the distro, 534 00:28:13,970 --> 00:28:15,620 you'll see it in a lot of places. 535 00:28:15,620 --> 00:28:17,870 Anonymous functions or callback functions 536 00:28:17,870 --> 00:28:24,860 rather being passed into things like the dialogs, and the fades, 537 00:28:24,860 --> 00:28:26,747 and a few other places. 538 00:28:26,747 --> 00:28:28,580 In the take turns state for example, there's 539 00:28:28,580 --> 00:28:30,920 a function that takes in at a callback function as well. 540 00:28:30,920 --> 00:28:38,210 And that's effectively how you can chain asynchronous behavior that 541 00:28:38,210 --> 00:28:41,105 executes over time, rather than it being blocking. 542 00:28:41,105 --> 00:28:44,630 Does anybody have any questions so far as to how this works, at all? 543 00:28:44,630 --> 00:28:47,780 544 00:28:47,780 --> 00:28:51,980 All right, so when the fade is done-- 545 00:28:51,980 --> 00:28:54,440 we're still the start state here-- 546 00:28:54,440 --> 00:28:58,820 at this point, the fade is done, we're executing this anonymous function. 547 00:28:58,820 --> 00:29:09,840 We're going to pop the start state off of the stack in this case. 548 00:29:09,840 --> 00:29:12,570 And then we're going to push a-- 549 00:29:12,570 --> 00:29:15,780 we're going to do two pushes here. 550 00:29:15,780 --> 00:29:20,960 One is to push a play state, which recall is where the NPC [INAUDIBLE] 551 00:29:20,960 --> 00:29:23,210 character walking around. 552 00:29:23,210 --> 00:29:27,294 And another one is to push a dialogue state. 553 00:29:27,294 --> 00:29:29,960 And so what this will have the effect of doing is rather than us 554 00:29:29,960 --> 00:29:33,150 immediately going into the play state and being able to walk around, 555 00:29:33,150 --> 00:29:35,634 we're actually put right into a world where 556 00:29:35,634 --> 00:29:37,550 there is a message waiting for us that we have 557 00:29:37,550 --> 00:29:40,640 to press Enter on in order to continue. 558 00:29:40,640 --> 00:29:45,230 And when we press Enter, because we're pushing the play state first, 559 00:29:45,230 --> 00:29:47,410 and then the dialogue state, the dialogue state 560 00:29:47,410 --> 00:29:49,670 is at the top of the stack, right, because things 561 00:29:49,670 --> 00:29:53,060 get pushed onto like a stack of plates. 562 00:29:53,060 --> 00:29:56,150 You put a play state plate on the bottom and then another plate on top, 563 00:29:56,150 --> 00:30:00,180 and that plate is the dialogue state in this case. 564 00:30:00,180 --> 00:30:02,330 And you can only interact with the top-- 565 00:30:02,330 --> 00:30:06,290 we're only updating the top plate at once in this model. 566 00:30:06,290 --> 00:30:08,630 We could obviously make a more complicated state 567 00:30:08,630 --> 00:30:14,090 stack that allows us to have several layers of states being updated at once, 568 00:30:14,090 --> 00:30:19,940 but for simplicity, we only opted to allow the top layer to be updated. 569 00:30:19,940 --> 00:30:21,986 The dialog state is going to be the active state, 570 00:30:21,986 --> 00:30:23,360 it's going to be receiving input. 571 00:30:23,360 --> 00:30:25,930 All of them are going to be rendered, so we're 572 00:30:25,930 --> 00:30:27,680 going to render things from the bottom up. 573 00:30:27,680 --> 00:30:28,940 We're going to render the play state, then 574 00:30:28,940 --> 00:30:31,010 we're going to render the dialog state, but the dialog state's 575 00:30:31,010 --> 00:30:31,910 going to be active. 576 00:30:31,910 --> 00:30:35,120 We're only going to be able to press anything on that state. 577 00:30:35,120 --> 00:30:40,550 And then lastly, actually, even beyond the dialogue state, 578 00:30:40,550 --> 00:30:43,500 we're pushing another state, we're pushing a fade out state. 579 00:30:43,500 --> 00:30:47,150 And in this case, it's the opposite of the fade in state, 580 00:30:47,150 --> 00:30:51,170 it just takes in an RGB, and we'll go from 255 opacity 581 00:30:51,170 --> 00:30:54,180 to zero opacity in that case. 582 00:30:54,180 --> 00:31:00,470 And so what that allows us to do for playing right, 583 00:31:00,470 --> 00:31:03,320 we're here in the start state, pressing Enter. 584 00:31:03,320 --> 00:31:06,860 That's our fade in state was there. 585 00:31:06,860 --> 00:31:11,510 And then we pushed to the play state and the dialogue state and the fade 586 00:31:11,510 --> 00:31:15,440 out state at once, so you would almost think 587 00:31:15,440 --> 00:31:18,020 that we push a fade in and then the fade out, 588 00:31:18,020 --> 00:31:21,560 but we have to lay that foundation before we 589 00:31:21,560 --> 00:31:24,170 put the fade out state on top of the stack, 590 00:31:24,170 --> 00:31:27,720 right, because the top layer gets updated. 591 00:31:27,720 --> 00:31:30,890 So we have to push the fade out state on top of all of those. 592 00:31:30,890 --> 00:31:32,797 That will get updated, that will fade out, 593 00:31:32,797 --> 00:31:34,880 and then we're back to the two states that we push 594 00:31:34,880 --> 00:31:36,870 before we pushed the fadeout state. 595 00:31:36,870 --> 00:31:39,240 Does that make since? 596 00:31:39,240 --> 00:31:40,300 OK. 597 00:31:40,300 --> 00:31:44,710 Does anybody have any questions as to how that sort of flow works? 598 00:31:44,710 --> 00:31:47,110 Cool. 599 00:31:47,110 --> 00:31:49,510 All right, so that's the gist behind, I mean, 600 00:31:49,510 --> 00:31:54,280 that's essentially the core of what we're doing today 601 00:31:54,280 --> 00:31:56,890 is the state stack pushing multiple states. 602 00:31:56,890 --> 00:31:58,940 And then just figuring out the right order 603 00:31:58,940 --> 00:32:02,710 the need to push them in to get the desired appearance that you want, 604 00:32:02,710 --> 00:32:03,340 right? 605 00:32:03,340 --> 00:32:07,180 We push the fade out state while we're in the start state, 606 00:32:07,180 --> 00:32:08,430 or fade in state rather. 607 00:32:08,430 --> 00:32:10,990 That will take us to white, and then like sort 608 00:32:10,990 --> 00:32:17,440 of, almost like underneath the-- behind the curtain, we're popping everything, 609 00:32:17,440 --> 00:32:20,770 and then we're adding the play, dialogue, and then another fade out 610 00:32:20,770 --> 00:32:21,380 state. 611 00:32:21,380 --> 00:32:25,419 And so you sort of have to balance the order that you put things in in order 612 00:32:25,419 --> 00:32:26,710 to achieve the desired results. 613 00:32:26,710 --> 00:32:28,876 It may not necessarily be exactly as you intuitively 614 00:32:28,876 --> 00:32:32,110 think until you think about just how we're updating and rendering 615 00:32:32,110 --> 00:32:34,030 things on a stack. 616 00:32:34,030 --> 00:32:38,195 And so that's the ultimate hurdle I think in really getting comfortable 617 00:32:38,195 --> 00:32:41,320 with the distro, but once you've gotten that, everything else sort of falls 618 00:32:41,320 --> 00:32:42,290 into place. 619 00:32:42,290 --> 00:32:46,600 That and the sort of abundance of asynchronous functions, as we'll 620 00:32:46,600 --> 00:32:49,660 see pretty shortly when we look at GUIs, and how we've implemented 621 00:32:49,660 --> 00:32:51,590 a lot of basic GUI functionality. 622 00:32:51,590 --> 00:32:54,460 A lot of that is very, very call back driven, 623 00:32:54,460 --> 00:32:58,012 just because of the nature of it being based on user input, right? 624 00:32:58,012 --> 00:33:00,220 You don't know when the user's going to do any input, 625 00:33:00,220 --> 00:33:04,240 so defer whatever happens with that GUI code 626 00:33:04,240 --> 00:33:08,140 with the triggers involved when the user presses Spacebar, 627 00:33:08,140 --> 00:33:13,660 Enter, and then call that function that you've passed into that GUI widget. 628 00:33:13,660 --> 00:33:17,020 All right, so we've taken a look at the state stack. 629 00:33:17,020 --> 00:33:20,270 We've taken a look at the start state, the fade in state, 630 00:33:20,270 --> 00:33:22,290 let's take a look now at the play state. 631 00:33:22,290 --> 00:33:25,690 632 00:33:25,690 --> 00:33:26,624 So the play state-- 633 00:33:26,624 --> 00:33:28,540 a lot of this is actually very similar to what 634 00:33:28,540 --> 00:33:35,080 we did back with Zelda, which is a very similar type of game top down. 635 00:33:35,080 --> 00:33:40,450 View, the only difference really with that was RPGs of this nature-- 636 00:33:40,450 --> 00:33:42,730 Final Fantasy, Pokemon, Dragon Quest, they're 637 00:33:42,730 --> 00:33:47,110 tile based to the degree of even your movement is tile based. 638 00:33:47,110 --> 00:33:51,620 And so we've striven to implement that with this lecture. 639 00:33:51,620 --> 00:33:57,340 So when we move our player, our character, 640 00:33:57,340 --> 00:34:02,660 it doesn't have free motion like we did with Zelda for example. 641 00:34:02,660 --> 00:34:03,950 So I'll demonstrate this. 642 00:34:03,950 --> 00:34:07,360 So I can go to the field state here, the play state, sorry. 643 00:34:07,360 --> 00:34:09,969 And then when I move, if I press right, he 644 00:34:09,969 --> 00:34:13,850 moves in that direction at a perfect grid interval. 645 00:34:13,850 --> 00:34:16,690 So if I move up, I'm taking my hand instantly away, 646 00:34:16,690 --> 00:34:20,980 he's going to keep moving, and he's going to stick hard set to this grid. 647 00:34:20,980 --> 00:34:25,130 And that's just a sort of trend that these games have implemented. 648 00:34:25,130 --> 00:34:29,139 It allows you to stay perfectly aligned with the grid, and helps you 649 00:34:29,139 --> 00:34:30,800 I guess certain game-- 650 00:34:30,800 --> 00:34:33,429 I don't think it's strictly necessary for probably 651 00:34:33,429 --> 00:34:37,239 most of the games that choose to implement this. 652 00:34:37,239 --> 00:34:41,500 I think it was a symptom of tile based games from the NES and Gameboy 653 00:34:41,500 --> 00:34:47,170 era being easier to design and implement, 654 00:34:47,170 --> 00:34:51,699 because they're very tile based systems. 655 00:34:51,699 --> 00:34:55,030 But I mean, even as an aesthetic choice, I suppose it makes sense, 656 00:34:55,030 --> 00:34:57,472 because everything aligns very perfectly. 657 00:34:57,472 --> 00:35:00,430 So that's the core difference really with the field state in this game. 658 00:35:00,430 --> 00:35:09,160 So how can we go about implementing a grid aligned movement system like this 659 00:35:09,160 --> 00:35:12,170 with our player relative to how we did it in Zelda for example? 660 00:35:12,170 --> 00:35:16,690 661 00:35:16,690 --> 00:35:18,862 How do we think-- sure yeah? 662 00:35:18,862 --> 00:35:23,200 AUDIENCE: So we don't x and y's, we just have the tile positions. 663 00:35:23,200 --> 00:35:26,410 SPEAKER 1: So you don't have x and y's, we just have the tile positions. 664 00:35:26,410 --> 00:35:30,790 Close, I would say it's more focused on the tile positions, 665 00:35:30,790 --> 00:35:33,790 but you still do need an x and a y, because you still 666 00:35:33,790 --> 00:35:37,142 need to draw that sprite at that exact position. 667 00:35:37,142 --> 00:35:38,250 Right, yes Tony? 668 00:35:38,250 --> 00:35:42,400 AUDIENCE: Well, when you need to move the sprite, instead 669 00:35:42,400 --> 00:35:47,080 of moving at every update, you tween it between the two tile locations. 670 00:35:47,080 --> 00:35:51,680 SPEAKER 1: Exactly, so rather than moving the sprite 671 00:35:51,680 --> 00:35:57,970 at exact pixel positions per update, you tween the sprite when you receive input 672 00:35:57,970 --> 00:35:59,950 to a specific location. 673 00:35:59,950 --> 00:36:02,780 And then we actually stop input at that point as well. 674 00:36:02,780 --> 00:36:08,020 There's no use for us having any input when we're not exactly at a given tile, 675 00:36:08,020 --> 00:36:12,170 so we disable input while he's walking effectively. 676 00:36:12,170 --> 00:36:16,150 And so this is implemented, if we're looking at the distro in the entity 677 00:36:16,150 --> 00:36:19,318 class, there is a-- 678 00:36:19,318 --> 00:36:20,350 I believe it's in here-- 679 00:36:20,350 --> 00:36:24,660 680 00:36:24,660 --> 00:36:25,800 maybe player, hold on. 681 00:36:25,800 --> 00:36:32,360 682 00:36:32,360 --> 00:36:35,030 Oh sorry, no it's entity walk state, not the entity. 683 00:36:35,030 --> 00:36:38,600 Entity is just a container for the information that's relevant. 684 00:36:38,600 --> 00:36:42,510 So here in the entity walk state, we have attempt move. 685 00:36:42,510 --> 00:36:45,395 And so what attempt move does is essentially 686 00:36:45,395 --> 00:36:49,820 it looks to make sure that we're within the bounds of the map, right? 687 00:36:49,820 --> 00:36:51,970 And then if we are-- 688 00:36:51,970 --> 00:36:56,917 every entity in this game now has a map y and x, and a regular y and x. 689 00:36:56,917 --> 00:36:59,000 And so the regular y and x, we still need in order 690 00:36:59,000 --> 00:37:01,880 to draw our sprite at a specific location on the map. 691 00:37:01,880 --> 00:37:09,320 We still need to draw it going between 240 something and 230 something, right? 692 00:37:09,320 --> 00:37:12,650 But we need a map x and a map y to basically say, OK, 693 00:37:12,650 --> 00:37:15,680 the sprite should be at this position on the map. 694 00:37:15,680 --> 00:37:19,220 And then we'll just tween it between that position times 16, 695 00:37:19,220 --> 00:37:22,610 and it's the position plus or minus x or y 696 00:37:22,610 --> 00:37:26,000 times 16, which will give us the exact x and y value that we 697 00:37:26,000 --> 00:37:27,480 need to draw it onto the map. 698 00:37:27,480 --> 00:37:28,980 And so that's what we're doing here. 699 00:37:28,980 --> 00:37:32,630 So were going to call attempt move on input. 700 00:37:32,630 --> 00:37:34,440 So anytime we do any input-- 701 00:37:34,440 --> 00:37:39,950 and this is done in the player like idle, or player, yeah, player 702 00:37:39,950 --> 00:37:41,900 idle class-- 703 00:37:41,900 --> 00:37:43,820 player idle state. 704 00:37:43,820 --> 00:37:46,520 We change the animation to write animation. 705 00:37:46,520 --> 00:37:48,710 And then we get it's current map x and y. 706 00:37:48,710 --> 00:37:51,410 And then based on whatever direction the player is looking, 707 00:37:51,410 --> 00:37:56,720 or the entity is looking, we could use this for an NPC class, or the like. 708 00:37:56,720 --> 00:37:59,870 We just modify our 2x and 2y. 709 00:37:59,870 --> 00:38:04,390 So to 2x and 2y is going to be the value that we're tweening towards times 16, 710 00:38:04,390 --> 00:38:05,950 right? 711 00:38:05,950 --> 00:38:10,940 And so if we're trying to go outside the map boundaries, 712 00:38:10,940 --> 00:38:13,340 just changing us back to idle won't let us do that. 713 00:38:13,340 --> 00:38:19,620 Otherwise, set our map y and map x to that position immediately, 714 00:38:19,620 --> 00:38:22,880 right, because that's just a minus or plus one operation. 715 00:38:22,880 --> 00:38:28,010 And then over the course of 0.5 seconds, actually tween to that value. 716 00:38:28,010 --> 00:38:30,770 And we can see here, we're tweening to the tile size, 717 00:38:30,770 --> 00:38:35,212 and actually to the tile size minus self.entity.height divided by 2. 718 00:38:35,212 --> 00:38:36,170 Do we know why that is? 719 00:38:36,170 --> 00:38:40,820 720 00:38:40,820 --> 00:38:45,385 We do that, because if we're looking at the field, we can see here, 721 00:38:45,385 --> 00:38:48,010 notice that we're not perfectly lined up with the grass, right? 722 00:38:48,010 --> 00:38:50,050 It's kind of like we're halfway above it, 723 00:38:50,050 --> 00:38:53,050 because it looks just a little bit more natural this way, 724 00:38:53,050 --> 00:38:54,967 this is how most sort of games look. 725 00:38:54,967 --> 00:38:56,800 And if you're in a game like this and you're 726 00:38:56,800 --> 00:38:58,821 like walking up against a wall for example, 727 00:38:58,821 --> 00:39:00,820 this will allow you to sort of look as if you're 728 00:39:00,820 --> 00:39:03,100 up against the wall rather than sort of being 729 00:39:03,100 --> 00:39:06,880 at the edge of where the bottom of the wall is, and kind of looks unnatural. 730 00:39:06,880 --> 00:39:12,290 Hence why we minus 1/2 our height right there. 731 00:39:12,290 --> 00:39:15,910 And then when we're finished, we actually 732 00:39:15,910 --> 00:39:18,770 test to see whether we're still pressing a key, and if we are, 733 00:39:18,770 --> 00:39:20,710 then change our state to walk again, which 734 00:39:20,710 --> 00:39:24,727 we'll just repeat this process depending on which direction we're looking at. 735 00:39:24,727 --> 00:39:25,810 And that's effectively it. 736 00:39:25,810 --> 00:39:28,462 And that's what allows us to get this grid based movement. 737 00:39:28,462 --> 00:39:29,920 Any questions as to how this works? 738 00:39:29,920 --> 00:39:33,280 739 00:39:33,280 --> 00:39:33,780 Cool. 740 00:39:33,780 --> 00:39:37,335 741 00:39:37,335 --> 00:39:43,200 Let's take a look then at the play state, let's go back to it. 742 00:39:43,200 --> 00:39:46,110 So we have a level, the level contains our entity, 743 00:39:46,110 --> 00:39:49,394 and it can contain all of our entities, and whatever 744 00:39:49,394 --> 00:39:50,685 objects you want it to contain. 745 00:39:50,685 --> 00:39:53,190 746 00:39:53,190 --> 00:39:55,530 In this case, when we're in the play state as well, 747 00:39:55,530 --> 00:39:57,279 we're going to check to see if we press P, 748 00:39:57,279 --> 00:39:59,820 because that's recall, where we can heal our Pokemon, 749 00:39:59,820 --> 00:40:05,410 just a little game hack just to make demoing it a little bit easier. 750 00:40:05,410 --> 00:40:11,800 But if we press P, we play the heal sound, we take our-- 751 00:40:11,800 --> 00:40:16,110 and we'll look a little bit more detail as to this, all this in a little bit. 752 00:40:16,110 --> 00:40:24,090 But self.level.player.pa rty.pokemon@index1.currenthp 753 00:40:24,090 --> 00:40:29,416 equals self.level.player.party.pokemon@1.hp. 754 00:40:29,416 --> 00:40:32,040 So the difference is current HP is whatever you currently have, 755 00:40:32,040 --> 00:40:33,330 you could have taken damage. 756 00:40:33,330 --> 00:40:35,730 HP is whatever your max HP is. 757 00:40:35,730 --> 00:40:38,860 And this is like in a nutshell how you get 758 00:40:38,860 --> 00:40:44,820 like stat changes in games and RPGs, and health and mp differences. 759 00:40:44,820 --> 00:40:48,577 You've got to keep track of a max and a current value for all of those things, 760 00:40:48,577 --> 00:40:50,910 and then depending on whether you're buffed or debugged, 761 00:40:50,910 --> 00:40:54,120 or whether you have taken damage or not, or used spells or not, 762 00:40:54,120 --> 00:40:56,610 you can have an accurate reflection of where 763 00:40:56,610 --> 00:41:01,350 your character is and then always return back to that state 764 00:41:01,350 --> 00:41:03,420 whenever you need to. 765 00:41:03,420 --> 00:41:06,570 The interesting thing here, the slightly more complicated thing 766 00:41:06,570 --> 00:41:10,350 is when we press P, we want to show a dialog that says, 767 00:41:10,350 --> 00:41:13,680 and I'll demonstrate this, we want to show a dialog just 768 00:41:13,680 --> 00:41:18,120 like this one that says, we press P, your Pokemon has been healed, right? 769 00:41:18,120 --> 00:41:19,200 Now I can't move. 770 00:41:19,200 --> 00:41:20,790 I'm pressing the arrow keys. 771 00:41:20,790 --> 00:41:23,430 I can't move my character at all, because this dialog state-- 772 00:41:23,430 --> 00:41:28,950 we're in a new state, well, we've pushed a new state onto the state stack. 773 00:41:28,950 --> 00:41:32,380 And that's the dialog state here, which has taken a value. 774 00:41:32,380 --> 00:41:37,030 And because it's the top layer of the stack, it can't get updated, 775 00:41:37,030 --> 00:41:40,200 or it's being updated, and we can't update the play state, right, 776 00:41:40,200 --> 00:41:44,850 based on how we've modeled our state stacks operation, or how it works. 777 00:41:44,850 --> 00:41:47,970 And then as soon as I press Enter, it gets popped off, 778 00:41:47,970 --> 00:41:49,030 we've just popped it off. 779 00:41:49,030 --> 00:41:51,570 Now the place states at the top, I can move again. 780 00:41:51,570 --> 00:41:52,740 So that's what's going on. 781 00:41:52,740 --> 00:42:02,700 So the dialog state then is actually very similar in a sense, to the fade 782 00:42:02,700 --> 00:42:06,450 in and fade out state in that, notice that it takes an anonymous function. 783 00:42:06,450 --> 00:42:09,251 When does this anonymous function get called? 784 00:42:09,251 --> 00:42:09,750 Do we know? 785 00:42:09,750 --> 00:42:12,750 786 00:42:12,750 --> 00:42:16,311 At the end of what? 787 00:42:16,311 --> 00:42:18,600 AUDIENCE: [INAUDIBLE] 788 00:42:18,600 --> 00:42:24,790 SPEAKER 1: Yeah, well, when the user closes the dialog box, correct. 789 00:42:24,790 --> 00:42:27,800 So let's take a look at the dialog state then. 790 00:42:27,800 --> 00:42:32,640 And we can see, it's actually pretty simple, it's pretty small. 791 00:42:32,640 --> 00:42:36,480 We have a text that it takes and a callback, right? 792 00:42:36,480 --> 00:42:39,600 The text is used here. 793 00:42:39,600 --> 00:42:42,870 We instantiate, and this we'll see in detail when we start looking at GUIs, 794 00:42:42,870 --> 00:42:45,450 and all the widgets they've implemented here. 795 00:42:45,450 --> 00:42:52,020 This text box gets put at a hard coded position, and it receives this text. 796 00:42:52,020 --> 00:42:56,490 And then we set our self.callback to that callback function. 797 00:42:56,490 --> 00:43:00,630 If we have closed the text box, meaning, we're 798 00:43:00,630 --> 00:43:03,990 looking to see at self.textbox.isClosed, which 799 00:43:03,990 --> 00:43:07,080 is a function of the text box class. 800 00:43:07,080 --> 00:43:12,660 If it's closed, then execute self.callback, and then pop 801 00:43:12,660 --> 00:43:15,870 this dialog state of the stack, right? 802 00:43:15,870 --> 00:43:19,710 So it's similar in a sense, to the fade in and fade out, 803 00:43:19,710 --> 00:43:21,430 and then it takes anonymous function. 804 00:43:21,430 --> 00:43:23,388 The only difference is in how it gets executed. 805 00:43:23,388 --> 00:43:25,350 With the fade in state, the anonymous function 806 00:43:25,350 --> 00:43:28,160 was called at the end of the finish function, which 807 00:43:28,160 --> 00:43:30,100 is part of the tween object. 808 00:43:30,100 --> 00:43:33,840 In this case, we're executing the callback function explicitly when 809 00:43:33,840 --> 00:43:35,460 we've closed the text box. 810 00:43:35,460 --> 00:43:40,440 So we're waiting for user input versus waiting for some asynchronous operation 811 00:43:40,440 --> 00:43:42,570 to finish. 812 00:43:42,570 --> 00:43:45,990 And then of course, we call text box render, 813 00:43:45,990 --> 00:43:49,566 and then we'll see all of these methods shortly as part of these widgets, 814 00:43:49,566 --> 00:43:52,690 but at a glance, this is all that's really happening with the dialog state. 815 00:43:52,690 --> 00:43:55,980 Very simple, using the same pattern that we've 816 00:43:55,980 --> 00:44:01,530 seen of deferring future behavior to anonymous functions. 817 00:44:01,530 --> 00:44:07,025 Any questions as to how this works, or anything so far? 818 00:44:07,025 --> 00:44:09,164 Cool. 819 00:44:09,164 --> 00:44:11,330 All right, let's take a look back at the play state, 820 00:44:11,330 --> 00:44:14,180 I believe we're getting close to being finished with the play state. 821 00:44:14,180 --> 00:44:18,810 Yes, so everything, that's basically what the play state is in this game. 822 00:44:18,810 --> 00:44:22,170 And then a lot of what's going on takes place in a level as well. 823 00:44:22,170 --> 00:44:29,000 So in a nutshell, we have two maps, two layers, right, 824 00:44:29,000 --> 00:44:32,990 because the grass in the tile sheet is its own sort of [? alphaed ?] 825 00:44:32,990 --> 00:44:36,440 out object, it's got transparency around it. 826 00:44:36,440 --> 00:44:40,100 We keep a layer of the base, a layer of the grass underneath, 827 00:44:40,100 --> 00:44:43,610 and then a separate layer for the tall grass. 828 00:44:43,610 --> 00:44:45,950 And then we can just look and to see when 829 00:44:45,950 --> 00:44:51,260 we're walking in the player walk state when we've walked over tall grass. 830 00:44:51,260 --> 00:44:55,076 And then what do we need to do to start a random encounter? 831 00:44:55,076 --> 00:45:01,171 832 00:45:01,171 --> 00:45:01,670 Yes? 833 00:45:01,670 --> 00:45:04,710 AUDIENCE: [INAUDIBLE] 834 00:45:04,710 --> 00:45:07,040 SPEAKER 1: Yes, how do we initiated though? 835 00:45:07,040 --> 00:45:08,890 That what are we looking for? 836 00:45:08,890 --> 00:45:11,297 We do push a battle state as soon as we've triggered one, 837 00:45:11,297 --> 00:45:12,380 but how do we trigger one? 838 00:45:12,380 --> 00:45:13,702 What are we looking for? 839 00:45:13,702 --> 00:45:17,750 AUDIENCE: [INAUDIBLE] player is in the grass. 840 00:45:17,750 --> 00:45:20,150 I don't know if it's on moving to a new grass, 841 00:45:20,150 --> 00:45:22,870 or if it's time spent in the grass. 842 00:45:22,870 --> 00:45:25,820 Yeah, we do a random chance whenever the players on grass. 843 00:45:25,820 --> 00:45:29,539 And it's whenever they start to walk and there on grass in this case. 844 00:45:29,539 --> 00:45:31,330 But you can do it either way, you can do it 845 00:45:31,330 --> 00:45:33,830 when they're leaving the grass, walking into the grass. 846 00:45:33,830 --> 00:45:35,871 In this case, it's whenever you press the button, 847 00:45:35,871 --> 00:45:38,780 and they happen to be on grass, it'll do a random chance, one in 10. 848 00:45:38,780 --> 00:45:43,130 And if it's equal to 1, 10% chance it'll trigger an encounter. 849 00:45:43,130 --> 00:45:46,670 So that's the gist behind triggering a random encounter, 850 00:45:46,670 --> 00:45:48,602 and a lot of these games really-- 851 00:45:48,602 --> 00:45:49,810 some games do it differently. 852 00:45:49,810 --> 00:45:52,795 They'll sometimes make it more likely the more steps you've taken, 853 00:45:52,795 --> 00:45:55,670 they'll like sort of keep a counter to say, oh, I've taken 100 steps, 854 00:45:55,670 --> 00:45:57,680 it should be a lot more likely now. 855 00:45:57,680 --> 00:46:01,700 Some games will just be completely random, 1 in 10, 1 in 5, 856 00:46:01,700 --> 00:46:05,210 depending on how the developers decided to implement their game. 857 00:46:05,210 --> 00:46:08,540 The former is a bit more robust. 858 00:46:08,540 --> 00:46:11,750 But for simplicity, we just chose, math.random10 equals 1. 859 00:46:11,750 --> 00:46:14,680 860 00:46:14,680 --> 00:46:19,410 So yeah, we create the tile maps here, pretty straightforward. 861 00:46:19,410 --> 00:46:26,630 And then the actual random encountering takes place in the player walk state. 862 00:46:26,630 --> 00:46:29,570 So here we have check for encounter. 863 00:46:29,570 --> 00:46:33,800 And so what this does is whenever we enter the walk state, which 864 00:46:33,800 --> 00:46:37,650 is we press the button to enter, or to walk, 865 00:46:37,650 --> 00:46:40,190 this entire function gets called, because we 866 00:46:40,190 --> 00:46:43,160 do the transition to the player walk state in the state machine. 867 00:46:43,160 --> 00:46:45,826 All of the entities are still using just a regular state machine 868 00:46:45,826 --> 00:46:46,880 not a state stack. 869 00:46:46,880 --> 00:46:49,400 Wasn't necessary for this demonstration, though I'm sure 870 00:46:49,400 --> 00:46:52,879 there are some used cases for using a state stack for an entity. 871 00:46:52,879 --> 00:46:55,170 In this case, we're just using a regular state machine. 872 00:46:55,170 --> 00:46:59,360 So when we change to the walk state, we are calling enter as we've seen. 873 00:46:59,360 --> 00:47:02,830 And then we call self, checkForEncounter. 874 00:47:02,830 --> 00:47:07,340 And so self, checkForEncounter will set a flag 875 00:47:07,340 --> 00:47:14,290 if we have not started an encounter basically and will allow us to move. 876 00:47:14,290 --> 00:47:17,525 And if we have checked for an encounter, it will, 877 00:47:17,525 --> 00:47:21,470 or if we have triggered an encounter, it will push in checkForEncounter, 878 00:47:21,470 --> 00:47:26,310 it'll actually push a battle state onto the stack. 879 00:47:26,310 --> 00:47:30,900 So checkForEncounter just basically does what we said before. 880 00:47:30,900 --> 00:47:34,957 If the grass layer, because we have two layers, 881 00:47:34,957 --> 00:47:37,040 right, we have the base layer and the grass layer. 882 00:47:37,040 --> 00:47:43,760 So if the layer at yx where yx is are entities map x and map y. 883 00:47:43,760 --> 00:47:46,610 If the ID of that is equal to tall grass, 884 00:47:46,610 --> 00:47:50,750 and we have just a global constant table called 885 00:47:50,750 --> 00:47:52,960 Tile IDs, which has all these IDs. 886 00:47:52,960 --> 00:47:57,080 And math.random10 is equal to 1, OK, change the entity state to idle, 887 00:47:57,080 --> 00:48:00,500 so don't let them keep walking. 888 00:48:00,500 --> 00:48:02,645 Pause the field music rather than stopping, 889 00:48:02,645 --> 00:48:06,380 so that way when we come back to the field later and we press play, 890 00:48:06,380 --> 00:48:09,980 it will be at the exact point that it was before. 891 00:48:09,980 --> 00:48:14,900 Triggered the battle music, and then, we've seen this already, fade in state, 892 00:48:14,900 --> 00:48:16,940 push to the stack, right? 893 00:48:16,940 --> 00:48:19,945 So over one second, we're going to fade to white. 894 00:48:19,945 --> 00:48:22,070 So this will have the effect of the music starting, 895 00:48:22,070 --> 00:48:23,960 but we're fading to white right away, which 896 00:48:23,960 --> 00:48:27,785 is very sort of similar to how most RPGs do it. 897 00:48:27,785 --> 00:48:29,660 And then we have our callback function, which 898 00:48:29,660 --> 00:48:32,720 will execute as soon as the fade in state's done, right? 899 00:48:32,720 --> 00:48:35,720 In this case, push to battle state. 900 00:48:35,720 --> 00:48:37,900 Battle state takes an entity, and the entity 901 00:48:37,900 --> 00:48:39,650 has all of our Pokemon information, that's 902 00:48:39,650 --> 00:48:41,710 why we're passing that into the battle state. 903 00:48:41,710 --> 00:48:44,290 So the battle state can say, oh, what Pokemon do you have? 904 00:48:44,290 --> 00:48:49,010 OK, I'll be able to look at your party and say, OK, your first Pokemon 905 00:48:49,010 --> 00:48:52,520 is this, send him out to battle, et cetera, right? 906 00:48:52,520 --> 00:48:56,180 And then lastly, push a fade out state, right, 907 00:48:56,180 --> 00:49:02,570 because now we've got the battle state on top of the play state, 908 00:49:02,570 --> 00:49:05,260 but we want to fade into it, right? 909 00:49:05,260 --> 00:49:08,180 So we're going to fade, we're going to put the battle state first, 910 00:49:08,180 --> 00:49:10,820 and then because we're using a stack, we're 911 00:49:10,820 --> 00:49:14,450 going to put the fate out state on top of that, and then fade out to that, 912 00:49:14,450 --> 00:49:15,990 pop that off the stack. 913 00:49:15,990 --> 00:49:19,760 And then we have our battle state that we just pushed, right? 914 00:49:19,760 --> 00:49:21,760 And then self.encounterFound get's set here. 915 00:49:21,760 --> 00:49:25,130 And that's creating an encounter, checking randomly, 916 00:49:25,130 --> 00:49:27,760 pushing the right things under the stack, battle state, 917 00:49:27,760 --> 00:49:30,200 fade state, fade in, fade out. 918 00:49:30,200 --> 00:49:32,900 And then you're set to go. 919 00:49:32,900 --> 00:49:35,400 So that's effectively what the-- 920 00:49:35,400 --> 00:49:41,600 it's known in RPGs as the field versus the battle or encounter state. 921 00:49:41,600 --> 00:49:44,882 Even though we're calling it play state here, we've left the field, 922 00:49:44,882 --> 00:49:46,590 we've gone into the battle at this point. 923 00:49:46,590 --> 00:49:48,500 And so now we've seen basically everything 924 00:49:48,500 --> 00:49:51,790 that the field has to offer us. 925 00:49:51,790 --> 00:49:54,530 And we've covered everything that's relevant there. 926 00:49:54,530 --> 00:49:59,030 So we're going to take a break now for five to 10 minutes, 927 00:49:59,030 --> 00:50:01,980 and then when we get back from the break, 928 00:50:01,980 --> 00:50:04,640 we'll talk about GUI elements, panels, text boxes, 929 00:50:04,640 --> 00:50:09,470 and then we'll dive into the sort of mechanics of the battle state. 930 00:50:09,470 --> 00:50:12,600 All right, welcome back to lecture 7, Pokemon. 931 00:50:12,600 --> 00:50:14,960 So before the break, we talked about the play state, 932 00:50:14,960 --> 00:50:17,280 we talked about the states stack more importantly, 933 00:50:17,280 --> 00:50:20,870 and then we talked about how a anonymous functions are 934 00:50:20,870 --> 00:50:25,500 sort of the backbone to how we get a lot of this asynchronous 935 00:50:25,500 --> 00:50:29,820 and deferred behavior for our game, which is very common in RPGs, 936 00:50:29,820 --> 00:50:34,550 and I mean, a lot of genres, a lot of complicated genres of this sort. 937 00:50:34,550 --> 00:50:39,560 Another big key part of games like this are the graphical user 938 00:50:39,560 --> 00:50:42,890 interfaces, or GUIs as they're shortened to. 939 00:50:42,890 --> 00:50:46,550 Things like panels on the screen, things like labels-- 940 00:50:46,550 --> 00:50:53,880 text labels that move around, things like lists, text boxes, scroll bars, 941 00:50:53,880 --> 00:50:56,150 and you can get a lot crazier with it. 942 00:50:56,150 --> 00:51:03,140 In this particular lecture, we'll be talking mostly about panels, labels, 943 00:51:03,140 --> 00:51:05,870 text boxes, and scroll bars-- 944 00:51:05,870 --> 00:51:08,760 progress bars rather, not scroll bars. 945 00:51:08,760 --> 00:51:12,220 But the sort of the first I think corner-- 946 00:51:12,220 --> 00:51:17,000 or the first sort of like keystone GUI widget 947 00:51:17,000 --> 00:51:21,410 that we should take into consideration is the panel. 948 00:51:21,410 --> 00:51:27,203 So a panel is [INAUDIBLE]. 949 00:51:27,203 --> 00:51:33,330 950 00:51:33,330 --> 00:51:41,680 So if we look at this in a game-- 951 00:51:41,680 --> 00:51:44,500 just pretend this is a panel I guess. 952 00:51:44,500 --> 00:51:47,710 So this is effectively all a panel is, right? 953 00:51:47,710 --> 00:51:49,960 It's just sort of a rectangle. 954 00:51:49,960 --> 00:51:54,107 It allows us to-- if you're looking at most user interfaces, 955 00:51:54,107 --> 00:51:56,440 like text boxes on your screen, or if you're on Facebook 956 00:51:56,440 --> 00:52:00,250 and you're looking at almost anything, like your little message 957 00:52:00,250 --> 00:52:03,520 window, a lot of those things at the very core, the very bottom, 958 00:52:03,520 --> 00:52:05,530 the foundational part is just a panel. 959 00:52:05,530 --> 00:52:11,023 So any guesses to how in Love2D, we can make a simple panel? 960 00:52:11,023 --> 00:52:12,899 AUDIENCE: Two rectangles of different colors. 961 00:52:12,899 --> 00:52:14,814 SPEAKER 1: Two rectangles of different colors, 962 00:52:14,814 --> 00:52:16,360 that's exactly what we end up doing. 963 00:52:16,360 --> 00:52:18,650 So that's effectively how we can make a panel. 964 00:52:18,650 --> 00:52:24,100 There's another way of making a panel, which we won't do in this lecture, 965 00:52:24,100 --> 00:52:26,530 but it's called-- 966 00:52:26,530 --> 00:52:30,640 we use as a construct called a nine patch. 967 00:52:30,640 --> 00:52:37,240 So a nine patch is-- 968 00:52:37,240 --> 00:52:41,000 imagine taking this little image here, and it's of some arbitrary size, 969 00:52:41,000 --> 00:52:42,704 but it's very small. 970 00:52:42,704 --> 00:52:44,620 And this is very similar to how a lot of games 971 00:52:44,620 --> 00:52:48,220 implemented their panels or their graphical user 972 00:52:48,220 --> 00:52:52,270 interfaces back in the 80s and 90s, I mean, to a lot of games till this day. 973 00:52:52,270 --> 00:52:58,330 But back when hardware was fundamentally tile based, 974 00:52:58,330 --> 00:53:06,850 you could take a image like this, split it up into nine pieces-- 975 00:53:06,850 --> 00:53:11,060 nine patch is where the terminology comes from. 976 00:53:11,060 --> 00:53:15,700 And sort of similar to how we actually constructed the Zelda dungeon, recall, 977 00:53:15,700 --> 00:53:20,950 where you have corner pieces, and then a top, bottom, right, and left side. 978 00:53:20,950 --> 00:53:24,320 You just layer this, one of each of these, 979 00:53:24,320 --> 00:53:28,000 first off, right, of the corner pieces. 980 00:53:28,000 --> 00:53:33,580 And then however many you need of these on the sides 981 00:53:33,580 --> 00:53:36,220 to create this rectangle, right? 982 00:53:36,220 --> 00:53:39,040 So imagine we've created-- 983 00:53:39,040 --> 00:53:45,260 these are all, if we can visualize these as being a bunch of tiles, right? 984 00:53:45,260 --> 00:53:52,750 985 00:53:52,750 --> 00:53:55,120 So just imagine that we've taken these corner pieces, 986 00:53:55,120 --> 00:53:58,240 these are the corner pieces, we've taken one of each of those. 987 00:53:58,240 --> 00:54:02,410 And then we take these side pieces, and we just like draw a bunch of them 988 00:54:02,410 --> 00:54:04,000 like that. 989 00:54:04,000 --> 00:54:06,730 And then we take this centerpiece, and then we 990 00:54:06,730 --> 00:54:11,260 can either layer it, or tile it a bunch of times, or just stretch it. 991 00:54:11,260 --> 00:54:15,160 And stretching it has a bunch of nice bonuses associated with it depending 992 00:54:15,160 --> 00:54:18,660 on how you've set your filter mode, love.graphics.setdefaultfilter, 993 00:54:18,660 --> 00:54:21,130 if you set it to bilinear versus nearest, 994 00:54:21,130 --> 00:54:23,230 you can actually get a nice gradient. 995 00:54:23,230 --> 00:54:26,020 And if you set it to nearest, you get a nice pixelated look. 996 00:54:26,020 --> 00:54:29,761 But you'll see this often, and Unity has nice support for this. 997 00:54:29,761 --> 00:54:32,260 Take an image that has maybe more complicated than you could 998 00:54:32,260 --> 00:54:34,100 get with just two rectangles, right? 999 00:54:34,100 --> 00:54:37,780 Something that actually has a design and maybe a gradient color, and actually 1000 00:54:37,780 --> 00:54:40,270 layer-- 1001 00:54:40,270 --> 00:54:46,030 I mean, create a arbitrarily sized text box to fit your needs. 1002 00:54:46,030 --> 00:54:49,770 And if these aren't even increments or whatever your tile size 1003 00:54:49,770 --> 00:54:53,680 is on your 9 patch, you could just scale the top, bottom, left, and right side 1004 00:54:53,680 --> 00:54:56,690 as well just to keep it scaled, the centerpiece. 1005 00:54:56,690 --> 00:54:58,865 So does that makes sense. 1006 00:54:58,865 --> 00:55:01,240 So this is common, we won't be using that in our lecture, 1007 00:55:01,240 --> 00:55:06,182 but it's a very, very common piece to a lot of graphical user interface design. 1008 00:55:06,182 --> 00:55:09,390 In a lot of games, you'll see it a lot if you get more into game development, 1009 00:55:09,390 --> 00:55:12,400 so it's definitely worth talking about. 1010 00:55:12,400 --> 00:55:17,620 Another piece that we'll be talking about today is the text box. 1011 00:55:17,620 --> 00:55:20,814 So I mean, what's a guess as to what the text box, 1012 00:55:20,814 --> 00:55:23,730 how we can implement a text box, and how we will implement a text box? 1013 00:55:23,730 --> 00:55:27,450 1014 00:55:27,450 --> 00:55:33,000 So what foundational piece can we start with? 1015 00:55:33,000 --> 00:55:35,023 We already have-- yeah? 1016 00:55:35,023 --> 00:55:37,765 AUDIENCE: You just put use the love print 1017 00:55:37,765 --> 00:55:40,171 to the screen over one of those boxes. 1018 00:55:40,171 --> 00:55:43,420 SPEAKER 1: So use the love print to the screen over one of the boxes, exactly. 1019 00:55:43,420 --> 00:55:44,280 Yep. 1020 00:55:44,280 --> 00:55:49,800 So maintain a list of text items, right, text. 1021 00:55:49,800 --> 00:55:57,090 And then just draw them inside a panel, and there's a text box. 1022 00:55:57,090 --> 00:56:00,360 You've taken two ideas, and sort of mix them together. 1023 00:56:00,360 --> 00:56:03,080 A selection is kind of the same thing. 1024 00:56:03,080 --> 00:56:07,290 It's a the only difference being that with a selection-- 1025 00:56:07,290 --> 00:56:10,720 so a selection is another thing if we think about, 1026 00:56:10,720 --> 00:56:15,970 for example a menu where we have fight, and like run, 1027 00:56:15,970 --> 00:56:20,880 and it may be in a more fleshed out game, we have like an item thing, 1028 00:56:20,880 --> 00:56:21,840 right? 1029 00:56:21,840 --> 00:56:25,830 So that's a menu effectively. 1030 00:56:25,830 --> 00:56:28,650 It is very similar to what we get with a text box, 1031 00:56:28,650 --> 00:56:32,910 but it's got a set of ingredients here, fight, item, run, 1032 00:56:32,910 --> 00:56:40,170 which they aren't set to wrap, they're not one like contiguous set of text. 1033 00:56:40,170 --> 00:56:42,420 It's just a bunch of items. 1034 00:56:42,420 --> 00:56:45,870 And then nice thing about a selection is that you can 1035 00:56:45,870 --> 00:56:49,830 have a cursor on your selection, right? 1036 00:56:49,830 --> 00:56:53,052 And then what do we need to associate with like, for example, 1037 00:56:53,052 --> 00:56:54,760 if we want this to actually do something, 1038 00:56:54,760 --> 00:56:57,220 and if we think about what we've been doing so far, 1039 00:56:57,220 --> 00:56:59,220 how do we go about implementing functionality 1040 00:56:59,220 --> 00:57:00,680 with a selection like this? 1041 00:57:00,680 --> 00:57:04,353 Like what needs to get associated with each of those entries in our selection? 1042 00:57:04,353 --> 00:57:08,430 1043 00:57:08,430 --> 00:57:09,910 Callback function, right? 1044 00:57:09,910 --> 00:57:11,680 Just as we've done with everything else. 1045 00:57:11,680 --> 00:57:15,690 If you have a fight item here, each of these, if we think of the selection 1046 00:57:15,690 --> 00:57:19,110 as being just this part of what we're looking at, 1047 00:57:19,110 --> 00:57:22,700 right, because this background part is just a panel, we don't care about that. 1048 00:57:22,700 --> 00:57:24,450 We care about the selection at the moment. 1049 00:57:24,450 --> 00:57:27,250 The selection is the items and the arrow, right? 1050 00:57:27,250 --> 00:57:30,630 When as we'll see in the assignment, your goal will actually 1051 00:57:30,630 --> 00:57:33,750 be to take selection and get rid of the arrow functionality, 1052 00:57:33,750 --> 00:57:36,060 because for the assignment, you don't need 1053 00:57:36,060 --> 00:57:40,620 or want to have a selection active, a cursor active. 1054 00:57:40,620 --> 00:57:43,620 You just want a list of things. 1055 00:57:43,620 --> 00:57:52,570 But based on what the cursor is pointing at and when we press Enter or whatnot, 1056 00:57:52,570 --> 00:57:55,770 we should index into the selection, and then 1057 00:57:55,770 --> 00:57:59,680 execute a callback that's associated with each of these items. 1058 00:57:59,680 --> 00:58:02,400 And that's how we can get behavior out of the selection, 1059 00:58:02,400 --> 00:58:05,410 rather than just being a list of things that we render to the screen. 1060 00:58:05,410 --> 00:58:08,340 If we have fight, and we click Enter, a callback 1061 00:58:08,340 --> 00:58:12,247 is set to maybe push a state onto the stack that 1062 00:58:12,247 --> 00:58:15,330 will trigger an interaction between the two entities on the screen, right? 1063 00:58:15,330 --> 00:58:17,010 The first one will attack the second one, 1064 00:58:17,010 --> 00:58:18,600 the second one will attack the first one. 1065 00:58:18,600 --> 00:58:21,766 And that's sort of its own asynchronous set of states that do its own thing, 1066 00:58:21,766 --> 00:58:24,750 but it's kicked off via an anonymous function 1067 00:58:24,750 --> 00:58:27,980 that we've associated with each of these things, right? 1068 00:58:27,980 --> 00:58:32,460 An item pushes another state, which is like an item mini state, where then you 1069 00:58:32,460 --> 00:58:36,240 open up a brand new set of menus that you can look through all your items, 1070 00:58:36,240 --> 00:58:40,246 and each of those items has a callback associated with it, right? 1071 00:58:40,246 --> 00:58:42,120 Your potion has a callback associated with it 1072 00:58:42,120 --> 00:58:45,750 that says, when I click on this, either by default, 1073 00:58:45,750 --> 00:58:48,120 just restore the HP of my active Pokemon, 1074 00:58:48,120 --> 00:58:50,070 or let me choose who to restore. 1075 00:58:50,070 --> 00:58:53,960 So therefore, push another state, which is like a select Pokemon 1076 00:58:53,960 --> 00:58:58,120 screen with its own set of callbacks associated with each of those. 1077 00:58:58,120 --> 00:59:01,911 It's just in order to get all of this sort of complicated behavior 1078 00:59:01,911 --> 00:59:04,410 that you need to, it's really ultimately just pushing states 1079 00:59:04,410 --> 00:59:07,290 and adding callback functions to all of these different options 1080 00:59:07,290 --> 00:59:09,570 that you can select. 1081 00:59:09,570 --> 00:59:13,589 And then run, push a fade state, and then pop this state, 1082 00:59:13,589 --> 00:59:14,880 and then push a fade out state. 1083 00:59:14,880 --> 00:59:16,380 And that's really all we're doing. 1084 00:59:16,380 --> 00:59:20,250 And so this look at all of these GUI widgets 1085 00:59:20,250 --> 00:59:24,060 here is just sort of a conceptual look, but we'll take a look very shortly 1086 00:59:24,060 --> 00:59:25,830 at some actual implementation. 1087 00:59:25,830 --> 00:59:34,060 The last one that I want to look at is the progress bar. 1088 00:59:34,060 --> 00:59:37,350 So a progress bar for example, the HP that we've 1089 00:59:37,350 --> 00:59:45,000 seen in the actual battle where when we take damage, it goes from right to 1090 00:59:45,000 --> 00:59:46,009 left. 1091 00:59:46,009 --> 00:59:48,300 Any guesses as to how we've implemented a progress bar? 1092 00:59:48,300 --> 00:59:48,914 Yes, Tony? 1093 00:59:48,914 --> 00:59:50,534 AUDIENCE: Once again, two rectangles. 1094 00:59:50,534 --> 00:59:52,200 SPEAKER 1: Two rectangles, yes, exactly. 1095 00:59:52,200 --> 00:59:55,860 One, and then the nice thing about rectangles in Love2D 1096 00:59:55,860 --> 01:00:00,840 is you can set the edges on them to be rounded or not 1097 01:00:00,840 --> 01:00:02,760 via an optional parameter. 1098 01:00:02,760 --> 01:00:05,760 So without anything more complicated than a rectangle 1099 01:00:05,760 --> 01:00:09,917 we can just create these sort of almost ellipsoid progress 1100 01:00:09,917 --> 01:00:11,250 bars, very simple progress bars. 1101 01:00:11,250 --> 01:00:14,310 Ones the red, right, the red that's the background. 1102 01:00:14,310 --> 01:00:15,870 And then ones the outline, the black. 1103 01:00:15,870 --> 01:00:18,780 And one is set to fill with the first parameter, 1104 01:00:18,780 --> 01:00:21,850 one's set to line with the first parameter. 1105 01:00:21,850 --> 01:00:24,750 Now how do we go about animating whether or not, 1106 01:00:24,750 --> 01:00:29,080 how do we animate the decreasing amount of health when we take damage? 1107 01:00:29,080 --> 01:00:29,580 Yes? 1108 01:00:29,580 --> 01:00:31,597 AUDIENCE: Between the width. 1109 01:00:31,597 --> 01:00:33,180 SPEAKER 1: Between the width, exactly. 1110 01:00:33,180 --> 01:00:34,560 And what are we tweening it by? 1111 01:00:34,560 --> 01:00:36,626 How are we tweening it? 1112 01:00:36,626 --> 01:00:38,792 How would we calculate how much we need to tween it? 1113 01:00:38,792 --> 01:00:44,536 AUDIENCE: Well, you could just have your width equal your health remaining. 1114 01:00:44,536 --> 01:00:47,160 SPEAKER 1: If your width is set to equal your health remaining, 1115 01:00:47,160 --> 01:00:49,860 then your health is maybe 10. 1116 01:00:49,860 --> 01:00:52,860 And you want your health bar to be like 100 pixels 1117 01:00:52,860 --> 01:00:54,585 long, how is that going to work though? 1118 01:00:54,585 --> 01:00:55,740 AUDIENCE: Multiply it. 1119 01:00:55,740 --> 01:00:57,810 SPEAKER 1: You could multiply it, but if you 1120 01:00:57,810 --> 01:01:01,260 know the width that you want your progress bar to be, 1121 01:01:01,260 --> 01:01:05,760 you can just multiply the width by the ratio of the max 1122 01:01:05,760 --> 01:01:12,030 value of your HP, or sorry, the ratio of your current HP over your max HP, 1123 01:01:12,030 --> 01:01:12,990 right? 1124 01:01:12,990 --> 01:01:16,200 So if you're missing-- if you have 50 HP, and you're missing 5 HP, 1125 01:01:16,200 --> 01:01:18,240 your ratio is 45 over 50. 1126 01:01:18,240 --> 01:01:22,950 And if you multiply that by your width, you get the exact amount of width 1127 01:01:22,950 --> 01:01:26,625 that you need regardless of how wide you want the bar to be, 1128 01:01:26,625 --> 01:01:29,250 if you want to be 1,000 pixels, if you want it to be 50 pixels, 1129 01:01:29,250 --> 01:01:35,569 as long as you multiply current health over max health times the width, 1130 01:01:35,569 --> 01:01:37,110 you'll get that ratio no matter what. 1131 01:01:37,110 --> 01:01:38,764 Does that makes sense? 1132 01:01:38,764 --> 01:01:39,590 Cool. 1133 01:01:39,590 --> 01:01:43,140 So that's a look at all the GUI widgets that we're looking at, how they sort 1134 01:01:43,140 --> 01:01:46,630 relate to what we're doing. 1135 01:01:46,630 --> 01:01:48,760 We'll take a look at their implementation here. 1136 01:01:48,760 --> 01:01:51,141 So I'm going to go ahead and open up the panel. 1137 01:01:51,141 --> 01:01:52,890 And I'm going to move a little bit quickly 1138 01:01:52,890 --> 01:01:57,150 so we can get into sort of the meat of the battle here. 1139 01:01:57,150 --> 01:02:03,420 The panel is as we've said before just two rectangles, right? 1140 01:02:03,420 --> 01:02:06,000 It takes in an xy within a height. 1141 01:02:06,000 --> 01:02:08,060 And then we would just draw two rectangles. 1142 01:02:08,060 --> 01:02:09,750 One is larger than the other. 1143 01:02:09,750 --> 01:02:12,930 The bottom rectangle is slightly larger than the top rectangle. 1144 01:02:12,930 --> 01:02:16,010 So the first rectangle gets drawn and it's whitish. 1145 01:02:16,010 --> 01:02:21,020 And then-- oh, I'm sorry, sorry about that. 1146 01:02:21,020 --> 01:02:23,810 We have a xy within a height. 1147 01:02:23,810 --> 01:02:26,120 And then we're drawing two rectangles to the screen. 1148 01:02:26,120 --> 01:02:29,330 We have the background rectangle, which is drawn first, 1149 01:02:29,330 --> 01:02:32,840 which is going to be the full xy width and height of the panel. 1150 01:02:32,840 --> 01:02:36,290 And then we're going to draw that at a white color, and then draw-- 1151 01:02:36,290 --> 01:02:39,500 in the context of this game-- we're drawing everything at the same color, 1152 01:02:39,500 --> 01:02:40,760 but we can change the color. 1153 01:02:40,760 --> 01:02:42,900 If we wanted to parameterize it, we could do that. 1154 01:02:42,900 --> 01:02:46,070 We could set, we could have a color option here in the constructor. 1155 01:02:46,070 --> 01:02:49,190 We're not doing that, we're just drawing everything the same color. 1156 01:02:49,190 --> 01:02:51,510 But that's how you would get like customized menus, 1157 01:02:51,510 --> 01:02:54,694 some RPGs let you do that. 1158 01:02:54,694 --> 01:02:57,860 And then what we're doing here is we're just within a small slightly smaller 1159 01:02:57,860 --> 01:02:58,730 boundary. 1160 01:02:58,730 --> 01:03:02,179 So just two pixels smaller on the x and y. 1161 01:03:02,179 --> 01:03:04,220 Where you are going to draw the second rectangle, 1162 01:03:04,220 --> 01:03:06,950 which is a kind of dark shade of gray. 1163 01:03:06,950 --> 01:03:09,425 And that is a panel, that is all panel is. 1164 01:03:09,425 --> 01:03:11,300 And then we could just have a function called 1165 01:03:11,300 --> 01:03:14,430 toggle, which sets it to visible or not visible. 1166 01:03:14,430 --> 01:03:19,130 And if it's visible, get rid of it, or if it's visible, sorry, draw it. 1167 01:03:19,130 --> 01:03:21,560 Otherwise, don't draw anything when it gets rendered. 1168 01:03:21,560 --> 01:03:23,240 So that's a panel in a nutshell. 1169 01:03:23,240 --> 01:03:26,160 Any questions? 1170 01:03:26,160 --> 01:03:26,960 Cool. 1171 01:03:26,960 --> 01:03:32,160 So the next thing that we should look at is the text box. 1172 01:03:32,160 --> 01:03:33,290 So a text box-- 1173 01:03:33,290 --> 01:03:37,340 so the text box is a little bit more complicated than a panel. 1174 01:03:37,340 --> 01:03:41,990 A text box in a nutshell needs to take in some arbitrary body of text, 1175 01:03:41,990 --> 01:03:45,590 and it needs to chop it up based on how wide your text box is. 1176 01:03:45,590 --> 01:03:49,070 And if it surpasses the height of your text box, 1177 01:03:49,070 --> 01:03:54,710 right, ideally, you should page your text so that you can press Space bar, 1178 01:03:54,710 --> 01:04:00,020 Enter and go through pages of text until you've exhausted all of your text. 1179 01:04:00,020 --> 01:04:06,170 And you press Enter one last time, and you get rid of that text box. 1180 01:04:06,170 --> 01:04:11,210 And so we have a panel here, which we have an xy width and height 1181 01:04:11,210 --> 01:04:12,710 in our constructor for the text box. 1182 01:04:12,710 --> 01:04:14,349 And we have our text as well. 1183 01:04:14,349 --> 01:04:16,640 And then we have a font if we want to explicitly decide 1184 01:04:16,640 --> 01:04:19,490 what font we want to use. 1185 01:04:19,490 --> 01:04:25,190 In this case, or at large, we're going to say 1186 01:04:25,190 --> 01:04:30,530 that we instantiate a panel at xy width and height, nothing too fancy. 1187 01:04:30,530 --> 01:04:35,510 And then the fancyish part, the slightly more complicated part 1188 01:04:35,510 --> 01:04:38,330 is here on line 20 where we say, underscore 1189 01:04:38,330 --> 01:04:46,170 self.textChucks gets self.font, getWrap, self.text, self.width minus 12. 1190 01:04:46,170 --> 01:04:49,190 So anybody know what this function does or want to take a guess? 1191 01:04:49,190 --> 01:04:55,190 1192 01:04:55,190 --> 01:04:55,690 Yes? 1193 01:04:55,690 --> 01:04:58,023 AUDIENCE: Is that the page thing you were talking about? 1194 01:04:58,023 --> 01:05:01,192 SPEAKER 1: Exactly, it's the paging of the text. 1195 01:05:01,192 --> 01:05:02,650 Is the chunking of the text rather. 1196 01:05:02,650 --> 01:05:07,060 Not the paging of the text, so much as is the chunking of the text, which 1197 01:05:07,060 --> 01:05:08,650 we will use to page the text. 1198 01:05:08,650 --> 01:05:12,430 So we take some you know arbitrarily large body of text, 1199 01:05:12,430 --> 01:05:16,060 it can be as large as we want it to be, and given-- 1200 01:05:16,060 --> 01:05:20,090 this is actually a function of to Love2D font object. 1201 01:05:20,090 --> 01:05:23,020 So this is given to us from Love2D. 1202 01:05:23,020 --> 01:05:26,350 Get wrap will return two values, the second of which 1203 01:05:26,350 --> 01:05:32,620 is all of the pieces of text that the main big body is divided into 1204 01:05:32,620 --> 01:05:33,770 based on the width. 1205 01:05:33,770 --> 01:05:37,270 So this self.width of minus 12, that's how wide 1206 01:05:37,270 --> 01:05:39,917 it's going to divide our text into chunks of up to, 1207 01:05:39,917 --> 01:05:42,250 it could be slightly smaller than, because it divides it 1208 01:05:42,250 --> 01:05:44,740 based on the word. 1209 01:05:44,740 --> 01:05:51,280 But no piece of text will ever exceed self.width minus 12 width. 1210 01:05:51,280 --> 01:05:57,040 And this will allow us to then render several lines of text within our text 1211 01:05:57,040 --> 01:06:01,420 box, and they will never exceed the boundary, right? 1212 01:06:01,420 --> 01:06:05,770 And so the paging functionality is actually in next chunks. 1213 01:06:05,770 --> 01:06:09,400 So we call self next here at the end of [? knitt ?] function. 1214 01:06:09,400 --> 01:06:13,750 And then self next basically checks to see, OK, are we at the end of the text? 1215 01:06:13,750 --> 01:06:16,350 If we are, then we're not going to display any text, 1216 01:06:16,350 --> 01:06:18,450 and we're going to close the window. 1217 01:06:18,450 --> 01:06:20,110 We're going to close the panel. 1218 01:06:20,110 --> 01:06:24,470 But if we are not at the end of the text, like we still get text left, 1219 01:06:24,470 --> 01:06:26,830 what we want to do is new table. 1220 01:06:26,830 --> 01:06:30,940 And then we're going to, up to three iterations, 1221 01:06:30,940 --> 01:06:33,220 we keep track of where we are in our chunks, right? 1222 01:06:33,220 --> 01:06:36,827 We get self.text chunks equal to all of those chunks, right. 1223 01:06:36,827 --> 01:06:38,410 And that could be an arbitrary number. 1224 01:06:38,410 --> 01:06:41,719 It can be only one chunk, there could be like 30 chunks, right? 1225 01:06:41,719 --> 01:06:43,510 We need a counter to keep track of where we 1226 01:06:43,510 --> 01:06:47,530 are in terms of like based on what page we're on, right, 1227 01:06:47,530 --> 01:06:51,680 and however many lines we rendered to the screen thus far. 1228 01:06:51,680 --> 01:06:55,030 So starting at I, and I get's chunk counter, 1229 01:06:55,030 --> 01:06:57,100 and chunk counter will get incremented by three 1230 01:06:57,100 --> 01:07:00,430 every time we call next chunks, which is every page. 1231 01:07:00,430 --> 01:07:04,030 We could have easily just called this next page as well. 1232 01:07:04,030 --> 01:07:05,950 It's going to insert into that chunks table 1233 01:07:05,950 --> 01:07:08,560 that we just created, self.textChucks at i. 1234 01:07:08,560 --> 01:07:12,250 And once we've reached the number of chunks total 1235 01:07:12,250 --> 01:07:16,420 that we returned from get wrap, we're going to flag end of text 1236 01:07:16,420 --> 01:07:19,990 as being true, and then we're going to return it. 1237 01:07:19,990 --> 01:07:22,300 And so what this will do is, eventually, we're 1238 01:07:22,300 --> 01:07:26,920 going to be equal to the number of chunks that we got from font get wrap, 1239 01:07:26,920 --> 01:07:28,300 right? 1240 01:07:28,300 --> 01:07:31,585 And once we are, that will signal with next 1241 01:07:31,585 --> 01:07:34,570 that it's time to close the text box, because end of text 1242 01:07:34,570 --> 01:07:38,920 will have been set to true at the end of that last chunking process. 1243 01:07:38,920 --> 01:07:41,562 And then we can see here, when we update text box, 1244 01:07:41,562 --> 01:07:43,520 and that whenever it's on the top of the stack, 1245 01:07:43,520 --> 01:07:47,000 remember, we're looking for a Space or an Enter press, 1246 01:07:47,000 --> 01:07:48,880 and then we just call self next. 1247 01:07:48,880 --> 01:07:53,170 And that will have the effect of eventually closing our text box. 1248 01:07:53,170 --> 01:07:56,230 And then is closed recall, we looked at that earlier, we checked 1249 01:07:56,230 --> 01:07:59,300 to see it is the text box closed? 1250 01:07:59,300 --> 01:08:01,270 And that's just a flag that we set here. 1251 01:08:01,270 --> 01:08:06,280 And then for rendering purposes, we render the panel first. 1252 01:08:06,280 --> 01:08:10,750 And then for each of our displaying chunks, so we only have up to three 1253 01:08:10,750 --> 01:08:16,480 displaying chunks at one time, which gets set by the next chunks function. 1254 01:08:16,480 --> 01:08:22,569 We just print that to the screen using i as a multiplier on our y. 1255 01:08:22,569 --> 01:08:29,439 And so that will render up two or three lines, i, i plus 1, i plus 2. 1256 01:08:29,439 --> 01:08:31,899 Any questions as to how the text box works? 1257 01:08:31,899 --> 01:08:34,460 1258 01:08:34,460 --> 01:08:36,939 It's a little more work than the panel for sure, 1259 01:08:36,939 --> 01:08:38,470 but it's fairly straightforward. 1260 01:08:38,470 --> 01:08:40,960 We're just keeping a list of a bunch of text things, 1261 01:08:40,960 --> 01:08:46,200 and then we're just chunking them based on how wide the text 1262 01:08:46,200 --> 01:08:48,100 box is, the dimensions thereof. 1263 01:08:48,100 --> 01:08:50,710 1264 01:08:50,710 --> 01:08:53,040 And then let's take one look at this selection. 1265 01:08:53,040 --> 01:09:01,240 So a selection is basically, a list of text items with a cursor, right? 1266 01:09:01,240 --> 01:09:04,540 And as I said before when we were looking at the screen over there, 1267 01:09:04,540 --> 01:09:08,890 each of those text items has a text value and a callback function. 1268 01:09:08,890 --> 01:09:10,840 And the callback function is what allows us 1269 01:09:10,840 --> 01:09:16,130 to assign behavior to this selection object beyond just displaying things, 1270 01:09:16,130 --> 01:09:16,630 right? 1271 01:09:16,630 --> 01:09:18,921 Because when you have a menu, when you have a selection 1272 01:09:18,921 --> 01:09:22,479 and you select something, you want behavior to happen, right? 1273 01:09:22,479 --> 01:09:26,439 So each of these items indef.items will expect to have a callback function. 1274 01:09:26,439 --> 01:09:29,939 1275 01:09:29,939 --> 01:09:32,649 And then here, when we update the selection, what we're doing 1276 01:09:32,649 --> 01:09:35,398 is we're updating whatever our current selection is, which is just 1277 01:09:35,398 --> 01:09:38,740 a number between 1 and the number of items in that selection making sure 1278 01:09:38,740 --> 01:09:42,590 that if we're at one and we go minus one, that we go back to the bottom. 1279 01:09:42,590 --> 01:09:45,310 And if we're at the bottom when we press, and we go up, 1280 01:09:45,310 --> 01:09:47,240 we go back to the top. 1281 01:09:47,240 --> 01:09:51,880 And we play sounds, cutesy, things like that. 1282 01:09:51,880 --> 01:09:52,979 And then for each-- 1283 01:09:52,979 --> 01:09:56,440 and for our selection here, from one to number of items, 1284 01:09:56,440 --> 01:09:58,720 we calculate how much padding that we need. 1285 01:09:58,720 --> 01:10:01,480 And we draw the cursor at our current selection, 1286 01:10:01,480 --> 01:10:06,700 and then we draw each item based on i and whatever our gap width is 1287 01:10:06,700 --> 01:10:08,680 of our panel, which we assign it to. 1288 01:10:08,680 --> 01:10:11,920 So we divide our panel up, and then basically just 1289 01:10:11,920 --> 01:10:14,650 keep track of where current y is and draw 1290 01:10:14,650 --> 01:10:17,620 the actual selection and the cursor if that's 1291 01:10:17,620 --> 01:10:19,300 the current selection to the screen. 1292 01:10:19,300 --> 01:10:21,820 1293 01:10:21,820 --> 01:10:25,060 Any questions as to how a selection sort of works? 1294 01:10:25,060 --> 01:10:29,740 1295 01:10:29,740 --> 01:10:35,260 Notice here, if we press Return, if our selection is being updated, 1296 01:10:35,260 --> 01:10:40,450 self.items at self.currentSelection.onSelect. 1297 01:10:40,450 --> 01:10:44,680 So it's expected that that item will have an onSelect function, which 1298 01:10:44,680 --> 01:10:47,560 is that callback function. 1299 01:10:47,560 --> 01:10:50,259 OK, and lastly, we'll take a look at the menu. 1300 01:10:50,259 --> 01:10:52,300 And then we'll finally take a look at the battle, 1301 01:10:52,300 --> 01:10:55,420 which is where sort of everything kind of comes together with all of this. 1302 01:10:55,420 --> 01:10:56,810 And that'll be it. 1303 01:10:56,810 --> 01:10:59,600 And then we'll talk about the assignment. 1304 01:10:59,600 --> 01:11:01,660 So the menu is a panel and a selection together. 1305 01:11:01,660 --> 01:11:05,770 That's the gist behind what a menu is in this game. 1306 01:11:05,770 --> 01:11:07,930 You can define a menu to be a lot of things, 1307 01:11:07,930 --> 01:11:11,620 and you can get a lot more complicated with a menu, but in this example, 1308 01:11:11,620 --> 01:11:15,190 in this implementation, we're just saying a menu is a selection 1309 01:11:15,190 --> 01:11:17,950 and a panel put together as one item. 1310 01:11:17,950 --> 01:11:24,810 And we've seen it in the game, [? if we're ?] going to run it. 1311 01:11:24,810 --> 01:11:26,910 That's just a text box. 1312 01:11:26,910 --> 01:11:28,557 Going to look for a battle. 1313 01:11:28,557 --> 01:11:32,050 1314 01:11:32,050 --> 01:11:33,077 OK, so here's a battle. 1315 01:11:33,077 --> 01:11:35,410 That's just an empty panel at the bottom, regular panel, 1316 01:11:35,410 --> 01:11:36,410 but now it's a text box. 1317 01:11:36,410 --> 01:11:38,710 We push the text box onto the stack. 1318 01:11:38,710 --> 01:11:40,840 Push another text box onto the stack. 1319 01:11:40,840 --> 01:11:42,710 And so this is a menu right here. 1320 01:11:42,710 --> 01:11:45,910 Notice that there is a cursor and there's 1321 01:11:45,910 --> 01:11:47,890 a selection embedded within a panel. 1322 01:11:47,890 --> 01:11:50,380 And each of those items, the fight and the run, 1323 01:11:50,380 --> 01:11:54,440 those have a callback associated with them. 1324 01:11:54,440 --> 01:11:56,950 The purpose of the fight callback is to trigger a new state 1325 01:11:56,950 --> 01:12:02,830 where the two Pokemon asynchronously attack each other, in chain behavior 1326 01:12:02,830 --> 01:12:03,760 one after the other. 1327 01:12:03,760 --> 01:12:07,720 And then run pushes a dialogue, then pushes a fade state, 1328 01:12:07,720 --> 01:12:11,650 then pops both of them, and then pushes a fade out state 1329 01:12:11,650 --> 01:12:13,330 and puts us back to the play state. 1330 01:12:13,330 --> 01:12:15,330 So that's effectively what's going on and that's 1331 01:12:15,330 --> 01:12:18,130 an example of what the menu looked like. 1332 01:12:18,130 --> 01:12:21,970 And so a menu, just a selection with a panel put together. 1333 01:12:21,970 --> 01:12:26,650 When we draw the menu, we draw the panel and then the selection. 1334 01:12:26,650 --> 01:12:29,860 And then when we update the menu, we only update the selection, 1335 01:12:29,860 --> 01:12:32,305 because that's all we care about. 1336 01:12:32,305 --> 01:12:34,060 And that's basically it. 1337 01:12:34,060 --> 01:12:37,810 And so the menu itself will get a def, that def 1338 01:12:37,810 --> 01:12:41,362 should have items, that items will get passed to the selection. 1339 01:12:41,362 --> 01:12:44,140 1340 01:12:44,140 --> 01:12:46,105 That's pretty much, that's it for the-- 1341 01:12:46,105 --> 01:12:47,580 oh, progress bar as well. 1342 01:12:47,580 --> 01:12:51,440 We'll look at progress bars when we get to the actual battle state. 1343 01:12:51,440 --> 01:12:55,390 So now, let's take a look at a few of the classes and data structures 1344 01:12:55,390 --> 01:12:57,800 that are pertinent to the Pokemon themselves. 1345 01:12:57,800 --> 01:13:00,670 So if you look at party as are first class, very 1346 01:13:00,670 --> 01:13:03,250 simple class, literally just this-- 1347 01:13:03,250 --> 01:13:07,060 self.pokemon is def.pokemon is just a container at this point. 1348 01:13:07,060 --> 01:13:09,970 You can take this-- 1349 01:13:09,970 --> 01:13:12,640 I mean, even in I think a fully fleshed game, 1350 01:13:12,640 --> 01:13:15,850 you wouldn't really need much more than just this. 1351 01:13:15,850 --> 01:13:18,230 But if you needed to expand upon this idea at all 1352 01:13:18,230 --> 01:13:21,700 and you know preserve metadata that exists for the party, 1353 01:13:21,700 --> 01:13:24,340 this would be a perfect way to do it. 1354 01:13:24,340 --> 01:13:31,390 The actual pokemon class itself is not a whole lot more than effectively 1355 01:13:31,390 --> 01:13:33,400 a bunch of stats. 1356 01:13:33,400 --> 01:13:36,240 And that's a lot of what an RPG is. 1357 01:13:36,240 --> 01:13:38,876 This genre is-- it's mostly just numbers. 1358 01:13:38,876 --> 01:13:40,750 You're just comparing numbers against numbers 1359 01:13:40,750 --> 01:13:42,640 and then adding a roll of the dice. 1360 01:13:42,640 --> 01:13:46,690 That's effectively, that's what Dungeons & Dragons, a lot of it is. 1361 01:13:46,690 --> 01:13:47,696 And that's-- yes? 1362 01:13:47,696 --> 01:13:49,630 AUDIENCE: Would it make more sense to store 1363 01:13:49,630 --> 01:13:57,100 just delta per level and your initial one, so you can have fewer variables? 1364 01:13:57,100 --> 01:13:58,460 SPEAKER 1: Say it one more time. 1365 01:13:58,460 --> 01:14:00,376 AUDIENCE: Wouldn't it make more sense, instead 1366 01:14:00,376 --> 01:14:03,150 of storing your HP and everything for each level 1367 01:14:03,150 --> 01:14:06,490 to store your initial stats in each area, 1368 01:14:06,490 --> 01:14:09,990 and how much you would go up per level. 1369 01:14:09,990 --> 01:14:14,080 SPEAKER 1: Would it make more sense to store the amount that you go up 1370 01:14:14,080 --> 01:14:16,450 per level for your Pokemon? 1371 01:14:16,450 --> 01:14:19,070 Yes, that is what we're doing. 1372 01:14:19,070 --> 01:14:20,800 So we have a base-- 1373 01:14:20,800 --> 01:14:24,910 so here's how the split works for the stats in this case, right? 1374 01:14:24,910 --> 01:14:28,860 We have base HP, base attack, base defense, and base speed. 1375 01:14:28,860 --> 01:14:31,600 A level 1 Pokemon has-- a level 0 Pokemon 1376 01:14:31,600 --> 01:14:35,800 has these stats of this species, right? 1377 01:14:35,800 --> 01:14:39,430 Every Bamboon or whatever Pokemon that we choose 1378 01:14:39,430 --> 01:14:42,820 will have whatever we've allocated it to be it's base HP, 1379 01:14:42,820 --> 01:14:45,280 base, attack, base defense, base speed. 1380 01:14:45,280 --> 01:14:50,500 And then the thing about Pokemon and I mean, a lot of RPGs 1381 01:14:50,500 --> 01:14:52,660 will sort of do this thing, but we need some way 1382 01:14:52,660 --> 01:14:58,420 of leveling up the Pokemon in an necessarily non-deterministic way. 1383 01:14:58,420 --> 01:15:02,782 Like two Piggies that level up may not have the same stats, right? 1384 01:15:02,782 --> 01:15:04,990 One might have slightly higher attack than the other, 1385 01:15:04,990 --> 01:15:07,240 one might have slightly higher defense than the other. 1386 01:15:07,240 --> 01:15:11,020 We do this using what's called an IV, and that's what Pokemon itself does. 1387 01:15:11,020 --> 01:15:13,450 And it's short for individual value, this is sort of 1388 01:15:13,450 --> 01:15:16,810 like the DNA of your Pokemon, right? 1389 01:15:16,810 --> 01:15:23,420 So this HP IV is separate from your base attack, base speed, base et cetera. 1390 01:15:23,420 --> 01:15:26,890 And this basically, it gets compared against a dice roll every time 1391 01:15:26,890 --> 01:15:28,480 you level up three times. 1392 01:15:28,480 --> 01:15:31,610 1393 01:15:31,610 --> 01:15:34,330 And this is how I've programmed it, it's not necessarily 1394 01:15:34,330 --> 01:15:38,890 how Pokemon itself does it, but you will roll a dice six times, 1395 01:15:38,890 --> 01:15:42,760 or three times, one through six like a normal die. 1396 01:15:42,760 --> 01:15:49,630 And you'll look to see if that roll is greater than your IV, right? 1397 01:15:49,630 --> 01:15:55,990 Or it'll check to see whether your IV is less than or equal to that dice roll. 1398 01:15:55,990 --> 01:15:57,560 And if it is-- 1399 01:15:57,560 --> 01:16:00,640 or sorry, if it's greater than or equal to that dice roll. 1400 01:16:00,640 --> 01:16:06,580 And if it is, it will increment that stat by 1 for those three dice rolls. 1401 01:16:06,580 --> 01:16:11,500 So you can get up to three more, or you can increase the stat 1402 01:16:11,500 --> 01:16:14,200 by up to three times per level. 1403 01:16:14,200 --> 01:16:16,990 But you can only have an IV up to five. 1404 01:16:16,990 --> 01:16:23,056 So you're rolling against a six, and you will occasionally not roll a 6. 1405 01:16:23,056 --> 01:16:27,970 It checks to see whether or not the IV is 1406 01:16:27,970 --> 01:16:29,800 greater than or equal to the dice roll. 1407 01:16:29,800 --> 01:16:32,650 And if it's not greater than or equal to the dice roll in the event 1408 01:16:32,650 --> 01:16:36,430 that it is a six, or if the IV is up to a four 1409 01:16:36,430 --> 01:16:39,700 for example, which means a five or six will go against it, 1410 01:16:39,700 --> 01:16:41,770 then it will not get a stat increase. 1411 01:16:41,770 --> 01:16:44,920 And this is a sort of simple way of implementing this DNA based system. 1412 01:16:44,920 --> 01:16:47,320 It's randomized, but it's a weighted, right? 1413 01:16:47,320 --> 01:16:50,050 If you have a higher IV, you have a higher likelihood 1414 01:16:50,050 --> 01:16:53,350 of being greater than or equal to the dice roll. 1415 01:16:53,350 --> 01:16:55,960 And so that's how we implement stat increases. 1416 01:16:55,960 --> 01:17:03,130 And then we need a way of keeping track of what our stats are, 1417 01:17:03,130 --> 01:17:04,660 like our actual stats. 1418 01:17:04,660 --> 01:17:07,330 So our actual HP, our actual attack, our actual defense, 1419 01:17:07,330 --> 01:17:10,165 and actual speed that's been calculated level by level, 1420 01:17:10,165 --> 01:17:11,665 we need a way to keep track of that. 1421 01:17:11,665 --> 01:17:14,190 We need level, we need our current XP, and then 1422 01:17:14,190 --> 01:17:15,940 we need our-- and the amount of XP to gain 1423 01:17:15,940 --> 01:17:19,270 a level, which will get higher and higher per level, as you can see here, 1424 01:17:19,270 --> 01:17:24,520 because it takes in the self.level times self.level. 1425 01:17:24,520 --> 01:17:28,150 And then it multiplies that by five times 0.75. 1426 01:17:28,150 --> 01:17:29,470 And then your current HP. 1427 01:17:29,470 --> 01:17:32,340 1428 01:17:32,340 --> 01:17:38,230 So we're really not storing our value level by level, 1429 01:17:38,230 --> 01:17:42,220 we need the base because we need to know what our base was. 1430 01:17:42,220 --> 01:17:46,910 I mean, we could effectively globally reference these variables, 1431 01:17:46,910 --> 01:17:49,810 but it's minor efficiency gains at that point. 1432 01:17:49,810 --> 01:17:52,300 But we need the IVs and we need the-- 1433 01:17:52,300 --> 01:17:56,050 I mean, we need a reference to the IVs, we need a reference to the base HP, 1434 01:17:56,050 --> 01:18:01,750 and we need to keep track of whatever our actual stats are, 1435 01:18:01,750 --> 01:18:04,210 and then our current HP always, because our current HP 1436 01:18:04,210 --> 01:18:07,010 can differ from our actual HP. 1437 01:18:07,010 --> 01:18:10,690 And in the actual game, you can have your attack, defense, 1438 01:18:10,690 --> 01:18:13,960 and speed also vary match by match, because you 1439 01:18:13,960 --> 01:18:17,770 have moves that lower your speed, lower your attack, 1440 01:18:17,770 --> 01:18:19,450 lower your defense, et cetera. 1441 01:18:19,450 --> 01:18:21,200 In this case, we haven't implemented that, 1442 01:18:21,200 --> 01:18:23,459 so we don't have a current attack, current defense. 1443 01:18:23,459 --> 01:18:26,500 But in a more complete implementation, you would have that sort of thing. 1444 01:18:26,500 --> 01:18:28,125 Does that sort of answer your question? 1445 01:18:28,125 --> 01:18:29,290 Is that in the right vain? 1446 01:18:29,290 --> 01:18:29,790 OK. 1447 01:18:29,790 --> 01:18:32,390 1448 01:18:32,390 --> 01:18:35,020 And so here's the level up code. 1449 01:18:35,020 --> 01:18:38,200 So like I said, three dice rolls, one to three. 1450 01:18:38,200 --> 01:18:43,450 If six is less than or equal to our IV, so it could be a six, in which case, 1451 01:18:43,450 --> 01:18:47,160 it would be greater than what are max IV could possibly be. 1452 01:18:47,160 --> 01:18:52,150 IVs range from one to five, but if it's less than or equal to that IV, 1453 01:18:52,150 --> 01:18:54,250 then we're going to consider that a stat increase. 1454 01:18:54,250 --> 01:19:03,490 It's a weighted odd to determine whether or not we get a stat boost. 1455 01:19:03,490 --> 01:19:07,340 And it does this for every stat, and then it returns all of the increases. 1456 01:19:07,340 --> 01:19:11,590 And this is relevant, this line 95 for a return HP increase, 1457 01:19:11,590 --> 01:19:13,540 return attack increase, defense increase. 1458 01:19:13,540 --> 01:19:16,690 This will be relevant for assignment 7, because your goal is 1459 01:19:16,690 --> 01:19:20,650 to take these increases and actually display them to this user in the battle 1460 01:19:20,650 --> 01:19:23,560 state when he gets a victory, or he or she gets a victory 1461 01:19:23,560 --> 01:19:25,310 and has gained a level. 1462 01:19:25,310 --> 01:19:29,740 You will display a menu with a selection that has all of these things, 1463 01:19:29,740 --> 01:19:30,970 and you'll need this value. 1464 01:19:30,970 --> 01:19:36,550 So it returns these values here, and you'll be calling this function any way 1465 01:19:36,550 --> 01:19:39,390 from your battle state stats level up. 1466 01:19:39,390 --> 01:19:45,310 Or we'll be calling level up rather, which returns self stats level up. 1467 01:19:45,310 --> 01:19:47,630 And that's all a Pokemon is. 1468 01:19:47,630 --> 01:19:50,700 It's effectively mostly a data structure. 1469 01:19:50,700 --> 01:19:57,640 And we use this in our battles to throw dice effectively back and forth, 1470 01:19:57,640 --> 01:20:05,650 and have a victor and a loser, and then gain XP and gain levels that way. 1471 01:20:05,650 --> 01:20:09,490 So any questions as to how a Pokemon object class works? 1472 01:20:09,490 --> 01:20:12,370 1473 01:20:12,370 --> 01:20:13,962 Cool. 1474 01:20:13,962 --> 01:20:16,670 We'll take a quick look at what the actual definitions look like, 1475 01:20:16,670 --> 01:20:18,240 which you can probably take a guess. 1476 01:20:18,240 --> 01:20:20,870 It's very simple, just key names. 1477 01:20:20,870 --> 01:20:24,300 And then we have the actual name, we have the sprite names, 1478 01:20:24,300 --> 01:20:26,810 we have the HP, attack, defense-- 1479 01:20:26,810 --> 01:20:29,390 all the things that get put into the actual object, 1480 01:20:29,390 --> 01:20:31,700 they need a reference to in the definitions. 1481 01:20:31,700 --> 01:20:34,101 And so Pokemon ultimately are just this, they're 1482 01:20:34,101 --> 01:20:37,100 just data, right, which is what we talked about in a prior lecture, data 1483 01:20:37,100 --> 01:20:38,210 driven design. 1484 01:20:38,210 --> 01:20:40,220 The more you can take all of your Pokemon 1485 01:20:40,220 --> 01:20:44,210 and make them into, or anything, Pokemon or any object, 1486 01:20:44,210 --> 01:20:47,270 and turn it into an easy to write data structure like this, 1487 01:20:47,270 --> 01:20:49,040 the easier it is for you to add more. 1488 01:20:49,040 --> 01:20:53,304 We could easily add, it wouldn't take too long to create 150 of these. 1489 01:20:53,304 --> 01:20:55,220 I mean, they wouldn't be all that interesting, 1490 01:20:55,220 --> 01:20:58,200 because we don't have moves implemented yet. 1491 01:20:58,200 --> 01:21:03,800 But in an ideal world, we'd find a way to also model moves as data, 1492 01:21:03,800 --> 01:21:07,610 and therefore, you can just link moves to your data structure, 1493 01:21:07,610 --> 01:21:09,410 to your Pokemon object like this. 1494 01:21:09,410 --> 01:21:10,936 Yes Tony, did you have a question? 1495 01:21:10,936 --> 01:21:13,310 AUDIENCE: Well, I just wanted to mention that the paradox 1496 01:21:13,310 --> 01:21:15,150 games are very good about that. 1497 01:21:15,150 --> 01:21:16,832 [INAUDIBLE] 1498 01:21:16,832 --> 01:21:18,290 SPEAKER 1: Oh, like Crusader Kings? 1499 01:21:18,290 --> 01:21:18,915 AUDIENCE: Yeah. 1500 01:21:18,915 --> 01:21:21,960 1501 01:21:21,960 --> 01:21:25,590 SPEAKER 1: The comment was Paradox Games are very good about data driven design. 1502 01:21:25,590 --> 01:21:28,417 I'm assuming you've dug through their files? 1503 01:21:28,417 --> 01:21:30,250 AUDIENCE: To some extent, and also it's just 1504 01:21:30,250 --> 01:21:33,927 if you play their games for awhile, it's everywhere, like to the extent 1505 01:21:33,927 --> 01:21:36,260 that sometimes on the Wiki, they put the source code up. 1506 01:21:36,260 --> 01:21:37,880 SPEAKER 1: Oh, yeah. 1507 01:21:37,880 --> 01:21:40,340 Yeah, no, it's just good game design. 1508 01:21:40,340 --> 01:21:41,880 Ultimately, if you want to-- 1509 01:21:41,880 --> 01:21:44,660 and their games are large, they have a lot of content. 1510 01:21:44,660 --> 01:21:46,901 If you want to have a lot of content in your game, 1511 01:21:46,901 --> 01:21:49,400 you need to find a way to take the burden off the programmer 1512 01:21:49,400 --> 01:21:51,316 and put it onto the designer, or at least make 1513 01:21:51,316 --> 01:21:53,650 it easier for the programmer, because making source code 1514 01:21:53,650 --> 01:21:56,899 and debugging source code all day long, especially for very complicated things 1515 01:21:56,899 --> 01:21:57,740 is not easy. 1516 01:21:57,740 --> 01:22:01,100 And it's ultimately not a desired thing to do, right? 1517 01:22:01,100 --> 01:22:04,610 It's a lot easier for me to whip up a new creature in 10 lines of code 1518 01:22:04,610 --> 01:22:10,700 here and feel good about it than hard coding a lot of these sort of things, 1519 01:22:10,700 --> 01:22:11,780 right? 1520 01:22:11,780 --> 01:22:17,000 So shifting as much of it to data as you possibly can should be your end goal. 1521 01:22:17,000 --> 01:22:19,670 So that's what Pokemon defs look like. 1522 01:22:19,670 --> 01:22:21,565 Before we get into the actual battle, we want 1523 01:22:21,565 --> 01:22:23,420 to take a look at what a battle sprite is. 1524 01:22:23,420 --> 01:22:27,470 So a battle sprite is what was rendering onto the screen, right? 1525 01:22:27,470 --> 01:22:29,720 So we take a look here. 1526 01:22:29,720 --> 01:22:33,920 That's not a battle sprite, but almost a battle sprite. 1527 01:22:33,920 --> 01:22:35,900 That was just a texture. 1528 01:22:35,900 --> 01:22:43,160 So if we get into a battle, slowly but surely. 1529 01:22:43,160 --> 01:22:46,850 All right, so these are battle sprites, and they don't look much different 1530 01:22:46,850 --> 01:22:48,980 than a regular sprite, and they're not that much 1531 01:22:48,980 --> 01:22:50,630 different than a regular sprite. 1532 01:22:50,630 --> 01:22:55,940 But they have some functionality that's important, mainly that functionality 1533 01:22:55,940 --> 01:23:01,760 where one is flashing, and then one was being opaque, right? 1534 01:23:01,760 --> 01:23:07,730 So in order to do both of those things, we need to store some sort of data 1535 01:23:07,730 --> 01:23:09,850 within our sprite, right? 1536 01:23:09,850 --> 01:23:10,964 Yes? 1537 01:23:10,964 --> 01:23:14,470 AUDIENCE: Zelda for the invulnerability flashing. 1538 01:23:14,470 --> 01:23:15,470 SPEAKER 1: Yes, exactly. 1539 01:23:15,470 --> 01:23:18,050 For what we used in Zelda for the invulnerability flashing. 1540 01:23:18,050 --> 01:23:24,560 For the enemy, or I should say, for whoever is getting attacked, yes. 1541 01:23:24,560 --> 01:23:28,080 They are getting an opacity flag stored. 1542 01:23:28,080 --> 01:23:32,730 They have an opacity flag stored in their object that we can tween, right, 1543 01:23:32,730 --> 01:23:34,730 we can tween on and off over the course of time. 1544 01:23:34,730 --> 01:23:38,074 That's what we did with the entity in Zelda when it took damage. 1545 01:23:38,074 --> 01:23:40,615 And we set it to invulnerable, and while it was invulnerable, 1546 01:23:40,615 --> 01:23:42,320 it was flashing on and off. 1547 01:23:42,320 --> 01:23:47,930 But we can't necessarily do that with the sprite that's blinking white, 1548 01:23:47,930 --> 01:23:52,970 because there's not really a like white flag, right? 1549 01:23:52,970 --> 01:23:55,760 We can't make something completely white with just a flag. 1550 01:23:55,760 --> 01:23:59,060 That's something that we actually need to use a shader for. 1551 01:23:59,060 --> 01:24:03,200 And so a shader, and we're not going to get into too much detail about this, 1552 01:24:03,200 --> 01:24:07,520 shaders are pretty complex, a little arcane at first. 1553 01:24:07,520 --> 01:24:10,340 But what they are is effectively a little program that 1554 01:24:10,340 --> 01:24:13,520 runs on your graphics card, and that looks at when you're drawing something, 1555 01:24:13,520 --> 01:24:16,400 it looks at every pixel depending on what kind of shader you're doing. 1556 01:24:16,400 --> 01:24:19,130 But for the sake of this demonstration, we'll look at every pixel 1557 01:24:19,130 --> 01:24:23,510 that you're drawing to the screen, and perform some sort of function 1558 01:24:23,510 --> 01:24:27,890 on that pixel, and produce a new value, right? 1559 01:24:27,890 --> 01:24:31,610 And this is how you get a lot of really crazy awesome things to happen, 1560 01:24:31,610 --> 01:24:34,350 but it can be pretty insane. 1561 01:24:34,350 --> 01:24:39,482 Shader Toy, I think is the website that has a ton of really cool-- 1562 01:24:39,482 --> 01:24:42,440 I'm not going to pull it up now, just 'cause I don't remember the name, 1563 01:24:42,440 --> 01:24:44,000 I believe it's shader toy. 1564 01:24:44,000 --> 01:24:47,041 There's a website where people post all the shaders that they've written, 1565 01:24:47,041 --> 01:24:49,460 and you can see a lot of really crazy stuff, things 1566 01:24:49,460 --> 01:24:53,720 that you would never imagined were possible with just code like this 1567 01:24:53,720 --> 01:24:56,150 effectively, looking at positions of pixels 1568 01:24:56,150 --> 01:24:58,670 and [? pictures ?] on the screen and whatnot. 1569 01:24:58,670 --> 01:25:05,450 But effectively what this does, this is a white shader, the goal of this shader 1570 01:25:05,450 --> 01:25:07,490 is to just turn a sprite completely white. 1571 01:25:07,490 --> 01:25:10,610 That's all the goal of this shader is. 1572 01:25:10,610 --> 01:25:14,390 So it gets a float called white factor, which [? you'd ?] say here. 1573 01:25:14,390 --> 01:25:17,240 And then white factor effectively is just 1574 01:25:17,240 --> 01:25:20,810 going to be summed onto whatever the RGB is 1575 01:25:20,810 --> 01:25:25,350 of that pixel, whatever pixel that we're drawing when the shader is active. 1576 01:25:25,350 --> 01:25:29,990 What that has the effect of doing is, white factor, if it's equal to 1. 1577 01:25:29,990 --> 01:25:32,720 Here's the thing about shaders and a lot of this stuff, 1578 01:25:32,720 --> 01:25:35,240 a lot of the data structures within shaders 1579 01:25:35,240 --> 01:25:37,890 are based on floats that are from zero to one. 1580 01:25:37,890 --> 01:25:43,790 So if we assign the RGB of something to a vec 3 that's 1, which is 111, 1581 01:25:43,790 --> 01:25:46,520 that's going to be 255, 255, 255. 1582 01:25:46,520 --> 01:25:50,660 Therefore, that pixels RGB is white, pure white, right? 1583 01:25:50,660 --> 01:25:58,460 And so what we're doing here is on our battle sprite, self.blinking 1584 01:25:58,460 --> 01:26:01,775 and one or zero, remember, that's the LUA [? turnerri ?] operations. 1585 01:26:01,775 --> 01:26:07,070 So we're saying, if self.blinking is true, one else zero. 1586 01:26:07,070 --> 01:26:15,860 So send our shader white factor based on whatever value self.blinking is. 1587 01:26:15,860 --> 01:26:19,700 And so that will have the effect of the shader getting a one or a zero, 1588 01:26:19,700 --> 01:26:22,400 and adding a one or a zero to the RGB of that sprite. 1589 01:26:22,400 --> 01:26:25,670 And if blinking is set to true, the sprite's 1590 01:26:25,670 --> 01:26:29,270 going to basically be drawn every pixel at 255, 255, 255. 1591 01:26:29,270 --> 01:26:33,500 Otherwise, it'll get drawn with whatever that image's pixel value is 1592 01:26:33,500 --> 01:26:35,085 at that position. 1593 01:26:35,085 --> 01:26:37,220 Does that makes sense? 1594 01:26:37,220 --> 01:26:37,907 OK. 1595 01:26:37,907 --> 01:26:39,740 The syntax is a little bit weird, but that's 1596 01:26:39,740 --> 01:26:42,020 what's happening here in this shader. 1597 01:26:42,020 --> 01:26:44,540 And there's a link here where I found the shader, 1598 01:26:44,540 --> 01:26:47,960 but it's a very simple, very simple shader, 1599 01:26:47,960 --> 01:26:50,840 probably like one of the simplest shaders you could write. 1600 01:26:50,840 --> 01:26:55,460 But it's a great example of what you can do with a shader, and pretty simply. 1601 01:26:55,460 --> 01:26:59,210 And it's nice, because you can take like texture coordinates and do math 1602 01:26:59,210 --> 01:27:02,060 based on that, or pixel coordinates and do math based on that. 1603 01:27:02,060 --> 01:27:04,910 You can pass in like a sine function for example, in your file, 1604 01:27:04,910 --> 01:27:09,379 and have that sine function perform work on like RG or B value of your sprite 1605 01:27:09,379 --> 01:27:10,670 and do all kinds of cool stuff. 1606 01:27:10,670 --> 01:27:14,154 It's really neat, like the possibilities are limitless with shaders. 1607 01:27:14,154 --> 01:27:16,070 But that's how we get it to blink, because you 1608 01:27:16,070 --> 01:27:18,410 can't do that outside of this-- 1609 01:27:18,410 --> 01:27:21,830 I mean, there's probably some weird way could get it to work as well, 1610 01:27:21,830 --> 01:27:28,820 but this is probably the simplest way we can get our sprites blinking white. 1611 01:27:28,820 --> 01:27:36,890 And so self.blinking just gets a timer.every0.1 or whatever. 1612 01:27:36,890 --> 01:27:41,010 We'll actually see that in the attack state. 1613 01:27:41,010 --> 01:27:45,350 But that'll flick to self.blinking between true and false. 1614 01:27:45,350 --> 01:27:49,150 It'll negate itself over and over again. 1615 01:27:49,150 --> 01:27:51,590 All right, so that's the battle sprite. 1616 01:27:51,590 --> 01:27:56,180 Last thing we'll look at is another extremely simple class, opponent. 1617 01:27:56,180 --> 01:27:59,370 All the opponent is is it has a party, that's it. 1618 01:27:59,370 --> 01:28:01,370 But in a fully fleshed game, your opponent 1619 01:28:01,370 --> 01:28:03,680 might have a like trainer sprite. 1620 01:28:03,680 --> 01:28:06,185 A message that it says, like a full party 1621 01:28:06,185 --> 01:28:08,810 of Pokemon, a gold value that will give you when you defeat it, 1622 01:28:08,810 --> 01:28:09,643 all kinds of things. 1623 01:28:09,643 --> 01:28:12,020 But it's here just as a simple illustration. 1624 01:28:12,020 --> 01:28:12,520 Yeah? 1625 01:28:12,520 --> 01:28:14,925 AUDIENCE: [INAUDIBLE] put a method for on defeat 1626 01:28:14,925 --> 01:28:17,540 if you want to maybe have it kind of collapse 1627 01:28:17,540 --> 01:28:19,266 the room or something like that. 1628 01:28:19,266 --> 01:28:21,260 That would be another thing that you could do. 1629 01:28:21,260 --> 01:28:22,260 SPEAKER 1: Oh, a method? 1630 01:28:22,260 --> 01:28:26,780 Yeah, we can associate a method with an opponent called on defeat, 1631 01:28:26,780 --> 01:28:29,959 or whatnot that will do arbitrary things, collapse the room, 1632 01:28:29,959 --> 01:28:30,500 or otherwise. 1633 01:28:30,500 --> 01:28:31,910 Yes, absolutely. 1634 01:28:31,910 --> 01:28:34,250 Or even push a new state, like to like teleport 1635 01:28:34,250 --> 01:28:36,299 us to a new location in the world map. 1636 01:28:36,299 --> 01:28:38,090 Maybe we like cleared the elite four and we 1637 01:28:38,090 --> 01:28:42,590 want to get teleported to like the end credits, exactly. 1638 01:28:42,590 --> 01:28:45,150 Limitless possibility. 1639 01:28:45,150 --> 01:28:48,860 So let's go ahead and take a look now while we have just like 20 more minutes 1640 01:28:48,860 --> 01:28:49,390 or so left. 1641 01:28:49,390 --> 01:28:51,764 We'll take a look at the battle state, because the battle 1642 01:28:51,764 --> 01:28:56,930 state and the states that they're in are probably the more complicated side 1643 01:28:56,930 --> 01:28:59,340 of how this works. 1644 01:28:59,340 --> 01:29:03,282 So a battle state, we have a player, we have a bottom panel, the bottom panel 1645 01:29:03,282 --> 01:29:05,240 for when we start the state just for that part, 1646 01:29:05,240 --> 01:29:08,720 but otherwise, we're always pushing things onto it. 1647 01:29:08,720 --> 01:29:14,200 Whether we've started the battle or not, because when we are fading in-- 1648 01:29:14,200 --> 01:29:16,700 sorry, yeah. 1649 01:29:16,700 --> 01:29:28,710 Because when we initialize this state, we also push a fadeout state onto it. 1650 01:29:28,710 --> 01:29:32,930 But we don't want to trigger the tween of the Pokemon sliding 1651 01:29:32,930 --> 01:29:35,360 from left to right until after that state gets popped. 1652 01:29:35,360 --> 01:29:38,600 So we have a flag here, which will get set to true on the very first update 1653 01:29:38,600 --> 01:29:39,500 iteration. 1654 01:29:39,500 --> 01:29:41,450 And then when that gets set to true, we'll 1655 01:29:41,450 --> 01:29:44,180 actually tween the Pokemon going left to right, 1656 01:29:44,180 --> 01:29:46,610 and kick off all the other sort of asynchronous processes 1657 01:29:46,610 --> 01:29:50,250 that exist thereafter. 1658 01:29:50,250 --> 01:29:56,330 But let's look at the battle one more time just to see what's going on. 1659 01:29:56,330 --> 01:29:58,940 So I'm going to walk until I get into a battle. 1660 01:29:58,940 --> 01:29:59,910 OK, we got a battle. 1661 01:29:59,910 --> 01:30:05,200 So notice here, the fade in happens as soon as the-- 1662 01:30:05,200 --> 01:30:08,160 the slide in happens as soon as the fade starts, right, 1663 01:30:08,160 --> 01:30:10,402 as soon as the fade finishes, I should say. 1664 01:30:10,402 --> 01:30:12,360 We get a message popped onto the screen, right? 1665 01:30:12,360 --> 01:30:14,550 It says a wild X appears. 1666 01:30:14,550 --> 01:30:16,040 Right, that's the enemy Pokemon. 1667 01:30:16,040 --> 01:30:17,370 We hit Enter. 1668 01:30:17,370 --> 01:30:19,140 Turn this down a little bit. 1669 01:30:19,140 --> 01:30:21,930 We hit Enter, and then we pop another-- 1670 01:30:21,930 --> 01:30:24,600 push another state onto the stack, another battle message, which 1671 01:30:24,600 --> 01:30:26,100 is very similar to a dialog state. 1672 01:30:26,100 --> 01:30:30,030 Says go our Pokemon. 1673 01:30:30,030 --> 01:30:34,080 And then we push a menu onto the screen, right? 1674 01:30:34,080 --> 01:30:37,190 We've got a menu that says, fight or run, a selection. 1675 01:30:37,190 --> 01:30:39,230 It's a menu, which has a selection. 1676 01:30:39,230 --> 01:30:42,420 And then now, this is the top of the stack, right? 1677 01:30:42,420 --> 01:30:44,470 So it's the only thing getting input. 1678 01:30:44,470 --> 01:30:48,096 Everything else is rendering beneath it, but nothing's getting input. 1679 01:30:48,096 --> 01:30:49,970 So we have the option to either fight or run. 1680 01:30:49,970 --> 01:30:51,170 Let's say we fight. 1681 01:30:51,170 --> 01:30:55,802 We fight, we got a new state now, we're in an attack state. 1682 01:30:55,802 --> 01:30:57,010 Several things just happened. 1683 01:30:57,010 --> 01:31:01,880 So what happens as soon as we kick off the attack state? 1684 01:31:01,880 --> 01:31:02,380 Yeah? 1685 01:31:02,380 --> 01:31:04,745 AUDIENCE: You get a text box saying, x attacked y. 1686 01:31:04,745 --> 01:31:06,870 SPEAKER 1: Yep, so the first thing we have happened 1687 01:31:06,870 --> 01:31:10,385 is, a text box that says, x attacked y, where 1688 01:31:10,385 --> 01:31:12,510 it could be either us or the opponent, because it's 1689 01:31:12,510 --> 01:31:14,700 based on whoever has the higher speed. 1690 01:31:14,700 --> 01:31:16,612 And then what happens next? 1691 01:31:16,612 --> 01:31:17,950 AUDIENCE: [INAUDIBLE]. 1692 01:31:17,950 --> 01:31:19,140 SPEAKER 1: Well, it does. 1693 01:31:19,140 --> 01:31:21,600 So let's take a look at it right now and tell 1694 01:31:21,600 --> 01:31:24,750 me what exactly happens as soon as the text box pops up. 1695 01:31:24,750 --> 01:31:27,750 1696 01:31:27,750 --> 01:31:30,940 So what were the pieces that happened there? 1697 01:31:30,940 --> 01:31:31,800 AUDIENCE: Flash. 1698 01:31:31,800 --> 01:31:34,260 SPEAKER 1: OK, so the attacker flashes white, 1699 01:31:34,260 --> 01:31:36,220 right, which is the shader that we looked at. 1700 01:31:36,220 --> 01:31:38,080 That's the shader blinking on and off. 1701 01:31:38,080 --> 01:31:41,970 There's some timer that says, every 0.1 seconds, blink on or off. 1702 01:31:41,970 --> 01:31:43,610 And then what happens? 1703 01:31:43,610 --> 01:31:46,660 AUDIENCE: Then the damage is dealt. [INAUDIBLE].. 1704 01:31:46,660 --> 01:31:50,220 SPEAKER 1: Well, damage is dealt, yes, but what happens visually as soon 1705 01:31:50,220 --> 01:31:53,669 as the white blinks? 1706 01:31:53,669 --> 01:31:54,960 AUDIENCE: The other one blinks. 1707 01:31:54,960 --> 01:31:56,293 SPEAKER 1: The other one blinks. 1708 01:31:56,293 --> 01:31:59,415 What's the other one blinking? 1709 01:31:59,415 --> 01:32:00,390 AUDIENCE: I'm not sure. 1710 01:32:00,390 --> 01:32:02,067 SPEAKER 1: So it's opacity, right? 1711 01:32:02,067 --> 01:32:05,150 So remember, we're doing the exact same thing we just did with that white, 1712 01:32:05,150 --> 01:32:08,900 with the blinking, but we're tweening every 0.1 seconds 1713 01:32:08,900 --> 01:32:11,750 the opacity of the defending Pokemon. 1714 01:32:11,750 --> 01:32:13,677 And then we take damage. 1715 01:32:13,677 --> 01:32:15,260 Then what happens when we take damage? 1716 01:32:15,260 --> 01:32:17,520 AUDIENCE: The reverse basically. 1717 01:32:17,520 --> 01:32:20,510 SPEAKER 1: Well, what gets animated when the thing takes damage? 1718 01:32:20,510 --> 01:32:22,880 We've animated the blinking, we've animated the opacity. 1719 01:32:22,880 --> 01:32:24,550 AUDIENCE: [INAUDIBLE]. 1720 01:32:24,550 --> 01:32:26,240 SPEAKER 1: The health bar drops, right? 1721 01:32:26,240 --> 01:32:28,100 So we're chaining several things together. 1722 01:32:28,100 --> 01:32:32,760 We're chaining-- first, we're doing them every 0.1 seconds for six times, 1723 01:32:32,760 --> 01:32:34,430 blink white. 1724 01:32:34,430 --> 01:32:37,982 Then blink the other thing opacity, right? 1725 01:32:37,982 --> 01:32:40,190 And we're playing sound effects at the same time too, 1726 01:32:40,190 --> 01:32:43,190 we're playing a sound effect for the attack, sound effect for the hit. 1727 01:32:43,190 --> 01:32:46,750 And then once that's finished, tween the health bar, right? 1728 01:32:46,750 --> 01:32:51,050 So we've modified the health of the defending Pokemon. 1729 01:32:51,050 --> 01:32:54,856 And then what happens after the first one, after that process is finished. 1730 01:32:54,856 --> 01:32:57,724 1731 01:32:57,724 --> 01:32:59,640 AUDIENCE: Repeat for the other side? 1732 01:32:59,640 --> 01:33:04,410 SPEAKER 1: Exactly, repeat the exact same thing, but for the other side. 1733 01:33:04,410 --> 01:33:06,530 But what are we doing in between each of those? 1734 01:33:06,530 --> 01:33:07,530 We have to do something. 1735 01:33:07,530 --> 01:33:08,730 AUDIENCE: Checking if somebody dies. 1736 01:33:08,730 --> 01:33:10,646 SPEAKER 1: Checking if somebody dies, exactly. 1737 01:33:10,646 --> 01:33:12,840 And if somebody dies-- 1738 01:33:12,840 --> 01:33:14,890 let's say we die, what happens? 1739 01:33:14,890 --> 01:33:16,710 AUDIENCE: [INAUDIBLE]. 1740 01:33:16,710 --> 01:33:19,140 SPEAKER 1: Well, we yeah, we go back to the play state. 1741 01:33:19,140 --> 01:33:22,170 We fade out to black, and then we go back to the play state. 1742 01:33:22,170 --> 01:33:24,536 What happens if we knock out the enemy? 1743 01:33:24,536 --> 01:33:25,894 AUDIENCE: Go to this screen. 1744 01:33:25,894 --> 01:33:28,060 SPEAKER 1: Exactly, and what happens on this screen? 1745 01:33:28,060 --> 01:33:29,750 So what's the first thing that happens? 1746 01:33:29,750 --> 01:33:32,387 Well, so recall, what happened when the Pokemon died? 1747 01:33:32,387 --> 01:33:32,970 What happened? 1748 01:33:32,970 --> 01:33:34,678 AUDIENCE: It fell off its platform thing. 1749 01:33:34,678 --> 01:33:39,060 SPEAKER 1: Exactly, so that's a tween probably, right, on his y value. 1750 01:33:39,060 --> 01:33:40,550 Then what happens? 1751 01:33:40,550 --> 01:33:42,270 AUDIENCE: [INAUDIBLE]. 1752 01:33:42,270 --> 01:33:46,120 SPEAKER 1: Exactly, we've pushed a battle message state onto the screen. 1753 01:33:46,120 --> 01:33:48,756 And then what happens when we press Enter? 1754 01:33:48,756 --> 01:33:50,301 AUDIENCE: [INAUDIBLE]. 1755 01:33:50,301 --> 01:33:52,050 SPEAKER 1: What just happened right there? 1756 01:33:52,050 --> 01:33:53,758 AUDIENCE: [INAUDIBLE] text box that says, 1757 01:33:53,758 --> 01:33:55,400 you earned whatever experience points. 1758 01:33:55,400 --> 01:33:57,645 Then you get your XP goes up. 1759 01:33:57,645 --> 01:33:59,751 And presumably, it checks if you leveled up. 1760 01:33:59,751 --> 01:34:00,750 SPEAKER 1: Yes, correct. 1761 01:34:00,750 --> 01:34:03,600 AUDIENCE: [INAUDIBLE] to level up. 1762 01:34:03,600 --> 01:34:05,610 SPEAKER 1: Exactly, so when push a dialogue 1763 01:34:05,610 --> 01:34:09,980 to the screen that says you've earned x experience points, the XP bar tweens, 1764 01:34:09,980 --> 01:34:10,620 right? 1765 01:34:10,620 --> 01:34:15,740 We've gone up to however our ratio of current XP to next level XP is. 1766 01:34:15,740 --> 01:34:19,780 We animate our text bar that way, or progress bar that way. 1767 01:34:19,780 --> 01:34:23,820 Then we push a fade in state, right, to white. 1768 01:34:23,820 --> 01:34:27,360 And then we have to pop everything off the stack, 1769 01:34:27,360 --> 01:34:32,417 and then push a fade out state to the top of the stack, 1770 01:34:32,417 --> 01:34:34,000 and then we're back to the play state. 1771 01:34:34,000 --> 01:34:41,610 But if we do level up, we need to play the right music, play the right sound, 1772 01:34:41,610 --> 01:34:45,370 and then part of the assignment will be actually, in that exact function, 1773 01:34:45,370 --> 01:34:48,432 you're going to need to add some behavior that will do what? 1774 01:34:48,432 --> 01:34:50,892 AUDIENCE: [INAUDIBLE] display the change basically, 1775 01:34:50,892 --> 01:34:51,720 and what the new one will be. 1776 01:34:51,720 --> 01:34:53,886 SPEAKER 1: Yes, and what are we going to need to do. 1777 01:34:53,886 --> 01:34:55,650 What will we need to do in order to? 1778 01:34:55,650 --> 01:34:57,790 AUDIENCE: [? Explain, ?] what was it called? 1779 01:34:57,790 --> 01:35:00,680 The selection box, but without the selection part basically. 1780 01:35:00,680 --> 01:35:03,900 SPEAKER 1: Yes, so once we've taken-- once we've leveled up 1781 01:35:03,900 --> 01:35:07,680 and we're in that victory state of the battle state, right, 1782 01:35:07,680 --> 01:35:13,560 we need to push a new state, a new menu state, which 1783 01:35:13,560 --> 01:35:17,160 has all of those stats and the amount that they've increased. 1784 01:35:17,160 --> 01:35:19,920 And then when we press Enter, presumably, we 1785 01:35:19,920 --> 01:35:24,090 should pop that off, and then pop everything else back to the play state, 1786 01:35:24,090 --> 01:35:26,310 and then do the fade in as normal. 1787 01:35:26,310 --> 01:35:29,310 And that is the battle state in a nutshell, 1788 01:35:29,310 --> 01:35:32,850 a lot of pieces that sort of are waiting on each other and input and stuff 1789 01:35:32,850 --> 01:35:33,660 like that. 1790 01:35:33,660 --> 01:35:37,985 But fairly easy to understand, just because a lot of it is very simple 1791 01:35:37,985 --> 01:35:40,110 things that are just chained together over and over 1792 01:35:40,110 --> 01:35:42,480 again to produce this sort of interesting behavior. 1793 01:35:42,480 --> 01:35:45,070 1794 01:35:45,070 --> 01:35:47,320 So here we have sprites, recall the sprites are what 1795 01:35:47,320 --> 01:35:49,380 we're going to need to animate those. 1796 01:35:49,380 --> 01:35:52,860 We have health bars, which are progress bars, which 1797 01:35:52,860 --> 01:35:55,890 are just two rectangles that are-- 1798 01:35:55,890 --> 01:35:59,520 ones a line, a black line, and ones a fill that fills beneath the line, 1799 01:35:59,520 --> 01:36:06,000 so that we get a sense of how much is missing, right? 1800 01:36:06,000 --> 01:36:08,290 We get the width, the height, a color. 1801 01:36:08,290 --> 01:36:10,470 We can give our progress bar any color we want to, 1802 01:36:10,470 --> 01:36:13,710 which is how we get the difference between, say, a health bar and an XP 1803 01:36:13,710 --> 01:36:14,370 bar. 1804 01:36:14,370 --> 01:36:17,619 We just make one red and one blue, and we draw them in different spots, right, 1805 01:36:17,619 --> 01:36:20,220 but they're both equally progress bars. 1806 01:36:20,220 --> 01:36:21,570 And then they get a value. 1807 01:36:21,570 --> 01:36:28,050 Their value is whatever sort of determines how much of the rectangle 1808 01:36:28,050 --> 01:36:29,130 is scaled. 1809 01:36:29,130 --> 01:36:33,390 And the max is how much that should be divided by in order 1810 01:36:33,390 --> 01:36:36,420 to produce a ratio for the total width-- 1811 01:36:36,420 --> 01:36:38,640 a scaler for the total width, which will allow us 1812 01:36:38,640 --> 01:36:41,580 to get the sense of an amount missing. 1813 01:36:41,580 --> 01:36:43,875 1814 01:36:43,875 --> 01:36:45,930 And then a player circle x, opponent circle 1815 01:36:45,930 --> 01:36:51,180 x for the ellipses, just the graphical details for the actual Pokemon, 1816 01:36:51,180 --> 01:36:54,690 so that we can get their stats, so that we can actually do dice rolls, or not 1817 01:36:54,690 --> 01:36:58,230 really dice rolls in this case, but so that we can add or subtract 1818 01:36:58,230 --> 01:36:59,790 HP based on attack and defense. 1819 01:36:59,790 --> 01:37:03,570 1820 01:37:03,570 --> 01:37:06,030 And so here was the update, so trigger slide in. 1821 01:37:06,030 --> 01:37:09,470 So what trigger slide in does, is a one second tween, 1822 01:37:09,470 --> 01:37:10,720 which you talked about, right? 1823 01:37:10,720 --> 01:37:14,410 The Pokemon going left to right, or left to right, right to left. 1824 01:37:14,410 --> 01:37:18,330 There x values, just tweening in over one second. 1825 01:37:18,330 --> 01:37:22,360 As soon as that's finished, we're going to trigger starting dialogue. 1826 01:37:22,360 --> 01:37:26,760 So the starting dialogue is push a battle message state onto the stack. 1827 01:37:26,760 --> 01:37:30,500 The battle message state is just like a dialogue state in that it gets a string 1828 01:37:30,500 --> 01:37:33,300 here, so a wild something appears. 1829 01:37:33,300 --> 01:37:36,690 It gets a callback function for once we press Enter on that. 1830 01:37:36,690 --> 01:37:41,520 And the callback function is itself another push of a battle message state 1831 01:37:41,520 --> 01:37:43,900 that says, go, and then our Pokemon. 1832 01:37:43,900 --> 01:37:47,460 So notice that we're referencing the self.opponent.party.pokemon there, 1833 01:37:47,460 --> 01:37:52,560 and self.player.party.pokemon there to get the actual name. 1834 01:37:52,560 --> 01:37:59,790 And then once we've popped that off, then we push a battle menu state here, 1835 01:37:59,790 --> 01:38:00,660 right? 1836 01:38:00,660 --> 01:38:02,820 So let's take a look at the battle menu state. 1837 01:38:02,820 --> 01:38:06,660 So this is interesting, because this is where we actually define 1838 01:38:06,660 --> 01:38:08,880 the behavior for our menu works, right? 1839 01:38:08,880 --> 01:38:12,080 Recall, we need something to tells us what happens when we press Fight, 1840 01:38:12,080 --> 01:38:13,950 and what happens when we click Run. 1841 01:38:13,950 --> 01:38:16,830 So when we click Fight, notice here items, 1842 01:38:16,830 --> 01:38:20,810 right, self.battlemenu gets menu, and menu expects items. 1843 01:38:20,810 --> 01:38:30,180 This items key, this table gets fed right into the selection, right? 1844 01:38:30,180 --> 01:38:33,300 And the selection, it expects remember, a text, 1845 01:38:33,300 --> 01:38:36,179 because it has to know what to render at that index. 1846 01:38:36,179 --> 01:38:37,470 And then an on select function. 1847 01:38:37,470 --> 01:38:39,261 And that on select function is the callback 1848 01:38:39,261 --> 01:38:42,990 that gets executed when you press Enter at that particular location 1849 01:38:42,990 --> 01:38:43,960 in the menu. 1850 01:38:43,960 --> 01:38:48,300 In this case, fight, what that does is it pops this battle menu state where 1851 01:38:48,300 --> 01:38:51,180 we no longer need the menu, so pop it. 1852 01:38:51,180 --> 01:38:54,120 And then push a new take turn state. 1853 01:38:54,120 --> 01:38:58,830 And then take turn state in this game is the Pokemon fighting each other, that's 1854 01:38:58,830 --> 01:39:00,250 what the take turn state is. 1855 01:39:00,250 --> 01:39:03,030 And it could have been called fight state, for example, 1856 01:39:03,030 --> 01:39:05,080 but take turn state is a little more versatile. 1857 01:39:05,080 --> 01:39:07,850 If we wanted to maybe make, maybe one Pokemon wants to run, 1858 01:39:07,850 --> 01:39:10,590 the enemy wants to run and we want to fight, right? 1859 01:39:10,590 --> 01:39:13,680 But you can't always run, so they should try to run, 1860 01:39:13,680 --> 01:39:15,480 and then we can still fight them. 1861 01:39:15,480 --> 01:39:18,595 Or they can use an item, or we can use an item, right? 1862 01:39:18,595 --> 01:39:20,470 There's a lot of different things you can do. 1863 01:39:20,470 --> 01:39:24,096 Or we want to throw a Poke ball at them, and if we fail, 1864 01:39:24,096 --> 01:39:25,470 then they should fight us, right? 1865 01:39:25,470 --> 01:39:27,930 Take turn is just a general purpose state 1866 01:39:27,930 --> 01:39:31,050 that we could repurpose for whatever use we 1867 01:39:31,050 --> 01:39:35,190 want to with any interaction between us and the opponent, 1868 01:39:35,190 --> 01:39:38,370 whether it's fighting, running away, or using items, catching them, any 1869 01:39:38,370 --> 01:39:39,900 of these combinations of things. 1870 01:39:39,900 --> 01:39:43,020 But in this case, for the sake of this example, for simplicity, 1871 01:39:43,020 --> 01:39:44,940 we've only implemented fighting. 1872 01:39:44,940 --> 01:39:49,219 The we and the opponent fight each other during this state, which 1873 01:39:49,219 --> 01:39:51,510 is, one attacks the other, and then we check for deaths 1874 01:39:51,510 --> 01:39:52,740 in between both of those. 1875 01:39:52,740 --> 01:39:57,990 And then go to victory or feinting depending on which of those holds true, 1876 01:39:57,990 --> 01:40:00,030 if either. 1877 01:40:00,030 --> 01:40:01,930 Running is slightly different. 1878 01:40:01,930 --> 01:40:07,890 So if we run, I've programmed it to be 100%, it will 100% of the time work. 1879 01:40:07,890 --> 01:40:10,600 In Pokemon, you actually have a chance to run 1880 01:40:10,600 --> 01:40:12,860 based on what the delta is between you and your enemy. 1881 01:40:12,860 --> 01:40:16,740 So if they're stronger than you, you actually aren't guaranteed to run away. 1882 01:40:16,740 --> 01:40:23,400 So what we do here in my implementation is, we just pop the battle menu, 1883 01:40:23,400 --> 01:40:24,670 so it's gone. 1884 01:40:24,670 --> 01:40:30,880 And then we push, you fled successfully to the screen, this battle message. 1885 01:40:30,880 --> 01:40:36,870 But there's a difference here versus the other battle messages that we've shown. 1886 01:40:36,870 --> 01:40:40,490 I mean, it's not really different, but it's something to keep in mind. 1887 01:40:40,490 --> 01:40:43,100 So I'm going to get into a battle. 1888 01:40:43,100 --> 01:40:45,912 1889 01:40:45,912 --> 01:40:48,870 And so first of all, with that message that you just saw on the screen, 1890 01:40:48,870 --> 01:40:50,430 I had to actually press Enter, right? 1891 01:40:50,430 --> 01:40:53,490 I discarded it explicitly by pressing Enter. 1892 01:40:53,490 --> 01:40:56,490 1893 01:40:56,490 --> 01:40:58,382 And that holds true also for these messages. 1894 01:40:58,382 --> 01:41:00,090 It won't do anything until I press Enter. 1895 01:41:00,090 --> 01:41:03,570 So I press Enter, and then I press Enter, and it does it's thing. 1896 01:41:03,570 --> 01:41:06,510 But notice the difference between when I hit Run. 1897 01:41:06,510 --> 01:41:10,230 I'm going to hit Run, I fled, and it does it on its own. 1898 01:41:10,230 --> 01:41:14,235 It's not waiting for input, right? 1899 01:41:14,235 --> 01:41:16,159 So how have we implemented that? 1900 01:41:16,159 --> 01:41:19,540 1901 01:41:19,540 --> 01:41:20,155 Yeah? 1902 01:41:20,155 --> 01:41:24,680 AUDIENCE: Using timer, you'd automatically 1903 01:41:24,680 --> 01:41:29,010 do it the same way you would afterwards, instead of waiting for you input, 1904 01:41:29,010 --> 01:41:31,330 you just wait for the timer to end. 1905 01:41:31,330 --> 01:41:34,570 SPEAKER 1: Exactly, so we use a timer, and then when the timer is finished, 1906 01:41:34,570 --> 01:41:40,390 we pop the battle message just like we would have popped it by pressing Enter. 1907 01:41:40,390 --> 01:41:43,080 This false flag is what allows us to do that. 1908 01:41:43,080 --> 01:41:46,870 We press false and false is, can we input or not? 1909 01:41:46,870 --> 01:41:47,890 And we can't. 1910 01:41:47,890 --> 01:41:51,230 So actually, if we didn't do any timer thing after this, 1911 01:41:51,230 --> 01:41:54,400 and we just did that false flag, the battle message would be there forever, 1912 01:41:54,400 --> 01:41:56,400 and we could never get rid of it, ever. 1913 01:41:56,400 --> 01:41:58,420 It would get stuck forever. 1914 01:41:58,420 --> 01:42:03,610 So we got to be responsible and say, OK, we're going to put a timer, 1915 01:42:03,610 --> 01:42:08,800 we're going to call timer.after 0.5 seconds immediately after that. 1916 01:42:08,800 --> 01:42:11,110 We're going to push a fade in state. 1917 01:42:11,110 --> 01:42:15,190 And then we're going to do these two pop operations here as soon as that fade in 1918 01:42:15,190 --> 01:42:16,180 happens. 1919 01:42:16,180 --> 01:42:19,960 This first pop will pop the message, right, this message here 1920 01:42:19,960 --> 01:42:22,910 that we didn't pop through input. 1921 01:42:22,910 --> 01:42:26,350 So this is actually garbage collecting, in a sense, for us. 1922 01:42:26,350 --> 01:42:31,150 It's discarding the message that we couldn't discard automatically. 1923 01:42:31,150 --> 01:42:33,940 And then we're going to pop the battle state, right? 1924 01:42:33,940 --> 01:42:38,860 So running will push the battle message, trigger a timer tween 1925 01:42:38,860 --> 01:42:44,440 for our timer.after five seconds, sorry, push a fade in state. 1926 01:42:44,440 --> 01:42:48,010 And then after the fade in states done, then pop both of those states. 1927 01:42:48,010 --> 01:42:53,420 The message and the battle state take us back to the play state. 1928 01:42:53,420 --> 01:42:56,360 And that's where we'll be as soon as that's all done. 1929 01:42:56,360 --> 01:43:00,880 And that's all that's in the battle menu state. 1930 01:43:00,880 --> 01:43:04,120 Any questions as to how the battle menu works, the difference between fight 1931 01:43:04,120 --> 01:43:08,340 and run and sort of how those operate? 1932 01:43:08,340 --> 01:43:09,560 OK. 1933 01:43:09,560 --> 01:43:13,730 So let's take a look then at the take turn 1934 01:43:13,730 --> 01:43:19,700 state, which is the last piece and the largest piece I would say. 1935 01:43:19,700 --> 01:43:24,090 This is the most relevant to the assignment. 1936 01:43:24,090 --> 01:43:28,250 So we maintain a reference to which Pokemon is first or second to go, 1937 01:43:28,250 --> 01:43:31,460 which sprite is first or second to go, and which progress bar is 1938 01:43:31,460 --> 01:43:33,400 first or second to go up here. 1939 01:43:33,400 --> 01:43:36,020 And we do that, like I said, based on speed. 1940 01:43:36,020 --> 01:43:40,400 So whichever Pokemon is faster, and we could have also 1941 01:43:40,400 --> 01:43:45,330 made this a little bit shorter, just by keeping the sprites and the progress 1942 01:43:45,330 --> 01:43:49,400 bars as members of the Pokemon object, or the class, 1943 01:43:49,400 --> 01:43:53,150 but since they're kind of separated, like we don't necessarily 1944 01:43:53,150 --> 01:43:56,870 want a Pokemon to have a reference to it's progress bar at all times, 1945 01:43:56,870 --> 01:43:58,025 or I mean, you could. 1946 01:43:58,025 --> 01:43:59,900 There's nothing preventing you from doing it. 1947 01:43:59,900 --> 01:44:04,020 It would only serve the purpose of shortening this code here. 1948 01:44:04,020 --> 01:44:10,640 But we need to keep a reference to this so that we can call attack here, 1949 01:44:10,640 --> 01:44:16,400 which is this large bit of code twice, without needing 1950 01:44:16,400 --> 01:44:18,560 to duplicate all of that code twice. 1951 01:44:18,560 --> 01:44:21,076 Does that makes sense? 1952 01:44:21,076 --> 01:44:22,450 So Tony, did you have a question? 1953 01:44:22,450 --> 01:44:24,800 AUDIENCE: Well, I was just thinking, you could probably 1954 01:44:24,800 --> 01:44:26,716 put that into a helper function where you just 1955 01:44:26,716 --> 01:44:29,260 change the order you pass it in. 1956 01:44:29,260 --> 01:44:30,090 SPEAKER 1: Sorry? 1957 01:44:30,090 --> 01:44:30,640 Say it again. 1958 01:44:30,640 --> 01:44:33,870 AUDIENCE: I just kind of feel like, I guess you could take the code, 1959 01:44:33,870 --> 01:44:36,373 and you could avoid duplicating that I guess. 1960 01:44:36,373 --> 01:44:40,000 'Cause it's just reversed, so what you could do is you could-- 1961 01:44:40,000 --> 01:44:44,620 if you passed into a helper function, which you would just, 1962 01:44:44,620 --> 01:44:48,350 instead of passing it first-- 1963 01:44:48,350 --> 01:44:50,730 instead of passing it, opponent Pokemon, player Pokemon, 1964 01:44:50,730 --> 01:44:53,504 you would pass it, player Pokemon, opponent Pokemon. 1965 01:44:53,504 --> 01:44:55,132 And that would probably work I think. 1966 01:44:55,132 --> 01:44:57,590 SPEAKER 1: Well, you also have to take into consideration-- 1967 01:44:57,590 --> 01:45:04,060 so the comment was, you could pass in the player Pokemon and the opponent 1968 01:45:04,060 --> 01:45:08,355 Pokemon into a function, and then you reverse them in that function, 1969 01:45:08,355 --> 01:45:10,480 I'm assuming, have reverence them and reverse them. 1970 01:45:10,480 --> 01:45:13,780 But the sprites are decoupled from the Pokemon, 1971 01:45:13,780 --> 01:45:17,170 and the progress bars are also decoupled from the Pokemon. 1972 01:45:17,170 --> 01:45:27,790 So we could shorten this by making these four things here fields 1973 01:45:27,790 --> 01:45:31,030 of the Pokemon objects, but they're not strictly 1974 01:45:31,030 --> 01:45:34,180 pertinent to the operation of the Pokemon object. 1975 01:45:34,180 --> 01:45:39,740 And it sort of kind of makes the Pokemon objects a little 1976 01:45:39,740 --> 01:45:43,586 too, not basically abstract or lightweight enough, 1977 01:45:43,586 --> 01:45:45,460 and it only serves the purpose of this point, 1978 01:45:45,460 --> 01:45:47,660 of just shortening this bit of code. 1979 01:45:47,660 --> 01:45:53,020 There's probably a more elegant way to do it, but it's hard to say. 1980 01:45:53,020 --> 01:45:56,550 If this code were to get larger, maybe. 1981 01:45:56,550 --> 01:45:58,690 But the gist of this is basically to have 1982 01:45:58,690 --> 01:46:04,380 a pointer to whatever Pokemon, progress bars, and sprites should operate first 1983 01:46:04,380 --> 01:46:06,790 in the attack versus what should operate second. 1984 01:46:06,790 --> 01:46:10,730 And then the two will trade blows in order based on who's first and who 1985 01:46:10,730 --> 01:46:12,530 second. 1986 01:46:12,530 --> 01:46:14,560 So when we enter the take turn state, we're 1987 01:46:14,560 --> 01:46:18,730 going to trigger that attack, here this function attack, which we'll take in 1988 01:46:18,730 --> 01:46:22,210 first, second, first, second, first, second for the Pokemon 1989 01:46:22,210 --> 01:46:24,760 sprite and progress bars. 1990 01:46:24,760 --> 01:46:27,850 And then anonymous function, which get's executed as 1991 01:46:27,850 --> 01:46:31,810 soon as the attack is finished, right? 1992 01:46:31,810 --> 01:46:35,800 So this is a code that will pop a message that gets pushed in attack, 1993 01:46:35,800 --> 01:46:39,040 and then this is where we actually check deaths, right? 1994 01:46:39,040 --> 01:46:42,380 And it will determine whether we go to victory or faint screen or not. 1995 01:46:42,380 --> 01:46:44,920 If not, and we return if so. 1996 01:46:44,920 --> 01:46:47,186 If not, we're going to do another attack, but see, 1997 01:46:47,186 --> 01:46:48,310 everything is reversed now. 1998 01:46:48,310 --> 01:46:53,281 Now it's second, first, second, first, second, first. 1999 01:46:53,281 --> 01:46:55,030 So we have the same function, self attack, 2000 01:46:55,030 --> 01:46:57,130 which just takes in the attacker. 2001 01:46:57,130 --> 01:47:00,310 And it's effectively, attacker, defender, attacker, defender, attacker, 2002 01:47:00,310 --> 01:47:05,860 defender for the Pokemon sprites and progress bars. 2003 01:47:05,860 --> 01:47:09,350 And so the attack function here first pushes a-- 2004 01:47:09,350 --> 01:47:10,120 well, OK. 2005 01:47:10,120 --> 01:47:11,329 What does the attack-- 2006 01:47:11,329 --> 01:47:12,620 let's go over it one more time. 2007 01:47:12,620 --> 01:47:18,279 What do we think the attack function does in order. 2008 01:47:18,279 --> 01:47:20,070 We covered them just a moment ago, but what 2009 01:47:20,070 --> 01:47:24,070 was the order that happens when something attacks another thing? 2010 01:47:24,070 --> 01:47:25,188 Yeah? 2011 01:47:25,188 --> 01:47:27,235 AUDIENCE: The attacker blinks white. 2012 01:47:27,235 --> 01:47:28,645 SPEAKER 1: Attacker blinks white. 2013 01:47:28,645 --> 01:47:33,900 AUDIENCE: Then the defender blinks opacity. 2014 01:47:33,900 --> 01:47:36,626 SPEAKER 1: The defender toggles it's opacity. 2015 01:47:36,626 --> 01:47:38,244 AUDIENCE: And the health bar shrinks. 2016 01:47:38,244 --> 01:47:39,494 SPEAKER 1: Health bar shrinks. 2017 01:47:39,494 --> 01:47:42,850 2018 01:47:42,850 --> 01:47:45,570 Exactly, and then that's basically it for attack, right? 2019 01:47:45,570 --> 01:47:49,690 Blink, play a sound, blink, play a sound, shrink the bar, 2020 01:47:49,690 --> 01:47:52,810 and also we're doing damage in that function as well. 2021 01:47:52,810 --> 01:47:55,450 We actually have to change the status of the Pokemon. 2022 01:47:55,450 --> 01:47:59,590 2023 01:47:59,590 --> 01:48:02,150 So this is effectively where it starts, right? 2024 01:48:02,150 --> 01:48:05,557 We place a battle message state onto the stack that says, 2025 01:48:05,557 --> 01:48:07,390 the attacker name attacks the defender name. 2026 01:48:07,390 --> 01:48:10,510 2027 01:48:10,510 --> 01:48:15,490 Notice that it gets false just like the run message 2028 01:48:15,490 --> 01:48:17,830 did, because we're not accepting input here. 2029 01:48:17,830 --> 01:48:25,870 But it's up to us actually, it done up here at line 42 of the enter state. 2030 01:48:25,870 --> 01:48:32,260 But we're going to after 0.5 seconds, play the attack animation. 2031 01:48:32,260 --> 01:48:36,400 So power up sound every 0.1 second. 2032 01:48:36,400 --> 01:48:39,340 We're going to member the blinking flag on the sprite, 2033 01:48:39,340 --> 01:48:42,980 we're going to toggle it by setting it not to itself. 2034 01:48:42,980 --> 01:48:46,290 So if something is not itself, if it's a truthy value, it becomes falsy, 2035 01:48:46,290 --> 01:48:48,340 if it's falsy, it becomes truthy. 2036 01:48:48,340 --> 01:48:51,100 So basically, toggling between true and false. 2037 01:48:51,100 --> 01:48:53,530 Limit of six, right, because remember, every will 2038 01:48:53,530 --> 01:48:56,200 do something every amount of time indefinitely, 2039 01:48:56,200 --> 01:49:00,700 unless you pass in a limit of some value, in this case, a limit of six. 2040 01:49:00,700 --> 01:49:04,870 So we're saying, only execute this code six times, only blink six times, right, 2041 01:49:04,870 --> 01:49:07,690 only toggle six times, blink three times, right, 2042 01:49:07,690 --> 01:49:09,800 because it has to go on and off. 2043 01:49:09,800 --> 01:49:12,550 And then as soon as those six iterations are completed, 2044 01:49:12,550 --> 01:49:16,360 we call the finished function on that timer object, 2045 01:49:16,360 --> 01:49:18,156 which takes an honest function. 2046 01:49:18,156 --> 01:49:22,542 As soon as that happens, we do the opacity bit, right? 2047 01:49:22,542 --> 01:49:25,250 We blinked the attackers, so now we've got to blink the defender. 2048 01:49:25,250 --> 01:49:27,760 So we play the hit sound. 2049 01:49:27,760 --> 01:49:32,110 We do the exact same thing that we just did for the blinking, only now, 2050 01:49:32,110 --> 01:49:37,480 every 0.1 second, we are setting its opacity to either 64 or 255, 2051 01:49:37,480 --> 01:49:40,900 depending on what the value of its opacity is, right? 2052 01:49:40,900 --> 01:49:43,240 So we are toggling between 64 and 255. 2053 01:49:43,240 --> 01:49:47,050 Limit of six, take a function, calculate damage, 2054 01:49:47,050 --> 01:49:53,210 which we've just very simply done it, attack minus defense, right, up to 1 2055 01:49:53,210 --> 01:49:53,710 though. 2056 01:49:53,710 --> 01:49:55,918 So if the defense is actually higher than the attack, 2057 01:49:55,918 --> 01:49:58,000 which will still do at least one damage. 2058 01:49:58,000 --> 01:50:03,370 And then over 0.5 seconds, we take the defenders bar, 2059 01:50:03,370 --> 01:50:08,650 and we tween the value equal to their current HP minus damage, right? 2060 01:50:08,650 --> 01:50:15,580 And then that will set in the bar, in the progress bar, it'll set its value. 2061 01:50:15,580 --> 01:50:21,460 And even though the progress bar is behind state wise, 2062 01:50:21,460 --> 01:50:24,760 right, it's on the bottom of the stack, because it's on the battle state. 2063 01:50:24,760 --> 01:50:27,000 And we're in currently the take turn state, 2064 01:50:27,000 --> 01:50:30,580 but because we're still manipulating the values of that state, 2065 01:50:30,580 --> 01:50:33,640 and we're rendering every state, we're actually still manipulating 2066 01:50:33,640 --> 01:50:37,040 that state regardless of the fact that it's not on the top of the stack. 2067 01:50:37,040 --> 01:50:43,510 So that allows us to shrink that Pokemon's progress bar regardless of it 2068 01:50:43,510 --> 01:50:45,360 being on the top of the stock or not. 2069 01:50:45,360 --> 01:50:47,800 Then once that's finished, once the tween is finished, 2070 01:50:47,800 --> 01:50:49,591 actually set the current HP to that amount, 2071 01:50:49,591 --> 01:50:52,450 because we're only tweening the progress bar's value, which is 2072 01:50:52,450 --> 01:50:55,277 independent from the Pokemon's value. 2073 01:50:55,277 --> 01:50:56,860 And then that's the end of the attack. 2074 01:50:56,860 --> 01:50:59,300 The attack is completely finished at that point. 2075 01:50:59,300 --> 01:51:02,940 So any questions as to how the attack works? 2076 01:51:02,940 --> 01:51:06,610 Just a chain of tweens basically. 2077 01:51:06,610 --> 01:51:10,110 So we do an attack, then check deaths is the next function. 2078 01:51:10,110 --> 01:51:14,400 And we're almost finished, I'm going to kind of go quickly here, it's at 7:30. 2079 01:51:14,400 --> 01:51:18,540 Check deaths is the player Pokemon current HP less and equal to 0, 2080 01:51:18,540 --> 01:51:21,540 or is the opponent Pokemon current HP less and equal to zero. 2081 01:51:21,540 --> 01:51:24,750 If the former's true, we need to faint, and if the latter is true, 2082 01:51:24,750 --> 01:51:25,860 we need to go to victory. 2083 01:51:25,860 --> 01:51:32,880 So faint is effectively a battle state, right, when it says, you fainted. 2084 01:51:32,880 --> 01:51:33,817 And then what? 2085 01:51:33,817 --> 01:51:36,799 Remember what happens when we faint? 2086 01:51:36,799 --> 01:51:41,780 AUDIENCE: [INAUDIBLE] text box, and then it leaves. 2087 01:51:41,780 --> 01:51:44,051 SPEAKER 1: It leaves, do you remember how 2088 01:51:44,051 --> 01:51:46,550 it leaves as it differs from like running away, for example? 2089 01:51:46,550 --> 01:51:48,790 AUDIENCE: [INAUDIBLE]. 2090 01:51:48,790 --> 01:51:50,672 SPEAKER 1: Well, beyond that, aesthetically, 2091 01:51:50,672 --> 01:51:52,130 do you remember how it's different? 2092 01:51:52,130 --> 01:51:55,119 AUDIENCE: [INAUDIBLE] differently to black, I think. 2093 01:51:55,119 --> 01:51:55,910 SPEAKER 1: It does. 2094 01:51:55,910 --> 01:51:57,081 It fades to black instead. 2095 01:51:57,081 --> 01:51:59,330 So that's how we can differentiate when we're fainting 2096 01:51:59,330 --> 01:52:00,891 versus when we're running away. 2097 01:52:00,891 --> 01:52:02,390 And so that's what we're doing here. 2098 01:52:02,390 --> 01:52:06,580 Notice that the fade in state RGB is zero, all of those. 2099 01:52:06,580 --> 01:52:12,890 So it's going to fade in to 000255, as opposed to 255, 255, 255, 255. 2100 01:52:12,890 --> 01:52:17,000 So it's going to be a black fade in versus a white fade in. 2101 01:52:17,000 --> 01:52:18,217 And then once we've-- 2102 01:52:18,217 --> 01:52:20,300 this it just sort of a thing that I implemented so 2103 01:52:20,300 --> 01:52:21,883 that we can keep playing indefinitely. 2104 01:52:21,883 --> 01:52:25,790 But once that's finished, restore the player Pokemon to full health, 2105 01:52:25,790 --> 01:52:27,740 resume all the field music stuff. 2106 01:52:27,740 --> 01:52:31,851 And then once we've pushed a fade out state, 000, 2107 01:52:31,851 --> 01:52:34,910 and then we've gone back to the field, let's push. 2108 01:52:34,910 --> 01:52:38,360 Notice that here it takes a function, right, after the fade out state's done. 2109 01:52:38,360 --> 01:52:42,620 Once the fade out is finished-- so as soon as we're back to the play state, 2110 01:52:42,620 --> 01:52:44,630 push a dialogue state that says, your Pokemon 2111 01:52:44,630 --> 01:52:47,300 has been fully restored, try again. 2112 01:52:47,300 --> 01:52:49,770 Which will take the context, and we'll [INAUDIBLE] 2113 01:52:49,770 --> 01:52:51,374 to press Enter to get past it. 2114 01:52:51,374 --> 01:52:52,040 That's fainting. 2115 01:52:52,040 --> 01:52:54,620 2116 01:52:54,620 --> 01:52:58,070 Victory is a little bit more robust. 2117 01:52:58,070 --> 01:53:02,748 So victory is-- do you remember what happen when we get a victory? 2118 01:53:02,748 --> 01:53:06,644 2119 01:53:06,644 --> 01:53:11,027 AUDIENCE: Well, it has to check leveling up as well. 2120 01:53:11,027 --> 01:53:17,500 It says, you've defeated your opponent, then your XP bar increases. 2121 01:53:17,500 --> 01:53:20,212 Then if you've leveled up, it tells you that you leveled up, 2122 01:53:20,212 --> 01:53:21,480 and then it leaves. 2123 01:53:21,480 --> 01:53:27,850 SPEAKER 1: So it tells you you defeated your opponent, XP bar increases, 2124 01:53:27,850 --> 01:53:30,700 checks for a level up, and then leaves. 2125 01:53:30,700 --> 01:53:35,810 After displaying the level up message or not, it leaves. 2126 01:53:35,810 --> 01:53:39,460 It pops everything back to the play state, exactly. 2127 01:53:39,460 --> 01:53:42,070 So remember, the very first thing that happens 2128 01:53:42,070 --> 01:53:46,780 though, the opponent sprite gets tweened over the course of 0.2 seconds, 2129 01:53:46,780 --> 01:53:49,040 it's y value to virtual height, which means, 2130 01:53:49,040 --> 01:53:50,998 all the way to the bottom of the screen, right? 2131 01:53:50,998 --> 01:53:56,050 The typical defeated your opponent from Pokemon sort of animation. 2132 01:53:56,050 --> 01:53:58,420 Once that's finished, play victory music, 2133 01:53:58,420 --> 01:54:01,190 push a battle message state that says, victory, right? 2134 01:54:01,190 --> 01:54:04,860 Once that's popped of the stack, calculate the XP, 2135 01:54:04,860 --> 01:54:09,330 which is, I just chose arbitrarily sum all the IVs of that Pokemon times 2136 01:54:09,330 --> 01:54:12,500 it's level, and that's the XP you got. 2137 01:54:12,500 --> 01:54:18,340 Push a state that says, you earned x XP, right? 2138 01:54:18,340 --> 01:54:21,985 It's false, so that means it doesn't take input. 2139 01:54:21,985 --> 01:54:24,610 So that means it's up to us in order to pop that off the stack. 2140 01:54:24,610 --> 01:54:29,830 So after 1.5 seconds, we play a sound, and then we tween that XP bar going up, 2141 01:54:29,830 --> 01:54:31,120 right? 2142 01:54:31,120 --> 01:54:34,470 So that's what's going on here, self.battleState.playerxpbar, 2143 01:54:34,470 --> 01:54:40,210 we're tweening of the math.men, of the XP plus XP, 2144 01:54:40,210 --> 01:54:45,850 or XP to level, because if we don't, it could go past the edge of the XP bar, 2145 01:54:45,850 --> 01:54:49,240 because we could go over our XP to level, right? 2146 01:54:49,240 --> 01:54:52,330 Let's say we have 10 XP till we gain a level, we could gain 20 XP. 2147 01:54:52,330 --> 01:54:53,860 We'd be 10 XP overboard. 2148 01:54:53,860 --> 01:54:58,450 So we don't want to tween our XP bar past the edge of the XP bar, 2149 01:54:58,450 --> 01:55:00,110 it would be a graphical glitch. 2150 01:55:00,110 --> 01:55:05,410 So a math.men our XP plus XP, and our XP to level, 2151 01:55:05,410 --> 01:55:08,740 which will take the lesser of the two values. 2152 01:55:08,740 --> 01:55:12,250 Once that's done, it's tweened, we're going to pop the message off, 2153 01:55:12,250 --> 01:55:15,760 and then we're going to actually add the XP, level up. 2154 01:55:15,760 --> 01:55:19,390 So this is where we level up if the XP is greater than XP to level. 2155 01:55:19,390 --> 01:55:26,260 Play a sound, set the XP to the current XP minus our 2 level XP, 2156 01:55:26,260 --> 01:55:30,130 which will mean that we'll have some carry over, right? 2157 01:55:30,130 --> 01:55:32,060 And then actually call the level up function. 2158 01:55:32,060 --> 01:55:35,230 Now here is where-- 2159 01:55:35,230 --> 01:55:37,990 oh, and also after that, congratulations, you've leveled up. 2160 01:55:37,990 --> 01:55:40,570 Fadeout white, which is just a white fade out here. 2161 01:55:40,570 --> 01:55:43,360 I used it twice, so I made a function for it. 2162 01:55:43,360 --> 01:55:46,300 Just pushes a fade in state. 2163 01:55:46,300 --> 01:55:50,440 Stop the victory music, play the field music, pop, push a fade out state. 2164 01:55:50,440 --> 01:55:56,110 So either way, when we've got a victory, we're going to push a fade out white, 2165 01:55:56,110 --> 01:55:58,360 or we're going to call fade out white, correct? 2166 01:55:58,360 --> 01:56:02,920 So push a battle message state, and then as soon 2167 01:56:02,920 --> 01:56:06,370 as we press Enter, because we leveled up, fade out to white. 2168 01:56:06,370 --> 01:56:08,690 And if we didn't level up, but we still got to victory, 2169 01:56:08,690 --> 01:56:10,360 we still need to fade out white. 2170 01:56:10,360 --> 01:56:13,280 And so this is where your assignment is, assignment 7. 2171 01:56:13,280 --> 01:56:17,517 Assignments 7 is, notice that we have self.playerPokemon level up. 2172 01:56:17,517 --> 01:56:19,600 The key thing that we are going to need to do here 2173 01:56:19,600 --> 01:56:23,020 is add a menu that shows us how we leveled up. 2174 01:56:23,020 --> 01:56:27,160 And if you recall, playerPokemon level up returns all the stats 2175 01:56:27,160 --> 01:56:29,260 that you've increased this level. 2176 01:56:29,260 --> 01:56:34,980 So you can show a menu that just says, your HP plus that amount, right? 2177 01:56:34,980 --> 01:56:36,480 You're going to get all four values. 2178 01:56:36,480 --> 01:56:38,650 It's going to explode to all four of those values. 2179 01:56:38,650 --> 01:56:42,460 And then you're going to create a new battle-- 2180 01:56:42,460 --> 01:56:46,330 or not new battle menu, but a new menu of whatever you want, 2181 01:56:46,330 --> 01:56:51,760 but probably on the right side of some vertical height for items. 2182 01:56:51,760 --> 01:56:53,890 The only difference here, the only key thing 2183 01:56:53,890 --> 01:56:55,930 that you're going to take into consideration 2184 01:56:55,930 --> 01:56:59,290 is, and I'll go back to the slides, because we're actually 2185 01:56:59,290 --> 01:57:01,660 done at this point going over the code. 2186 01:57:01,660 --> 01:57:07,180 But the selection items, you won't be able to actually select anything, 2187 01:57:07,180 --> 01:57:09,220 it's just going to be purely visual. 2188 01:57:09,220 --> 01:57:12,520 So you're going to need to edit selection to have the option 2189 01:57:12,520 --> 01:57:13,504 to not have a cursor. 2190 01:57:13,504 --> 01:57:15,670 And this is detailed in the spec, which was actually 2191 01:57:15,670 --> 01:57:17,330 released before lecture today. 2192 01:57:17,330 --> 01:57:18,910 So you can take a look at that. 2193 01:57:18,910 --> 01:57:21,760 But you'll need to make a change to selection. 2194 01:57:21,760 --> 01:57:23,070 But all the pieces are there. 2195 01:57:23,070 --> 01:57:24,945 It should be a fairly easy assignment as long 2196 01:57:24,945 --> 01:57:28,390 as you understand how the states work, how the menu works, 2197 01:57:28,390 --> 01:57:33,040 and how to create a menu based on those values, 2198 01:57:33,040 --> 01:57:35,320 and how to actually get the values from level up. 2199 01:57:35,320 --> 01:57:38,830 So some missing features that we didn't talk about, which we didn't implement 2200 01:57:38,830 --> 01:57:41,380 are, for example, the detailed level of screen, 2201 01:57:41,380 --> 01:57:45,040 which is your assignment, monster catching, right? 2202 01:57:45,040 --> 01:57:49,150 We only have a party of one Pokemon throughout this whole entire thing, 2203 01:57:49,150 --> 01:57:53,500 but one of the arguably main appeals of the game is to be able to catch more. 2204 01:57:53,500 --> 01:57:57,790 So that would be something to add, to prioritize probably adding to the game. 2205 01:57:57,790 --> 01:58:00,880 A field menu so can actually look at all the Pokemon you've caught. 2206 01:58:00,880 --> 01:58:04,390 That would be nice, so you can actually see how much HP they have. 2207 01:58:04,390 --> 01:58:07,330 In item inventory, because the game, the regular games have items. 2208 01:58:07,330 --> 01:58:10,420 You can use potions, you can find gold nuggets 2209 01:58:10,420 --> 01:58:12,370 that you sell for a ton of money. 2210 01:58:12,370 --> 01:58:15,702 Different abilities, currently we only have basically one fight operation, 2211 01:58:15,702 --> 01:58:16,660 which is like a tackle. 2212 01:58:16,660 --> 01:58:19,240 And the game itself, the regular game has 2213 01:58:19,240 --> 01:58:22,270 like over 100 different moves that have elemental attributes, 2214 01:58:22,270 --> 01:58:25,600 and do different things, and cause status effects, 2215 01:58:25,600 --> 01:58:27,250 buff you or your opponent. 2216 01:58:27,250 --> 01:58:30,790 So adding those is appealing, and maybe being 2217 01:58:30,790 --> 01:58:33,814 able to represent them as data is nice to. 2218 01:58:33,814 --> 01:58:36,730 Trainers that you can encounter in the game that have their own preset 2219 01:58:36,730 --> 01:58:38,954 or randomized Pokemon for to fight. 2220 01:58:38,954 --> 01:58:41,620 Monster evolution, because that's like one of the funnest things 2221 01:58:41,620 --> 01:58:43,661 is taking a really weak Pokemon, and like raising 2222 01:58:43,661 --> 01:58:46,850 it to become really strong, and evolving it at a certain level. 2223 01:58:46,850 --> 01:58:52,870 Towns, routes, other levels beyond just our basic square area. 2224 01:58:52,870 --> 01:58:55,600 Monster breeding, which is introduced in the second series, 2225 01:58:55,600 --> 01:58:58,050 so that you can take two Pokemon and have a chance 2226 01:58:58,050 --> 01:59:02,074 to get an egg with really good stats or a really rare Pokemon from it. 2227 01:59:02,074 --> 01:59:04,990 And then like a day night cycle maybe where different Pokemon come out 2228 01:59:04,990 --> 01:59:06,560 at different times of the day. 2229 01:59:06,560 --> 01:59:11,680 So you are incentivize to play at different times 2230 01:59:11,680 --> 01:59:14,590 of the day for that purpose. 2231 01:59:14,590 --> 01:59:16,450 But that was it for Pokemon. 2232 01:59:16,450 --> 01:59:19,030 Next week we'll actually be diving into Unity. 2233 01:59:19,030 --> 01:59:23,200 So we're actually done with LOVE 2D, which is a lot of fun, 2234 01:59:23,200 --> 01:59:26,090 but now we'll be going into how to make 3D games. 2235 01:59:26,090 --> 01:59:28,840 So this is a screenshot from the game we'll be making next week, 2236 01:59:28,840 --> 01:59:32,470 which is a 3D sort of side scrolling Flappy Bird esque helicopter 2237 01:59:32,470 --> 01:59:38,590 game based on a famous web game called Helicopter Game. 2238 01:59:38,590 --> 01:59:44,250 And it was sort of one of the early ancestors to Flappy Bird. 2239 01:59:44,250 --> 01:59:46,990 On the Wikipedia page, it actually says that too. 2240 01:59:46,990 --> 01:59:51,452 I remember playing, it was back in like 2007, or 2006, or something like that. 2241 01:59:51,452 --> 01:59:54,160 But your goal in this game-- this is a modified version of that-- 2242 01:59:54,160 --> 01:59:58,130 your goal is your-- everything is 3D, but it's a side scrolling perspective. 2243 01:59:58,130 --> 02:00:01,570 So this is called 2.5D for that reason. 2244 02:00:01,570 --> 02:00:04,360 You're controlling a helicopter, you're the purple helicopter. 2245 02:00:04,360 --> 02:00:07,670 And your goal is to in an infinitely scrolling world. 2246 02:00:07,670 --> 02:00:11,760 So we'll revisit infinite scrolling, but in 3D, avoid skyscrapers. 2247 02:00:11,760 --> 02:00:15,880 So you can see there is a green skyscraper, crudely modeled. 2248 02:00:15,880 --> 02:00:18,880 Collect coins, so you can see there's a coin there, it's a 3D coin, 2249 02:00:18,880 --> 02:00:20,440 it will always be spinning. 2250 02:00:20,440 --> 02:00:22,570 Your coins are up at the top right. 2251 02:00:22,570 --> 02:00:24,880 You'll see a background that's infinitely scrolling. 2252 02:00:24,880 --> 02:00:26,740 And then you'll have jets that will randomly 2253 02:00:26,740 --> 02:00:31,090 fly above you to sort of give you another sort of layer or dimension 2254 02:00:31,090 --> 02:00:32,950 of obstacles to watch out for. 2255 02:00:32,950 --> 02:00:36,910 And this will teach us a lot of the basics of how unity works, 2256 02:00:36,910 --> 02:00:41,110 so we can start getting into even more interesting things like a first person 2257 02:00:41,110 --> 02:00:43,090 like sort of core exploration game. 2258 02:00:43,090 --> 02:00:45,820 And then lastly, when we end the semester with Portal, 2259 02:00:45,820 --> 02:00:48,130 we'll look at a couple of fancy things there. 2260 02:00:48,130 --> 02:00:49,380 But that was it for Pokemon. 2261 02:00:49,380 --> 02:00:51,255 Thanks for coming, and I'll see you guys next 2262 02:00:51,255 --> 02:00:52,430 time. 2263 02:00:52,430 --> 02:00:54,075