Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / Proper game structure?

Author
Message
Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 05:46 Edited at: 17th May 2010 05:46
I've just decided to get some practice with OOP and figured making a small game would be the best practice.

So far it has worked out fairly well, but now I'm hitting a road block with the structure I've built up.

Attached is the basic structure layout. There's a bit more to it (namely the Input handling class, which handles player input and AI input to be used by Characters) but that's really the jist of it so far.

Here it is in text, though. The main.cpp file creates an instance of the EntityHandler class and calls an update for it every loop. The EntityHandler class controls most everything, such as creating characters and calling updates to the particle handler. Characters create instances of the weapons that they'll be using, so they are responsible for their creation and updates. Weapons, in turn, are responsible for creating their own bullets and calling updates from them. That was what made the most sense to me when I created this.

Now, the part I'm stuck on is... how do I run checks for bullet collision with characters? Attempting to even create a pointer to the character class generates an error during compilation (probably due to the dependancy loop it creates). Also, bullets should be making particles, but the particle handler is being handled by the entity handler... this, I can forward down a pointer for them to gain access to creating particles, but is there a better way for that?

I guess what I'm really stumped about here, is that sometimes I need the dependants to check against entities that are lower down on the dependancy chain and I'm not sure how to go about doing that.


Perhaps there is some sort of C++ function that I'm not aware of that would allow me to do this, but I just can't see it. Can someone help me out here? Is there a way to do what I'm wanting? Or is there a better structure that I should use for this?


The one and only,


Attachments

Login to view attachments
Ultimate_H
15
Years of Service
User Offline
Joined: 11th Mar 2009
Location: A place that is neither here nor there
Posted: 17th May 2010 06:03
depending on the organization of your code (or if the game is multi document the headers you have included), you should be able to make calls to the particle handler class from the bullet handler class.

Something like this should work:



you have to be sure to actually create an instance of the particle handler class before calling the function, or it wont work.

as for checking collisions with bullets and players, I know of one solution that should work:

