Placeholder Image

Subtitles section Play video

  • hello.

  • In this video, I wanted to create an easy to use men.

  • Ewing system on not just easy to use for the player, but also easy to use for me, the programmer.

  • And even though that might not sound like the most interesting of ideas, it turns out that the implementation of such a thing we'll use several c++ tricks that we've not seen on the channel before.

  • And I think it turned out to be quite interesting on the solution is quite elegant.

  • But before we start, let's take a look at what I'm building.

  • So the menu looks like this little pop up menu, and it's probably familiar thio people that enjoy retro games of a certain role playing game franchise.

  • And the idea is the following.

  • You have a list off commands that you can choose on.

  • You can see here that the list could be scroll up and down.

  • So the panel of the menu is a fixed site on Aiken Select.

  • One of the entries on a separate sub menu pops up on.

  • I can select one of those entries on.

  • We see a table of items that can be chosen, too, so the items within the panels do not need to be listed in just a vertical order.

  • A table can be created and we can see we can also block out certain items from being chosen.

  • The school bus here, on the right hand side of the panel, are in some way intelligence.

  • So they inform the user whether there are options below or above the current mouse cursor.

  • At any point, I compress the back button on to choose a different menu.

  • So let's choose Ah, white magic.

  • This time, when we get a different set of options, I can't move the cursor toe options that don't exist.

  • And it turned out you can also block off even sub menu.

  • So it's basically a hierarchical tree structure where we consent the properties that each branch and leaf of the tree.

  • When I do select an option such as the attack, there is no sub menu, so the system it elicits a small event.

  • I can go and do something with that event later on in my program.

  • In this case, it's got an I D.

  • 101 on.

  • I can see the name of it, too.

  • I'm going to pop the menu back up again, and this time the institute Black on will choose Bio to here so you can see the events appear in a nice, consistent way.

  • In many ways, this could be regarded as a graphical user interface on dhe.

  • Unlike many graphical user interface technologies, I wanted to build it in such a way that it was easy for me to use and to demonstrate this rather oddly, I'm going to look at some of the final code before we start programming.

  • Fundamentally, the system contained two objects.

  • The menu object on the menu manager.

  • The menu object is the tree.

  • We can access the levels of the tree by their own name, so Maine is the overall menu.

  • This is the attacks of menu.

  • This is the magics of menu on.

  • If we wanted further sub menus, we simply just make them exist.

  • To hear I created the White Magic menu on rather than typing this out each time, I can create a quick reference to that location on.

  • Then add in the sub items.

  • The panel sizes are in some way intelligence about what size they need to be, but they contain a two dimensional table.

  • So the top level menu, if you remember, was just a linear vertical list.

  • So it's got one column of entries.

  • But four visible rows of entries on this allows me to control the size of the menu, depending on where I want to place it on the screen.

  • In contrast, the magic menus are a bit larger.

  • So here I'm setting.

  • The tables have three columns across and six visible rose down.

  • Now, even though I've specified a two dimensional table, I still add to the items to the menu in a sequential order.

  • I can update some of the properties of the items simply by calling those properties while Stan creating the item.

  • And in fact, I could do this at any point after the item has been created.

  • So I can change the states of the item in real time, depending on the conditions of the game.

  • So if you recall in the Black Magic menu there were two options which were disabled, you see this set I d everywhere.

  • That's actually an optional extra.

  • I could very well use the string identify to determine what event has occurred, but sometimes it's easier to work with ideas in your program so wanted both options available, so this is really an optional extra.

  • In fact, anything like this is an optional extra.

  • Once I've constructed the full menu and then build it and that goes and recursive, Lee constructs all of the panels to be the right size and sets off the layout and makes a few intelligent decisions about what to display on.

  • I tell the menu manager you're going to work with this menu object, so the menu object is the tree.

  • The menu manager is the user interface to the tree, and here I've linked to user interface to that menu manager.

  • So as the user presses, the arrow keys were going to navigate around the menu system when they press the space key.

  • That's going to be a confirmed action, and several things might happen when you press the space key.

  • If there's a sub menu available, it'll pop up the sub menu.

  • If there isn't, it will assume that we're at the leaf of the tree, and therefore what we've selected is an action, and it will return the menu object associated with that location.

  • We can also press the back button.

  • And so if they returned, command object is not no pointer.

  • Some sort of user action has occurred, and we can interrogate that menu object and perform the relevant action as necessary.

  • The menu is also responsible for drawing itself.

  • In fact, all I need to do is call this draw function off the menu manager.

  • It feels a little unusual looking at the implementation code at the start of the video, but I wanted to put into context what we're really trying to do here.

  • I want to use a navigable, intuitive menu.

  • It's also very easy for the programmer to use, and you should compare this to regular graphical user interface frameworks on.

  • In fact, it just so happens I have one.

  • I've not made a video about this before, nor have I release the source code for it.

  • But it is actually a working and flexible windowing systems for the pixel game engine.

  • So we've got windows that can be selected and moved around.

  • We can choose the individual controls, got controls that highlight on mouse cursor over on things such as text entry on different dialogs can be selected two, for example, in this case, open a file.

  • This is a far more sophisticated graphical user interface framework, but you pay the price for that sophistication because the implementation of it is also quite sophisticated.

  • It's highly object oriented where we create one layer on, add other similar layers to it at certain locations.

  • And then we have an event system which passes around all of the different event that the user can throw at it.

  • And then we need to build the dialogues and the frameworks in order to be shown.

  • So all of this is actually concealed away in a pixel game engine extension, as I've mentioned not yet released and we can see the construction off the dialogue.

  • So this was the dialogue with the Czech buttons, and the test buttons on is a little bit more complicated.

  • We need to choose a particular component type, set its properties, set its location and then added to a parent window on all of these controls.

  • Just Azzan, WX widgets and Q T.

  • These air also eligible to be parent windows so we can customize things at quite a fine level.

  • On this sort of approach is great for Windows based interfaces, so if you've got a mouse and lots of options, which are going to be fiddly and lots of men using you need buttons and scroll bars and lists and all that sort of thing perfect.

  • But if you just want a quick pop up contextual menu in your game, then this object oriented approach is considerably overkill.

  • Now I know to some, the concept of a full, integrated, gooey framework would be a really exciting video, and maybe I'll make a video about that in the future.

  • But in this instance, I wanted something that was simple and quick and easy to use.

  • And this this entire menu system could be put on top of whatever you're rendering in the background, for example, a battle scene.

  • And quite importantly, I feel it doesn't require the use of the mouse, so we could also tie in some controller input quite easily.

  • So let's get started.

  • But just before we do, I wanted to bring your attention to a small community endeavor.

  • It's the community 0.1 loan coded dot com blawg on.

  • The idea is that members of the Discord community analyst YouTube community can write technical articles about programming technology game reviews.

  • Whatever that interests us is a community for others to see on.

  • It's early days yet, so there's not a great many articles here, but there are some already particularly talking about how to use the pixel game engine in certain ways.

  • This one, for example, is looking at how we can explore binary mathematics on the rules so far is that anything that's interesting to a member of the community is eligible to be included on the platform.

  • So if you're feeling creative on, want to write for a platform that people do actually visit and we'll see the articles, then shout out on the discord server for now, and we'll get you settled now back to the menu ING system.

  • We know that the manual system is going to consist off panels, and each panel is going to contain a table on the table consists of a certain number of columns and a certain number of visible rose.

  • So in this case, our table is two by four.

  • Candle itself is a menu object on the table.

  • Cells also contain menu objects, and as I add more menu objects to the table, the table gets populated in the following order.

  • If we've got more objects than we have visible cells, then you can conceptually assume these air being added below.

  • Now let's suppose I take any one of these men you objects.

  • Let's take D here.

  • I can specify that De is also going to have some Children, and I don't need to specify that explicitly.

  • I just add Children to it in the same way I've added a through N here, and I do apologize.

  • If there was some issues with the sound at the moment, there is quite a storm raging.

  • Whilst I'm recording this video, it's a shame that forthis many objects my table is going to be one comma five.

  • So it's only going to have one column of entries, but it's going to have five visible rose and again as we add items to them.

  • The same story applies because D in this menu object is a menu object that has Children.

  • We can identify it as being the title off.

  • Some sober menu that's going to appear on will do that by putting a small red icon pointing to the right.

  • So when the user moves the cursor to the D location and presses.

  • The action button will pop up the sub menu belonging Toa Item D, and we can continue constructing our tree using this approach with his many levels as we like, because menu objects can have a whole set of properties associated with them.

  • And in this video, I'm really looking at a very simple one, such as the ability to be enabled and disabled.

  • We can change how we draw the menu object in the table cell.

  • Now, don't forget.

  • The primary goal is to come up with a system which is easy for me to use on your notice.

  • We've not specified the dimensions of anything other than the sizes of the tables we want in our menus.

  • Each menu object is able to return the dimensions off the space it requires to be viewed.

  • Now, in my simple menu system, all we're looking at is one line of text.

  • But looking at this menu, for example, how do we determine how wide it needs to be?

  • Well, suppose we started to add items to it, said well at Cat Dog orange.

  • I want to ensure that the largest command in the list is fully visible.

  • And so when we construct the menu object, it will look at its Children in order to work out which is the largest and use that dimension to influence the size of the panel.

  • The same thing happens in a two dimensional table.

  • In this case, orange is still our largest entry, so all of our cell wits will be able to accommodate the word orange.

  • Captain Dog will just be left justified on this gives a pleasing visual aesthetic of order.

  • A table cell will naturally be the same size as the largest object within the menu object.

  • But you might not want to draw them old right next to each other.

  • You're going to need some space around them, too.

  • On I called this Paddick, which is how much space do we want around our table cells.

  • To construct our menu, we effectively build a tree off nothing but menu objects.

  • So a menu object can have many child menu objects, which can have child menu objects, which can have child menu objects, et cetera, et cetera.

  • Each menu object is given a name, so in this case, our root menu is Maine, and it's got too many objects which don't have any further Children attack and defend.

  • But it does have one that has two Children magic, so we'll make sure that magic is drawn with our little sub menu indicator effectively.

  • The names highlighted are the titles of the menu object, and we differentiate between the menu object being a command or a Superman you based on whether or not it is a leaf of this structure.

  • And so the leaves we have here are attack and defend, but also ice fire on our white magic spells to when the user presses confirm over one of these, we can effectively fire an event back to the host system.

  • When a menu object is selected, that's not a leaf.

  • Then we'll open up the child menu.

  • So I think we've established now that all of the data is menu objects.

  • But to manage the cursor and the drawing of the menus, we have a menu manager because this is a tree.

  • There is only one singular path from this item through to this item here, and I want to display all of the menus that we've taken to get to that path.

  • And so the menu manager will maintain a sort off stack where our root menu system it is always at the bottom of the stack on the menu currently being interacted with the user is at the top of the stack.

  • The menu objects themselves are responsible for positioning a cursor.

  • And so when the user presses the up, down left, right and action keys, we just forward those events on to whatever is at the top of the stack.

  • In this case, we've got a single one column list, so the left and right keys aren't really going to do anything.

  • But the up and down case we'll move our cursor accordingly when the user presses the back key or we need to do is pop whatever is off the top of the stack.

  • And naturally, our focus returns to the menu object, which is now at the top of the stack.

  • We should have been the preceding menu object, so because we only have this singular path through to a final action, a Stack makes a really nice data structure to maintain our rendering order on dhe deduce where we need to send the event to in this two dimensional table menu Of course, the left and right keys now matter so the cursor can be moved anywhere within this table.

  • But if they are here on, they press the action button.

  • We know that because this particular cell happens to have some Children, we return to the menu manager.

  • A new menu object to put on the top of its stack, and therefore it opens up this menu object I mentioned a few minutes ago that thes panels are actually windows into infinitely long tables, tables with an infinite number of rows.

  • By maintaining what is our top visible row, we can determine if we need to place indicators to the user.

  • That's the menu can effectively be scroll vertically.

  • In this case, if there are more entered rose in the menu objects than a visible, then yes, we do need to display some sort of indication.

  • If they use a house scroll down a bit.

  • We can use this top visible row indicator on the dimensions of the table behind the menu.

  • Object to determine these indicators in both directions.

  • I want the rendering of the panels to be in some way skin herbal.

  • I don't want them to always look the same.

  • So I'm going to use the nine patch approach to determine what's the boundary and contents of a panel should look like now.

  • This approach is quite commonly seen on systems where the controls may have variable sizes, and in principle it allows you to specify the four corners, the horizontal boundaries, the vertical boundaries onto the Phil off a rectangular shape on the screen of any dimension.

  • So, for example, I have a single sprite, which contains the information I need to render my panel and it split up into nine patches.

  • It just so happens that my patches happen to be eight pixels by eight pixels on.

  • I've chosen this for a reason.

  • It's because the built in front for the pixel game engine happens to be eight by eight pixels.

  • And so, by working in patch space, I could make sure everything is neat and tidy without having to do lots of cumbersome calculations.

  • So in this nine patch layout of my top left corner, which looks something like this on my bottom right corner, that's bottom left that one's button right on top, right?

  • So I got my four corners and then also specify my top boundary, my bottom boundary, the left boundary on the right boundary.

  • These could be graphically quite nice, and I'll show you mine in a minute.

  • But then I'll fill in everything else, and you notice all fill in this center cell that just with a plain background color needn't be playing.

  • It could be a texture that matches up with the cells either side of it to maintain a nice, curved corner aesthetic.

  • Regardless of what's in the background.

  • I've actually set these areas too transparent, and in fact, here is the sprite that I'm going to use.

  • So it's very small pixel art base Sprite on.

  • We can see my nine patches, so these are all eight by eight cells, which I'll creatively snap out of this spite in order to construct the final panel window.

  • I've also included some overlays for the indicators.

  • For more items open down on the sub menu on have included a two by two patch.

  • This approach allows me to change the look of the man Ewing system entirely, even run time, if necessary.

  • I could even have animated panels on just change the Sprite over time.

  • The menu system doesn't care.

  • All it cares about is the location of these primary objects in this source Sprite.

  • I'm almost done with the slides now, and I'm going to go through the code quite quickly for this video simply because a lot of it is the calculations of drawing positions.

  • It's not very interesting, but there is one facet I do want to talk about, and that is how do we store the data in principle, I'm going to use a standard map on We've seen standard map on the channel before in the code it yourself role playing game, Siri's effectively.

  • It allows you to store keys and value pairs.

  • So in a very pseudo conceptual level, you could consider, for example, map Apple equals one map.

  • Orange equals two.

  • And yes, I really do mean we can use a string is the identify so it looks like an array.

  • But we can effectively use another object as the index to that array, rather than just a new miracle index what you would with a normal array or director.

  • But in my map, instead of just pointing to a basic primitive type like that, I'm going to store a menu object on all of my menu.

  • Objects are going to have a map that holds the Children.

  • So taking a menu object, I could look at it's associative map passing the name off some supper menu object, which would return a new menu object so I could look at its map and look at the sub menu.

  • Objects returned there on so forth.

  • So I got this sort of recurrent data structure on by overloading the array access operator.

  • I can actually get rid of this bit, which means I can access a specific menu object in an easy to use and very clear syntax manner on.

  • I'm going to start out by doing it like this, but will quickly see there is a problem doing it this way.

  • But let's start writing some code.

  • As usual, I'm going to use the OLC pixel game engine, and here I just got a blank pixel game engine project.

  • If you want to see how to create one of these in Visual Studio 2019 then click.

  • The little Link of Bob made a video explicitly.

  • But how to set up one of these projects in that environment on all this program does so far is, it decides what the patch size is going to be, which is going to be eight by eight pixels on it includes standard map.

  • It also then goes and loads thestreet asset that I need to draw the menus and his views of this channel.

  • No, I love the retro aesthetics.