• <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>

            天行健 君子當(dāng)自強(qiáng)而不息

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

             

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

             

            cMapIcs::get_next_long,cMapIcs::get_next_float

            //----------------------------------------------------------------------------
            // Return long value from next line in file.
            //----------------------------------------------------------------------------
            long get_next_long(FILE* fp)
            {
                
            char buf[1024];
                
            long pos = 0;
                
            int c;

                
            // Read until EOF or EOL
                while(1) 
                {
                    
            if((c = fgetc(fp)) == EOF || c == '\n' || pos == sizeof(buf)-1)
                        
            break;

                    
            if((c >= '0' && c <= '9') || c == '.' || c == '-')
                        buf[pos++] = c;
                }

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

                buf[pos] = 0;

                
            return atol(buf);
            }

            //----------------------------------------------------------------------------
            // Return float value from next line in file.
            //----------------------------------------------------------------------------
            float get_next_float(FILE* fp)
            {
                
            char buf[1024];
                
            long pos = 0;
                
            int c;

                
            // Read until EOF or EOL
                while(1) 
                {
                    
            if((c = fgetc(fp)) == EOF || c == '\n' || pos == sizeof(buf)-1)
                        
            break;

                    
            if((c >= '0' && c <= '9') || c == '.' || c == '-')
                        buf[pos++] = c;
                }

                buf[pos] = 0;

                
            return (float)atof(buf);
            }
             

            構(gòu)造函數(shù)、析構(gòu)函數(shù)

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

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

            cMapIcs::load, cMapIcs::save, and cMapIcs::free

            As their names suggest, this trio of functions loads, saves, and frees a list of items
            that belong to a map. The first of the three, Load, loads and creates a list of items.
            For simplicity, store all items in a text file, using the following format:


            MIL_ItemNum
            Quantity
            XPos
            YPos
            ZPos
            ParentID


            Each item uses six lines of text, and each entry (group of six lines) is numbered
            sequentially (the first item in the file is item #0, the second item is #1, and so on).
            Here’s a sample file that contains two items:


            // Item #0 as follows:
            10 // MIL Item # (long value)
            1 // Quantity (long value)
            10.0 // XPos (float value)
            0.0 // YPos (float value)
            600.0 // ZPos (float value)
            -1 // Owner (-1 = none, index # otherwise)
            // Item #1 as follows:
            1 // MIL Item #
            1 // ...
            10.0
            0.0
            600.0
            0 // belongs to item #0 (first item in file)

            The preceding comments are for clarification; the actual storage file does not use
            them. When reading in a list of items such as the preceding ones, the Load function
            converts the text into usable numbers. Using those numbers, it creates a sMapItem
            structure for each item in the map to be loaded, constructing a linked list as the
            items are loaded. After every item is read in, all objects that belong to another are
            matched up (using the Parent pointer in the sMapItem structure).


            There’s really nothing too difficult here, so jump right into the cMapIcs::load code:

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

                FILE* fp;

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

                
            long item_index;

                sMapItemPtr item;
                sMapItemPtr item_ptr = NULL;

                
            // loop forever reading in items
                while(1)
                {
                    
            // 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 sMapItem;

                    
            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->x_pos       = get_next_float(fp);
                    item->y_pos       = get_next_float(fp);
                    item->z_pos       = get_next_float(fp);        
                    item->owner_index = 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_index == -1)
                        
            continue;

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

                
            return true;
            }

            Save takes an internal list of items and, using the filename you specify, saves that list
            to a file on disk. The Save function is typically used to update the game data, because
            players might consistently pick up and drop items.

            The Save function first assigns an index value to each sMapItem structure in the
            linked list (based on their order). The first item in the linked list is 0 (zero), the
            second item is 1, and so on. Each child item’s Owner variable is updated as well at
            this point, and finally all data is written to a file:


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

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

                sMapItemPtr item;
                
            long index = 0;

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

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

                    fprintf(fp, "%lu\r\n%lu\r\n%lf\r\n%lf\r\n%lf\r\n%ld\r\n",
                            item->item_index, item->quantity,
                            item->x_pos, item->y_pos, item->z_pos,
                            item->owner_index);
                }
                
                fclose(fp);

                
            return true;
            }

            Finally, you use the Free function when destroying the class (thus, deleting the
            linked list of items). Here’s the code for free:


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

              delete m_root_item;  
            }

            You’re just deleting the item linked list and getting the class ready for further use.

             

            cMapIcs::Add and cMapIcs::Remove

            As items are added to the map (as the result of a player dropping them, for example),
            you need to call add to make sure those dropped items make it into the list of
            map objects. The add function does this by first allocating a sMapItem structure, filling
            it with the appropriate item information that you give it and then linking it into the
            map’s list of items:

            //----------------------------------------------------------------------------
            // Add map item into list.
            //----------------------------------------------------------------------------
            void cMapIcs::add(long item_index, long quantity, 
                              
            float x_pos, float y_pos, float z_pos, 
                              sMapItemPtr owner_item)
            {
                sMapItemPtr item = 
            new sMapItem;

                
            // fill the item structure
                item->item_index = item_index;
                item->quantity   = quantity;
                item->x_pos      = x_pos;
                item->y_pos      = y_pos;
                item->z_pos      = z_pos;
                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;
            }

            Just as the Add function is used to add objects to the map’s list of items, you’ll need
            to use Remove to remove items from a map. You call Remove using the item’s identifier
            that you wish to remove from the map’s list. Remove also deletes the allocated item
            structure and takes care of items that belong to the removed item:


             
            //----------------------------------------------------------------------------
            // Remove map item from list.
            //----------------------------------------------------------------------------
            void cMapIcs::remove(sMapItemPtr item)
            {
                sMapItemPtr item_ptr;
                sMapItemPtr next_item;

                
            // remove child objects first
                for(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;
            }

             

            cMapIcs::get_num_items,cMapIcs::get_parent_item,and cMapIcs::get_item

            You use these three functions to retrieve the number of items that belong to the map and to retrieve the parent
            sMapItem or specified item structure in the linked list. The first two of the following three functions return a single variable while the third function does the hard work by scanning through the linked list of objects, returning the specified item in the list:

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

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

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

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

                
            return item;
            }

             

            cMapIcs類的使用

            Every map in your game will have an associated list of items that belongs to it. The
            map ICS will load those items and provide them to your engine whenever it needs
            to render the map or add a specific item to a player’s inventory (when an item
            contained in the map is picked up).


            Take a look at the following code bit, which loads a sample list of items, adds a
            single item, removes another item, and saves the list of items:

            cMapIcs MapICS;

            MapICS.load(“sample.mi”); // Load the file

            // Add 1 of item # 10
            MapICS.add(10, 1, 0.0f, 0.0f, 100.0f, NULL);

            // Remove 2nd item from list
            MapICS.remove(MapICS.GetItem(1));

            // Save list back out
            MapICS.save(“sample.mi”);

            Although this is a simple example of modifying a map’s item list, why not go ahead
            and see just how complicated it can become.


            The MapICS demo (see following snap) contains the full cMapICS class and the sItem structure from the MIL edit program.  You use the map ICS and MIL to render a list of objects spread around a simple level.

            The MapICS loads the map items and uses their coordinate data to draw
            a generic item mesh in the scene. Whenever you approach an item, a
            targeting icon appears and displays the name of the item.

            NOTE
            The MapICS demo allows you to walk around a simple level by using the
            arrow keys and mouse.You can pick up items by standing in front of one and
            pressing the left mouse button. Pressing the right mouse button
            causes you to drop a random item.

            Once the level is rendered out, each item in the map is scanned and drawn if in
            view. The closest item is detected, and its name is printed to the screen. The code
            is well commented, so you should have no problem breezing through it.

             

            posted on 2007-11-07 19:28 lovedday 閱讀(303) 評論(0)  編輯 收藏 引用


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            公告

            導(dǎo)航

            統(tǒng)計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關(guān)鏈接

            搜索

            最新評論

            性欧美丰满熟妇XXXX性久久久| 天天爽天天爽天天片a久久网| 久久久精品国产Sm最大网站| 日本加勒比久久精品| 久久精品国产99国产精品导航| 丰满少妇高潮惨叫久久久| 久久久久久国产精品美女| 亚洲国产美女精品久久久久∴| 色综合久久最新中文字幕| 久久人妻少妇嫩草AV蜜桃| 国产成人久久精品二区三区| 亚洲AV成人无码久久精品老人| 亚洲一区二区三区日本久久九| 久久人人添人人爽添人人片牛牛| Xx性欧美肥妇精品久久久久久 | 久久久久亚洲av无码专区喷水| 天天久久狠狠色综合| 久久99国产综合精品免费| 国产精品久久久久久久人人看| 亚洲综合婷婷久久| 久久这里只有精品久久| 99久久er这里只有精品18| 午夜精品久久久久久久久| 色妞色综合久久夜夜| 久久这里只精品99re66| 久久免费99精品国产自在现线| 77777亚洲午夜久久多喷| 久久亚洲私人国产精品vA| 亚洲精品无码久久一线| 精品国产青草久久久久福利| 欧美激情一区二区久久久| 久久久久久午夜精品| 亚洲综合日韩久久成人AV| 久久精品一本到99热免费| 久久精品免费一区二区| 99久久国产精品免费一区二区| 久久久久亚洲av成人网人人软件 | 久久精品夜夜夜夜夜久久| 久久久婷婷五月亚洲97号色 | 色成年激情久久综合| 国内精品伊人久久久久网站|