you have an array (initialized to a negative number) that holds all of the identifiers for the objects/sprites of your bullets. you then use a collision handler to check for collisions by running through the array (skipping any negative numbers since sprites/objects can't have negative identifiers to my knowledge).

if you are using 3d and you have Sparky's Collision DLL, then you can just set each bullet to the same group and check the player collision to the bullet group.

Hope that makes sense
-H

PS: if it doesnt, i can probably whip up a small example of what i'm talking about.

Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 06:14
My game is 2D. I know the maths for 2D collision detection backward and forward, so the actual calculations are not the problem. My only problem here is gaining access to the character array information in the Entity Handler from within the bullet class.

The only thing I could come up with was to have the Entity Handler do the collision detection since it would have access to everything and simply have it run through each weapon's bullet array, do proper collision detection against the character array that it already has control over.... but then the structure that I've built would be meaningless since the entity handler would essentially be doing everything and it'd be little different than a non-OOP setup where everything is contained within one big file and everything has access to everything else anyway.


I was trying to simplify the code by using this setup, where objects that need to be created are only created and handled by the object that would be using it... and it all worked out wonderfully so far, until I came to need the collision to be handled. That required the bullets to have access to the character array, which I am not entirely sure how to go about doing.

I fought with structure designs all last night, and ended up deciding to ask here when I couldn't think of anything.


The one and only,


Ultimate_H
15
Years of Service
User Offline
Joined: 11th Mar 2009
Location: A place that is neither here nor there
Posted: 17th May 2010 06:34
I just remembered one thing that you could do, without having to change the way things are set up.

basically, you create a retriever function in the bullet class that will access the player array. but, instead of defining it inside the bullet class, you declare it in the bullet class, and define it under the player array declaration. This will allow you to access the player array with the function, even though the main class is actually defined above the player class.

you would also have to create a giving function (one that gives out private data) if you are looking for a private data item.

if all that sounds confusing, you can also refer to this, which shows what I am talking about:


Hope that's what you're looking for
-H

Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 06:49 Edited at: 17th May 2010 06:55
Makes sense, but how would I set that up with headers? Your structure for class clsB is broken up around the structure of class clsA.

In my setup, I've created header files for all of my classes and their accompanying .cpp files for writing out the functions. (Though, I do admit that most of their functions are actually written directly in the class)

So, my classes aren't declared inline in the main.cpp, they are only included when necessary.

So, let's say I have class clsB's structure in the clsB.h header file, and it's functions are written in clsB.cpp. In order to use the clsA.h function in clsB.cpp it would need to include clsA.h, correct?

I'm not sure about how the compiler would handle that, or if it would work, assuming that clsA.h also included clsB.h.

The way I see your structure set up with seperate files is like so:

clsB.h
-is included in-
clsA.h
-which is included in-
clsB.cpp

I know your code doesn't necessitate that structure, but mine would.

Now, the question I have on this topic would be... to what structure would my own code necessitate? Something like this?

Bullet.h
-is included in-
Weapon.h
-which is included in-
Character.h
-Which is included in-
EntityHandler.h
-which is included in-
Bullet.cpp

Which I could then access EntityHandler.h's methods from within Bullet.cpp without creating a dependancy loop? It makes sense written like that, but then where do the intermediate classes lie in this instance?


*scratches head* I'll need some pain killer for this one.

[EDIT]

Just thought about it when looking at the actual code...

I would need the original instance of the EntityHandler object within the Bullet.cpp code. How do I obtain that?

Your code works because you have a global handler created in an area where any following function declarations can have access to it. Mine does not.


The one and only,


JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 17th May 2010 07:02
I don't know what's actually happening with your code, but from what I can tell, your Particle-Handler should be a Singleton object. Perhaps some of your other classes too... Here's the jist of such a thing;

.H Header file:


.CPP source file:


This way, all you have to do to get ahold of the current particle-handler is to call its GetInstance() method...



I, personally, use this method in several places within the Capt-Ooze game that I'm writing... Look for it soon in the DarkGDK Competition thread!

Hope this helps,
JTK
Ultimate_H
15
Years of Service
User Offline
Joined: 11th Mar 2009
Location: A place that is neither here nor there
Posted: 17th May 2010 07:06
if you are using header files and source files for each class, then you would just make sure you include the header that defines whatever class you are trying to access, and then also declare the class (as an extern so that it has the same data in it as the main one) before defining the class'es function.

you have to make sure, if your entity handler is a class, that you declare it before you try accessing the functions, since you interface with the instance (what actually holds the data) rather than interface with the definition.

if the bullet is created only after the entity handler is created, then it shouldn't create a dependency loop. the compiler doesn't need an instance of the bullet class(the owned class) to be there in order for it to try and access the entity handler, it just needs the entity handler (the owner class) to be there.

so basically, in simple terms, if you need to access a function from the entity handler, you just have to make sure that you include the header of said handler, and also declare it so that you have something to work with.

as for the instances of the other intermediate classes, this setup shouldn't even have to consider them, since it interfaces directly with the needed class rather than chaining back to the original class.

hope you get the gist
-H

Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 07:16
...

The logic behind that escapes me.

How is such a class instanced if the constructor is protected? Where is the m_Handler set?

And beyond anything, what's the point of having that kind of class? I must be missing something here. Does this setup offer any sort of benefit over a "normal" class? What is the purpose of a "Singleton object"? I haven't seen that referenced anywhere.


The one and only,


JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 17th May 2010 07:28
Singletons are like globals in some respects;

they can be accessed anywhere through their respective get methods (GetInstance() in this case), but they are *not* global in nature (ie: not g_pObject variable access)...

As for their creations, unlike "global variales", they won't have their constructor called until the first call to their get method (again - GetInstance() in this case) and will remain "there" (ie: valid) until destruction (program exit)...

This is a trick of the ISingleton interface that, if you've not heard of already, will be of great importance to you later... try it out and see for yourself... It works! As I've said before, I use this approach in several instances already in my own current works...

JTK
JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 17th May 2010 07:33
Lookup "ISingleton" on yahoo, google or bing and see if that helps explain things better for you... It's a very important concept of OOP - I think you'll find it very helpful too...


JTK
Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 07:56
Okay, I just searched for ISingleton... I didn't find any articles relating directly to C++ and its implementation... but I did find a lot of people making statements about the Singleton's contradiction to OO structure.

If you can find me an article for it related directly to C++, I would be grateful.


@Ultimate_H:

Sorry, I didnt see your post. You posted while I was typing my reply to JTK.

I looked up the extern storage type and think it might be useful for this, but am afraid that it might break up the structure I have created... though, if no other alternative is present, it may be the only way. I suppose this might also help for using my camera and having it accessible by other classes down the line.

I'll play around witht he idea and see how it goes.


Thanks to both of you for the help, btw.


The one and only,


Ultimate_H
15
Years of Service
User Offline
Joined: 11th Mar 2009
Location: A place that is neither here nor there
Posted: 17th May 2010 08:02
is your entity handler the main class, or is it owned by another class. if it's the main class, then the extern keyword (if you have the entity handler declared global {outside of void DarkGDK()}) will only make it so that you can see the class in that cpp file as well. basically, you declare it like you do in your main file, just place the keyword extern in front of the whole thing.

if its owned by another class, then yes, it will most likely break up your structure.

hope that makes sense
-H

Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 08:05
The entity handler is only used by the main.cpp file, and only one instance is created (which is probably why JTK suggested using a Singleton object...), so I suppose making that instance global in the main.cpp file and referencing it as extern in any necessary classes down the line would allow me to have access to it.

I am also thinking of taking the ParticleHandler and doing the same thing, removing it from under the EntityHandler and making it a global instance throughout the project, so any entities that need to create particles will be able to do so without interfering with structure.


The one and only,


Ultimate_H
15
Years of Service
User Offline
Joined: 11th Mar 2009
Location: A place that is neither here nor there
Posted: 17th May 2010 08:18
making the particle system separate from the entity system sounds like a good idea in terms of ease of access.

i'm not sure why you would have it held by the entity handler anyways, its a strange relation.

The way the book I learned OOP from described OOP talked about it in terms of actual objects. so in terms of actual objects, you wouldn't place something like a sprinkler system(particle handler) as being owned by a 4 door car(entity handler), even though you may need both at the same time (who knows why).

Also, when making an object externally accessible, you don't place the extern keyword in front of the object declaration in the main file ( you will get the compiler after you), only in other files that will access it.

Globalizing(not a real word, i know) single instances of things that will be used a lot(not just classes, but also var's) is a good idea, since it will have a much larger scope(visibility).

hope that makes sense
-H

JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 17th May 2010 08:40
Quote: "
The entity handler is only used by the main.cpp file, and only one instance is created (which is probably why JTK suggested using a Singleton object...), so I suppose making that instance global in the main.cpp file and referencing it as extern in any necessary classes down the line would allow me to have access to it.
"


This will work so long as the instance is a pointer; that is, created with new (having the *); otherwise, the entirety of the class definition would be required...

Hence:

.h of Using class:


Or, if extern is used:



Unless #include "UsedClass.H" is added to the header file in which the forward declarations would not be needed...

So, if you're using pointers to those classes, then you can disregard everything I've been saying...

I myself don't use pointers unless I have to (pointer indirection costs cpu time) - so I try to avoid them whenever possible...

Additionally, I try to avoid globals too, because I don't want to inadvertantly corrupt a global state - hence my use of singletons. However, when using a singleton, I am explicitly stating as such with the CSingleton:: reference before the actual call...

Personal preference, I suppose...


JTK

NOTE: Wikipedia, btw, has several explicit C++ examples for you... I am only trying to offer a suggestion as to how to achieve your final goal - making the program work, without re-engineering your current structure. You can, of course, follow the global variable route, but it too has its drawbacks...
Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 17th May 2010 09:40
Thanks for the suggestions, you two.

I think I will go with the global route and use extern for referencing the instance of my handlers. That makes the most sense to me. This has been very informative and I think I have a better grasp of how things will work out in the end.


The one and only,


Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 22nd May 2010 08:41
Welp, I gave the global route a go and I'm having the same problem that I had in the beginning.

In order to use the global pointer, i need to include the header file of the class that the global is using, but this creates a compile loop when I try to use it in a class that is further down the line from said class.


In the structure setup pictured in my first post, I am wanting to access the EntityHandler instance from within the Weapon class. However, since the EntityHandler class is dependant upon the character class, which in turn is dependant upon the weapon class, the compile freaks out when i try to make the weapon class dependant upon the EntityHandler class.... as you can see, there would be a loop.

So, after much fighting with the compiler, I feel I must revert back to the original question in this thread... How can I structure this to have it work the way I need it to work?

Is it bad to set it up the way I have it set up? Can someone come up with a better structure for this that I'm just not seeing?

I'm getting extremely frustrated with this!!!


The one and only,


JTK
14
Years of Service
User Offline
Joined: 10th Feb 2010
Location:
Posted: 22nd May 2010 16:19
try adding the following lines to each of the respective header files:



Then, in each .cpp file, make sure you #include all three header files...

This approach should work so long as the relationships use pointers...

Hope this helps,

JTK
Plystire
21
Years of Service
User Offline
Joined: 18th Feb 2003
Location: Staring into the digital ether
Posted: 23rd May 2010 04:22
Alright... I think I've solved this.

In case anyone is interested int he way I've worked around this, here is what I did.

I made the EntityHandler take care of all Bullets created. It holds the vector which contains all bullets in the game, so it can update said bullets and run collision routines when it needs to.

That being said, the weapon class still needs to notify the EntityHandler when to create bullets, where, what kind, and at what angle. So, I set up a variable in the weapon class called "bFire", which would be set to true when the weapon needs to be fired. Then, during each loop, when the EntityHandler updates the Characters, the character update routine will return a vector of bullets that had been fired, to be added to the main bullet vector for handling. After the character updates, the bullet vector is updated and collision detection is executed. This keeps the weapon from having to keep tabs on all of the bullets it creates and brings everything together within the entityhandler.


The one and only,


Login to post a reply

Server time is: 2024-11-19 23:16:55
Your offset time is: 2024-11-19 23:16:55