General Game Structure: Part 2
BlitzMax Forums/BlitzMax Beginners Area/General Game Structure: Part 2
| ||
Hi Everyone! I'm still trying to figure out how I'll ultimately structure my game for good performance and ease of read, but I haven't found the ultimate way of doing this but I have had some ideas after playing around with Types and Functions. If I understand correctly, Types can be used for almsot everything that needs to be redone more then once. The only downside is the fact that they depends on inside values to function so the difference between two of the same type is limited. If that makes any sense. The way I see it, is: Let's say you have Type TButton... and you have a TRoom and you wana place Buttons into a room it can be done(via method and functions) but it will be the same for all the rooms you may be able to change the values of those button inside the TRoom type but not how many you have of them. So basicly Types is basicly duplicable storage space with internal behavior (mewthod and functions), no? So I though then I have no other way to make it so every room is different then to make an outside Functions to contain all the information of all the different room as.. follow: This is the simple structure I came out with, it's jsut a global idea of how I'd do it: Graphics 800,600,0 Global CurrentRoom:Int=0 Global intro:TRoom=New TRoom intro.Name="Intro" Global menu:TRoom=New TRoom menu.Name="Menu" While Not KeyHit(KEY_ESCAPE) UpdateRoom() Flip; Cls Wend; End Type TRoom Field Name:String End Type Function UpdateRoom() If CurrentRoom=0 Then ' Room Intro DrawText intro.Name,10,10 If KeyHit(KEY_ENTER) CurrentRoom:+1 EndIf EndIf If CurrentRoom=1 Then ' Room Menu DrawText menu.Name,10,10 EndIf End Function What do you guys think? Any better ideas? Am I way off? Or over complicating stuff.. like I usually do lol? |
| ||
Here is a great tutorial on types if you haven't read it yet. http://www.blitzbasic.com/Community/posts.php?topic=59233 I'd might do your example like this, keeping Update() within the type: |
| ||
I know about doing it that way, however did you read my second or third paragraph, what if you wana add alot of different information for a room, you cannot insert that kind of information into an object that is why I did it the way I did. If you have TButton, TTextfield... Let's say I wana place 3 TButton and 2 TTextfield in the first room then 5 TButton and 1 TTextfield in the second room.. You cannot insert very differencial information into an object... Graphics 800,600,0 Local intro:TRoom=New TRoom Local CurrentRoom:TRoom = intro 'point CurrentRoom to the first room intro.Name="Intro" Local menu:TRoom=New TRoom menu.Name="Menu" intro.NextRoom = menu 'the room you enter when you press "Enter" key menu.NextRoom = intro While Not KeyHit(KEY_ESCAPE) Cls CurrentRoom = CurrentRoom.Update() Flip Wend Type TRoom Field Name:String Field NextRoom:TRoom Method Update:TRoom() DrawText Name,10,10 If KeyHit(KEY_ENTER) Return NextRoom 'if enter is pressed, return the next room Else Return Self 'if not, then return the current room End If End Method End Type Type TButton Field x:Int, y:Int Field width:Int Field height:Int Method Create( xstart:Int, ystart:Int, wstart:Int, hstart:Int) x=xstart y=ystart w=wstart h=hstart End Method End Type Can't add 2 TButtons to the Update of TRoom without it applying to all rooms .. what if you want to add different number of TButtons per room.. Hmm Hope it make sense somewhat? EDITED rooms will contain alot of stuff thus why i think i need to make a function to make/controle all the stff inside the room... i wonder why shouldt i use Select Case instead of if then? |
| ||
Did you read the tutorial in the link I provided? It will give you a lot of info about types and how to better use them. As far as different objects in the room, it is quite possible to have each room with it's own TButtons, TTexts, TItems, TMonsters, etc.... Each room can have the same number, different number or none at all. There are different ways to do this, reading the tutorial and some of the posts here will show you a few. One way is to use arrays. |
| ||
This is just awesome, I didn't know you could use types like this, I have read Types tutorials but I couldn't come up with something like this. That is extremely useful, I'll have to re-read a few time and try to understand this better. Thanks a bunch. And about that tutorial I just finished downloading the PDF read(reformated recently). |
| ||
Oh my oh my, I think I understand! I can put a list of object inside another object such as TButton into TRoom via an array. And then use the TRoom's Update to loop through via a for loop to update all the buttons in that array. There's still a place I'm abit fuzzy on but not quite clear on what it is so when I am, I'll post back here lol. |
| ||
Yes yes I think you're getting it now! You'll basically have an array of TRooms and each TRoom will have its own array of buttons, monsters etc. These rooms... are the rooms in your level, or "scenes" of some kind? Because intro and menu don't seem like names of rooms in a dungeon lol. |
| ||
Yeah, that is why I need to change the concept abit. So basicly TRoom will be all the stuff before actually being in-game, like: @ Introduction( intro:TRoom ) Logo(s), Story Clip(Cinematic if you can call it that) @ Main Menu ( menu:TRoom ) The player could now choose from "Singleplayer", "Multiplayer"(not any time soon), "Settings", "Credits", "Exit" And then Rooms for all thoses probably except Exit. I'll focus on the Singleplayer story mode and making the mechanics of the game, like the tile system, player, enemies... ect. It will take long but it sure will be a challenge and fun :D As for ingame, I was thinking of using TWorld and TArea(inside the TWorld) hehe |
| ||
I gotta say, I'm having trouble understanding some parts completely, I tried to make my own example:SuperStrict Graphics 800,600,0 Global startup:TRoom=New TRoom startup.Buttons=New TButton[1] startup.Buttons[0]=New TButton startup.Buttons[0].Create(10,10,70,15,"Click Now") While Not KeyHit(KEY_ESCAPE) startup.UpdateRoom() Flip; Cls Wend; End Type TRoom Field Buttons:TButton[] Method UpdateRoom() For Local i:Int = 0 To Buttons.length-1 Buttons[i].Update() Next End Method End Type Type TButton Field Text:String Field xpos:Int Field ypos:Int Field Width:Int Field Height:Int Field Clicked:Int=False Method Create(xstart:Int, ystart:Int, wstart:Int, hstart:Int, tstart:String) xpos=xstart ypos=ystart Width=wstart Height=hstart text=tstart End Method Method Update() ' Clicked If(MouseX()>xpos)And(MouseX()<xpos+Width)And(MouseY()>ypos)And(MouseY()<ypos+Height)Then If MouseHit(1)=True Then Clicked=True EndIf EndIf If Clicked=True Then Text="Clicked" Draw() End Method Method Draw() SetColor(100,100,100) DrawRect xpos, ypos, Width, Height SetColor(255,255,255) DrawText Text,xpos,ypos End Method End Type Ok this works, now here's teh first place I'd need more explication on: startup.Buttons=New TButton[1] startup.Buttons[0]=New TButton First one seems to create a new TButton Object. But isn't it the startup.Buttons being the array? TButton isnt an array its an object why is there a [1] As for teh second line it stores a TButton object into the first Row of the array. ------- The Next part I'm having trouble with is the For Local i:Int = 0 To Buttons.length-1 Button.length gives you the number of rows within a array I think? At first the -1 was confusing me but then I though 1 entry total length 1 but Array line 0.. cuz 0,1,2,3.. So yeah I understand why -1 now .. hehe edited Love this: Global startup:TRoom=New TRoom startup.Buttons=New TButton[5] For Local i:Int = 0 To startup.Buttons.length-1 startup.Buttons[i]=New TButton Next startup.Buttons[0].Create(10,10,90,15,"Click Now") startup.Buttons[1].Create(10,30,90,15,"Click Now") startup.Buttons[2].Create(10,50,90,15,"Click Now") startup.Buttons[3].Create(10,70,90,15,"Click Now") startup.Buttons[4].Create(10,90,90,15,"Click Now") EDITED Even more Practice, I made two Rooms, if you click all the buttons in the first room it will go to the next room! :) (or you can cheat by pressing enter) SuperStrict Graphics 800,600,0 '-------------------- ' FIRST ROOM: STARTUP Global startup:TRoom=New TRoom startup.Buttons=New TButton[5] For Local i:Int = 0 To startup.Buttons.length-1 startup.Buttons[i]=New TButton Next startup.Buttons[0].Create(10,10,90,15,"Click Now") startup.Buttons[1].Create(10,30,90,15,"Click Now") startup.Buttons[2].Create(10,50,90,15,"Click Now") startup.Buttons[3].Create(10,70,90,15,"Click Now") startup.Buttons[4].Create(10,90,90,15,"Click Now") '-------------------- ' SECOND ROOM: SECOND Global second:TRoom=New TRoom second.Buttons=New TButton[2] For Local i:Int = 0 To second.Buttons.length-1 second.Buttons[i]=New TButton Next second.Buttons[0].Create(10,10,90,15,"Click Now") second.Buttons[1].Create(110,10,90,15,"Click Now") '-------------------- ' VARIABLES Global CurrentRoom:TRoom=startup:TRoom While Not KeyHit(KEY_ESCAPE) CurrentRoom.UpdateRoom() Flip; Cls Wend; End Type TRoom Field Buttons:TButton[] Method UpdateRoom() Local totalB:Int For Local i:Int = 0 To Buttons.length-1 Buttons[i].Update() If(Buttons[i].Clicked=True)Then totalB:+1 If(totalB=Buttons.length)Then CurrentRoom=second:TRoom EndIf EndIf Next If KeyHit(KEY_ENTER) Then CurrentRoom=second:TRoom End Method End Type Type TButton Field Text:String Field xpos:Int Field ypos:Int Field Width:Int Field Height:Int Field Clicked:Int=False Method Create(xstart:Int, ystart:Int, wstart:Int, hstart:Int, tstart:String) xpos=xstart ypos=ystart Width=wstart Height=hstart text=tstart End Method Method Update() ' Clicked If(MouseX()>xpos)And(MouseX()<xpos+Width)And(MouseY()>ypos)And(MouseY()<ypos+Height)Then If MouseHit(1)=True Then Clicked=True EndIf EndIf If Clicked=True Then Text="Clicked" Draw() End Method Method Draw() SetColor(100,100,100) DrawRect xpos, ypos, Width, Height SetColor(255,255,255) DrawText Text,xpos,ypos End Method End Type |
| ||
startup.Buttons=New TButton[1] startup.Buttons[0]=New TButton When startup is created, you have a field called Buttons which is an array of TButtons, but it hasn't been initialized with a dimension yet. Startup.Buttons=new TButtons[1] tells the program that you now want Buttons to be initialized with a size of 1. You are not assigning it a specific TButton, but telling it to allocate an array with a dimension of 1 for TButtons. Startup.Buttons[0] = New TButton now assigns element 0 of the array to an actual TButton object, so now you can use the object in your program. Another example here, using Ints and TImages: Local IntArray:Int[] IntArray = New Int[10] 'Make IntArray 10 elements long IntArray[0] = 4 'assign a value to IntArray[0] Local ImageArray:TImage[] 'an array of images ImageArray = new TImage[10] 'Make ImageArray 10 elements long ImageArray[0] = New TImage ' assign a TImage to ImageArray[0] |
| ||
If you're doing a -1 thingy on a For loop, you can use Until So For Local i:Int = 0 Until second.Buttons.lengthis the same as For Local i:Int = 0 To second.Buttons.length-1 It just makes things a little less cluttered :) |
| ||
hehe nice. For a practice, I'm trying to design what you would call a "Simple GUI" for my game. Basicly it's 4 type objects, TWindow, TButton, TTextfield and TTextview. This should be good practice, I called it "QGI" which means Quick Game Interface. QGI.bmx just needs to be included into a project for it to work. But I've been having "mouse Over" Problems with my button object... I feel my button doesn't light up fast enough so I tried to use "Flip 0", it did improve it however it feels as though my style of coding or teh way I coded it is making it slow. So maybe you could check how good and optimised my code is, it's quite readable. Ok first file is the main.bmx: QGI File I'm only working with the TWindow and TButton, I haven't worked really on the others yet. I appreciate the help Czar Flavius! |
| ||
Try using [ codebox ] instead of [ code ] then you get nice scroll bars on your code : ) |
| ||
Done, so you see the mouse over button things is not really optimised and I wonder how can I optimise them to make the mouse over effect faster? |
| ||
The speed seems OK for me. You've duplicated some code in the QGI_TButton draw() method but that shouldn't matter. The other thing you need to do is store off mousex() and mousey() values to check against. You might want to consider images which can be checked using a collision layer for all the buttons. |
| ||
Yeah I though the duplication of the Draw Method could slow it down, but then I couldn't figure out another way that would improve it. as for "The other thing you need to do is store off mousex() and mousey() values to check against." What do you mean? (kinda lost with that sentence) |
| ||
Test mousex() and mousey() once per loop and return the values into variables: local mx:int=mousex() local my:int=mousey() You might consider creating a mouse object to hold this kind of data. You're not doing enough in your update() to cause anything to slowdown so it could be a driver issue. Try GL driver and see what happens. Try omitting the drawline stuff and see what happens. There's nothing I can see wrong with the code itself. <edit> P.S. Have you bought Bmax yet? |
| ||
Haven't ever tried OpenGL so I'm scared to dive into it right now :o To the EDIT Maybe I have maybe I haven't ;D |
| ||
Haven't ever tried OpenGL so I'm scared to dive into it right now :o You simply add Setgraphicsdriver glmax2ddriver() just before your graphics statement. As long as you're using native Bmax commands it does the rest for you. Maybe I have maybe I haven't ;D OK, I'll check again each time you post. |
| ||
Seems to run way better with the GLMax2DDriver() thingy. This is great, does it mean it can run on mac now, since it's using openGL drivers? :o |
| ||
If you're using native Bmax commands only then it's very possible it'll compile and run on Mac. |
| ||
I'm looking around but I can't find.. how can you destroy an object? I tried Delete but, no good? |
| ||
The object will be destroyed when there are no more references to it. |
| ||
If KeyHit(KEY_ENTER) Then test.Buttons[0]=Null Wouldn't that remove the reference to it? i got an error :S |
| ||
What error? Setting all references to it to Null should delete the object. |
| ||
If KeyHit(KEY_ENTER) Then test.Buttons[0]=Null Method Update() ' Buttons For Local i:Int = 0 To Buttons.Length-1 If Not Button[i]=Null Then Buttons[i].Update() EndIf Next Error's at the Update() so i added a if not NULL.. then.. but that didn't help either it makes an error at it now lol. |
| ||
You're calling it Button and ButtonS is that the problem? What is the actualy error message you are receiving? |
| ||
Sorry for the late reply, Czar Flavius. I wasn't at home for a few days. Thanks for pointing that out it missed an "s" as soon as I corrected that everything worked. |