"WEBVTTKind: captionsLanguage: enSPEAKER 1: All right,welcome to GD 50, lecture 7.This week we'll be talking about oneof my favorite franchises of all time,a core part of my childhood--Pokemon as shown by the PokeBall on the screen there.So back in 1997 I thinkit was, the first Pokemongame was released, Red and Blue.I believe it was released ayear earlier in Japan where itwas released as Red, Blue, and Green.And the overall goal of thegame was fairly straightforward.You were a Pokemon trainer.Your goal was to go out intothe world and try and captureany number of 151 differenttypes of these creatures calledPokemon that were based on a wholebunch of different types of creatures.Shown in the screenshot here, there'sa Weepinbell fighting and Geodude.A Geodude was a rock type,Weepinbeel was a grass type.You had different types of Pokemon.When they fight each other, sometypes were better than other types,like this sort of very large rock,paper, scissors relationship.And it was just a veryaddicting formula.You'd have a team of these creaturesthat you had caught and raisedand battled, and you'dfight other trainers.And the awesome part ofthis was you could goand you could actuallyfight your friends,or trade Pokemon with yourfriends that they had caught.And you would often sharestories back and forthabout the different rare creaturesthat you would have encountered,and all sorts of things.You'd have a customized partythat was sort of a part of you.And so this is Pokemon Red.The series has evolved over time.This is a screenshot of Gold and Silver,which was released a couple of yearsafterwards for the Gameboy Color.Again, this was releasedfor the regular Gameboy.Gold and Silver introduced a bunchof new features including breeding,and a day, night cycle,and a lot of other thingsthat became part of the core series.Here is Ruby and Sapphire, whichwas for the Gameboy Advanceand got a significant graphicalupdate, but the core formulastayed much the same.Here is Diamond and Pearl,which is for the DS, whichit made use of two screens, asseen on the top and bottom there.Here is Black and White,which was another step forwardin that it introduced three dimensionalgraphics for the over world,so you could actually see some sort of3D for the first time in the franchise.And then more recently, we've seenfor the 3DS, games like X and Y,which is shown here, andOmega Sapphire, Alpha Ruby--Alpha Sapphire and OmegaRuby, and Moon and Sun.And so this is a greatillustration of whythe RPG genre of videogames, role playing game,even though it's sort of itsown unique take on the formula.But it allows us to, we can sortof dissect this and take a lookat what makes an RPG and whatmakes a Pokemon game altogetherfor a nice cool demonstration.So today, we'll be talkingabout a few new things.We'll be doing things a lotdifferently in this lecture examplerelative to other examples, becausewe're transitioning away from the statemachine and talking about a constructcalled the state stack, whichis effectively a more advancedversion of the state machine.Whereas before, we had a state machinethat was in one state at a time,whereby we could be in the playstate or the start state or whatnot, we can now actuallyhave multiple statesthat exist in parallel that are on astack of data structure, which you'veseen in CS 50 if you'vetaken, where we can have,for example, the field state, theplay state at the very bottom,which is always there, and thenwe can push states onto the stackas we need to forexample, a dialog stateso that we can actuallydisplay some dialog,some text to the screen withoutgetting rid of the play statethat we had there before.It allows us to render multiplethings at the same time,and then also returnback to prior states,rather than completelycreate new states every timewe want to make a transition.We'll be talking aboutturn based systems.So an RPGs like Pokemonand others, thereare often battlesystems that are usuallyturn based in this particular genrewhere you're fighting-- you haveone team or one character fightingagainst against one other team or oneother character, and you taketurns fighting each other.And you have an indefinite amountof time to make your decisionand then form some sortof strategy as to howyou want to approach the problem.We'll be taking a look at a veryprimitive turn based system,but a fully functional one today.Another huge aspect of this genreis graphical user interfaces or GUIsas they're shortened.Things like panels, and scrollbars, and text boxes, and menus, allsorts of these things that allow usto get a more visual sort of lookat our data, and allow us to navigatea much more complex game ecosystem moreefficiently.And to tie it all together,RPG mechanics at large,we'll be looking at thingslike leveling up and experienceand how to calculate the damage thatone party does to the other partythroughout the course of a battle.And so it will be a fairlycomplicated set of examples,but fairly illustrativeof the genre as a whole.So I'd like to demonstrate sort ofthe example that I put together.If I could get a volunteer from theaudience to come up and take a look.Tony that'd be awesome,thank you so much.So this is my simple but fully featured,more or less, demonstration of Pokemon.So if you want to enter or return.So this is a--so here we have a--we can see right off the bat, wehave a text box and a play statelike we did before.So this text box is actually a statethat's layered above the place.So you can see it has some instructionsabout, if you want to press P,you can heal your Pokemon.You can press Enter to dismiss.So if you go ahead andpress Enter, you'llbe able to actually move around now.And so something to note isbefore, input was actuallyhalted while the dialogue was on thetop of the screen for the play state.You're actually not allowed toaccess or update this bottom state,because the state stack is onlyallowing input to the top state.And so I have limited theplay here just to this box,but if we walk in the tallgrass down here, in Pokemon,in order to actuallyinitiate an encounterwith another Pokemon or anotherwild Pokemon, you walk in the grass.So here we've walked in the grass.There's a random chance for thisto happen, there's a 1 in 10 chancebasically.So it's saying that awild Bamboon appeared.So a wild creature appeared.He's level 5, we're level 5,should be a fairly even battle.So you can press Enter,and it will say gothe name of your Pokemon, whichis an Aardart in this case,and it's randomlyallocated at the moment.So go ahead and pressEnter one more time.Now we can see on the bottomright, we have a menu.So we can fight or we canrun, so those two choices.So we can go ahead and fight.So we fight, whicheverPokemon has the higherspeed will go first and do damage.We obviously, do a lot more damage,but he's a little bit faster,so he's going to go first.So we fight one more time.We should be able to knock him out.So as soon as we do, we get a victorymessage, we get a victory song.If we press Enter, we'llactually get some experiencefor defeating that enemy.So we've got quite a bit ofexperience, we got 65 XP.In that bottom bar, we can seewe have all these GUI elements,we've got a panel here, we havetext boxes, we have progress bars,all these pieces are coming together togive us sort of this turn based system.And so after this, we maylevel up just to demonstrateleveling, which is part of theRPG mechanic side of this game.So we have to press this one more time.We did, perfectly.So they leveled up.And so now we're level 6, so we can seethe 6 changed above our progress bars.So now will be a littlebit stronger every time.And the stats aren't shown here, it'sactually a part of the assignmentis to create a menu that willactually show you how you leveled up,what stats actually increased.But underneath thehood, behind the scenes,you actually are getting stat increases.And so here we can see that if weour HP goes all the way down to zero,we faint.And when we faint, the screeninstead of fading to whitewill actually fade to blackto illustrate the differencebetween the two transitions.And so that we can keepplaying indefinitely,the game will restore yourPokemon back to full health.And so this will go on forever.This is effectively whatthe simulator is, it's justa simple series of infinite battles.There are random Pokemon in the grass.There's five total that you can fight.But all the core pieces ofwhat make the game are here.So actually, let'sillustrate running tooif you wouldn't mind, just so thatwe can see if there is a difference.So we can actually flee, and thenbattle we'll get cut short there.We won't get any XP, wewon't faint, but we stillget taken back to the play state.So that's all for the Pokemon demo.Thanks so much Tony forcoming up to demo it.Well, there's a lot of piecesinvolved here, but as we will see,once we have a lot of these sortof foundational pieces implemented,it's not too difficult to startlayering more and more of theseonto the game to make it even more rich.In fact, the assignment is to--and we'll see this at the end,I'll recap this at the end--but the assignments goal isfor you to implement a menu--similar to the menu that we sawwhere fight and run were shown--that will show you what your currentstat is for each of your stats,there's attack, defense,speed, and your HP.It will show you what your statis before leveling, the amountthat it will increase by,and then the final amount,which is sort of similar to howthe actual Pokemon games work,so you can see rather than just seeing,oh I increased my level from 5 to 6,6 to 7, you can see, oh, mystrength increased from 12 to 14.I'm a little bit stronger, I'm goingto do more damage on the next playthrough.So our goal here, we're going to takea look at the field state, the playstate, and the battle state.And there's a common dichotomyin most of these sorts of games,be it Final Fantasy, orDragon Quest, or Pokemonwhere there is a field,where you are walking around,you're character interacting with a gameworld with NPCs, going through towns,and what have you.And then a battle mode,sort of a battle statewhere you're actually fightingagainst some sort of enemy,or a series of enemies, aparty or a single creature.And so we've implemented simpleversions of both of these to illustrateand also the transitions between them.Before we start, I want tomake another sort of plugfor this howtomakeanrpg.com, this book,I actually learned a lot from thisand about using LUA in thecontext of game development.And I pitched this I think inone of the earlier lectures,but if you want a deeper diveinto a lot of these constructs,and to sort of get a sense for how youmight do something like cut scenes,or more complicated battlelayouts, and a lot more like--it goes into a lot of detailabout a lot of awesome things,definitely check it out.It's not free, but if you'reinterested in this genre, which I am,it's definitely worthwhile.Here's what the sprite sheetslook like that we'll beusing for this sort of demonstration.The Pokemon aside, whichare individual textures.Here we're using a simplesprite sheet, whichjust has a bunch of tiles,most of which we did not use.Note that the bush, the tall grassis not on any sort of background.And therefore, we needto layer, basicallyhave two separate tile maps as opposedto one, which we didn't do last time.And we were reusing the sprite sheetthat we used in the Zelda lecture.Before, we used it for all theenemies, the skeletons, ghosts,and slimes, et cetera.But now we're actually using itfor the PCs that it contains.Specifically, just the male NPChere, which is our main character.The foundational class thatwe're using in this lecturethat sort of everything elserevolves around and makes this workis the state stack.And so before, what we hadwas a state machine, right,where we were in one state at a time.So you can almost think ofit like, we have a box here,and it just has one socket.And then we're alwayslooking at this one socket,whether it's the playstate, or the battle state,or a transition of some kind.And now we're transitioninginto the idea of, instead,of just one state that we can onlysee at once, we'll make it a stack.And so what we can do with thisis, rather than just having one,we can therefore render multiplestates at a time, right?So let's say this is like thefield, right, or the play state.And then maybe this is like adialogue, or something, right?Like we saw before in thefield, we had a text box.We can actually layerthings on top of each other.And then maybe this is like afade out, right, or a fade in.So we start with the play statemaybe, and we're walking around,and we interact with in NPC.Rather than transition theplay state to a dialog state,which would, in our previous model,completely eliminate the play state,because there's only one statethat could be active at a time.Now we just render, however manystates we have in our stack,we just render them sequentially basedon the order that they were popped in.We would rendered this first, webasically render from the bottom up.Render the play state, thenthe dialogue, then the fade in.And this will have the effect of doinga whole bunch of different things, whichwe'll see in the distro.But we only really ever needto update one state at a time,right, because if we have the playstate active and the dialog state activeand the fade in state active,in this order, as a stack,right, we were pushing the operationfor pushing for getting somethingonto the stack is calleda push, and getting it offis called a pop if unfamiliar.If we're pushing all of thesestates on, then usually,we only need to updatewhatever's on top, right?If there's no fade infor example, and we onlyhave a dialog state active,or a dialogue and a placestate in that order topto bottom, then we usuallydon't want him update what'sgoing on in the play state.We're only concerned with thedialogue that's taking place.We only want that to take input.And when we press Spacebar,Enter, or whateverbutton clears that dialogstate, we pop it off, right,and then we're back to the play state.Then we're just updating the play state.And so being able to updatejust what's on top whilebeing able to rendereverything that's on bottom.And this doesn't hold truefor all game formulas,there's certainly some games where youcan have a dialogue and a play stateboth get updated, but that's stillusing a state stack of sorts,you're just then updatingthings in a top down way.But this allows us to do allkinds of things like transitions,and preserving-- like for example,the fact that we have a play stateand we can pop a battlestate on top of that,where we don't see theplay state underneath it,we only see the battle state,and that's all updating.But it is we pop thebattle state off, we'reright back where we justwere in the play state.It's preserved its state, for lackof a better word, from before.And this is something that thismodel affords us comfortably.And so that's sort of thefoundational class that'simplemented in thisdistro, which will allowus to do all kinds of awesome things.So let's go ahead and take alook at what that looks like.I have state stack open here.So state stack has justa set of states here.And then whenever wewant to insert a state,it's going to be at theend of the state stack.So it's going to be whatever the last--so if we're looking at it asa series of states in a table,it'll be whatever the lastindex is in the table.That will be our, the top of our stack.And you can implement this eitherway in reverse if you wanted to.It's just easier, because you can justdo a simple table.remove to get ridof the--table.remove on that tableto get rid of the last statewithout having to shift back everything.So if we did it starting at index one,you'd have to shift everything back.And it would also be a little bitweird, because you would start at one,and then things would go left.But basically, in order toupdate whatever our end state is,we just do at #self.states, which willbe however large our state stack is,we just call update on that state.And then process AI is here,although we're not using it.But if you had AI, itwould be the same thingas basically an update for artificialintelligence for your state.Rather than renderingjust one state at a time,we iterate throughall of our states hereusing ipairs, which williterate through them numericallystarting at one going to the end.So we call for istate, andipairs of self.state, render it,so that will render everythingback to front, or bottom to top,and allow us to getthis layered look wherewe have a play state goingon underneath for example,and then a dialogue on top.Or we have a battle stategoing at the very top,and maybe that battle stateitself pushes a dialoguestate to the top of the stack,or a bunch of other states,a transition, whatever you would like.To clear it, we just resetthe table to an empty table.To push a state, we just do aninsert on that state, and thenwe call enter on that state.As we did before, sort of similarly withstate machine, when we changed a state,we would call enter on itand exit, but now we'rejust calling enter when we push.And then to pop, all we dois call exit on whateverthe last state is in ourstate stack, and then justcall table.remove on self.states.And by default, when you calltable.remove on a table, just a tablewith no other arguments,it'll remove whateverthe last index is of that table.Does that makes sense?Anybody have any questions asto how the state stack works?All right, awesome.So let's take a lookthen at the start state.So this is the start date.Fairly simple, we just havea couple of text labels,and then we have just a randomlyassigned sprite going left to right.How do we think we'reachieving the movement?Yep, timer.tween, andthen we're just drawingan ellipse, right, pretty simple.And then when we pressEnter, note the transition.Notice that there's a fade towhite, and then fade to transparent.And so if we recall from when we lookedat match three, how do we do this,do we remember?AUDIENCE:SPEAKER 1: Exactly, and therectangle was stored where?Sorry, to repeat for thecamera, we had a rectanglethat filled the entire screen, and wejust tween the transparency for it,which is true.The rectangle therebefore though was storedin whatever state was active at thetime, which was like the start date,or the I think begingame state was the name.The actual state that wasn'tnecessarily relevant at the transition.But using a state stack, we canactually decouple this idea.We can take the concept of atransition, and because imagineif we wanted to make a transitionbetween every single statethat existed in our game, right?If we wanted to transitionfrom the battle to the field,or the field to the battle, or whateverelse we might want, like the startto the field, we would need arectangle in every single oneof those that has an opacitythat we're keeping track of.And that's not necessarily germaneto the purpose of that state, right?So because we now have astate stack, we can actuallyabstract out this idea of a transition,and turn it into its own state.We can have a transition state.And recall that since we'rejust layering everythingall these states, andwe're rendering them sequentially,having a state that possesses it'sown for example, opacity rectangle,we can just layer that, push thatonto the stack, and render that,and it'll give us the illusionof having this transition.But we don't need to actuallyhave it be part of the statethat we're trying totransition out of and into.Does that make sense?So let's take a look,for example, at the--let's take a look atthe start state first,just so we can see where thatactually gets kicked off.So the start state, we kick offsome music, we have a sprite,and a sprite x and y.These are values that are relevant tothe sprite that's moving, actually,we only have one spriteever moving left to right.It just gets teleported tothe right edge of the screenas soon as it gets taken to one edge.So we only have one sprite, one x and y.And then every threeseconds as we see here,we have a callback function that willtween the sprites x to negative 64over 0.2 seconds, so really quickly.And then on finish,teleport it to the right.And then do the sameexact thing, but tween itto the center over 0.2 seconds.And then as soon as we pressEnter or Return, note this here,we have gStateStack, nota gStateMachine anymore,and we're pushing onto it a fade in state,which takes an RGB, a duration,and a callback function.Now if you look atmain.lua, this is relevant,because now we no longerhave a state machine, right?We previously had a globalstate machine, gStateMachine.We would give it a list of indexesinto functions, anonymous functions.Those would return theinstantiation of a state.And then when we calledchange, the state machine willindex into its list of states,and call that anonymous function,which would have the result ofchanging the state to some statethat we've implementedas a class, right?Now we just create astate stack and we justpush a new start state onto the class.And so what this will do iseffectively the same thing, only nowwe can layer things onto thestart state, right, or play state,or whatever we want to, and we'renot going to ever get rid of it.I mean, we can get rid ofit, but we don't have to.For the play state, especially, wewant that to pretty much never getpopped off the stack,because that's goingto preserve all of our information.We're going to default back to that tostore all of our character information,our Pokemon information,whatever else we mightwant to add onto this shellof a game in inventory,et cetera, a world state at large.We want to preserve that and keep thatconsistent across all of our battlestates and so forth.And the battle states will justpull information from that world,from that play state, andconstruct a battle as needed.Does that makes sense?OK, so here we're effectively, theonly real changes we've made to mainare no longer a state machine,now we have a state stack,going to push startstate, that start statehas some behavior just like any otherstate that we've implemented before.And what I was about to get into beforewas here on line 36 of the start state,we're pushing anotherstate onto the stack.So there's already a start state, andit's from within the start state itselfactually.We're going to take that stack,which is just one level deep,and then we're going tomake it two levels deep now.So now we're going toadd a fade in state.And the fade in state as wecan see, takes in an RGB.Does anybody have a guess as towhat the RGB is relevant for?AUDIENCE:SPEAKER 1: To whether you wantto fade in black or white?Yes, any color.We can make this, we can make ita fade to red if we wanted to,or fade to blue.But we don't have to create twoseparate classes for a fade in white,fade in black, fade outblack, fade out white.We can just give it a color.And then I mean, we could evengo a level further with this,and make it take in an opacity as well,so that we don't need a fade in state,or a fade out state, we justneed a fade state, right?And the fade state willdetermine, based on whateverlast opacity parameter we give it,the right way to fade in and out.But in this case, the differencebetween the fade in stateand the fade out state is one knowsto go to 0, one knows to go to 255.That's really the only key difference.And then this 1, the duration, right,we need to tell it how long to fade.And then this last bithere is a function.We're giving it an anonymousfunction, this is a callback function,because the fade in state bynature is an asynchronous state.It does its behavior over time.So we need a way, weneed to tell it, OK,when you finished doing whatyou're doing, call this bit of codehere, so that we can dosomething not immediately,we can sort of defer itsexecution till later.And this is something that we'llsee common throughout this lecture,because we have this implementedalso in like dialogue for example,because we don't know when the user isgoing to press Spacebar on the dialogstate and clear the window.But what if we want that window,the clearing of that dialogto trigger some sort of event, right?For example, if they press Enterwhen they're in the battle,we want it to go to the next action.We don't necessarily knowwhen it's going to happen,so we'll just pass in an anonymousfunction to that dialogue statethat the class will call whenever theclose function is called on that dialogstate.It says, when closed, executethis anonymous function.And then that anonymous functioncan do whatever you want to do.It could pop another otherseveral states onto the stack.But this is what allows us tochain asynchronous behavior.That's the key here.So this anonymous function-- sowe'll take a look now actuallyat the fade in state, just sowe can see what this looks like.So we see here, fade in state,right, takes in the color.We saw before, that willbe the color we fade to.The length of time that it'll take usto actually perform the transition.And what are we using for the transitiondo we think, timer.tween, right?So most everythingthat we'll do actuallythroughout the course of this lecturethat has asynchronous behavior,we can implement it withtimer, which is nice.It allows us to fairlysuccinctly and declaratively tellright out what exactly wewant to have happen over time.In this case, we're going totween over the course of timethe opacity of our self to 255.So the fade in is going to fadeinto the full color of whatever wehave given it.So it's going to go from 0, whichis shown here by default, to 255.And then as soon aswe finish that tween,that is when we pop the fade in state.We're going to pop ourselves offthe state effectively, off the stackeffectively.And then here, we'recalling on fade complete.And that's where theanonymous function is.On fade complete is passed in here.So by putting that function into thefinish function of the tween operation,we've allowed ourselves to defer thatfunction that we've written up in the--it's in the start state.We defer the execution of this functionuntil after that tween operationtakes place.Does that make sense?OK, awesome.And that's effectively what it is.And that's a common theme that we'll seeif you're looking through the distro,you'll see it in a lot of places.Anonymous functionsor callback functionsrather being passed into thingslike the dialogs, and the fades,and a few other places.In the take turns statefor example, there'sa function that takes in ata callback function as well.And that's effectively how you canchain asynchronous behavior thatexecutes over time, ratherthan it being blocking.Does anybody have any questions sofar as to how this works, at all?All right, so when the fade is done--we're still the start state here--at this point, the fade is done, we'reexecuting this anonymous function.We're going to pop the start stateoff of the stack in this case.And then we're going to push a--we're going to do two pushes here.One is to push a play state, whichrecall is where the NPCcharacter walking around.And another one is topush a dialogue state.And so what this will have theeffect of doing is rather than usimmediately going into the playstate and being able to walk around,we're actually putright into a world wherethere is a message waitingfor us that we haveto press Enter on in order to continue.And when we press Enter, becausewe're pushing the play state first,and then the dialoguestate, the dialogue stateis at the top of the stack,right, because thingsget pushed onto like a stack of plates.You put a play state plate on thebottom and then another plate on top,and that plate is thedialogue state in this case.And you can only interact with the top--we're only updating the topplate at once in this model.We could obviously makea more complicated statestack that allows us to have severallayers of states being updated at once,but for simplicity, we only opted toallow the top layer to be updated.The dialog state is goingto be the active state,it's going to be receiving input.All of them are goingto be rendered, so we'regoing to render thingsfrom the bottom up.We're going to renderthe play state, thenwe're going to render the dialogstate, but the dialog state'sgoing to be active.We're only going to be able topress anything on that state.And then lastly, actually,even beyond the dialogue state,we're pushing another state,we're pushing a fade out state.And in this case, it's theopposite of the fade in state,it just takes in an RGB, andwe'll go from 255 opacityto zero opacity in that case.And so what that allows usto do for playing right,we're here in the startstate, pressing Enter.That's our fade in state was there.And then we pushed to the play stateand the dialogue state and the fadeout state at once, soyou would almost thinkthat we push a fade inand then the fade out,but we have to lay thatfoundation before weput the fade out stateon top of the stack,right, because the toplayer gets updated.So we have to push the fade outstate on top of all of those.That will get updated,that will fade out,and then we're back to thetwo states that we pushbefore we pushed the fadeout state.Does that make since?OK.Does anybody have any questionsas to how that sort of flow works?Cool.All right, so that'sthe gist behind, I mean,that's essentially the coreof what we're doing todayis the state stackpushing multiple states.And then just figuringout the right orderthe need to push them in to get thedesired appearance that you want,right?We push the fade out statewhile we're in the start state,or fade in state rather.That will take us towhite, and then like sortof, almost like underneath the-- behindthe curtain, we're popping everything,and then we're adding the play,dialogue, and then another fade outstate.And so you sort of have to balance theorder that you put things in in orderto achieve the desired results.It may not necessarily beexactly as you intuitivelythink until you think about justhow we're updating and renderingthings on a stack.And so that's the ultimate hurdle Ithink in really getting comfortablewith the distro, but once you've gottenthat, everything else sort of fallsinto place.That and the sort of abundance ofasynchronous functions, as we'llsee pretty shortly when we lookat GUIs, and how we've implementeda lot of basic GUI functionality.A lot of that is very,very call back driven,just because of the nature of itbeing based on user input, right?You don't know when theuser's going to do any input,so defer whatever happenswith that GUI codewith the triggers involvedwhen the user presses Spacebar,Enter, and then call that function thatyou've passed into that GUI widget.All right, so we've takena look at the state stack.We've taken a look at thestart state, the fade in state,let's take a look now at the play state.So the play state--a lot of this is actuallyvery similar to whatwe did back with Zelda, which is avery similar type of game top down.View, the only difference reallywith that was RPGs of this nature--Final Fantasy, Pokemon,Dragon Quest, they'retile based to the degree of evenyour movement is tile based.And so we've striven toimplement that with this lecture.So when we move ourplayer, our character,it doesn't have free motion likewe did with Zelda for example.So I'll demonstrate this.So I can go to the field statehere, the play state, sorry.And then when I move,if I press right, hemoves in that direction ata perfect grid interval.So if I move up, I'm takingmy hand instantly away,he's going to keep moving, and he'sgoing to stick hard set to this grid.And that's just a sort of trendthat these games have implemented.It allows you to stay perfectlyaligned with the grid, and helps youI guess certain game--I don't think it's strictlynecessary for probablymost of the games thatchoose to implement this.I think it was a symptom of tilebased games from the NES and Gameboyera being easier todesign and implement,because they're very tile based systems.But I mean, even as an aestheticchoice, I suppose it makes sense,because everythingaligns very perfectly.So that's the core difference reallywith the field state in this game.So how can we go about implementing agrid aligned movement system like thiswith our player relative to howwe did it in Zelda for example?How do we think-- sure yeah?AUDIENCE: So we don't x and y's,we just have the tile positions.SPEAKER 1: So you don't have x andy's, we just have the tile positions.Close, I would say it's morefocused on the tile positions,but you still do need an xand a y, because you stillneed to draw that spriteat that exact position.Right, yes Tony?AUDIENCE: Well, when you needto move the sprite, insteadof moving at every update, you tweenit between the two tile locations.SPEAKER 1: Exactly, sorather than moving the spriteat exact pixel positions per update, youtween the sprite when you receive inputto a specific location.And then we actually stopinput at that point as well.There's no use for us having any inputwhen we're not exactly at a given tile,so we disable input whilehe's walking effectively.And so this is implemented, if we'relooking at the distro in the entityclass, there is a--I believe it's in here--maybe player, hold on.Oh sorry, no it's entitywalk state, not the entity.Entity is just a container forthe information that's relevant.So here in the entity walkstate, we have attempt move.And so what attemptmove does is essentiallyit looks to make sure that we'rewithin the bounds of the map, right?And then if we are--every entity in this game now has amap y and x, and a regular y and x.And so the regular y andx, we still need in orderto draw our sprite at aspecific location on the map.We still need to draw it going between240 something and 230 something, right?But we need a map x and amap y to basically say, OK,the sprite should be atthis position on the map.And then we'll just tween itbetween that position times 16,and it's the positionplus or minus x or ytimes 16, which will give usthe exact x and y value that weneed to draw it onto the map.And so that's what we're doing here.So were going to callattempt move on input.So anytime we do any input--and this is done in the playerlike idle, or player, yeah, playeridle class--player idle state.We change the animationto write animation.And then we get it'scurrent map x and y.And then based on whateverdirection the player is looking,or the entity is looking, we could usethis for an NPC class, or the like.We just modify our 2x and 2y.So to 2x and 2y is going to be the valuethat we're tweening towards times 16,right?And so if we're trying to gooutside the map boundaries,just changing us back toidle won't let us do that.Otherwise, set our map y and mapx to that position immediately,right, because that's just aminus or plus one operation.And then over the course of 0.5seconds, actually tween to that value.And we can see here, we'retweening to the tile size,and actually to the tile size minusself.entity.height divided by 2.Do we know why that is?We do that, because if we're lookingat the field, we can see here,notice that we're not perfectlylined up with the grass, right?It's kind of likewe're halfway above it,because it looks just a littlebit more natural this way,this is how most sort of games look.And if you're in a gamelike this and you'relike walking up againsta wall for example,this will allow you tosort of look as if you'reup against the wallrather than sort of beingat the edge of where the bottom of thewall is, and kind of looks unnatural.Hence why we minus 1/2our height right there.And then when we'refinished, we actuallytest to see whether we're stillpressing a key, and if we are,then change our stateto walk again, whichwe'll just repeat this process dependingon which direction we're looking at.And that's effectively it.And that's what allows us toget this grid based movement.Any questions as to how this works?Cool.Let's take a look then at theplay state, let's go back to it.So we have a level, thelevel contains our entity,and it can contain all ofour entities, and whateverobjects you want it to contain.In this case, when we'rein the play state as well,we're going to checkto see if we press P,because that's recall, wherewe can heal our Pokemon,just a little game hack just tomake demoing it a little bit easier.But if we press P, we playthe heal sound, we take our--and we'll look a little bit more detailas to this, all this in a little bit.But self.level.player.party.pokemon@index1.currenthpequalsself.level.player.party.pokemon@1.hp.So the difference is current HPis whatever you currently have,you could have taken damage.HP is whatever your max HP is.And this is like in anutshell how you getlike stat changes in games andRPGs, and health and mp differences.You've got to keep track of a max and acurrent value for all of those things,and then depending on whetheryou're buffed or debugged,or whether you have taken damageor not, or used spells or not,you can have an accuratereflection of whereyour character is and thenalways return back to that statewhenever you need to.The interesting thing here, theslightly more complicated thingis when we press P, we wantto show a dialog that says,and I'll demonstrate this,we want to show a dialog justlike this one that says, we press P,your Pokemon has been healed, right?Now I can't move.I'm pressing the arrow keys.I can't move my character atall, because this dialog state--we're in a new state, well, we'vepushed a new state onto the state stack.And that's the dialog statehere, which has taken a value.And because it's the top layer ofthe stack, it can't get updated,or it's being updated, and wecan't update the play state, right,based on how we've modeled our statestacks operation, or how it works.And then as soon as I pressEnter, it gets popped off,we've just popped it off.Now the place states atthe top, I can move again.So that's what's going on.So the dialog state then is actuallyvery similar in a sense, to the fadein and fade out state in that, noticethat it takes an anonymous function.When does this anonymousfunction get called?Do we know?At the end of what?AUDIENCE:SPEAKER 1: Yeah, well, when theuser closes the dialog box, correct.So let's take a look atthe dialog state then.And we can see, it's actuallypretty simple, it's pretty small.We have a text that ittakes and a callback, right?The text is used here.We instantiate, and this we'll see indetail when we start looking at GUIs,and all the widgetsthey've implemented here.This text box gets put at a hard codedposition, and it receives this text.And then we set our self.callbackto that callback function.If we have closed thetext box, meaning, we'relooking to see atself.textbox.isClosed, whichis a function of the text box class.If it's closed, then executeself.callback, and then popthis dialog state of the stack, right?So it's similar in a sense,to the fade in and fade out,and then it takes anonymous function.The only difference isin how it gets executed.With the fade in state,the anonymous functionwas called at the end ofthe finish function, whichis part of the tween object.In this case, we're executing thecallback function explicitly whenwe've closed the text box.So we're waiting for user input versuswaiting for some asynchronous operationto finish.And then of course, wecall text box render,and then we'll see all of these methodsshortly as part of these widgets,but at a glance, this is all that'sreally happening with the dialog state.Very simple, using thesame pattern that we'veseen of deferring futurebehavior to anonymous functions.Any questions as to how thisworks, or anything so far?Cool.All right, let's take alook back at the play state,I believe we're getting close tobeing finished with the play state.Yes, so everything, that's basicallywhat the play state is in this game.And then a lot of what's going ontakes place in a level as well.So in a nutshell, we havetwo maps, two layers, right,because the grass in the tile sheetis its own sort ofout object, it's gottransparency around it.We keep a layer of the base, alayer of the grass underneath,and then a separatelayer for the tall grass.And then we can justlook and to see whenwe're walking in the player walk statewhen we've walked over tall grass.And then what do we need to doto start a random encounter?Yes?AUDIENCE:SPEAKER 1: Yes, how dowe initiated though?That what are we looking for?We do push a battle state assoon as we've triggered one,but how do we trigger one?What are we looking for?AUDIENCE:player is in the grass.I don't know if it's onmoving to a new grass,or if it's time spent in the grass.Yeah, we do a random chancewhenever the players on grass.And it's whenever they start to walkand there on grass in this case.But you can do it eitherway, you can do itwhen they're leaving thegrass, walking into the grass.In this case, it's wheneveryou press the button,and they happen to be on grass,it'll do a random chance, one in 10.And if it's equal to 1, 10%chance it'll trigger an encounter.So that's the gist behindtriggering a random encounter,and a lot of these games really--some games do it differently.They'll sometimes make it morelikely the more steps you've taken,they'll like sort of keep a counterto say, oh, I've taken 100 steps,it should be a lot more likely now.Some games will just be completelyrandom, 1 in 10, 1 in 5,depending on how the developersdecided to implement their game.The former is a bit more robust.But for simplicity, we justchose, math.random10 equals 1.So yeah, we create the tile mapshere, pretty straightforward.And then the actual random encounteringtakes place in the player walk state.So here we have check for encounter.And so what this does is wheneverwe enter the walk state, whichis we press the buttonto enter, or to walk,this entire functiongets called, because wedo the transition to the playerwalk state in the state machine.All of the entities are stillusing just a regular state machinenot a state stack.Wasn't necessary for thisdemonstration, though I'm surethere are some used cases forusing a state stack for an entity.In this case, we're justusing a regular state machine.So when we change to the walk state,we are calling enter as we've seen.And then we call self,checkForEncounter.And so self, checkForEncounterwill set a flagif we have not started an encounterbasically and will allow us to move.And if we have checkedfor an encounter, it will,or if we have triggered an encounter,it will push in checkForEncounter,it'll actually push abattle state onto the stack.So checkForEncounter justbasically does what we said before.If the grass layer,because we have two layers,right, we have the baselayer and the grass layer.So if the layer at yx where yxis are entities map x and map y.If the ID of that isequal to tall grass,and we have just a globalconstant table calledTile IDs, which has all these IDs.And math.random10 is equal to 1,OK, change the entity state to idle,so don't let them keep walking.Pause the field musicrather than stopping,so that way when we come back tothe field later and we press play,it will be at the exactpoint that it was before.Triggered the battle music, and then,we've seen this already, fade in state,push to the stack, right?So over one second, we'regoing to fade to white.So this will have the effectof the music starting,but we're fading towhite right away, whichis very sort of similarto how most RPGs do it.And then we have ourcallback function, whichwill execute as soon as thefade in state's done, right?In this case, push to battle state.Battle state takes anentity, and the entityhas all of our Pokemoninformation, that'swhy we're passing thatinto the battle state.So the battle state can say,oh, what Pokemon do you have?OK, I'll be able to look at yourparty and say, OK, your first Pokemonis this, send him out tobattle, et cetera, right?And then lastly, push afade out state, right,because now we've got the battlestate on top of the play state,but we want to fade into it, right?So we're going to fade, we're goingto put the battle state first,and then because we'reusing a stack, we'regoing to put the fate out state on topof that, and then fade out to that,pop that off the stack.And then we have our battlestate that we just pushed, right?And then self.encounterFoundget's set here.And that's creating anencounter, checking randomly,pushing the right thingsunder the stack, battle state,fade state, fade in, fade out.And then you're set to go.So that's effectively what the--it's known in RPGs as the fieldversus the battle or encounter state.Even though we're calling it playstate here, we've left the field,we've gone into thebattle at this point.And so now we've seenbasically everythingthat the field has to offer us.And we've covered everythingthat's relevant there.So we're going to take a breaknow for five to 10 minutes,and then when we getback from the break,we'll talk about GUIelements, panels, text boxes,and then we'll dive into the sortof mechanics of the battle state.All right, welcome backto lecture 7, Pokemon.So before the break, wetalked about the play state,we talked about the statesstack more importantly,and then we talked about howa anonymous functions aresort of the backbone to how weget a lot of this asynchronousand deferred behavior for ourgame, which is very common in RPGs,and I mean, a lot of genres, a lotof complicated genres of this sort.Another big key part of gameslike this are the graphical userinterfaces, or GUIs asthey're shortened to.Things like panels on thescreen, things like labels--text labels that move around, thingslike lists, text boxes, scroll bars,and you can get a lot crazier with it.In this particular lecture, we'll betalking mostly about panels, labels,text boxes, and scroll bars--progress bars rather, not scroll bars.But the sort of thefirst I think corner--or the first sort oflike keystone GUI widgetthat we should take intoconsideration is the panel.So a panel is .So if we look at this in a game--just pretend this is a panel I guess.So this is effectivelyall a panel is, right?It's just sort of a rectangle.It allows us to-- if you'relooking at most user interfaces,like text boxes on your screen,or if you're on Facebookand you're looking at almostanything, like your little messagewindow, a lot of those things atthe very core, the very bottom,the foundational part is just a panel.So any guesses to how in Love2D,we can make a simple panel?AUDIENCE: Two rectanglesof different colors.SPEAKER 1: Two rectanglesof different colors,that's exactly what we end up doing.So that's effectivelyhow we can make a panel.There's another way of making a panel,which we won't do in this lecture,but it's called--we use as a constructcalled a nine patch.So a nine patch is--imagine taking this little imagehere, and it's of some arbitrary size,but it's very small.And this is very similarto how a lot of gamesimplemented their panelsor their graphical userinterfaces back in the 80s and 90s, Imean, to a lot of games till this day.But back when hardware wasfundamentally tile based,you could take a image like this,split it up into nine pieces--nine patch is where theterminology comes from.And sort of similar to how we actuallyconstructed the Zelda dungeon, recall,where you have corner pieces, and thena top, bottom, right, and left side.You just layer this,one of each of these,first off, right, of the corner pieces.And then however many youneed of these on the sidesto create this rectangle, right?So imagine we've created--these are all, if we can visualizethese as being a bunch of tiles, right?So just imagine that we'vetaken these corner pieces,these are the corner pieces,we've taken one of each of those.And then we take these side pieces,and we just like draw a bunch of themlike that.And then we take thiscenterpiece, and then wecan either layer it, or tile it abunch of times, or just stretch it.And stretching it has a bunch of nicebonuses associated with it dependingon how you've set your filter mode,love.graphics.setdefaultfilter,if you set it tobilinear versus nearest,you can actually get a nice gradient.And if you set it to nearest,you get a nice pixelated look.But you'll see this often, andUnity has nice support for this.Take an image that has maybemore complicated than you couldget with just two rectangles, right?Something that actually has a designand maybe a gradient color, and actuallylayer--I mean, create a arbitrarilysized text box to fit your needs.And if these aren't even incrementsor whatever your tile sizeis on your 9 patch, you could just scalethe top, bottom, left, and right sideas well just to keep itscaled, the centerpiece.So does that makes sense.So this is common, we won'tbe using that in our lecture,but it's a very, very common piece to alot of graphical user interface design.In a lot of games, you'll see it a lotif you get more into game development,so it's definitely worth talking about.Another piece that we'll be talkingabout today is the text box.So I mean, what's a guessas to what the text box,how we can implement a text box, andhow we will implement a text box?So what foundationalpiece can we start with?We already have-- yeah?AUDIENCE: You justput use the love printto the screen over one of those boxes.SPEAKER 1: So use the love print to thescreen over one of the boxes, exactly.Yep.So maintain a list oftext items, right, text.And then just draw them insidea panel, and there's a text box.You've taken two ideas, andsort of mix them together.A selection is kind of the same thing.It's a the only differencebeing that with a selection--so a selection is anotherthing if we think about,for example a menu where wehave fight, and like run,and it may be in a more fleshed outgame, we have like an item thing,right?So that's a menu effectively.It is very similar to whatwe get with a text box,but it's got a set of ingredientshere, fight, item, run,which they aren't set to wrap, they'renot one like contiguous set of text.It's just a bunch of items.And then nice thing abouta selection is that you canhave a cursor on your selection, right?And then what do we need toassociate with like, for example,if we want this toactually do something,and if we think about whatwe've been doing so far,how do we go aboutimplementing functionalitywith a selection like this?Like what needs to get associated witheach of those entries in our selection?Callback function, right?Just as we've done with everything else.If you have a fight item here, eachof these, if we think of the selectionas being just this partof what we're looking at,right, because this background part isjust a panel, we don't care about that.We care about theselection at the moment.The selection is the itemsand the arrow, right?When as we'll see in theassignment, your goal will actuallybe to take selection and getrid of the arrow functionality,because for theassignment, you don't needor want to have a selectionactive, a cursor active.You just want a list of things.But based on what the cursor is pointingat and when we press Enter or whatnot,we should index intothe selection, and thenexecute a callback that'sassociated with each of these items.And that's how we can getbehavior out of the selection,rather than just being a list ofthings that we render to the screen.If we have fight, and weclick Enter, a callbackis set to maybe push astate onto the stack thatwill trigger an interaction betweenthe two entities on the screen, right?The first one willattack the second one,the second one willattack the first one.And that's sort of its own asynchronousset of states that do its own thing,but it's kicked off viaan anonymous functionthat we've associated witheach of these things, right?An item pushes another state, which islike an item mini state, where then youopen up a brand new set of menus thatyou can look through all your items,and each of those items has acallback associated with it, right?Your potion has a callbackassociated with itthat says, when I click onthis, either by default,just restore the HPof my active Pokemon,or let me choose who to restore.So therefore, push another state,which is like a select Pokemonscreen with its own set of callbacksassociated with each of those.It's just in order to get all ofthis sort of complicated behaviorthat you need to, it's reallyultimately just pushing statesand adding callback functions toall of these different optionsthat you can select.And then run, push a fadestate, and then pop this state,and then push a fade out state.And that's really all we're doing.And so this look at allof these GUI widgetshere is just sort of a conceptual look,but we'll take a look very shortlyat some actual implementation.The last one that I want tolook at is the progress bar.So a progress bar forexample, the HP that we'veseen in the actual battle where whenwe take damage, it goes from right toleft.Any guesses as to how we'veimplemented a progress bar?Yes, Tony?AUDIENCE: Once again, two rectangles.SPEAKER 1: Two rectangles, yes, exactly.One, and then the nice thingabout rectangles in Love2Dis you can set the edges onthem to be rounded or notvia an optional parameter.So without anything morecomplicated than a rectanglewe can just create these sortof almost ellipsoid progressbars, very simple progress bars.Ones the red, right, thered that's the background.And then ones the outline, the black.And one is set to fillwith the first parameter,one's set to line withthe first parameter.Now how do we go aboutanimating whether or not,how do we animate the decreasingamount of health when we take damage?Yes?AUDIENCE: Between the width.SPEAKER 1: Between the width, exactly.And what are we tweening it by?How are we tweening it?How would we calculate howmuch we need to tween it?AUDIENCE: Well, you could just haveyour width equal your health remaining.SPEAKER 1: If your width is setto equal your health remaining,then your health is maybe 10.And you want your healthbar to be like 100 pixelslong, how is that going to work though?AUDIENCE: Multiply it.SPEAKER 1: You couldmultiply it, but if youknow the width that you wantyour progress bar to be,you can just multiply thewidth by the ratio of the maxvalue of your HP, or sorry, the ratioof your current HP over your max HP,right?So if you're missing-- if you have50 HP, and you're missing 5 HP,your ratio is 45 over 50.And if you multiply that by your width,you get the exact amount of widththat you need regardless of howwide you want the bar to be,if you want to be 1,000 pixels,if you want it to be 50 pixels,as long as you multiply current healthover max health times the width,you'll get that ratio no matter what.Does that makes sense?Cool.So that's a look at all the GUI widgetsthat we're looking at, how they sortrelate to what we're doing.We'll take a look attheir implementation here.So I'm going to go aheadand open up the panel.And I'm going to movea little bit quicklyso we can get into sort ofthe meat of the battle here.The panel is as we've said beforejust two rectangles, right?It takes in an xy within a height.And then we would justdraw two rectangles.One is larger than the other.The bottom rectangle is slightlylarger than the top rectangle.So the first rectangle getsdrawn and it's whitish.And then-- oh, I'msorry, sorry about that.We have a xy within a height.And then we're drawing tworectangles to the screen.We have the backgroundrectangle, which is drawn first,which is going to be the full xywidth and height of the panel.And then we're going to draw thatat a white color, and then draw--in the context of this game-- we'redrawing everything at the same color,but we can change the color.If we wanted to parameterizeit, we could do that.We could set, we could have a coloroption here in the constructor.We're not doing that, we're justdrawing everything the same color.But that's how you wouldget like customized menus,some RPGs let you do that.And then what we're doing here is we'rejust within a small slightly smallerboundary.So just two pixelssmaller on the x and y.Where you are going todraw the second rectangle,which is a kind of dark shade of gray.And that is a panel,that is all panel is.And then we could justhave a function calledtoggle, which sets it tovisible or not visible.And if it's visible, get rid of it,or if it's visible, sorry, draw it.Otherwise, don't draw anythingwhen it gets rendered.So that's a panel in a nutshell.Any questions?Cool.So the next thing that weshould look at is the text box.So a text box--so the text box is a little bitmore complicated than a panel.A text box in a nutshell needs totake in some arbitrary body of text,and it needs to chop it up basedon how wide your text box is.And if it surpasses theheight of your text box,right, ideally, you should page yourtext so that you can press Space bar,Enter and go through pages of textuntil you've exhausted all of your text.And you press Enter one last time,and you get rid of that text box.And so we have a panel here, whichwe have an xy width and heightin our constructor for the text box.And we have our text as well.And then we have a font ifwe want to explicitly decidewhat font we want to use.In this case, or atlarge, we're going to saythat we instantiate a panel at xywidth and height, nothing too fancy.And then the fancyish part, theslightly more complicated partis here on line 20where we say, underscoreself.textChucks gets self.font,getWrap, self.text, self.width minus 12.So anybody know what this functiondoes or want to take a guess?Yes?AUDIENCE: Is that the pagething you were talking about?SPEAKER 1: Exactly, it'sthe paging of the text.Is the chunking of the text rather.Not the paging of the text, so muchas is the chunking of the text, whichwe will use to page the text.So we take some you knowarbitrarily large body of text,it can be as large as wewant it to be, and given--this is actually a functionof to Love2D font object.So this is given to us from Love2D.Get wrap will return twovalues, the second of whichis all of the pieces of text thatthe main big body is divided intobased on the width.So this self.width ofminus 12, that's how wideit's going to divide ourtext into chunks of up to,it could be slightly smallerthan, because it divides itbased on the word.But no piece of text will everexceed self.width minus 12 width.And this will allow us to then renderseveral lines of text within our textbox, and they will neverexceed the boundary, right?And so the paging functionalityis actually in next chunks.So we call self next here atthe end of function.And then self next basically checks tosee, OK, are we at the end of the text?If we are, then we're notgoing to display any text,and we're going to close the window.We're going to close the panel.But if we are not at the end of thetext, like we still get text left,what we want to do is new table.And then we're going to,up to three iterations,we keep track of where weare in our chunks, right?We get self.text chunks equalto all of those chunks, right.And that could be an arbitrary number.It can be only one chunk, therecould be like 30 chunks, right?We need a counter tokeep track of where weare in terms of like basedon what page we're on, right,and however many lines werendered to the screen thus far.So starting at I, andI get's chunk counter,and chunk counter willget incremented by threeevery time we call nextchunks, which is every page.We could have easily justcalled this next page as well.It's going to insertinto that chunks tablethat we just created,self.textChucks at i.And once we've reachedthe number of chunks totalthat we returned from get wrap,we're going to flag end of textas being true, and thenwe're going to return it.And so what this willdo is, eventually, we'regoing to be equal to the number ofchunks that we got from font get wrap,right?And once we are, thatwill signal with nextthat it's time to close thetext box, because end of textwill have been set to true at theend of that last chunking process.And then we can see here,when we update text box,and that whenever it'son the top of the stack,remember, we're looking fora Space or an Enter press,and then we just call self next.And that will have the effect ofeventually closing our text box.And then is closed recall, welooked at that earlier, we checkedto see it is the text box closed?And that's just a flag that we set here.And then for rendering purposes,we render the panel first.And then for each of our displayingchunks, so we only have up to threedisplaying chunks at one time, whichgets set by the next chunks function.We just print that to the screenusing i as a multiplier on our y.And so that will render up two orthree lines, i, i plus 1, i plus 2.Any questions as tohow the text box works?It's a little more workthan the panel for sure,but it's fairly straightforward.We're just keeping a listof a bunch of text things,and then we're just chunkingthem based on how wide the textbox is, the dimensions thereof.And then let's take onelook at this selection.So a selection is basically, a listof text items with a cursor, right?And as I said before when we werelooking at the screen over there,each of those text items has atext value and a callback function.And the callback functionis what allows usto assign behavior to this selectionobject beyond just displaying things,right?Because when you have a menu,when you have a selectionand you select something, youwant behavior to happen, right?So each of these items indef.items willexpect to have a callback function.And then here, when we updatethe selection, what we're doingis we're updating whatever ourcurrent selection is, which is justa number between 1 and the number ofitems in that selection making surethat if we're at one and we go minusone, that we go back to the bottom.And if we're at the bottomwhen we press, and we go up,we go back to the top.And we play sounds,cutesy, things like that.And then for each--and for our selection here,from one to number of items,we calculate how muchpadding that we need.And we draw the cursorat our current selection,and then we draw each item basedon i and whatever our gap width isof our panel, which we assign it to.So we divide our panel up,and then basically justkeep track of wherecurrent y is and drawthe actual selectionand the cursor if that'sthe current selection to the screen.Any questions as to how aselection sort of works?Notice here, if we press Return,if our selection is being updated,self.items atself.currentSelection.onSelect.So it's expected that that item willhave an onSelect function, whichis that callback function.OK, and lastly, we'lltake a look at the menu.And then we'll finallytake a look at the battle,which is where sort of everything kindof comes together with all of this.And that'll be it.And then we'll talkabout the assignment.So the menu is a paneland a selection together.That's the gist behind whata menu is in this game.You can define a menuto be a lot of things,and you can get a lot more complicatedwith a menu, but in this example,in this implementation, we'rejust saying a menu is a selectionand a panel put together as one item.And we've seen it in the game,going to run it.That's just a text box.Going to look for a battle.OK, so here's a battle.That's just an empty panelat the bottom, regular panel,but now it's a text box.We push the text box onto the stack.Push another text box onto the stack.And so this is a menu right here.Notice that there isa cursor and there'sa selection embedded within a panel.And each of those items,the fight and the run,those have a callbackassociated with them.The purpose of the fight callbackis to trigger a new statewhere the two Pokemon asynchronouslyattack each other, in chain behaviorone after the other.And then run pushes a dialogue,then pushes a fade state,then pops both of them, andthen pushes a fade out stateand puts us back to the play state.So that's effectivelywhat's going on and that'san example of what the menu looked like.And so a menu, just a selectionwith a panel put together.When we draw the menu, we drawthe panel and then the selection.And then when we update the menu,we only update the selection,because that's all we care about.And that's basically it.And so the menu itselfwill get a def, that defshould have items, that itemswill get passed to the selection.That's pretty much, that's it for the--oh, progress bar as well.We'll look at progress bars whenwe get to the actual battle state.So now, let's take a look at a fewof the classes and data structuresthat are pertinent tothe Pokemon themselves.So if you look at partyas are first class, verysimple class, literally just this--self.pokemon is def.pokemon isjust a container at this point.You can take this--I mean, even in I thinka fully fleshed game,you wouldn't really needmuch more than just this.But if you needed to expandupon this idea at alland you know preserve metadatathat exists for the party,this would be a perfect way to do it.The actual pokemon class itself isnot a whole lot more than effectivelya bunch of stats.And that's a lot of what an RPG is.This genre is-- it'smostly just numbers.You're just comparingnumbers against numbersand then adding a roll of the dice.That's effectively, that's whatDungeons & Dragons, a lot of it is.And that's-- yes?AUDIENCE: Would it makemore sense to storejust delta per level and your initialone, so you can have fewer variables?SPEAKER 1: Say it one more time.AUDIENCE: Wouldn't itmake more sense, insteadof storing your HP andeverything for each levelto store your initialstats in each area,and how much you would go up per level.SPEAKER 1: Would it make more senseto store the amount that you go upper level for your Pokemon?Yes, that is what we're doing.So we have a base--so here's how the split works forthe stats in this case, right?We have base HP, base attack,base defense, and base speed.A level 1 Pokemonhas-- a level 0 Pokemonhas these stats of this species, right?Every Bamboon or whateverPokemon that we choosewill have whatever we'veallocated it to be it's base HP,base, attack, base defense, base speed.And then the thing about Pokemonand I mean, a lot of RPGswill sort of do thisthing, but we need some wayof leveling up the Pokemon in annecessarily non-deterministic way.Like two Piggies that level up maynot have the same stats, right?One might have slightlyhigher attack than the other,one might have slightlyhigher defense than the other.We do this using what's called an IV,and that's what Pokemon itself does.And it's short for individualvalue, this is sort oflike the DNA of your Pokemon, right?So this HP IV is separate from yourbase attack, base speed, base et cetera.And this basically, it gets comparedagainst a dice roll every timeyou level up three times.And this is how I've programmedit, it's not necessarilyhow Pokemon itself does it, butyou will roll a dice six times,or three times, one throughsix like a normal die.And you'll look to see if that rollis greater than your IV, right?Or it'll check to see whether your IVis less than or equal to that dice roll.And if it is--or sorry, if it's greater thanor equal to that dice roll.And if it is, it will increment thatstat by 1 for those three dice rolls.So you can get up to three more,or you can increase the statby up to three times per level.But you can only have an IV up to five.So you're rolling against a six, andyou will occasionally not roll a 6.It checks to seewhether or not the IV isgreater than or equal to the dice roll.And if it's not greater than orequal to the dice roll in the eventthat it is a six, or ifthe IV is up to a fourfor example, which means afive or six will go against it,then it will not get a stat increase.And this is a sort of simple way ofimplementing this DNA based system.It's randomized, butit's a weighted, right?If you have a higher IV,you have a higher likelihoodof being greater than orequal to the dice roll.And so that's how weimplement stat increases.And then we need a way of keepingtrack of what our stats are,like our actual stats.So our actual HP, our actualattack, our actual defense,and actual speed that's beencalculated level by level,we need a way to keep track of that.We need level, we needour current XP, and thenwe need our-- and theamount of XP to gaina level, which will get higher andhigher per level, as you can see here,because it takes in theself.level times self.level.And then it multipliesthat by five times 0.75.And then your current HP.So we're really not storingour value level by level,we need the base because weneed to know what our base was.I mean, we could effectivelyglobally reference these variables,but it's minor efficiencygains at that point.But we need the IVs and we need the--I mean, we need a reference to the IVs,we need a reference to the base HP,and we need to keep track ofwhatever our actual stats are,and then our current HPalways, because our current HPcan differ from our actual HP.And in the actual game, youcan have your attack, defense,and speed also vary matchby match, because youhave moves that lower yourspeed, lower your attack,lower your defense, et cetera.In this case, we haven'timplemented that,so we don't have a currentattack, current defense.But in a more complete implementation,you would have that sort of thing.Does that sort of answer your question?Is that in the right vain?OK.And so here's the level up code.So like I said, threedice rolls, one to three.If six is less than or equal to our IV,so it could be a six, in which case,it would be greater than whatare max IV could possibly be.IVs range from one to five, but ifit's less than or equal to that IV,then we're going to considerthat a stat increase.It's a weighted odd to determinewhether or not we get a stat boost.And it does this for every stat, andthen it returns all of the increases.And this is relevant, this line95 for a return HP increase,return attack increase,defense increase.This will be relevant forassignment 7, because your goal isto take these increases and actuallydisplay them to this user in the battlestate when he gets a victory,or he or she gets a victoryand has gained a level.You will display a menu with aselection that has all of these things,and you'll need this value.So it returns these values here, andyou'll be calling this function any wayfrom your battle state stats level up.Or we'll be calling level up rather,which returns self stats level up.And that's all a Pokemon is.It's effectively mostlya data structure.And we use this in our battles tothrow dice effectively back and forth,and have a victor and a loser, andthen gain XP and gain levels that way.So any questions as to how aPokemon object class works?Cool.We'll take a quick look at whatthe actual definitions look like,which you can probably take a guess.It's very simple, just key names.And then we have the actualname, we have the sprite names,we have the HP, attack, defense--all the things that getput into the actual object,they need a referenceto in the definitions.And so Pokemon ultimatelyare just this, they'rejust data, right, which is what wetalked about in a prior lecture, datadriven design.The more you can takeall of your Pokemonand make them into, oranything, Pokemon or any object,and turn it into an easy towrite data structure like this,the easier it is for you to add more.We could easily add, it wouldn'ttake too long to create 150 of these.I mean, they wouldn'tbe all that interesting,because we don't havemoves implemented yet.But in an ideal world, we'd finda way to also model moves as data,and therefore, you can just linkmoves to your data structure,to your Pokemon object like this.Yes Tony, did you have a question?AUDIENCE: Well, I just wantedto mention that the paradoxgames are very good about that.SPEAKER 1: Oh, like Crusader Kings?AUDIENCE: Yeah.SPEAKER 1: The comment was Paradox Gamesare very good about data driven design.I'm assuming you've dugthrough their files?AUDIENCE: To some extent,and also it's justif you play their games for awhile,it's everywhere, like to the extentthat sometimes on the Wiki,they put the source code up.SPEAKER 1: Oh, yeah.Yeah, no, it's just good game design.Ultimately, if you want to--and their games are large,they have a lot of content.If you want to have a lotof content in your game,you need to find a way to takethe burden off the programmerand put it onto thedesigner, or at least makeit easier for the programmer,because making source codeand debugging source code all day long,especially for very complicated thingsis not easy.And it's ultimately not adesired thing to do, right?It's a lot easier for me to whip upa new creature in 10 lines of codehere and feel good about it than hardcoding a lot of these sort of things,right?So shifting as much of it to data as youpossibly can should be your end goal.So that's what Pokemon defs look like.Before we get into theactual battle, we wantto take a look at whata battle sprite is.So a battle sprite is what wasrendering onto the screen, right?So we take a look here.That's not a battle sprite,but almost a battle sprite.That was just a texture.So if we get into abattle, slowly but surely.All right, so these are battle sprites,and they don't look much differentthan a regular sprite,and they're not that muchdifferent than a regular sprite.But they have some functionality that'simportant, mainly that functionalitywhere one is flashing, and thenone was being opaque, right?So in order to do both of those things,we need to store some sort of datawithin our sprite, right?Yes?AUDIENCE: Zelda for theinvulnerability flashing.SPEAKER 1: Yes, exactly.For what we used in Zelda forthe invulnerability flashing.For the enemy, or I should say, forwhoever is getting attacked, yes.They are getting an opacity flag stored.They have an opacity flag stored intheir object that we can tween, right,we can tween on and offover the course of time.That's what we did with the entityin Zelda when it took damage.And we set it to invulnerable,and while it was invulnerable,it was flashing on and off.But we can't necessarily do that withthe sprite that's blinking white,because there's not reallya like white flag, right?We can't make somethingcompletely white with just a flag.That's something that we actuallyneed to use a shader for.And so a shader, and we're not goingto get into too much detail about this,shaders are pretty complex,a little arcane at first.But what they are is effectivelya little program thatruns on your graphics card, and thatlooks at when you're drawing something,it looks at every pixel dependingon what kind of shader you're doing.But for the sake of this demonstration,we'll look at every pixelthat you're drawing to the screen,and perform some sort of functionon that pixel, and producea new value, right?And this is how you get a lot ofreally crazy awesome things to happen,but it can be pretty insane.Shader Toy, I think is the websitethat has a ton of really cool--I'm not going to pull it up now, just'cause I don't remember the name,I believe it's shader toy.There's a website where people postall the shaders that they've written,and you can see a lot ofreally crazy stuff, thingsthat you would never imagined werepossible with just code like thiseffectively, lookingat positions of pixelsand onthe screen and whatnot.But effectively what this does, this isa white shader, the goal of this shaderis to just turn asprite completely white.That's all the goal of this shader is.So it gets a float called whitefactor, which say here.And then white factoreffectively is justgoing to be summed ontowhatever the RGB isof that pixel, whatever pixel thatwe're drawing when the shader is active.What that has the effect of doingis, white factor, if it's equal to 1.Here's the thing about shadersand a lot of this stuff,a lot of the datastructures within shadersare based on floats thatare from zero to one.So if we assign the RGB of somethingto a vec 3 that's 1, which is 111,that's going to be 255, 255, 255.Therefore, that pixels RGBis white, pure white, right?And so what we're doing here is onour battle sprite, self.blinkingand one or zero, remember, that'sthe LUA operations.So we're saying, if self.blinkingis true, one else zero.So send our shader white factor basedon whatever value self.blinking is.And so that will have the effect ofthe shader getting a one or a zero,and adding a one or a zeroto the RGB of that sprite.And if blinking is setto true, the sprite'sgoing to basically be drawnevery pixel at 255, 255, 255.Otherwise, it'll get drawn withwhatever that image's pixel value isat that position.Does that makes sense?OK.The syntax is a littlebit weird, but that'swhat's happening here in this shader.And there's a link herewhere I found the shader,but it's a very simple,very simple shader,probably like one of thesimplest shaders you could write.But it's a great example of what youcan do with a shader, and pretty simply.And it's nice, because you can takelike texture coordinates and do mathbased on that, or pixel coordinatesand do math based on that.You can pass in like a sinefunction for example, in your file,and have that sine function perform workon like RG or B value of your spriteand do all kinds of cool stuff.It's really neat, like the possibilitiesare limitless with shaders.But that's how we getit to blink, because youcan't do that outside of this--I mean, there's probably some weirdway could get it to work as well,but this is probably the simplest waywe can get our sprites blinking white.And so self.blinking just getsa timer.every0.1 or whatever.We'll actually see thatin the attack state.But that'll flick to self.blinkingbetween true and false.It'll negate itself over and over again.All right, so that's the battle sprite.Last thing we'll look at is anotherextremely simple class, opponent.All the opponent is is ithas a party, that's it.But in a fully fleshedgame, your opponentmight have a like trainer sprite.A message that itsays, like a full partyof Pokemon, a gold value thatwill give you when you defeat it,all kinds of things.But it's here just asa simple illustration.Yeah?AUDIENCE: puta method for on defeatif you want to maybehave it kind of collapsethe room or something like that.That would be anotherthing that you could do.SPEAKER 1: Oh, a method?Yeah, we can associate a methodwith an opponent called on defeat,or whatnot that will do arbitrarythings, collapse the room,or otherwise.Yes, absolutely.Or even push a new state,like to like teleportus to a new location in the world map.Maybe we like clearedthe elite four and wewant to get teleported tolike the end credits, exactly.Limitless possibility.So let's go ahead and take a look nowwhile we have just like 20 more minutesor so left.We'll take a look at the battlestate, because the battlestate and the states that they're inare probably the more complicated sideof how this works.So a battle state, we have a player, wehave a bottom panel, the bottom panelfor when we start thestate just for that part,but otherwise, we're alwayspushing things onto it.Whether we've started the battle ornot, because when we are fading in--sorry, yeah.Because when we initialize this state,we also push a fadeout state onto it.But we don't want to triggerthe tween of the Pokemon slidingfrom left to right untilafter that state gets popped.So we have a flag here, which will getset to true on the very first updateiteration.And then when thatgets set to true, we'llactually tween the Pokemongoing left to right,and kick off all the othersort of asynchronous processesthat exist thereafter.But let's look at the battle one moretime just to see what's going on.So I'm going to walkuntil I get into a battle.OK, we got a battle.So notice here, the fadein happens as soon as the--the slide in happens as soonas the fade starts, right,as soon as the fadefinishes, I should say.We get a message poppedonto the screen, right?It says a wild X appears.Right, that's the enemy Pokemon.We hit Enter.Turn this down a little bit.We hit Enter, and then we pop another--push another state onto the stack,another battle message, whichis very similar to a dialog state.Says go our Pokemon.And then we push a menuonto the screen, right?We've got a menu that says,fight or run, a selection.It's a menu, which has a selection.And then now, this is thetop of the stack, right?So it's the only thing getting input.Everything else is rendering beneathit, but nothing's getting input.So we have the optionto either fight or run.Let's say we fight.We fight, we got a new statenow, we're in an attack state.Several things just happened.So what happens as soon aswe kick off the attack state?Yeah?AUDIENCE: You get a textbox saying, x attacked y.SPEAKER 1: Yep, so thefirst thing we have happenedis, a text box thatsays, x attacked y, whereit could be either us orthe opponent, because it'sbased on whoever has the higher speed.And then what happens next?AUDIENCE: .SPEAKER 1: Well, it does.So let's take a look atit right now and tellme what exactly happens assoon as the text box pops up.So what were the piecesthat happened there?AUDIENCE: Flash.SPEAKER 1: OK, so theattacker flashes white,right, which is theshader that we looked at.That's the shader blinking on and off.There's some timer that says,every 0.1 seconds, blink on or off.And then what happens?AUDIENCE: Then the damageis dealt. ..SPEAKER 1: Well, damage is dealt,yes, but what happens visually as soonas the white blinks?AUDIENCE: The other one blinks.SPEAKER 1: The other one blinks.What's the other one blinking?AUDIENCE: I'm not sure.SPEAKER 1: So it's opacity, right?So remember, we're doing the exactsame thing we just did with that white,with the blinking, but we'retweening every 0.1 secondsthe opacity of the defending Pokemon.And then we take damage.Then what happens when we take damage?AUDIENCE: The reverse basically.SPEAKER 1: Well, what gets animatedwhen the thing takes damage?We've animated the blinking,we've animated the opacity.AUDIENCE: .SPEAKER 1: The health bar drops, right?So we're chainingseveral things together.We're chaining-- first, we're doingthem every 0.1 seconds for six times,blink white.Then blink the otherthing opacity, right?And we're playing soundeffects at the same time too,we're playing a sound effect for theattack, sound effect for the hit.And then once that's finished,tween the health bar, right?So we've modified the healthof the defending Pokemon.And then what happens after the firstone, after that process is finished.AUDIENCE: Repeat for the other side?SPEAKER 1: Exactly, repeat the exactsame thing, but for the other side.But what are we doing inbetween each of those?We have to do something.AUDIENCE: Checking if somebody dies.SPEAKER 1: Checking ifsomebody dies, exactly.And if somebody dies--let's say we die, what happens?AUDIENCE: .SPEAKER 1: Well, we yeah, wego back to the play state.We fade out to black, and thenwe go back to the play state.What happens if we knock out the enemy?AUDIENCE: Go to this screen.SPEAKER 1: Exactly, andwhat happens on this screen?So what's the first thing that happens?Well, so recall, what happenedwhen the Pokemon died?What happened?AUDIENCE: It fell offits platform thing.SPEAKER 1: Exactly, so that's a tweenprobably, right, on his y value.Then what happens?AUDIENCE: .SPEAKER 1: Exactly, we've pushed abattle message state onto the screen.And then what happenswhen we press Enter?AUDIENCE: .SPEAKER 1: What justhappened right there?AUDIENCE:text box that says,you earned whatever experience points.Then you get your XP goes up.And presumably, itchecks if you leveled up.SPEAKER 1: Yes, correct.AUDIENCE: to level up.SPEAKER 1: Exactly, sowhen push a dialogueto the screen that says you've earnedx experience points, the XP bar tweens,right?We've gone up to however our ratioof current XP to next level XP is.We animate our text bar thatway, or progress bar that way.Then we push a fade instate, right, to white.And then we have to popeverything off the stack,and then push a fade outstate to the top of the stack,and then we're back to the play state.But if we do level up, we need to playthe right music, play the right sound,and then part of the assignment willbe actually, in that exact function,you're going to need to addsome behavior that will do what?AUDIENCE:display the change basically,and what the new one will be.SPEAKER 1: Yes, and whatare we going to need to do.What will we need to do in order to?AUDIENCE:what was it called?The selection box, but withoutthe selection part basically.SPEAKER 1: Yes, so once we'vetaken-- once we've leveled upand we're in that victory stateof the battle state, right,we need to push a new state,a new menu state, whichhas all of those stats and theamount that they've increased.And then when we pressEnter, presumably, weshould pop that off, and then popeverything else back to the play state,and then do the fade in as normal.And that is the battlestate in a nutshell,a lot of pieces that sort of are waitingon each other and input and stufflike that.But fairly easy to understand, justbecause a lot of it is very simplethings that are just chainedtogether over and overagain to produce this sortof interesting behavior.So here we have sprites,recall the sprites are whatwe're going to need to animate those.We have health bars, whichare progress bars, whichare just two rectangles that are--ones a line, a black line, and onesa fill that fills beneath the line,so that we get a sense ofhow much is missing, right?We get the width, the height, a color.We can give our progressbar any color we want to,which is how we get the differencebetween, say, a health bar and an XPbar.We just make one red and one blue, andwe draw them in different spots, right,but they're both equally progress bars.And then they get a value.Their value is whatever sort ofdetermines how much of the rectangleis scaled.And the max is how much thatshould be divided by in orderto produce a ratio for the total width--a scaler for the totalwidth, which will allow usto get the sense of an amount missing.And then a player circlex, opponent circlex for the ellipses, just the graphicaldetails for the actual Pokemon,so that we can get their stats, so thatwe can actually do dice rolls, or notreally dice rolls in this case,but so that we can add or subtractHP based on attack and defense.And so here was the update,so trigger slide in.So what trigger slide indoes, is a one second tween,which you talked about, right?The Pokemon going left to right,or left to right, right to left.There x values, justtweening in over one second.As soon as that's finished, we'regoing to trigger starting dialogue.So the starting dialogue is push abattle message state onto the stack.The battle message state is just like adialogue state in that it gets a stringhere, so a wild something appears.It gets a callback function foronce we press Enter on that.And the callback function is itselfanother push of a battle message statethat says, go, and then our Pokemon.So notice that we're referencing theself.opponent.party.pokemon there,and self.player.party.pokemonthere to get the actual name.And then once we've popped that off,then we push a battle menu state here,right?So let's take a look atthe battle menu state.So this is interesting, becausethis is where we actually definethe behavior for our menu works, right?Recall, we need something to tellsus what happens when we press Fight,and what happens when we click Run.So when we click Fight,notice here items,right, self.battlemenu getsmenu, and menu expects items.This items key, this table gets fedright into the selection, right?And the selection, itexpects remember, a text,because it has to know whatto render at that index.And then an on select function.And that on selectfunction is the callbackthat gets executed when you pressEnter at that particular locationin the menu.In this case, fight, what that does isit pops this battle menu state wherewe no longer need the menu, so pop it.And then push a new take turn state.And then take turn state in this game isthe Pokemon fighting each other, that'swhat the take turn state is.And it could have been calledfight state, for example,but take turn state isa little more versatile.If we wanted to maybe make,maybe one Pokemon wants to run,the enemy wants to run andwe want to fight, right?But you can't always run,so they should try to run,and then we can still fight them.Or they can use an item, orwe can use an item, right?There's a lot of differentthings you can do.Or we want to throw a Pokeball at them, and if we fail,then they should fight us, right?Take turn is just ageneral purpose statethat we could repurposefor whatever use wewant to with any interactionbetween us and the opponent,whether it's fighting, running away,or using items, catching them, anyof these combinations of things.But in this case, for the sakeof this example, for simplicity,we've only implemented fighting.The we and the opponent fight eachother during this state, whichis, one attacks the other,and then we check for deathsin between both of those.And then go to victory or feintingdepending on which of those holds true,if either.Running is slightly different.So if we run, I've programmed it to be100%, it will 100% of the time work.In Pokemon, you actuallyhave a chance to runbased on what the delta isbetween you and your enemy.So if they're stronger than you, youactually aren't guaranteed to run away.So what we do here in my implementationis, we just pop the battle menu,so it's gone.And then we push, you fled successfullyto the screen, this battle message.But there's a difference here versus theother battle messages that we've shown.I mean, it's not really different,but it's something to keep in mind.So I'm going to get into a battle.And so first of all, with that messagethat you just saw on the screen,I had to actually press Enter, right?I discarded it explicitlyby pressing Enter.And that holds truealso for these messages.It won't do anythinguntil I press Enter.So I press Enter, and then I pressEnter, and it does it's thing.But notice the differencebetween when I hit Run.I'm going to hit Run, I fled,and it does it on its own.It's not waiting for input, right?So how have we implemented that?Yeah?AUDIENCE: Using timer,you'd automaticallydo it the same way you would afterwards,instead of waiting for you input,you just wait for the timer to end.SPEAKER 1: Exactly, so we use a timer,and then when the timer is finished,we pop the battle message just like wewould have popped it by pressing Enter.This false flag is whatallows us to do that.We press false and falseis, can we input or not?And we can't.So actually, if we didn't doany timer thing after this,and we just did that false flag, thebattle message would be there forever,and we could never get rid of it, ever.It would get stuck forever.So we got to be responsible andsay, OK, we're going to put a timer,we're going to call timer.after0.5 seconds immediately after that.We're going to push a fade in state.And then we're going to do these two popoperations here as soon as that fade inhappens.This first pop will pop themessage, right, this message herethat we didn't pop through input.So this is actually garbagecollecting, in a sense, for us.It's discarding the message thatwe couldn't discard automatically.And then we're going to popthe battle state, right?So running will push the battlemessage, trigger a timer tweenfor our timer.after five seconds,sorry, push a fade in state.And then after the fade in statesdone, then pop both of those states.The message and the battle statetake us back to the play state.And that's where we'll beas soon as that's all done.And that's all that's inthe battle menu state.Any questions as to how the battle menuworks, the difference between fightand run and sort of how those operate?OK.So let's take a lookthen at the take turnstate, which is the last pieceand the largest piece I would say.This is the most relevantto the assignment.So we maintain a reference to whichPokemon is first or second to go,which sprite is first or secondto go, and which progress bar isfirst or second to go up here.And we do that, like Isaid, based on speed.So whichever Pokemon isfaster, and we could have alsomade this a little bit shorter, justby keeping the sprites and the progressbars as members of thePokemon object, or the class,but since they're kind ofseparated, like we don't necessarilywant a Pokemon to have a referenceto it's progress bar at all times,or I mean, you could.There's nothing preventingyou from doing it.It would only serve the purposeof shortening this code here.But we need to keep a reference tothis so that we can call attack here,which is this large bit ofcode twice, without needingto duplicate all of that code twice.Does that makes sense?So Tony, did you have a question?AUDIENCE: Well, I was justthinking, you could probablyput that into a helperfunction where you justchange the order you pass it in.SPEAKER 1: Sorry?Say it again.AUDIENCE: I just kind of feel like,I guess you could take the code,and you could avoidduplicating that I guess.'Cause it's just reversed, sowhat you could do is you could--if you passed into a helperfunction, which you would just,instead of passing it first--instead of passing it, opponentPokemon, player Pokemon,you would pass it, playerPokemon, opponent Pokemon.And that would probably work I think.SPEAKER 1: Well, you also haveto take into consideration--so the comment was, you could pass inthe player Pokemon and the opponentPokemon into a function, and thenyou reverse them in that function,I'm assuming, have reverencethem and reverse them.But the sprites aredecoupled from the Pokemon,and the progress bars are alsodecoupled from the Pokemon.So we could shorten this by makingthese four things here fieldsof the Pokemon objects,but they're not strictlypertinent to the operationof the Pokemon object.And it sort of kind of makesthe Pokemon objects a littletoo, not basically abstractor lightweight enough,and it only serves thepurpose of this point,of just shortening this bit of code.There's probably a more elegantway to do it, but it's hard to say.If this code were to get larger, maybe.But the gist of thisis basically to havea pointer to whatever Pokemon, progressbars, and sprites should operate firstin the attack versus whatshould operate second.And then the two will trade blows inorder based on who's first and whosecond.So when we enter thetake turn state, we'regoing to trigger that attack, here thisfunction attack, which we'll take infirst, second, first, second,first, second for the Pokemonsprite and progress bars.And then anonymous function,which get's executed assoon as the attack is finished, right?So this is a code that will pop amessage that gets pushed in attack,and then this is where weactually check deaths, right?And it will determine whether we goto victory or faint screen or not.If not, and we return if so.If not, we're going to doanother attack, but see,everything is reversed now.Now it's second, first,second, first, second, first.So we have the samefunction, self attack,which just takes in the attacker.And it's effectively, attacker,defender, attacker, defender, attacker,defender for the Pokemonsprites and progress bars.And so the attack functionhere first pushes a--well, OK.What does the attack--let's go over it one more time.What do we think the attackfunction does in order.We covered them justa moment ago, but whatwas the order that happens whensomething attacks another thing?Yeah?AUDIENCE: The attacker blinks white.SPEAKER 1: Attacker blinks white.AUDIENCE: Then thedefender blinks opacity.SPEAKER 1: The defendertoggles it's opacity.AUDIENCE: And the health bar shrinks.SPEAKER 1: Health bar shrinks.Exactly, and then that'sbasically it for attack, right?Blink, play a sound, blink,play a sound, shrink the bar,and also we're doing damagein that function as well.We actually have to changethe status of the Pokemon.So this is effectivelywhere it starts, right?We place a battle messagestate onto the stack that says,the attacker name attacksthe defender name.Notice that it gets falsejust like the run messagedid, because we're notaccepting input here.But it's up to us actually, it doneup here at line 42 of the enter state.But we're going to after 0.5seconds, play the attack animation.So power up sound every 0.1 second.We're going to member theblinking flag on the sprite,we're going to toggle it bysetting it not to itself.So if something is not itself, ifit's a truthy value, it becomes falsy,if it's falsy, it becomes truthy.So basically, togglingbetween true and false.Limit of six, right,because remember, every willdo something every amountof time indefinitely,unless you pass in a limit of somevalue, in this case, a limit of six.So we're saying, only execute this codesix times, only blink six times, right,only toggle six times,blink three times, right,because it has to go on and off.And then as soon as thosesix iterations are completed,we call the finished functionon that timer object,which takes an honest function.As soon as that happens, wedo the opacity bit, right?We blinked the attackers, so nowwe've got to blink the defender.So we play the hit sound.We do the exact same thing that wejust did for the blinking, only now,every 0.1 second, we are settingits opacity to either 64 or 255,depending on what the valueof its opacity is, right?So we are toggling between 64 and 255.Limit of six, take afunction, calculate damage,which we've just very simply done it,attack minus defense, right, up to 1though.So if the defense is actuallyhigher than the attack,which will still do at least one damage.And then over 0.5 seconds,we take the defenders bar,and we tween the value equal totheir current HP minus damage, right?And then that will set in the bar, inthe progress bar, it'll set its value.And even though the progressbar is behind state wise,right, it's on the bottom of the stack,because it's on the battle state.And we're in currentlythe take turn state,but because we're still manipulatingthe values of that state,and we're rendering every state,we're actually still manipulatingthat state regardless of the factthat it's not on the top of the stack.So that allows us to shrink thatPokemon's progress bar regardless of itbeing on the top of the stock or not.Then once that's finished,once the tween is finished,actually set the currentHP to that amount,because we're only tweening theprogress bar's value, which isindependent from the Pokemon's value.And then that's the end of the attack.The attack is completelyfinished at that point.So any questions as tohow the attack works?Just a chain of tweens basically.So we do an attack, then checkdeaths is the next function.And we're almost finished, I'm going tokind of go quickly here, it's at 7:30.Check deaths is the player Pokemoncurrent HP less and equal to 0,or is the opponent Pokemoncurrent HP less and equal to zero.If the former's true, we need tofaint, and if the latter is true,we need to go to victory.So faint is effectively a battle state,right, when it says, you fainted.And then what?Remember what happens when we faint?AUDIENCE: textbox, and then it leaves.SPEAKER 1: It leaves,do you remember howit leaves as it differs fromlike running away, for example?AUDIENCE: .SPEAKER 1: Well, beyondthat, aesthetically,do you remember how it's different?AUDIENCE:differently to black, I think.SPEAKER 1: It does.It fades to black instead.So that's how we candifferentiate when we're faintingversus when we're running away.And so that's what we're doing here.Notice that the fade in stateRGB is zero, all of those.So it's going to fade in to 000255,as opposed to 255, 255, 255, 255.So it's going to be a blackfade in versus a white fade in.And then once we've--this it just sort of athing that I implemented sothat we can keep playing indefinitely.But once that's finished, restorethe player Pokemon to full health,resume all the field music stuff.And then once we've pusheda fade out state, 000,and then we've gone backto the field, let's push.Notice that here it takes a function,right, after the fade out state's done.Once the fade out is finished-- so assoon as we're back to the play state,push a dialogue statethat says, your Pokemonhas been fully restored, try again.Which will take the context,and we'llto press Enter to get past it.That's fainting.Victory is a little bit more robust.So victory is-- do you rememberwhat happen when we get a victory?AUDIENCE: Well, it has tocheck leveling up as well.It says, you've defeated youropponent, then your XP bar increases.Then if you've leveled up, ittells you that you leveled up,and then it leaves.SPEAKER 1: So it tells you you defeatedyour opponent, XP bar increases,checks for a level up, and then leaves.After displaying the levelup message or not, it leaves.It pops everything back tothe play state, exactly.So remember, the veryfirst thing that happensthough, the opponent sprite getstweened over the course of 0.2 seconds,it's y value to virtualheight, which means,all the way to the bottomof the screen, right?The typical defeated your opponentfrom Pokemon sort of animation.Once that's finished,play victory music,push a battle message statethat says, victory, right?Once that's popped of thestack, calculate the XP,which is, I just chose arbitrarilysum all the IVs of that Pokemon timesit's level, and that's the XP you got.Push a state that says,you earned x XP, right?It's false, so that meansit doesn't take input.So that means it's up to us inorder to pop that off the stack.So after 1.5 seconds, we play a sound,and then we tween that XP bar going up,right?So that's what's going on here,self.battleState.playerxpbar,we're tweening of themath.men, of the XP plus XP,or XP to level, because if we don't, itcould go past the edge of the XP bar,because we could go overour XP to level, right?Let's say we have 10 XP till wegain a level, we could gain 20 XP.We'd be 10 XP overboard.So we don't want to tween our XPbar past the edge of the XP bar,it would be a graphical glitch.So a math.men our XP plusXP, and our XP to level,which will take thelesser of the two values.Once that's done, it's tweened,we're going to pop the message off,and then we're going toactually add the XP, level up.So this is where we level up ifthe XP is greater than XP to level.Play a sound, set the XP to thecurrent XP minus our 2 level XP,which will mean that we'llhave some carry over, right?And then actually callthe level up function.Now here is where--oh, and also after that,congratulations, you've leveled up.Fadeout white, which isjust a white fade out here.I used it twice, so Imade a function for it.Just pushes a fade in state.Stop the victory music, play the fieldmusic, pop, push a fade out state.So either way, when we've got a victory,we're going to push a fade out white,or we're going to callfade out white, correct?So push a battle messagestate, and then as soonas we press Enter, because weleveled up, fade out to white.And if we didn't level up,but we still got to victory,we still need to fade out white.And so this is where yourassignment is, assignment 7.Assignments 7 is, notice that wehave self.playerPokemon level up.The key thing that we aregoing to need to do hereis add a menu that showsus how we leveled up.And if you recall, playerPokemonlevel up returns all the statsthat you've increased this level.So you can show a menu that justsays, your HP plus that amount, right?You're going to get all four values.It's going to explode toall four of those values.And then you're goingto create a new battle--or not new battle menu, but anew menu of whatever you want,but probably on the right side ofsome vertical height for items.The only differencehere, the only key thingthat you're going totake into considerationis, and I'll go back to theslides, because we're actuallydone at this point going over the code.But the selection items, you won'tbe able to actually select anything,it's just going to be purely visual.So you're going to need to editselection to have the optionto not have a cursor.And this is detailed in thespec, which was actuallyreleased before lecture today.So you can take a look at that.But you'll need to makea change to selection.But all the pieces are there.It should be a fairlyeasy assignment as longas you understand how thestates work, how the menu works,and how to create a menubased on those values,and how to actually getthe values from level up.So some missing features that we didn'ttalk about, which we didn't implementare, for example, thedetailed level of screen,which is your assignment,monster catching, right?We only have a party of one Pokemonthroughout this whole entire thing,but one of the arguably main appeals ofthe game is to be able to catch more.So that would be something to add, toprioritize probably adding to the game.A field menu so can actually lookat all the Pokemon you've caught.That would be nice, so you canactually see how much HP they have.In item inventory, because thegame, the regular games have items.You can use potions, youcan find gold nuggetsthat you sell for a ton of money.Different abilities, currently we onlyhave basically one fight operation,which is like a tackle.And the game itself,the regular game haslike over 100 different movesthat have elemental attributes,and do different things,and cause status effects,buff you or your opponent.So adding those isappealing, and maybe beingable to represent themas data is nice to.Trainers that you can encounter inthe game that have their own presetor randomized Pokemon for to fight.Monster evolution, because that'slike one of the funnest thingsis taking a really weakPokemon, and like raisingit to become really strong, andevolving it at a certain level.Towns, routes, other levelsbeyond just our basic square area.Monster breeding, which isintroduced in the second series,so that you can take twoPokemon and have a chanceto get an egg with really good statsor a really rare Pokemon from it.And then like a day night cycle maybewhere different Pokemon come outat different times of the day.So you are incentivize toplay at different timesof the day for that purpose.But that was it for Pokemon.Next week we'll actuallybe diving into Unity.So we're actually done withLOVE 2D, which is a lot of fun,but now we'll be goinginto how to make 3D games.So this is a screenshot from thegame we'll be making next week,which is a 3D sort of side scrollingFlappy Bird esque helicoptergame based on a famous webgame called Helicopter Game.And it was sort of one of theearly ancestors to Flappy Bird.On the Wikipedia page, itactually says that too.I remember playing, it was back in like2007, or 2006, or something like that.But your goal in this game-- thisis a modified version of that--your goal is your-- everything is 3D,but it's a side scrolling perspective.So this is called 2.5D for that reason.You're controlling a helicopter,you're the purple helicopter.And your goal is to in aninfinitely scrolling world.So we'll revisit infinite scrolling,but in 3D, avoid skyscrapers.So you can see there is a greenskyscraper, crudely modeled.Collect coins, so you can seethere's a coin there, it's a 3D coin,it will always be spinning.Your coins are up at the top right.You'll see a backgroundthat's infinitely scrolling.And then you'll havejets that will randomlyfly above you to sort of give youanother sort of layer or dimensionof obstacles to watch out for.And this will teach us a lot ofthe basics of how unity works,so we can start getting into even moreinteresting things like a first personlike sort of core exploration game.And then lastly, when we endthe semester with Portal,we'll look at a coupleof fancy things there.But that was it for Pokemon.Thanks for coming, andI'll see you guys nexttime.\n"