• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            天行健 君子當自強而不息

            游戲中物件的定義與使用(8)

             

            本篇是游戲中物件的定義與使用(7)的續篇。


            Developing a Character ICS

            Although developing a character’s inventory system might make you cringe at first,
            let me reassure you that it’s not much different from developing a map inventory
            control system. You have the ability to add and remove items, but you don’t have the
            problem of dealing with the item coordinates on the map. Instead, a player’s ICS
            keeps track of order, which means that players can rearrange the items as they see fit.


            Of course, this ordering is just a matter of arranging the linked list, but what about
            the items that can hold other items, such as backpacks? As long as you properly categorize
            the items as containers in the MIL Editor, you don’t need to worry.


            Speaking of categorizing, the real magic happens when you want to equip or use
            an item. Because each item is categorized, the character ICS can quickly determine
            what to do with the item in question. If the item is a weapon, the character ICS can
            ask to equip the item. If it’s a healing item, the player can consume it. Beginning
            to get the idea?

            Finally, a character ICS should allow the player to examine objects, which is the reason
            for the mesh and image parameters in the MIL Editor. Whenever the game’s
            player examines the object, the specific mesh or image is loaded and displayed.
            Now, turn your attention to putting together a character ICS and example by using
            the ICS.

             

            Defining the cCharICS Class

            Interface:

            //==================================================================================
            // This structure contains char item information list.
            //==================================================================================
            typedef struct sCharItem
            {
                
            long    item_index;     // MIL item index
                long    quantity;       // quantity of item (ie coins)    

                sCharItem*   prev;
                sCharItem*   next;

                
            long    index;           // map item index
                long    owner;

                sCharItem*   parent;     
            // parent of a contained item
                
                sCharItem()
                {
                    memset(
            this, 0, sizeof(*this));
                    owner = -1;
                }

                ~sCharItem()
                {
                    delete next;   
                }
            } *sCharItemPtr;

            //==================================================================================
            // This class encapsulate char inventory contrl system for character.
            //==================================================================================
            typedef class cCharIcs
            {
            private:
                
            long         m_num_items;
                sCharItemPtr m_root_item;

            private:
                
            long    get_next_long(FILE* fp);
                
            float   get_next_float(FILE* fp);

            public:
                cCharIcs();
                ~cCharIcs();

                
            bool load(const char* filename);
                
            bool save(const char* filename);
                
            void free();

                
            void add(long item_index, long quantity, sCharItemPtr owner_item);
                
            void remove(sCharItemPtr item);

                
            long get_num_items();
                sCharItemPtr get_root_item();
                sCharItemPtr get_item(
            long index);

                
            void sort();
                
            bool move_up(sCharItemPtr item);
                
            bool move_down(sCharItemPtr item);
            } *cCharIcsPtr;
             

            Much like the cMapICS class, the cCharICS class uses a special structure (sCharItem) that
            tracks the MIL item numbers and quantity and maintains a linked list. Unlike the
            sMapItem structure, however, sCharItem doesn’t care about the item’s coordinates.

            Implement:

            //----------------------------------------------------------------------------
            // Get numeric value from file.
            //----------------------------------------------------------------------------
            static void get_numeric_value(FILE* fp, char* buf, int size)
            {
                
            long pos;
                
            int c;

                
            // read until EOF or EOL or over buffer
                for(pos = 0; (c = fgetc(fp)) != EOF && c != 0x0a && pos != size-1; pos++)
                {
                    
            if((c >= '0' && c <= '9') || c == '.' || c == '-')
                        buf[pos] = c;
                }

                buf[pos] = 0;
            }

            //----------------------------------------------------------------------------
            // Constructor, initialize member data.
            //----------------------------------------------------------------------------
            cCharIcs::cCharIcs()
            {
                memset(
            this, 0, sizeof(*this));
            }

            //----------------------------------------------------------------------------
            // Destructor, free allocated resource. 
            //----------------------------------------------------------------------------
            cCharIcs::~cCharIcs()
            {
              free();
            }

            //----------------------------------------------------------------------------
            // free allocate resource.
            //----------------------------------------------------------------------------
            void cCharIcs::free()
            {
              m_num_items = 0;

              delete m_root_item;  
            }

            //----------------------------------------------------------------------------
            // Load all char items from file.
            //----------------------------------------------------------------------------
            bool cCharIcs::load(const char* filename)
            {
                free();     
            // free a prior set

                FILE* fp;

                
            if((fp = fopen(filename, "rb")) == NULL)
                    
            return false;    

                sCharItemPtr item;
                sCharItemPtr item_ptr = NULL;

                
            // loop forever reading in items
                while(1)
                {
                    
            long item_index;

                    
            // get next item number (break if no more items, which is represented by a return value of -1).
                    if((item_index = get_next_long(fp)) == -1)
                        
            break;

                    
            // create a new map item and link it in

                    item = 
            new sCharItem;

                    
            if(item_ptr == NULL)
                        m_root_item = item;
                    
            else
                    {
                        item->prev = item_ptr;
                        item_ptr->next = item;
                    }

                    item_ptr = item;

                    item->item_index  = item_index;
                    item->quantity    = get_next_long(fp);      
                    item->owner       = get_next_long(fp);
                    item->index       = m_num_items++;
                }

                fclose(fp);

                
            // match objects that belong to others
                for(item_ptr = m_root_item; item_ptr != NULL; item_ptr = item_ptr->next)
                {
                    
            // check if this item belongs to another
                    if(item_ptr->owner == -1)
                        
            continue;

                    
            // find matching parent item
                    for(item = m_root_item; item != NULL; item = item->next)
                    {
                        
            if(item_ptr->owner == item->index)
                        {
                            
            // a match, point to parent and stop scanning for parents.
                            item_ptr->parent = item;
                            
            break;
                        }
                    }
                }

                
            return true;
            }

            //----------------------------------------------------------------------------
            // Save all char items to file.
            //----------------------------------------------------------------------------
            bool cCharIcs::save(const char* filename)
            {
                FILE* fp;

                
            if((fp = fopen(filename, "wb")) == NULL)
                    
            return false;
                 
                
            long index = 0;

                
            for(sCharItemPtr item = m_root_item; item != NULL; item = item->next)
                {
                    item->index = index++;

                    
            // match child items to parents
                    if(item->parent)
                        item->owner = item->parent->index;
                    
            else
                        item->owner = -1;

                    fprintf(fp, "%lu\r\n%lu\r\n%ld\r\n", item->item_index, item->quantity, item->owner);
                }
                
                fclose(fp);

                
            return true;
            }

            //----------------------------------------------------------------------------
            // Add char item into list.
            //----------------------------------------------------------------------------
            void cCharIcs::add(long item_index, long quantity, sCharItemPtr owner_item)
            {
                sCharItemPtr item = 
            new sCharItem;

                
            // fill the item structure
                item->item_index = item_index;
                item->quantity   = quantity;
                item->parent     = owner_item;

                
            // insert into top of list

                item->next = m_root_item;

                
            if(m_root_item)
                    m_root_item->prev = item;

                m_root_item = item;
            }

            //----------------------------------------------------------------------------
            // Remove char item from list.
            //----------------------------------------------------------------------------
            void cCharIcs::remove(sCharItemPtr item)
            {    
                sCharItemPtr next_item;

                
            // remove child objects first
                for(sCharItemPtr item_ptr = m_root_item; item_ptr != NULL; item_ptr = next_item)
                {
                    next_item = item_ptr->next;

                    
            if(item_ptr->parent == item)
                        remove(item_ptr);
                }

                
            // remove from linked list and reset root if it's the current head of list.
                
                
            if(item->prev)
                    item->prev->next = item->next;
                
            else
                    m_root_item = item->next;

                
            if(item->next)
                    item->next->prev = item->prev;

                item->prev = item->next = NULL;
                delete item;
            }

            //----------------------------------------------------------------------------
            // Return number of map items.
            //----------------------------------------------------------------------------
            long cCharIcs::get_num_items()
            {
                
            return m_num_items;
            }

            //----------------------------------------------------------------------------
            // Return root map item.
            //----------------------------------------------------------------------------
            sCharItemPtr cCharIcs::get_root_item()
            {
                
            return m_root_item;
            }

            //----------------------------------------------------------------------------
            // Return map item with specified index.
            //----------------------------------------------------------------------------
            sCharItemPtr cCharIcs::get_item(long index)
            {
                sCharItemPtr item;

                
            // loop until reached item index
                for(item = m_root_item; item != NULL && index != 0; item = item->next)
                    index--;

                
            return item;
            }

            //----------------------------------------------------------------------------
            // Return long value from next line in file.
            //----------------------------------------------------------------------------
            long cCharIcs::get_next_long(FILE *fp)
            {
                
            char buf[1024];
                get_numeric_value(fp, buf, 
            sizeof(buf));

                
            if(strlen(buf) == 0)    // if there is no long value in file
                    return -1;

                
            return atol(buf);
            }

            //----------------------------------------------------------------------------
            // Return float value from next line in file.
            //----------------------------------------------------------------------------
            float cCharIcs::get_next_float(FILE *fp)
            {
                
            char buf[1024];
                get_numeric_value(fp, buf, 
            sizeof(buf));

                
            return (float)atof(buf);
            }

            The cCharICS class, again, is much like its cMapICS counterpart, except for the addition
            of three more public functions— sort, move_up, and move_down. You use these functions
            to sort the character’s list of items. Their code is as follows:


            //----------------------------------------------------------------------------
            // Arrange char ics.
            //----------------------------------------------------------------------------
            void cCharIcs::sort()
            {
                
            // start at top of linked list and float each item up that has a lesser item_index,
                // break if past bottom of list.
                for(sCharItemPtr item = m_root_item; item != NULL; item = item->next)
                {
                    
            // keep floating up while previous item has a lesser item_index value or
                    // until top of list has been rearched.
                    for(sCharItemPtr prev_item = item->prev; prev_item != NULL; prev_item = item->prev)
                    {
                        
            // break if no more to float up
                        if(prev_item->item_index <= item->item_index)
                            
            break;

                        
            // swap element

                        
            if(prev_item->prev)
                            prev_item->prev->next = item;

                        
            if((prev_item->next = item->next) != NULL)
                            item->next->prev = prev_item;

                        
            if((item->prev = prev_item->prev) == NULL)
                            m_root_item = item;
                        
                        prev_item->prev = item;
                        item->next = prev_item;
                    }
                }
            }

            //----------------------------------------------------------------------------
            // Move one char item up.
            //----------------------------------------------------------------------------
            bool cCharIcs::move_up(sCharItemPtr item)
            {
                sCharItemPtr prev_item = item->prev;

                
            if(prev_item == NULL)
                    
            return FALSE;

                
            // swap item and item before it

                
            if(prev_item->prev)
                    prev_item->prev->next = item;

                
            if((prev_item->next = item->next) != NULL)
                    item->next->prev = prev_item;

                
            if((item->prev = prev_item->prev) == NULL)
                    m_root_item = item;

                prev_item->prev = item;
                item->next = prev_item;

                
            return TRUE;
            }

            //----------------------------------------------------------------------------
            // Move one char item down.
            //----------------------------------------------------------------------------
            bool cCharIcs::move_down(sCharItemPtr item)
            {
                sCharItemPtr next_item = item->next;

                
            if(next_item == NULL)
                    
            return FALSE;

                
            // swap item and item after it

                
            if((item->next = next_item->next) != NULL)
                    next_item->next->prev = item;

                
            if((next_item->prev = item->prev) != NULL)
                    item->prev->next = next_item;
                
            else
                    m_root_item = next_item;

                next_item->next = item;
                item->prev = next_item;

                
            return TRUE;
            }

            Function 'sort' sorts the linked list of items based on each item’s MIL item number, from
            lowest to highest. If, on the other hand, you want to specifically order the list yourself,
            you can utilize the move_up and move_down functions, which take a pointer to a
            sCharItem structure that is already contained in the list.

            The move_up function moves the specified sItem structure up in the linked list, and
            move_down moves the specified structure down in the linked list. Figure 15.10 illustrates
            the concept of using the Arrange, move_up, and move_down functions on a sample
            linked list of items.

            The rest of the functions in cCharICS are identical in their functionality to the
            cMapICS class, with the obvious exclusion of the item coordinates used when adding
            an item to the list. Even the storage format for character items is identical to the
            map item format, except for the coordinates.

             

            Using the cCharICS Class

            To demonstrate the use of the character ICS system, I created a demo application
            named CharICS that maintains a list of items contained in the default.mil master
            item list file. When you start the demo, you’ll see the
            Inventory dialog box (shown in following snap). In the Inventory dialog box, the list
            box contains an imaginary character’s inventory, which you can manipulate by
            using the buttons on the dialog box.

            To use the CharICS demo, follow these steps:


            1. Click the Add Item button. The CharICS demo will add a random item from
            the MIL to the inventory list.


            2. Select an item from the list. Items are classified, so the Use and Equip buttons
            are enabled or disabled depending on which item you select from the
            list. Clicking Equip has no effect; it comes into play later when you deal with
            characters. Clicking Use, however, removes an item if it is flagged as USEONCE.

            3. Click the Drop button to drop an item (remove the item from the inventory
            list) if it is flagged as CANDROP.


            4. In order to arrange the items in the inventory, you can click an item and
            then click either Sort Up or Sort Down. The selected item then moves up or
            down in the list. To arrange the items by their item number in the list, click
            Sort.


            As a last, special treat, items that have matching meshes appear in the box on the
            right in the demo. The 3-D object spins around slowly so that you have a full view
            of all sides. Now, that’s cool!


            posted on 2007-11-08 15:05 lovedday 閱讀(419) 評論(0)  編輯 收藏 引用

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            一本大道久久东京热无码AV| 亚洲va国产va天堂va久久| 一本大道加勒比久久综合| 久久久久亚洲av毛片大| 中文字幕人妻色偷偷久久 | 久久99精品国产自在现线小黄鸭| 久久精品a亚洲国产v高清不卡| 久久成人永久免费播放| 久久久国产精华液| 品成人欧美大片久久国产欧美| 久久精品国产亚洲AV久| 久久精品亚洲欧美日韩久久| 无码超乳爆乳中文字幕久久 | 国产精品乱码久久久久久软件| 久久影院久久香蕉国产线看观看| 中文字幕热久久久久久久| 国产亚洲精午夜久久久久久| 日韩精品久久无码人妻中文字幕| 久久精品国产99久久久香蕉| 99久久中文字幕| 亚洲AV日韩AV天堂久久| 久久精品国产99国产精品导航| 久久精品国产国产精品四凭| 91精品国产91久久综合| 99久久精品免费看国产一区二区三区| 久久久久久一区国产精品| 国产一区二区精品久久| 国产精品欧美久久久天天影视| 亚洲精品无码成人片久久| 一级女性全黄久久生活片免费| 久久久无码精品午夜| 精品熟女少妇aⅴ免费久久| 久久香蕉一级毛片| 美女写真久久影院| 精品久久久久久99人妻| 看全色黄大色大片免费久久久| 国产高潮国产高潮久久久91 | 91久久国产视频| 国产激情久久久久影院小草 | 国产精品亚洲综合专区片高清久久久 | 国产精品无码久久四虎|