Thread: Multiple instances of the same object.

  1. #1
    Registered User
    Join Date
    Jan 2005
    Posts
    106

    Multiple instances of the same object.

    Hm. I guess this could go on the main programming board, but my reasons for doing it are more clear over HERE, because it is game related.

    I'm hunting the elusive beast known as the wumpus.

    I'm also in the process of making a text-based RPG. Or rather, planning one out and learning HOW to make one, because the odds of me actually making it aren't really HIGH.

    Anyway, I want to have multiple instances of the same object.

    * For items in the INVENTORY, I could just apply a simple in_inventory counter to the object.

    * However, let's say I have two objects in my world, in seperate rooms. I can't create a linked list and put the object in two seperate ones, or I break my next/previous pointers. Furthermore, if the objects are in the same room, the same thing ensues.

    * Someone mentioned using an enum or an array to handle this. However, I think at some point I'll have to derive new classes from original ones to specify SPECIAL OBJECTS that do NONSTANDARD THINGS, and hence I couldn't store them in a single item enum or item array. I'd actually probably use a vector. Same principle.

    * Someone suggested just using a massive switch/case statement as a member of each class, so that I wouldn't have to derive anything. This sounds sort of bloated an akward, though.

    * would using the STL list class alleviate all of my problems? I mean, with this program. I don't expect them to regrow my hair or give me an extra 1-2 inches. Not... that I'm bald, or... a guy. Er. Ahem. Moving on.

    * Could I use DMA to create new objects and handle it this way?

  2. #2
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Could I use DMA to create new objects and handle it this way?
    No. Not inside of Windows you won't be programming the DMA directly. Besides the data burst is so small I see no need to use the DMA.

  3. #3
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Hm... multi set?

  4. #4
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Code:
    class ObjectManager
    class Object
    {
      friend class ObjectManager;
      DWORD ID;
    
      bool bCanUse;
      bool bCanEat;
      bool bCanDrink;
      bool bCanOpenClose;
      bool bCanBreak;
      bool bCanHide;
      bool bCanExamine;
      bool bCanThrow;
    
      bool bCanCombine;
      
      DWORD CombinesWithID;
      DWORD CreatesID;
    
      Object(void):bCanUse(false),bCanEat(false),bCanDrink(false),bCanOpenClose(false),bCanBreak(false),bCanHide(false),bCanExamine(false),bCanThrow(false) {}
    
    };
    
    class ObjectManager
    {
      std::vector<Object> ListOfObjects;
      int NumObjects;
      public:
        Objects(void):ListOfObjects(NULL) {}
        virtual ~Objects 
        {
          ListOfObjects.clear();
        }
        
        unsigned int AddObject(Object *newobj)
        {
           ListOfObjects.push_back(&newobj);
           return ListOfObjects.size()-1;
        }
    
        void GetObject(Object *outObj,unsigned int ID)
        {
          *outObj=ListOfObjects[ID];
        }
    };
    This is rudimentary beginning to an object class and an object resource manager class. All object manipulation and access should go through the manager class using the object's ID number - which is just its position in the vector.

    So you can have any number of instances of the object class in the vector and you can have the same object twice in the game, but only once in memory by using its ID number to reference it instead of the actual object. Notice I did not put object location in the class because then that would link that object to one room and one room only.

    Inventory items would be relatively simple as well. You could use a vector or you could use a linked list from the STL or a simple one that you design.

    Code:
    struct InventoryItem
    {
       unsigned int ID;
       InventoryItem *Next;
       InventoryItem *Prev;
    };
    With this method all objects in the game are referred to by their ID numbers, not by the actual instance of the class or pointer to the instance.

  5. #5
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Huh. Okay. A few questions, though.

    Why do you need return ListOfObjects.size()-1? Also, in void GetObject(Object *outObj,unsigned int ID), where do outObj and ID take data from? What's a DWORD? And, finally, why is that one function virtual?
    Last edited by suzakugaiden; 03-17-2005 at 07:47 PM.

  6. #6
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Why do you need return ListOfObjects.size()-1?
    Because if you return size() you will return 1 past the actual size of the vector.

    Also, in void GetObject(Object *outObj,unsigned int ID), where do outObj and ID take data from?
    outObj is modified in the function, you must pass a pointer to an object of type Object. ID is the ID number of the object you request. I'm returning the actual object on the stack instead of returning a pointer address to the object. So this function basically is used like this:


    Object *myObject=NULL;
    GetObject(myObject,1);

    This will find the object in the list with an ID of 1, and will then return that object in myObject.


    What's a DWORD?
    It's a 32-bit assembly language data type. The reason I use it is because a DWORD is guaranteed to be 32-bits. It's equivalent in 32-bit C and on 32-bit compilers is unsigned int, but in 16-bit it would be unsigned long. In 64-bit, unsigned int actually would mean a 64-bit integer. DWORD, however, does not change as long as you are on an x86 platform.

    16 bit - unsigned long
    32 bit - unsigned int
    64 bit - ??

    And, finally, why is that one function virtual?
    I make all my destructors virtual out of habit. It really doesn't serve much purpose in my example but you should make it a habit.

    If you derive from Object there are certain circumstances that arise in code whereby the destructor for the derived class is not called. Making the destructor virtual will guarantee that all derived destructors will be called thereby immediately preventing a very hard to find memory leak and/or resource leak.

  7. #7
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Because if you return size() you will return 1 past the actual size of the vector.
    Er, right, I know that, but why do you need to return the size in the first place? Does it somehow involve returning an iterator to the beginning of your vector?

    And as for your outObj-function thing...

    What it does is passes in an object pointer, myObject, and and ID number. It then sets out object, and since you passed with pointers, I assume myObject, to whatever object is stored at position ID within your... data structure.

    Now, two questions. I'm assuming you're just setting to the pointer to that position in memory, so no assignment operator function is needed. That wasn't a question. !@#%.

    Anyway, the ID your passing in. How would you determine which ID you'd need to pass in the first place? In your example, you basically have 1 hardcoded in. Hence, outObj will always be obj at position 1. Is there some sort of large if/then / case/switch thing and several functions?

    Anyway, back to the virtual thinger.

    What disadvantages are there to making a function virtual? If you THINK you might derive one class from another, but aren't entirely positive, would it be okay to just start the thing out as virtual and go back and clean it up later if you don't need it as virtual?

    Oh, and er, one other question. Let's say I have two object classes -- swords and frogs. They're both derived from a parent class which is called "clothing." Now, via polymorphosism, the two are... like, pointer compatible. Or whatever. You know what I mean, right?

    Anyway, so say I need to store both of these in the same list of things. I'd need to use pointers here.

    So would I create an array of *clothing, or would I create an array of clothing and add *clothing = frogs to it?

    From this, I guess with the memory manager it'd just be itemlist[ID]->pointed_object; or something, right?

  8. #8
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    Anyway, the ID your passing in. How would you determine which ID you'd need to pass in the first place? In your example, you basically have 1 hardcoded in. Hence, outObj will always be obj at position 1. Is there some sort of large if/then / case/switch thing and several functions?
    Code:
    unsigned int AddObject(Object *newobj)
        {
           ListOfObjects.push_back(&newobj);
           return ListOfObjects.size()-1;
        }
    You add objects with this function and it returns the ID. The ID in this setup is just its position in the vector.

    As for the virtual thing, why take a chance when you can ensure that if you derive later your setup is correct.

    I'm not sure what your are saying with the pointer information. You can also pass a reference instead of doing what I did.
    Last edited by VirtualAce; 03-18-2005 at 05:07 PM.

  9. #9
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Wait, why do I need ID numbers? Can't I just have an array or vector or something and put multiple instances in that?

  10. #10
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    How are you going to refer to the object??

    Whether you do:

    Object *ObjectList=new Object[50];

    or

    std::vector<Object> ObjectList;

    You still refer to them via an index into the array in the first case, and into the vector in the second case.

    So to refer to Object number 45, you do:

    ObjectList[45].some_param=<some_value>;


    The 45 is its index into the array/vector and it is also easy to use this as the object's ID number.

    If you prefer to use more unique ID values then you will have to
    create a map and associate the key (the ID) with the object.

    This is no different than doing:

    Object *Object1=new Object;
    Object *Object2=new Object;

    But when you do it this way, you must define a unique pointer for each instance of Object. Inside of an array or vector, you don't have to do this because each element is a pointer to the object.
    Last edited by VirtualAce; 03-19-2005 at 07:47 AM.

  11. #11
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Quote Originally Posted by Bubba
    How are you going to refer to the object??
    This actually sort of hinges on how input is handled.

    If it's just taking player input, typed in from a keyboard, (Get book, for instance) then I can just write a simple search function to find that object, bump it off the room item list, and put it on the player's item list (inventory).

    In a second method, which would just list the items in the room through... say, the first nine items and bind them to a keyboard key, I'd just use the generic SDL setup of a switch/case for keyboard input and work in whatever code I need there. I haven't really messed with this much yet because, as I've mentioned in another topic, I'm not smart enough to get SDL to work.

  12. #12
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    You want to search for the object rather than know where it is in the list?

    I don't see why.

  13. #13
    Registered User
    Join Date
    Jan 2005
    Posts
    106
    Quote Originally Posted by Bubba
    You want to search for the object rather than know where it is in the list?

    I don't see why.
    Well, no, I probably won't be searching. I shouldn't have mentioned that.

    I'm basically just going to have a simple SDL get keydown routine from... letters A to H. I'll somehow map (Read: Not set up an actual MAP. More like have A being an object that points at some spot in my item array) and basically cycle through these values.

    Process:

    Player presses "get" button.
    Submenu opens.
    Submenu presents items A-H.
    Player presses one letter from A-H.
    Item that A-H points at gets removed from the room array and added to the inventory array.

    That's a vast oversimplification, but...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Animating Multiple Object - [Open Gl]
    By Tonto in forum Game Programming
    Replies: 6
    Last Post: 09-29-2006, 06:31 PM
  2. Making a script language?
    By Blackroot in forum Game Programming
    Replies: 10
    Last Post: 02-16-2006, 02:22 AM
  3. A question about constructors...
    By Wolve in forum C++ Programming
    Replies: 9
    Last Post: 05-04-2005, 04:24 PM
  4. How would you do this (object interlinking)
    By darksaidin in forum C++ Programming
    Replies: 7
    Last Post: 08-30-2003, 12:08 AM
  5. multiple object instances at runtime
    By mrukok in forum C++ Programming
    Replies: 1
    Last Post: 03-25-2003, 07:26 AM