Programming questions
Programming questions
Hello. I decided to switch from DarkBasic Pro to C++/Irrlicht, due to a necessity of OOP capability. I chose Irrlicht because it seems relatively easy to use, and fast. I've found OOP concepts pretty easy to understand, and coded a bit to make sure I could apply my knowledge, however I am a noob to C++. The game I'm planning on making is a single-player FPS/RPG.
Anyway, I have a few questions regarding the structure of my game, and the use of C++ features. In this planned game, one of my focuses is to be consistency for the sake of immersion. For example, rather than having a "pool" of ammunition from which you draw rounds from each time you reload, in this game each magazine would have a variable representing the number of rounds stored. So, different objects would share characteristics with others, and have some of their own (such as ammunition contained). This is why OOP is necessary.
I also want features such as rigid-body physics and bullet penetration, as well as inventory systems. You can probably begin to see why this is an issue I cannot resolve on my own. There would have to be many classes, and a good use of inheritance. I imagine I'd need to make arrays of objects, but how exactly? It seems that each lowest-level class would need its own array, but doing so for every one would lead to excessive RAM usage. Am I wrong in either of those assumptions? I suppose I need a way of changing the size of an array, and of managing memory.
Also, what about communication between the Irrlicht world and the game logic world? I've come to assume that the easiest (or just most obvious) way to manage multiple scene nodes in Irrlicht is to use arrays of pointers. In the game logic world, I'd have arrays of objects. How does one determine which scene node represents which object, and communicate between them? Thanks for any help.
Anyway, I have a few questions regarding the structure of my game, and the use of C++ features. In this planned game, one of my focuses is to be consistency for the sake of immersion. For example, rather than having a "pool" of ammunition from which you draw rounds from each time you reload, in this game each magazine would have a variable representing the number of rounds stored. So, different objects would share characteristics with others, and have some of their own (such as ammunition contained). This is why OOP is necessary.
I also want features such as rigid-body physics and bullet penetration, as well as inventory systems. You can probably begin to see why this is an issue I cannot resolve on my own. There would have to be many classes, and a good use of inheritance. I imagine I'd need to make arrays of objects, but how exactly? It seems that each lowest-level class would need its own array, but doing so for every one would lead to excessive RAM usage. Am I wrong in either of those assumptions? I suppose I need a way of changing the size of an array, and of managing memory.
Also, what about communication between the Irrlicht world and the game logic world? I've come to assume that the easiest (or just most obvious) way to manage multiple scene nodes in Irrlicht is to use arrays of pointers. In the game logic world, I'd have arrays of objects. How does one determine which scene node represents which object, and communicate between them? Thanks for any help.
Hello Baiame,
concerning a project structure, please check out the IrrWizard project (projects section). I feel this is a good start to see about irrlicht/game logic basics.
Concerning OOP, bullets and inventory: I recon OOP and encapsulation makes things a lot more "straight" concerning objects with individual assets (and I like this).
People tell me that all of this could aswell be achieved with non-OOP programming (like linked arrays, or whatever). So, if this is the only reason for you to switch to another concept, maybe first check if you could stay with the one you are familiar with? Of course, I don't want to prevent you from learning new things
Instead of having big fixed arrays of objects, I use the irrlicht built-in list feature; thus creating objects only when needed - and adding to the list. This works quite well for me.
In case you make a base class and derive other classes from that, only the finally created (dynamically with "new" or statically) object will actually use up memory. In case this is what you worry about ...
just a few thoughts...
concerning a project structure, please check out the IrrWizard project (projects section). I feel this is a good start to see about irrlicht/game logic basics.
Concerning OOP, bullets and inventory: I recon OOP and encapsulation makes things a lot more "straight" concerning objects with individual assets (and I like this).
People tell me that all of this could aswell be achieved with non-OOP programming (like linked arrays, or whatever). So, if this is the only reason for you to switch to another concept, maybe first check if you could stay with the one you are familiar with? Of course, I don't want to prevent you from learning new things
Instead of having big fixed arrays of objects, I use the irrlicht built-in list feature; thus creating objects only when needed - and adding to the list. This works quite well for me.
In case you make a base class and derive other classes from that, only the finally created (dynamically with "new" or statically) object will actually use up memory. In case this is what you worry about ...
just a few thoughts...
"Yessir, I'll be happy to make these unnecessary changes to this irrelevant document." (Dilbert)
Thanks alot Miko.
I would actually like to continue non-OOP progamming, at least for the time being. I was unaware that such complexity was practical without OOP. Can you explain, or link me to an article explaining, linked arrays? It's really the first I've heard of them. An internet search yielded very few results.
Thanks for informing me of Irrlicht's build-in list feature, I wasn't aware of its existence. As I said, I can use classes, so perhaps if I read more about Irrlicht's list feature, I can make a start. Do you have any thoughts on my question in the fourth paragraph?
I would actually like to continue non-OOP progamming, at least for the time being. I was unaware that such complexity was practical without OOP. Can you explain, or link me to an article explaining, linked arrays? It's really the first I've heard of them. An internet search yielded very few results.
Thanks for informing me of Irrlicht's build-in list feature, I wasn't aware of its existence. As I said, I can use classes, so perhaps if I read more about Irrlicht's list feature, I can make a start. Do you have any thoughts on my question in the fourth paragraph?
Hello Baiame,
first of all, sorry for that "linked array" term. I was more refering to "linked lists". (/Note to self: do better proof-reading).
Here we go with Irrlicht's list feature. This is how I would do it. Most probably, there are easier (and more intelligent) ways. Well, ...
This is all dummy code. Bare with me.
Asume we want to handle magazines that can be picked up by the player and are used until they run out of bullets.
Global vars/definitions
#define MAX_BULLETS_OF_A_MAGAZINE 100
struct
{
int iActualNumberOfBullets; // Amount will be reduced when firing
... // other things here aswell, maybe.
} S_MAGAZINE;
irr::core::list<S_MAGAZINE> m_MagazineInInventoryList;
S_MAGAZINE* pCurrentlyUsedMagazine; // the one currently used by the player
In the game code
Whenever the player pics up a magazine, it is added to the list. This does represent the "inventory" of the player (in terms of magazines, at least).
...
S_MAGAZINE aMagazine;
aMagazine.iActualNumberOfBullets = MAX_BULLETS_OF_A_MAGAZINE;
MagazineInInventoryList.push_back(aMagazine); // Add it to the inventory
...
Asuming this magazine is attached to the weapon
...
irr::core::list<S_MAGAZINE>::Iterator i = MagazineInInventoryList.GetLast(); // get the last one added (for this example)
pCurrentlyUsedMagazine = i; // pointing to the one in question
...
Later, when firing, number of bullets are reduced
...
if (pCurrentlyUsedMagazine->iActualNumberOfBullets > 0)
{
// Do the fire code here
...
pCurrentlyUsedMagazine->iActualNumberOfBullets--;
}
...
As said, there might be far better ways to do it...
greetings
miko
first of all, sorry for that "linked array" term. I was more refering to "linked lists". (/Note to self: do better proof-reading).
Here we go with Irrlicht's list feature. This is how I would do it. Most probably, there are easier (and more intelligent) ways. Well, ...
This is all dummy code. Bare with me.
Asume we want to handle magazines that can be picked up by the player and are used until they run out of bullets.
Global vars/definitions
#define MAX_BULLETS_OF_A_MAGAZINE 100
struct
{
int iActualNumberOfBullets; // Amount will be reduced when firing
... // other things here aswell, maybe.
} S_MAGAZINE;
irr::core::list<S_MAGAZINE> m_MagazineInInventoryList;
S_MAGAZINE* pCurrentlyUsedMagazine; // the one currently used by the player
In the game code
Whenever the player pics up a magazine, it is added to the list. This does represent the "inventory" of the player (in terms of magazines, at least).
...
S_MAGAZINE aMagazine;
aMagazine.iActualNumberOfBullets = MAX_BULLETS_OF_A_MAGAZINE;
MagazineInInventoryList.push_back(aMagazine); // Add it to the inventory
...
Asuming this magazine is attached to the weapon
...
irr::core::list<S_MAGAZINE>::Iterator i = MagazineInInventoryList.GetLast(); // get the last one added (for this example)
pCurrentlyUsedMagazine = i; // pointing to the one in question
...
Later, when firing, number of bullets are reduced
...
if (pCurrentlyUsedMagazine->iActualNumberOfBullets > 0)
{
// Do the fire code here
...
pCurrentlyUsedMagazine->iActualNumberOfBullets--;
}
...
As said, there might be far better ways to do it...
greetings
miko
"Yessir, I'll be happy to make these unnecessary changes to this irrelevant document." (Dilbert)
Thanks again Miko. That really helps me with understanding Irrlicht's list feature, but I'm still unclear on a few things. As I understand, whether I use classes or structures, I'll have lists for every kind of object. The "magazine" object has entries in the world object, physical object, and inventory object lists, then an entry in the special "magazine" list. Given that the lists are constantly changing size and their components rearranged, with what method can I reliably refer to entries describing the same object on different lists?
You don't.Baiame wrote:Thanks again Miko. That really helps me with understanding Irrlicht's list feature, but I'm still unclear on a few things. As I understand, whether I use classes or structures, I'll have lists for every kind of object. The "magazine" object has entries in the world object, physical object, and inventory object lists, then an entry in the special "magazine" list. Given that the lists are constantly changing size and their components rearranged, with what method can I reliably refer to entries describing the same object on different lists?
OOD Concepts
A player is in the world and an object is in the world (They are in the world scene graph and are drawn with the world)
You pick up the object (Object is removed from the world node and added to your player’s node. The object is now drawn when the player is drawn.)
This is a "Has a " relationship.
You don't have copies of the same object in multiple lists; you move the objects from list to list as needed.
OOD main concepts:
Class: Defines what a thing is. Its properties and characteristics
“Is a” relationship: The class Dog “Is a” Mammal
“Has a” relationship: The class Mammal “Has” Fur
Object: An instance of a class: The Dog named Spot means Spot is an instance of class Dog.
Encapsulation: hide the details inside a class. You can use Spots Move() without needing to know how Spots Move() works, you just use it.
Inheritance: A class inherits properties and functions from its parent class. For example, the class Mammal has fur and since a Dog “is a” Mammal then a Dog “has” fur.
Abstraction: Referring to groups of object by either there specific class or a parent class as needed for a situation. For example, when counting Dogs you would include Spot but not include Fluffy the Cat but if you were counting Mammals you would count both Spot and Fluffy since they both have the parent class of Mammal.
Polymorphism: A method defined in a parent class can be implemented differently in each of the child classes. If you have a collection of Mammals and you iterate through them asking each to Speak() then the Dog would bark while the Cat would meow because they are both Mammals they both have the Speak method yet they each do a Speak in a different manner.
//parent class
Class Mammal
{
Private:
bool warmblooded;
bool fur;
bool airbreather;
float X;
float Y;
float Z;
Public:
Mammal();//default constructer
Move(float lx, float ly, float lz);
Virtual void Speak();
};
Mammal::Mammal()
{
warmblooded = true;
fur = true;
aribreather=true;
}
Mammal::Move(float lx, float ly, float lz)
{
X = X + lx;
Y = Y + ly;
Z=Z + lz;
}
//child class
Class Dog : Public Mammal
{
Private:
bool fetches;
};
Dog::Dog()
{
::Mammal();
fetches = true;
}
Dog::Speak()
{
MakeBarkSound();
}
The class Dog is a child of the parent class Mammal. Therefore Dog has all the properties of Mammal plus any new properties that are added just for the class Dog.
Thanks CodeDog, I was thinking about how I could apply OOP concepts, but I must still be missing something.
When you make a list, the entire thing must be of the same datatype, correct? And from my experience it seems a particular class counts is the only thing that can be used as a datatype (i.e., you cannot simply have an "object" or "class" datatype).
When you instance a class, it also instances every class above it in the hierarchy (so instancing the dog class would also create an instance of the mammal class), correct? If all things are correct, then how can I create a list of all objects?
I could instance lowest-level classes, but it wouldn't do much use if I had to create a list for each one.
When you make a list, the entire thing must be of the same datatype, correct? And from my experience it seems a particular class counts is the only thing that can be used as a datatype (i.e., you cannot simply have an "object" or "class" datatype).
When you instance a class, it also instances every class above it in the hierarchy (so instancing the dog class would also create an instance of the mammal class), correct? If all things are correct, then how can I create a list of all objects?
I could instance lowest-level classes, but it wouldn't do much use if I had to create a list for each one.
You can make collections of parent class items. Then that collection can take all the different types of derived classes that have that parent class.Baiame wrote:Thanks CodeDog, I was thinking about how I could apply OOP concepts, but I must still be missing something.
When you make a list, the entire thing must be of the same datatype, correct? And from my experience it seems a particular class counts is the only thing that can be used as a datatype (i.e., you cannot simply have an "object" or "class" datatype).
this is polymorphisum.
You can use a derived class anywhere you could use the parent class.Baiame wrote: When you instance a class, it also instances every class above it in the hierarchy (so instancing the dog class would also create an instance of the mammal class), correct? If all things are correct, then how can I create a list of all objects?
I could instance lowest-level classes, but it wouldn't do much use if I had to create a list for each one.
I think you should get a good book on OOD that covers polymorphism.
It is one of the most powerful tools in the OOP toolkit yet it is the least understood by new OO programmers.
Let me give you a concrete example from windows programming.
There is a class called CWnd
Derived classes:
CDialog
Clistbox
CCombobox (actually uses multiple inheritances but lets not go there now)
CTextbox
CLabel
I can take a pointer and assign it to any instance of any of these classes and still call m_MyPointer->SetWindowText(“Hi There”); and it will work and I neither know nor care what the actual class is.
I could make a CList or CArray of CWnd objects and toss all these different classes into it and loop through them calling SetWindowText and it would work.
Every time you sit in front of a pc running windows you are watching polymorphism in action. Every program you have running has a parent class of CWnd somewhere in its class tree. But every program is a different class with different functions and properties yet they all share this common ancestry of CWnd. This means the OS can put all these different classes into a Z order stack together (A collection of CWnd objects) and treat them all the same. Letting you click happily away switching from program to program without a care as to what is really going on.
Okay, that really helps, I almost understand it now. Can you expand on the first point a bit (the one about "collections of parent class items")?
Or, could it be as simple as storing pointers to objects in a list? Please excuse my ignorance, multiple object handling is rarely a subject covered by online tutorials.
Or, could it be as simple as storing pointers to objects in a list? Please excuse my ignorance, multiple object handling is rarely a subject covered by online tutorials.
I'm bumping this topic, as I have a couple more questions.
I understood what everyone in this thread meant after reading the last link that CodeDog provided. You can make a list of pointers to objects, and it is the same datatype contained in each entry, as all pointers are the same size. Because of polymorphism, you can call any function in any derived class with just one list entry.
I've been wondering about something else, though (trying to structure my game ATM). I looked up about how to do inventory systems on the internet, and I didn't find anything helpful. The most obvious way is to have a single list for the player's inventory with pointers to the individual instances of the objects contained. But what if the number of agents who require an inventory is, at the time you're programming, indeterminite? It would seem to require lists within lists, and I don't know if that's possible.
Another way is to have variable in the inventory class that identifies the agent that it belongs to. But this would require a search through the main list every time an agent needs information on or needs to change its inventory state. Seems incredibly inefficient to me. If anyone can explain how it's done, I'd be very grateful. Thanks.
EDIT- Only editing this in case someone looks back through old topics, and sees that I'm a dumbass. I could just store a pointer to a list class instance for each inventory-possessing agent.
I understood what everyone in this thread meant after reading the last link that CodeDog provided. You can make a list of pointers to objects, and it is the same datatype contained in each entry, as all pointers are the same size. Because of polymorphism, you can call any function in any derived class with just one list entry.
I've been wondering about something else, though (trying to structure my game ATM). I looked up about how to do inventory systems on the internet, and I didn't find anything helpful. The most obvious way is to have a single list for the player's inventory with pointers to the individual instances of the objects contained. But what if the number of agents who require an inventory is, at the time you're programming, indeterminite? It would seem to require lists within lists, and I don't know if that's possible.
Another way is to have variable in the inventory class that identifies the agent that it belongs to. But this would require a search through the main list every time an agent needs information on or needs to change its inventory state. Seems incredibly inefficient to me. If anyone can explain how it's done, I'd be very grateful. Thanks.
EDIT- Only editing this in case someone looks back through old topics, and sees that I'm a dumbass. I could just store a pointer to a list class instance for each inventory-possessing agent.