From VbGORE Visual Basic Online RPG Engine
vbGORE's windows are very flexible and powerful, but at the cost of that comes complexity. This article is to help you learn your way around how windows work in vbGORE, and how to create your own. The windows referred to are in-game windows, such as the stats window or inventory.
Defining the window
The first step is to define the window. Every window consist of its own User Defined Type (UDT). This allows each window to carry its own elements, and function completely different from one another.
In the client, search for:
<vb> Public Type GameWindow </vb>
This will bring you to the end of the game windows list. First, look at how other windows are added and what they consist of. The most basic window consists of:
<vb> Public Type MyWindow
Screen As Rectangle SkinGrh As Grh
End Type </vb>
Screen defines the window itself, as a whole. The Rectangle type is just used to define the location and size of the window. SkinGrh tells us what Grh is used to draw the window. This is defined later in the skinning.
Once you create your window UDT, add it into the GameWindow UDT.
Next, you will have to define the ID of the window. A window's priority is ordered by its ID. A higher priority means it is drawn above other windows when in the background (not the last clicked window), and receives input events before others.
<vb> Public Const NumGameWindows As Byte = </vb>
Add your own window, such as:
<vb> Public Const MyWindow As Byte = 14 </vb>
and update the NumGameWindows value to the highest window index used. If you want to make your new window a higher priority, you may have to do a bit of number re-arranging.
<vb> Public Type GameWindow
... MyWindow As MyWindow
End Type </vb>
This will allow you to access the window through GameWindow.MyWindow, just like all the other windows.
Next step is to load up the window. The windows are defined in the skins file, located in \Data\Skins\. How you define the skinning is up to you. The most basic information would consist of the location and size of the screen, along with the Grh used to draw the window. All this information is entered in the Public Sub Engine_Init_GUI sub. See how the other windows load for examples.
For inner-screen areas, such as a button located on a window, you want to define the location as where it appears on the window and treat the variable as such. Whenever you go to make position-based calculations on that object, you use the ScreenLocation + ButtonLocation. This will make more sense later when we get to handling input.
In most all cases, all the rendering information will be located in the Private Sub Engine_Render_GUI_Window sub. Just add a new Case for your window:
Select Case WindowIndex Case MyWindow 'Do stuff ... End Select
You want to start with the window as a whole to be rendered first, followed by the objects located on the window. Keep in mind that which is rendered last, appears on top of those rendered before it.
This is where things get trickier. You often want to define support for left-clicking the window no matter if it uses click events or not. This will ensure that you can drag the window, or at least select it to make it the "last clicked window".
Left-click handling is all handled in the Input_Mouse_LeftClick_Window function. There are plenty of other windows in there to give you a good idea of what to do, but here are some important variables you might want to know about:
- Input_Mouse_LeftClick_Window = 1
- This means that the window was clicked. Once this returns = 1, no more windows will look for a click event. This prevents clicking more than one window at a time.
- LastClickedWindow = ...
- This variable will set this window to the up-most window, and give it highest priority.
- SelGameWindow = ...
- This variable "grabs" the window for dragging events. It is often used only if no other objects on the window were clicked.
For right-clicking, the idea is pretty much the same, but handled in the Input_Mouse_RightClick_Window function.
Finally, for dragging, we want to go to the Input_Mouse_Move sub. In this sub, scroll to the bottom. You will see many very similar ElseIf blocks. What this does is just changes the window's Screen values.
Copy the following, and paste it into the sub. Make sure to replace MyWindow with the name of your window.
ElseIf SelGameWindow = MyWindow Then With GameWindow.MyWindow.Screen .X = .X + MousePosAdd.X .Y = .Y + MousePosAdd.Y If WindowsInScreen Then If .X < 0 Then .X = 0 If .Y < 0 Then .Y = 0 If .X > ScreenWidth - .Width Then .X = ScreenWidth - .Width If .Y > ScreenHeight - .Height Then .Y = ScreenHeight - .Height End If End With
Putting the window to use
All that is left now is that you show the window by using ShowGameWindow(MyWindow) = 1. This will make your window visible. Attach any code you want to any events of the window that you want. You can also add in key-press events by going to the key-press routines in frmMain and checking if LastClickedWindow = MyWindow.