Creating an in game GUI from scratch...
BlitzMax Forums/BlitzMax Beginners Area/Creating an in game GUI from scratch...
| ||
I am creating my very beautiful game and I need an in game GUI. I have ifsoGUI and is very nice but a lots of gadgets are missing. For example there is no canvas gadget and I need it very very much for my game and my level editor. So I thought if I will create my own GUI from scratch it will be better with more gadgets and will fulfill the needs of my game. But there is one HUGE problem for now. I don't know how to create a GUI and the GUI theory in generic. I know in a GUI there are the windows and gadgets, but each gadget have and events too. Also I don't know little things about methods and lists. Any one of you , you have already working on your own GUI , do you have some idea how to setup my base gadget and how to inherit from this and add other objects (the gadgets) and how to link them. You can understand what I say, I have seen some source code from some guis but I don't understand some things about how the Create method works, how to add some object in a list. I created this code: Type Share_Variables Abstract Field x:Int Field y:Int Field width:Int Field height:Int Field gadget_list:TList = New TList Global window_list:TList = New TList End Type Type GUI_window Extends Share_Variables Function Create:GUI_window(x, y, width, height) Local w:GUI_window = New GUI_window w.x = x w.y = y w.width = width w.height = height w.gadget_list = New TList 'w.hidden = True Share_Variables.window_list.addlast(w) Return w EndFunction End Type Function Create_window:GUI_window(x:Int, y:Int, width:Float, height:Float) Return GUI_window.Create(x, y, width, height) EndFunction Graphics(640, 480, 0, 60) Global main_window:GUI_window main_window = Create_window(25, 25, 111, 122) While Not AppTerminate() Or KeyHit(KEY_ESCAPE) If KeyHit(KEY_ESCAPE) Then Ending() If KeyHit(KEY_SPACE) Then Ending() DrawText(String main_window.x, 0, 200) DrawText(String main_window.y, 0, 210) DrawText(String main_window.width, 0, 220) DrawText(String main_window.height, 0, 230) Flip - 1 Wend Function Ending() End End Function And it compiled. It returned the position and window dimensions. I think is a good start but I don't know the theory and what I do next. I will try to draw some graphic in those x,y,width and height variables. |
| ||
Have you looked at FryGUI, HighGUI 3 or CEGUI? |
| ||
I was thought to create one gui from scratch to understand how things work. The FryGUI is a dead link. Do other guis support canvas gadgets and skinnable interface? I don't understand how other guis work. And there is not book for blitzmax which explains all of these about types, methods lists etc... |
| ||
TAKE look at this one http://www.amazon.com/Programming-Absolute-Beginner-BlitzMax-ebook/dp/B005FCFGM0/ref=sr_1_1?ie=UTF8&qid=1350762993&sr=8-1&keywords=games+programming+for+the+absolute+beginner+with+blitzmax |
| ||
TAKE look at this one http://www.amazon.com/Programming-Absolute-Beginner-BlitzMax-ebook/dp/B005FCFGM0/ref=sr_1_1?ie=UTF8&qid=1350762993&sr=8-1&keywords=games+programming+for+the+absolute+beginner+with+blitzmax or this one http://www.truplo.com/blitzmaxbeginnersguide/wave1.html Hope that help :) |
| ||
I also recommend the Beginners Guide link that hotshot posted above. Explains a lot, very well. From this page there's also a link to a PDF. |
| ||
Ok, I have uploaded my copy of Fry.mod here. FryGUI says it supports both these things. CEGUI supports skins but it seems you have to figure out how to render to texture to create a canvas gadget. It has good docs/forum though. HighGUI 3 (thread here) supports both things too. It seems to be relatively simple so you could customize it if you want. There is a very detailed OOP/types tutorial by John J here. There is a linked list demo by fredborg here. There are also good examples posted to the online manual. "Games Programming for the Absolute Beginner with BlitzMax" is only on Kindle, it was also only sold as a book in N. America but you might find a 2nd hand copy. |
| ||
Thank you very much for you suggestions. The HighGUI 3 have dead links too. I am reading the books I found but I have difficulties with lists. |
| ||
The HighGUI 3 links work here. There is another book for BlitzMax called Game Programming for Teens, 3E (3rd edition) by Maneesh Sethi which is basically a beginner's tutorial for how to make an Invaders clone. It does touch on types and lists but not in much depth. There is also 3D Game Programming for Teens, 2nd Edition which is for Blitz3D. If you are confused about lists then look at the online manual data commands here. The examples posted there show you the basics pretty well. |
| ||
For GUI code look at Brucey's SFXR port, it shows how to code a simple GUI with buttons and sliders. GUI coding is sort of a conceptual bear at first but it's much simpler than you think. |
| ||
With the resources you gave me , I manage to create 2 windows (Very simple just squares) I can create as many windows as I want and I can put in any x,y position and make them at any size. Then I can change their color and their text. The code so far. (Works). 'Here are the types of the program Type Base_gadget Abstract Field x:Int Field y:Int Field width:Int Field height:Int Field parent:Base_gadget Field name:String Field gadget_color_red:Byte = 255 Field gadget_color_green:Byte = 50 Field gadget_color_blue:Byte = 255 Global gadget_list:TList = CreateList() EndType Type GUI_Window Extends Base_gadget Method Create:GUI_Window(wName:String, wX:Int, wY:Int, wW:Int, wH:Int, parent:Base_gadget) Local new_gadget:GUI_Window new_gadget = New GUI_Window Self.name = wName Self.x = wX Self.y = wY Self.width = wW Self.height = wH gadget_list.AddLast(new_gadget) EndMethod Method Show() SetColor(Self.gadget_color_red, Self.gadget_color_green, Self.gadget_color_blue) DrawRect(Self.x, Self.y, Self.width, Self.height) SetColor(255, 255, 255) DrawText(Self.name ,Self.x+2,Self.y+2) End Method Method Set_Color:GUI_Window(red:Byte, green:Byte, blue:Byte) Self.gadget_color_red = red Self.gadget_color_green = green Self.gadget_color_blue = blue End Method EndType 'Windowed Graphics(640, 480, 0, 60) 'Full Screen 'Graphics(640, 480, 32, 60, 1) SetMaskColor(255, 0, 255) SetBlend(ALPHABLEND | MASKBLEND) Global main_window:GUI_window = New GUI_window Global main_window2:GUI_window = New GUI_window main_window.Create("win1", 50, 50, 50, 50, Null) main_window2.Create("win2", 110, 50, 50, 50, Null) main_window.Set_Color(255, 0, 0) main_window2.Set_Color(255, 155, 50) main_window.Show() main_window2.Show() While Not AppTerminate() Or KeyHit(KEY_ESCAPE) If KeyHit(KEY_ESCAPE) Then Ending() If KeyHit(KEY_SPACE) Then Ending() DrawText(String main_window.x, 0, 100) DrawText(String main_window2.x, 0, 110) Flip - 1 Wend Function Ending() End End Function I still don't know how to select some object from the lists. In the create method I tried this code: Method Create:GUI_Window(wName:String, wX:Int, wY:Int, wW:Int, wH:Int, parent:Base_gadget) Local new_gadget:GUI_Window new_gadget = New GUI_Window new_gadget.name = wName new_gadget.x = wX new_gadget.y = wY new_gadget.width = wW new_gadget.height = wH gadget_list.AddLast(new_gadget) EndMethod Using new_gadget instead of self and didn't work. And I don't know how to select each of the new_gadget to change its color , position , size and text. With the self it worked. If you copy and paste the code above (before this one) and compile it works. |
| ||
Your problem is you've got 2 instances of the type a local one in create and the global. Either pass the global one as parameter to create and use it instead of the local or return the local and use a dummy global to access the method. Method Create:GUI_Window(wName:String, wX:Int, wY:Int, wW:Int, wH:Int, parent:Base_gadget) Local new_gadget:GUI_Window new_gadget = New GUI_Window new_gadget.name = wName new_gadget.x = wX new_gadget.y = wY new_gadget.width = wW new_gadget.height = wH gadget_list.AddLast(new_gadget) Return new_gadget EndMethod ... Global dummy:GUI_window = New GUI_window Global main_window:GUI_window = dummy.Create("win1", 50, 50, 50, 50, Null) Global main_window2:GUI_window = dummy.Create("win2", 110, 50, 50, 50, Null) Method Create:GUI_Window(wName:String, wX:Int, wY:Int, wW:Int, wH:Int, new_gadget:GUI_Window, parent:Base_gadget) new_gadget.name = wName new_gadget.x = wX new_gadget.y = wY new_gadget.width = wW new_gadget.height = wH gadget_list.AddLast(new_gadget) Return new_gadget EndMethod ... Global main_window:GUI_window = New GUI_window Global main_window2:GUI_window = New GUI_window main_window.Create("win1", 50, 50, 50, 50, main_window, Null) main_window2.Create("win2", 110, 50, 50, 50, main_window2, Null) |
| ||
Ok, the third way is to not use New in Create and use Self. Also, there is an example of how to look up the list.Method Create:GUI_Window(wName:String, wX:Int, wY:Int, wW:Int, wH:Int, parent:Base_gadget) Self.name = wName Self.x = wX Self.y = wY Self.width = wW Self.height = wH gadget_list.AddLast(Self) EndMethod ... Function Lookup() For Local a:GUI_Window=EachIn gadget_list Print a.name+","+a.x+","+a.y+":"+a.width+","+a.height Next End Function ... Global main_window:GUI_window = New GUI_window Global main_window2:GUI_window = New GUI_window main_window.Create("win1", 50, 50, 50, 50, Null) main_window2.Create("win2", 110, 50, 50, 50, Null) GUI_window.Lookup() |
| ||
I didn't understand what you mean with the dummy I will use the third example with self without add local new_gadget. I am still confused with lists. |
| ||
The dummy is just an instance of the type so you can access the methods or fields but apart from that it is not used. So by dummy I meant "An imitation of a real or original object, intended to be used as a practical substitute." Not sure what you don't understand about lists. A list is a collection of objects, usually you want them of the same type but you can have different objects in the same list and look up any type with an EachIn loop. It's similar to storing data in a one-dimensional array but more flexible. The list uses TLink internally hence the name, but normally you don't need to use links. |
| ||
If you want to find a specific object in a list you then have to iterate through the list from first object to the last (or at least until the object is found). Identify the object by comparing it with the object instance you want to find or with an id like: SuperStrict Type a Field id:Int Field s:String = "Test object of type A" EndType Local list:TList = New TList 'Create some test objects and store them in the list For Local i:Int = 0 To 9 Local obj:a = New a obj.id = i 'example of using an id to later identify the object list.addlast(obj) Next 'Finding object with id 5 Local found:Int For Local obj:a = EachIn list If obj.id = 5 Then found = True Print obj.s + " | ID=" + obj.id EndIf Next If Not found Then Print "Object not found" -Henri |
| ||
I advise that you really work hard to understand lists because they are unbelievably powerful and make a lot of previously hard things seem easy. If you run into trouble with them and just want to get your GUI done, you could try an array with a Top variable. So you would make windowarray:TWindow[100] Then you initialize it like so for i = 0 to 99 {because that is the way arrays count} Windowarray[i]=new TWindow {you have to initialize them or get an exception! NEVER FORGET because otherwise you will run into this again and again and never know why} Next Then as you add windows into that array you increment Top. When a window dies, decrement Top. When you need to walk your list of windows, do for i = 0 to top Windowarray[i].dostuff() Next If top ever exceeds your array size - 1, because again arrays count from zero, you can throw an error, or you can resize your array thus: Windowarray= Windowarray[..Top*2] This will expand the array as you need it, doubling the size each time, and will give you more space than you will ever need, with an optimally small number of resize operations because those are slow in some implementations. All that's basically what lists do for you. Also a list can hold anything, even different types of object. If you don't wanna mess with resizing, even though it's super simple, just allocate a window array as large as you want. Preallocating is generally sneered at as wasteful of memory but in these days of huge memory spaces that's a bogus concern and preallocation can pay large dividends in speed and smoothness because the garbage collector doesn't have to run at strange intervals. By doing a list within an array you are reinventing the wheel but that is a great way to learn how wheels work and if you already understand arrays, just use those until you understand how GUIs work. Then you can work on lists. One conceptual headache at a time. If you want to understand lists read this: http://en.m.wikibooks.org/wiki/BlitzMax/Modules/Data_structures/Linked_lists And the Blitzmax OO Tutorial by John. Type out all the examples and get them to run and you will understand, it's not as hard as it seems. |
| ||
instead of keeping references of old "windows" in your array you should null them if not used anymore. You then could replace for i = 0 to top Windowarray[i].dostuff() Next with for local window:TMyWindow = EachIn Windowarray window.dostuff() Next If you define your Windowarray to contain "guibaseobject" instead of "guiwidget" you could of course store other widgets too. The "eachin"-loop then skips all items not of type "TMyWindow" (or ancestors of TMyWindow). bye Ron |
| ||
Wow there is a lots of work :P Now I am working to skin my first window. Soon I will post a zip file with the graphics included. Another one obstacle is and I don't understand , how to add gadgets on this new window I have created and how to create event system. When I will finish with the skinning of the first window I will try to add one simple button on this new window. I will post a zip file , because the next code include and graphics too. Thank you very very much for your valuable information and help you provide me. |
| ||
The way to code an event system of sorts is as follows. Make a function InRect(x,y, ux,uy,lx,ly). This returns a 1 if x,y is within the rectangle (ux,uy,lx,ly) and a zero otherwise. You are going to be calling this function on every click, for every gui item. Make a type TClickRect. This will be your parent GUI object. It has an onclicked() method. That is what will get called every time it is clicked. This gets added to a TList thus: widgetlist:TList = new TList TestClickRect:TClickRect = new TClickRect widgetlist.addlast(TestClickRect) Then your click checking loop: if MouseHit(1) temprect:TClickRect = new TClickRect for temprect = eachin widgetlist if inrect(MouseX,MouseY, <widget upperx, uppery, lowerx, lowery>) temprect.onclicked() next endif That doesn't take into account whether there are overlapping items. You will need to figure that out yourself but basically you figure out which windows a mouseclick is within, and then of those, figure out which has the highest Z value which means the window that is on top of that window stack. Now when you make your TWindow, you extend TClickRect. Type TWindow contains a TList. TList contains a list of TClickRects. Those are your buttons. This is probably the simplest way to do windows. By making lists of TClickRects, you can also make button bars, menubars, all sorts of things. All windowing systems are basically built out of clickrects. If you really want to go crazy, learn about function pointers, and then assign functions to buttons when you create the buttons. That is a somewhat ghetto way of doing things but if you are doing it the easy way that will give you a lot of power. But if I WERE YOU I would figure out lists or how to make arrays of buttons, have a function AddButton(name:string, x:int, y:int, width:int, height:int, functionpointer) that adds buttons to a list or a static array, then use that to build up a button bar, and use that buttonbar within your game. This is a very simple way of doing things and it's pretty powerful, it lasted for years in the GLUT toolkit. Have a right click bring up a buttonbar right where you clicked, then a left click on an item calls that item's function pointer and makes the menu disappear again. Writing a GUI is a great learning experience and it's very interesting but learning it is not really trivial and it's really up to you whether you want to fart around with learning that right now or whether you want to work on your game. You could also do a very simple thing and use my mousewheel menu: Strict Global numitems = 7 Global currentitem:Int ' Which item is currently selected Global olditem:Int Global currenttextline:Int Graphics 640,480 Global ticks = 0 Global namearray:String[100] ' 100 menu items total Global menufadeouttimer:Int ' When this has elapsed, the menu disappears automatically ' This is your list of menu item names. namearray[0]="Thing1" namearray[1]="Thing2" namearray[2]="Redthing" namearray[3]="Bluething" namearray[4]="BarThing" namearray[5]="FooThing" namearray[6]="Exit" While Not KeyDown(KEY_ESCAPE) And Not (currentitem=6 And menufadeouttimer<0) ticks = ticks + 1 Cls currenttextline=0 olditem= currentitem currentitem= Abs(MouseZ()) Mod numitems ' Mousewheel Switches Tile Types If olditem<> currentitem menufadeouttimer = 60 EndIf menufadeouttimer:-1 If menufadeouttimer > 0 drawmenu() Else SetScale 2,2 SetColor 255,0,0 DrawText namearray[currentitem], 0,-2 SetScale 1,1 EndIf Flip Wend Function drawmenu() SetBlend alphablend SetAlpha .5 ' draw semi-transparent menu background SetColor 0,0,0 DrawRect 0,0,200,1000 SetAlpha 1 If menufadeouttimer < 50 And menufadeouttimer > 0 SetAlpha 1*(51/menufadeouttimer) 'SetColor 255,0,0 Local recty = 0*12 DrawRect 0,recty,200,24 SetScale 2,2 SetColor 255,0,0 DrawText namearray[currentitem], 0,-2 SetScale 1,1 SetColor 255,255,255 recty = currentitem*12 + 24 DrawRect 0,recty,200,12 For Local i = 0 To numitems If i = currentitem SetColor 0,0,0 Else SetColor 255,255,255 EndIf DrawText namearray[i], 10,i*12 + 24 SetColor 255,255,255 Next SetAlpha 1 End Function Function consoleprint(toprint$) currenttextline:+12 DrawText(toprint$,10,currenttextline) End Function But this is not complete! It needs to execute code somehow based on the selection you made. Either do that with a function pointer or a case statement. Here is a bit of code explaining how to bind function pointers to keys. A function pointer can also be bound to a buttonID. ' bindkey - binds key to function Global functions()[256] ' This is an array of function pointers, one for each ascii keycode. ' Not all of these will be initialized... ' If you are using this in your menu system, you will execute these on ' a given button press, as down below in the main loop. Graphics 320,200 Function bind(key:Int, func()) ' Binds a key to a function pointer. functions[key]=func End Function Function thing1() ' Example functions. These could be anything... DrawText "thing1", 10, 10 End Function Function thing2() DrawText "thing2", 10, 10 End Function Function bail() End End Function ' These are the binding statements. These bind a key to a function. ' Thing1, Thing2 and bail are all references to functions. bind(KEY_1,thing1) bind(KEY_2,thing2) bind(KEY_ESCAPE,bail) While(1) Repeat char% = GetChar() If char And functions[Int(char)] Cls functions[Int(char)] Flip EndIf ' Or for your button menu system, ' if somebuttonhit and functions[buttonID] ' in other words, if the button id has had a function assigned to it ' functions[buttonID] ' Execute whatever function corresponds to that button ID ' endif Until char=Null Wend |
| ||
Instead of "checking which widgets think they contain the widget" and afterwards filtering it: - have a list of widgets. Each time you add a widget, sort the list using a custom compare-function (which returns 1/0/-1 depending on the zindex compared to the other widget) So your list contains a zordered list - which you need anyway if you have overlapping widgets. When checking for "clicks" you check from "top to bottom". while rendering is from "bottom to top". As soon as an item registered a click, no other widget has to get checked. If you want to inform other widgets too - inform them via the widget itself (it sends out an event à la "widget clicked" with the widget as payload/sender). You may also consider to have a "GetScreenRect:TRectangle" method in each widget - it returns the visible area for the widget on the screen. It is calculated this way: x = parent.GetX() + x y = parent.GetY() + y w = max(parent.GetX(), x) - min(parent.GetX2(), GetX()) h = similar to w x2 is "x + w". I use "getX()" so it checks the parents parent and so on. Method GetX:Float() if parent then return parent.GetX() + x return x End Method bye Ron |
| ||
:) The very first version is ready GUI Ver 0.0001 It creates 3 windows with simple skin , (you can create as many windows you want) , you can change the color , you can make them hidden or show and you can change the text of the title bar. You can't move them yet not drag or select them and change their z order. (But you can initialize the size and position on creation only) Hmm change the z order and position on run time... I haven't figure out how to do this yet , but I will find it. The next step is to add one simple button gadget on this window. Edit: Oooops a lots of new posts added. I will try to make the window dragable and clickable and change the z order of the window. I confused a lot with the new code you sent me. |
| ||
I still think when you're trying to write a game and an editor, writing a windowing system so you can get to that point is way too much effort. It's really not a trivial undertaking and there are easier ways of doing almost anything than that. |
| ||
I still think when you're trying to write a game and an editor, writing a windowing system so you can get to that point is way too much effort. It's really not a trivial undertaking and there are easier ways of doing almost anything than that. I know there are easier ways to do it just using the ifsogui I am already have , but there is not any complete gui library for blitzmax. Even the high gui is not complete. Menus are missing , right button menus are missing too. Most of the guis don't have canvas gadget and other more complex gadgets. Creating a gui (If I will manage to finish it) will give me a lots of experience of object oriented programming and understanding other things that I still haven't understood with other languages too. On thing I wasn't understood in the past was the lists and classes with inheritance. Now I have learnt the inheritance is just the "extends" command in one struct or type and the class was one method or function inside the struct or type. This took me more than 6 years to understand it. Also I discovered the command eachin always I used the for loop with fixed variables. Ok I will try to make the window movable and change its z order. :) |
| ||
The whole "drag" thing is not that easy ... it's NOT just "if mouseover and mousehit then setDragged". In my gui I do not handle "drag n drop" properly, but I handle it. Just check how wxWidgets handle it: a drag event starts not on "mousedown/mouseup" but on "mousedown and moved mouse over a certain distance". Think of it as if the widgets are glued on the background and you need a specific force to unglue them. @missing things: A Menu is just a Canvas + Labels. A Context Menu is a Menu created as soon as a widget is configured to react that way on a right click. A GUI Toolkit just needs to provide you with basic widgets. Eg. is a "Spinner" nothing more than a "Input" + 2 small buttons with a glyph on each of them. A "Color selector" is a Canvas/Window with colored buttons (with design "inset") etc. If you want to have a color wheel, then that is a canvas which reacts to your clicks and has a custom render code. Do not blame the existing toolkits not to have "everything" you could imagine. There are always multiple ways to combine things to form something new: eg. I combined a "input" and a "list" to a dropdown-widget - using this approach it is even possible to "drag n drop" items from the dropdown widget to a list or other way around. A list is nothing more than a special "panel" (canvas) which listens to some events and contains scrollers (the area to scroll something). To keep things "easy to modify" you should think about the design before coding ... I have many things I would have better coded differently. I think "stubs" (functions doing nothing) are not that costly compared to the benefit you gain instead of having to copy-paste a lot of code from widget A to B. So something like DrawBackground() DrawContent() DrawOverlay() DrawDebug() helps to just override things changing between widgets. Also think a bit about connectors (Field onClick:int() = null) which you could easily attach custom functions too (same is possible for your draw methods) but it is similar to extending types to override behavior, don't know what is the preferable way of doing things. bye Ron |
| ||
A new versions is out GUI Ver 0.0001b It does the dragging effect but is not so smooth have lag. I don't have understood about the z order yet and when you overlap the windows you dragging and windows behind. This is just the drag effect , drag the window from the title bar. |
| ||
It seems this .self command do miracles. I fixed the zorder and now I can move my windows without picking up overlapped ones behind , but I did it little differently. The next version of my GUI. GUI Ver 0.0002 The next is to see how to add one gadget (for example a button over the existing window). I have issues when I move the mouse fast. The pointer goes outside of the window very fast and the window remains unmovable. How do I will fix this? |
| ||
You have it stay selected until the mouseclick is released. When it is first selected, give the mousepointer a "currentlygrabbedwindow" ID. If this ID is non-null, always have that window follow the mouse. When the click is released, give that ID a null or zero value. Looks like you are almost there. |
| ||
For such cases I have a "GUIManager" - it contains the "widget list", helper functions ("addWidget") but also contains the currently focused widget etc. So you could store the exact widget there (draggedWidget:TGUIWidget) or just the ID - but you then have to make sure that the ID is unique (a GUID) . You then have to "get(id)" each time you compare it (but you save to unset one reference). @rest Do like zoqfotpik suggested: split into "grab" and "release" - grab then of course could be like suggested above be a mix of "mousedown" and "moved distance > x". Similar you will have to handle "button clicks" - you should act on "mouseup" not on "mousedown" (store object on mousedown but emit "click" if mouseup is on the same object). bye Ron |
| ||
I don't have window IDs in my code! Do I need to add extra argument in my window create method? |
| ||
If it's a big problem you could make it a global variable. This gets incremented every time you create a window and in your window create method the window ID gets set to that variable. |
| ||
Just have something like this:TBaseWidget Field ID:int Global LastID:int = 0 Method New() LastID :+1 ID = LastID End Method End Type That "New" Method is also called as soon as you do a "new TMyWidget" - as soon as you extend "TMyWidget" from "TBaseWidget". Even if you override "Method New()" in your custom widgets, it gets "traversed" up to the baseWidget. bye Ron |
| ||
Now Derron, is there any other good way other than a global variable? I use globals. I may not use a *ton* of them but when I'm finished with a project I often have a screenful or more. Is it better to put it inside a type for reasons of modularity, and if you do that, wouldn't "lastID" be running into dangers of namespace incompatibility? |
| ||
how could the run into "namespace problems"? Instead of a global variable you could use a GUID ... eg. based on something like "amount of instances of my type" + nanoseconds since programmestart or so. You just have to make sure, that you cannot reuse an existing GUID (or think of threading ...). For predefined things a GUID is really handy (eg "enemy-01" "player-1") ... but for things like particle systems you will better use a global "lastID". If all your objects extend from a baseobject, you wont even pollute namespaces. Could you give an example (maybe I just do not understand enough from "namespaces" and problems arising there) ? bye Ron |
| ||
I just mean conflicting variable names. Of course there's an obvious way to fix that problem. Nothing technical regarding ID numbers, just a general question regarding global variables and naming. I usually precede mine with JT in things I package up for reuse. |
| ||
To avoid this I just use the globals in a "Manager"-type. The Manager itself is a singleton so its variables are "fields" - this way it could get properly exposed to LUA (reflection only handles Fields - and modded, it handles Const but not Global). bye Ron |