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

            天行健 君子當自強而不息

            共4頁: 1 2 3 4 
            re: 創建游戲內核(1) lovedday 2008-03-26 16:55
            啥牛人啊,大菜鳥一個,這些文章不過是自己看書時的摘要,寫出來也是方便自己查閱的,沒想到對大家還有用。
            re: 幾何檢測(3) lovedday 2008-03-14 13:02
            哪錯呢?
            re: 3D中的方位和角位移(5) lovedday 2008-02-28 09:12
            你的理解是對的,可能是作者的疏忽吧,應該是順指針120度。
            這個例子應該說作者舉錯了,即使是順時針240度,也不會和逆時針80度等價,而是和逆時針120度等價。
            re: 我的快樂哪里去了? lovedday 2008-02-27 08:51
            人活著總是有許多的無奈,快樂實在不是一件容易的事。
            不過大多數情況下人還是喜歡自尋煩惱。
            re: 3D中的方位和角位移(5) lovedday 2008-02-27 08:48
            《3D數學基礎:圖形與游戲開發》
            re: 創建3D圖形引擎(3) lovedday 2008-01-22 19:52
            據說《3D Game Engine Programming》不錯,不過只有英文版的。
            re: 莊子 lovedday 2008-01-21 22:37
            good!
            re: 生命不能承受之重 lovedday 2008-01-08 21:11
            @419111344
            很感謝你的關心,做了檢查,問題不太大,可能是我過于擔心了。

            回到家里心情好多了,我很喜歡C++博客,這里有一群對技術癡迷的程序員,還有很多內心充實熱愛生活關心他人的人,謝謝你們,讓我們一起努力吧。

            身體很重要,所有的技術都是身外之物。
            這本書我還想多看幾遍哩,不好意思啊。
            最好劃分出一個個單獨的大模塊,交給一個人獨立完成,協作是很困難的。
            程序這玩意,說實話,有時候人越多越麻煩。
            re: 來自soso.com的攻擊 lovedday 2007-12-27 18:46
            樹大招風啊!dudu辛苦了!
            re: 灌水 lovedday 2007-12-17 22:44
            精辟!
            re: 讀《程序設計總結》有感 lovedday 2007-12-09 13:08
            有道理。
            re: 復雜游戲的沉迷系統 lovedday 2007-12-05 21:38
            別沉迷就好,不過有些游戲設計的你不得不沉迷,不沉迷就玩不下去。
            所以不得不慎。。。。
            游戲這玩意容易沉迷,特別是經過精心設計的游戲。
            不錯,受益匪淺。
            re: 關于構造函數 lovedday 2007-11-30 20:17
            運行應該不會出問題,到這是糟糕的代碼。
            為什么要相乘,這違背了函數功能的本意。

            我覺得這樣就好:

            inline bool IsFloatZero(float x, float epsilon = 1e-6f)
            {
            return fabs(x) < epsilon;
            }

            中國現階段缺乏的就是對大型游戲的源碼剖析這樣的文章,我想現在不少人手里都有一些大型游戲的源碼,但是要看懂這么龐大的代碼不是一件容易的事,支持博主的做法!
            厲害,外行竟然可以研究到這種程度,佩服啊!
            我坐好板凳聽課了。 :)
            So the most beautiful scene is nature, not human built scene.
            But it just a nature photo, not painted by image porecessing software.
            我不是醫生,這個網站的草藥效果不錯,http://lxlzs.cn/gb2312/index.asp
            有沒有將UAC關了?

            原文:Most operations described below require elevated privileges, so disabling UAC (Run->MSCONFIG.EXE->
            Tools->Disable UAC) for the time being is recommended, Of course, it can be safely re-enabled after
            all steps have been performed. Otherwise OEMTOOL.EXE and some SLMGR.VBS operations must be explicitly
            run with adminstrative privileges.
            簡譯:安裝完畢后的第一件事情是首先應該先關閉掉UAC, 在START SEARCH里直接鍵入 MSCONFIG,然后在TOOL選 DISABLE UAC ,然后點擊右下的LAUNCH,重新啟動計算機。
            不錯,差不多就是這么個學習法。
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 17:45
            @foobar

            謝謝,我明白了作者的意思,但實際上正如文章所指出的那樣,這是一個糟糕的設計,實際上這些都導致了含混不清的語義和容易出錯的代碼,所以我說不要去重載函數。

            C++的復雜很大一部分原因是因為其糟糕的設計。
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 17:05
            #include <stdio.h>

            class Base
            {
            public:
            virtual void f(int x)
            {
            printf("call base f function\n");
            }
            };

            class Derived: public Base
            {
            public:
            virtual void f(double pd)
            {
            printf("call derived f function\n");
            }
            };

            int main()
            {
            Base* pb = new Derived;
            pb->f(10.5);

            return 0;
            }

            輸出:

            call base f function

            你說只要函數名稱相同子類就可以覆蓋父類函數的行為,但很顯然,這個例子說明了僅函數名稱相同是無法覆蓋的。如果你沒看懂,是不是說明還沒把多態搞清楚?
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 17:00
            @foobar

            很懷疑你是不是C++沒學好。
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 16:38
            在c++里,子類通過函數名字隱藏父類函數,而不是通過函數簽名!

            這個分析應該沒什么問題
            子類確實通過函數名字隱藏了父類的函數

            -------------------------------------------------------

            你的這個論斷顯然是錯的。

            #include <stdio.h>

            class Base
            {
            public:
            virtual void f(int x)
            {
            printf("call base f function\n");
            }
            };

            class Derived: public Base
            {
            public:
            virtual void f(double pd)
            {
            printf("call derived f function\n");
            }
            };

            int main()
            {
            Base* pb = new Derived;
            pb->f(10.5);

            return 0;
            }

            輸出:

            call base f function
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 15:37
            C++里還有函數重載和參數默認值,實際上這兩個機制是滋生bug的溫床,如果配合多態,將會導致十分難以理解的行為,所以別用函數重載和參數默認值。

            看看這個例子,絕對讓你抓狂,猜猜看輸出的i和j值是多少?

            #include <stdio.h>

            class PARENT
            {
            public:
            virtual int doIt( int v, int av = 10 )
            {
            return v * v;
            }
            };

            class CHILD : public PARENT
            {
            public:
            int doIt( int v, int av = 20 )
            {
            return v * av;
            }
            };

            int main()
            {
            PARENT *p = new CHILD();

            int i = p->doIt(3);
            printf("i = %d\n", i);

            CHILD* q = new CHILD();

            int j = q->doIt(3);
            printf("j = %d\n", j);

            return 0;
            }
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 15:34
            ps,說這些沒別的意思,只是說在實際項目中不應該這么使用運算符重載,當然sherrylso只是為了說明C++語法而編寫這些代碼。
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 15:29
            個人認為盡量少重載運算符,比如printf就比<<好用,實在沒有什么必要去重載<<,使用函數更好。
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 15:25
            #include <iostream>
            using namespace std;
            namespace Koenig
            {
            class MyArg
            {
            public:
            ostream& print(ostream& out) const
            {
            out<<"this is MyArg."<<endl;
            }
            };

            inline ostream& operator<<(ostream& out, const MyArg& myArg)
            {
            return myArg.print(out);
            }
            }

            int main()
            {
            Koenig::MyArg myArg;
            cout<<myArg;
            return 0;
            }

            這種代碼基本上屬于濫用運算符重載,實際上C++的不少機制都會導致被濫用,結果就是產生晦澀難懂且充滿bug的垃圾代碼,當然這種代碼做為反面教材還是不錯的,但若是在項目中使用這種代碼,那將是惡夢。
            re: c++晦澀語法背后的故事(一) lovedday 2007-11-11 15:16
            關于

            class Base
            {
            public:
            virtual void f(int x);
            };
            class Derived: public Base
            {
            public:
            virtual void f(double* pd);
            };
            int main()
            {
            Derived* pd = new Derived();
            pd->f(10); //compile error!!!
            }

            很顯然編譯報錯是對的,因為函數原型不一樣,所以不構成overwrite。

            既然不構成overwrite,那么你調用的就是Derived中的f函數,編譯器檢查后發現沒有匹配的函數,當然報錯。

            至于后面的解釋個人認為不著調。
            c++折騰到這種份上,完全本末倒置。
            這種做法比直接將聲明放在private更糟糕,簡單問題復雜話,如果確實需要僅提供接口,搞個純虛基類不就可以呢?
            re: 老史要發狠了? lovedday 2007-11-04 20:51
            挺佩服老史的,向他學習。
            #include <iostream>
            #include <string>

            using namespace std;

            void trim(string& str)
            {
            str.erase(str.find_last_not_of(' ')+1, string::npos);
            str.erase(0, str.find_first_not_of(' '));
            }

            int main()
            {
            string str = " hello world! ";

            trim(str);

            cout << "after trim:" << endl;
            cout << str << endl;

            return 0;
            }
            #include <string.h>
            #include <stdio.h>

            #pragma warning(disable : 4996)

            char* rtrim(char* s)
            {
            if(s == NULL)
            return NULL;

            // set tail white space as '\0'
            for(size_t i = strlen(s)-1; i >= 0 && s[i] == ' '; i--)
            s[i] = '\0';

            return s;
            }

            char* ltrim(char* s)
            {
            if(s == NULL)
            return NULL;

            char* p;

            // skip head white space
            for(p = s; *p == ' '; p++)
            ;

            if(p != s) // if address p is not same as address s
            {
            size_t length = strlen(p);

            if(length > 0) // so p is not null
            {
            memmove(s, p, length);
            s[length] = '\0';
            }
            }

            return s;
            }

            char* trim(char* s)
            {
            if(s == NULL)
            return NULL;

            rtrim(s);

            return ltrim(s);
            }

            int main()
            {
            char s[10];
            strcpy(s, " ab cde ");

            trim(s);

            printf("after trim:\n");

            if(*s != '\0')
            printf("%s, length = %d\n", s, strlen(s));
            else
            printf("s is null\n");

            return 0;
            }
            re: 老史要發狠了? lovedday 2007-11-04 00:45
            haha
            哈哈,獻丑了。
            我做了個試驗,試驗條件是XP + VS 2005,在Release版本下測試,結果相當令人吃驚。

            malloc版本:

            #define ITEM_TIMES 1000000

            #include <malloc.h>

            #define NULL 0

            typedef struct UPDATE_ITEM
            {
            bool down_succeeded;
            } *UPDATE_ITEM_PTR;

            typedef struct DOWN_ITEM
            {
            UPDATE_ITEM_PTR update_item;
            bool pack;

            DOWN_ITEM* next;
            } *DOWN_ITEM_PTR;

            DOWN_ITEM_PTR create_down_item(bool pack, bool down_succeeded)
            {
            DOWN_ITEM_PTR down_item = (DOWN_ITEM_PTR) malloc(sizeof(DOWN_ITEM));
            down_item->pack = pack;

            down_item->update_item = (UPDATE_ITEM_PTR) malloc(sizeof(UPDATE_ITEM));
            down_item->update_item->down_succeeded = down_succeeded;

            down_item->next = NULL;

            return down_item;
            }

            void free_all_down_item(DOWN_ITEM_PTR root_down_item)
            {
            DOWN_ITEM_PTR down_item_ptr = root_down_item;

            while(down_item_ptr)
            {
            if(down_item_ptr->update_item)
            free(down_item_ptr->update_item);

            DOWN_ITEM_PTR temp_ptr = down_item_ptr;
            down_item_ptr = down_item_ptr->next;

            free(temp_ptr);
            }
            }

            int main()
            {
            DOWN_ITEM_PTR first, last, ptr;

            for(int i = 0; i < ITEM_TIMES; i++)
            {
            if(i == 0)
            {
            first = create_down_item(true, false);
            last = first;
            }
            else
            {
            ptr = create_down_item(true, false);
            last->next = ptr;

            last = ptr;
            }
            }

            while(1)
            ;

            free_all_down_item(first);

            return 0;
            }

            vector版本:

            #include <vector>

            using namespace std;

            typedef struct UPADTE_ITEM
            {
            bool down_succeeded;

            UPADTE_ITEM()
            {
            down_succeeded = false;
            }
            } *UPADTE_ITEM_PTR;

            typedef struct DOWN_ITEM
            {
            UPADTE_ITEM_PTR update_item;
            bool pack;

            DOWN_ITEM()
            {
            update_item = NULL;
            pack = false;
            }

            DOWN_ITEM(UPADTE_ITEM_PTR _update_item, bool _pack)
            {
            update_item = _update_item;
            pack = _pack;
            }
            } *DOWN_ITEM_PTR;

            int main()
            {
            vector<DOWN_ITEM> down_item_vec;

            UPADTE_ITEM_PTR update_item_list = new UPADTE_ITEM[ITEM_TIMES];

            for(int i = 0; i < ITEM_TIMES; i++)
            down_item_vec.push_back(DOWN_ITEM(&update_item_list[i], true));

            while(1)
            ;

            delete[] update_item_list;

            return 0;
            }

            改變ITEM_TIMES的值以改變迭代次數。

            內存消耗比較:

            迭代1000次: malloc - 868k vector - 796K
            迭代10000次 : malloc - 1784k vector - 916k
            迭代100000次 : malloc - 10956k vector - 2000k
            迭代1000000次 : malloc - 102648k vector - 10008k

            vector版本內存消耗更少,我想應該是多次malloc導致內存消耗劇增,而vector只在必要的時候才重新分配內存。
            而malloc版本在代碼中所涉及的指針操作也相當煩瑣。
            似乎也涉及到內存的兩次分配,免不了了,STL的push_back必然需要拷貝一次原始對象,從這種意義上說,可以不用vector,哈哈。
            正確的做法應該是:

            downList.push_back(stDownItem(&item1, true));
            downList.push_back(stDownItem(&item2, false));
            你的代碼中涉及到內存的兩次分配。

              stDownItem downItem1(&item1, true); // 第一次分配
            stDownItem downItem2(&item2, false);

            downList.push_back(downItem1); // 第二次分配
            downList.push_back(downItem2);

            ---------------------------------------------------------------------------------------------------------

            而C風格僅涉及到一次內存分配。

            DOWN_ITEM_PTR down_item1 = create_down_item(true, false); // 就一次內存分配
            DOWN_ITEM_PTR down_item2 = create_down_item(false, false);

            down_item1->next = down_item2;
            也可能這么寫:

            #include <stdio.h>
            #include <malloc.h>

            typedef struct UPDATE_ITEM
            {
            bool down_succeeded;
            } *UPDATE_ITEM_PTR;

            typedef struct DOWN_ITEM
            {
            UPDATE_ITEM_PTR update_item;
            bool pack;

            DOWN_ITEM* next;
            } *DOWN_ITEM_PTR;

            DOWN_ITEM_PTR create_down_item(bool pack, bool down_succeeded)
            {
            DOWN_ITEM_PTR down_item = (DOWN_ITEM_PTR) malloc(sizeof(DOWN_ITEM));
            down_item->pack = pack;

            down_item->update_item = (UPDATE_ITEM_PTR) malloc(sizeof(UPDATE_ITEM));
            down_item->update_item->down_succeeded = down_succeeded;

            down_item->next = NULL;

            return down_item;
            }

            void free_all_down_item(DOWN_ITEM_PTR root_down_item)
            {
            DOWN_ITEM_PTR down_item_ptr = root_down_item;

            while(down_item_ptr)
            {
            if(down_item_ptr->update_item)
            free(down_item_ptr->update_item);

            DOWN_ITEM_PTR temp_ptr = down_item_ptr;
            down_item_ptr = down_item_ptr->next;

            free(temp_ptr);
            }
            }

            int main()
            {
            DOWN_ITEM_PTR down_item1 = create_down_item(true, false);
            DOWN_ITEM_PTR down_item2 = create_down_item(false, false);

            down_item1->next = down_item2;

            DOWN_ITEM_PTR down_item_ptr = down_item1;

            while(down_item_ptr)
            {
            down_item_ptr->update_item->down_succeeded = true;
            down_item_ptr = down_item_ptr->next;
            }

            free_all_down_item(down_item1);

            return 0;
            }
            不過我可能會這么寫:

            #include <malloc.h>
            #include <vector>

            using namespace std;

            typedef struct UPADTE_ITEM
            {
            bool down_succeeded;

            UPADTE_ITEM()
            {
            down_succeeded = false;
            }
            } *UPADTE_ITEM_PTR;

            typedef struct DOWN_ITEM
            {
            UPADTE_ITEM_PTR update_item;
            bool pack;

            DOWN_ITEM()
            {
            memset(this, 0, sizeof(*this));
            }
            } *DOWN_ITEM_PTR;

            int main()
            {
            vector<DOWN_ITEM> down_item_vec;

            UPADTE_ITEM item1;
            UPADTE_ITEM item2;

            DOWN_ITEM downItem1;
            downItem1.update_item = &item1;
            downItem1.pack = true;

            DOWN_ITEM downItem2;
            downItem2.update_item = &item2;
            downItem2.pack = false;

            down_item_vec.push_back(downItem1);
            down_item_vec.push_back(downItem2);

            for (vector<DOWN_ITEM>::const_iterator it = down_item_vec.begin(); it != down_item_vec.end(); ++it)
            {
            it->update_item->down_succeeded = true;
            }

            return 0;
            }
            共4頁: 1 2 3 4 

            公告

            導航

            統計

            常用鏈接

            隨筆分類(178)

            3D游戲編程相關鏈接

            搜索

            最新評論

            久久精品国产只有精品66| 久久综合九色综合网站| 青草影院天堂男人久久| 亚洲国产精品久久久久| 久久噜噜久久久精品66| 久久青青草视频| 精品国产91久久久久久久| 久久强奷乱码老熟女| 中文字幕人妻色偷偷久久| 国产 亚洲 欧美 另类 久久| 色老头网站久久网| 久久精品成人国产午夜| 久久这里都是精品| 一本大道加勒比久久综合| 免费精品国产日韩热久久| 久久99免费视频| 午夜精品久久久久久99热| 久久亚洲2019中文字幕| 91精品国产综合久久精品| 久久久久亚洲AV成人网人人网站 | 亚洲国产精品综合久久网络| 人妻少妇久久中文字幕| 国产精品久久久久久久久软件| 久久亚洲国产中v天仙www | 久久综合给合久久狠狠狠97色 | 色偷偷88欧美精品久久久| 69久久精品无码一区二区| 精品久久久久久久久免费影院 | 97久久超碰成人精品网站| 亚洲欧美一区二区三区久久| 久久国产精品视频| 色综合久久久久网| 99麻豆久久久国产精品免费| 久久久无码一区二区三区| 久久精品国产久精国产思思| 国产精品久久久香蕉| 波多野结衣久久一区二区| 久久综合亚洲色一区二区三区| 性做久久久久久久久浪潮| 中文字幕精品久久| 免费精品久久天干天干|