發表文章

目前顯示的是 4月, 2023的文章

MSVC 與 CRT 之間的恩怨情仇

圖片
MSVC 與 CRT 之間的恩怨情仇 這篇文章是引用自http://www.aiuxian.com/article/p-346587.html 很久沒有寫程式設計入門知識的相關文章了,這篇文章要來談談程式庫 (Library) 連結,以及關於 MSVC 與 CRT 之間的種種恩怨情仇。 如果你的作業系統是 Windows,而且你使用的程式整合開發環境是 MSVC 軟體撰寫 C++ 程式的話,這篇文章應該能夠幫助你釐清一些重要的基礎觀念。 身為程式設計者,在學習程式設計的過程中,你是否曾經遇過某些看起來不知所云的錯誤訊息,卻不知該如何解決?例如當你快快樂樂地寫完程式,並且確認所有的程式碼都能成功通過編譯之後,接著執行「建置方案」(Build Solution) 的步驟,結果卻跑出一堆莫名其妙的錯誤: LIBCMTD.lib(mlock.obj) : error LNK2005: __lock 已在 MSVCRTD.lib(MSVCR80D.dll) 中定義過了 LIBCMTD.lib(mlock.obj) : error LNK2005: __unlock 已在 MSVCRTD.lib(MSVCR80D.dll) 中定義過了 LIBCMTD.lib(crt0.obj) : error LNK2005: _mainCRTStartup 已在 MSVCRTD.lib(crtexe.obj) 中定義過了 ………… LINK : warning LNK4098: 預設的程式庫 ‘MSVCRTD’ 與其他使用的程式庫衝突,請使用 /NODEFAULTLIB:library LINK : warning LNK4098: 預設的程式庫 ‘LIBCMTD’ 與其他使用的程式庫衝突,請使用 /NODEFAULTLIB:library D:\Workspace\CrtLibTest\Debug\CrtLibTest.exe : fatal error LNK1169: 找到有一或多個已定義的符號 以一般的情況來說,如果在你的程式專案中有使用某些由他人所撰寫的第三方程式庫或是開源專案的程式庫,比較容易會發生上述的錯誤狀況。從上述這些看似離奇而令人摸不著頭緒的錯誤訊息中,我們大概可以猜測問題點應該在於 LIBCMTD.lib 與 MSVCRTD.lib 這兩個程式庫身上。但到底什麼是 LI...

魔術方塊

圖片
 魔術方塊

言魂事務所-03

言魂事務所-03 一陣強光之後,我看到一個手上有一顆白色的小球。 寒星說:「哇~真讓我驚訝,以第一次上工來說,你的表現很好呢!」 我問:「寒星,那個言魂是消失了嗎?」 寒星:「可能會消失,也可能不會。」 我說:「但是球已經沒有顏色了啊,不是代表他消失了嗎?」 寒星:「沒有顏色只是代表本心沒有出現拉扯,並不是代表言魂消失了喔!」 我:「我們不能讓言魂直接消失嗎?」 寒星說:「言魂是由語言的力量所生,說出去的話可以收回嗎?」 我問:「呃...不行。」 寒星說:「但本心受這語言的影響有多大,這力量就有多大。如果本心不在乎,那就沒有力量。如果小女孩不再在意被嘲笑的事,那這個力量就會變小,甚至消散,言魂就消失了,所以最終還是要看本心。」 寒星說:「力量沒有好壞,所以言魂也沒有好壞,一切都在於本心,這些力量有沒有讓本心違背他的意願,讓本心產生拉扯,才是我們要處理的問題。」 寒星說:「而且我們只能使用語言的力量,我們並沒有消滅或收回的能力。」 寒星說:「語言還有一種特性,就是它在就是在了。」 我:「蛤,什麼意思?」 寒星說:「不要去想一隻彩虹色的蟑螂。」 我:「彩虹色的...什麼?」 寒星說:「你現在腦袋裡是不是出現了什麼東西?」 我:「是啊,彩虹色的蟑螂,你說的。」 寒星說:「但我前面叫你不要去想了。」 我:「...」 寒星說:「沒有用對吧。」 寒星說:「如果是一個怕蟑螂的人聽到剛才那句話,他就會受到影響,這個語言就會產生力量,他可能突然會感到害怕,無論我前面是不是有加了『不要』,甚至是這世界上根本沒有彩虹色的蟑螂。」 我:「那他會產生彩虹色的蟑螂言魂嗎?」 寒星說:「可能會,不過這種情況也是一下子就消失了,因為大部分人不會一直去在意這種無厘頭的話。」 寒星說:「但你還是要小心,在就是在了,就算前面加了『不要』也一樣。」

言魂事務所-02-第一份工作

言魂事務所-02-第一份工作 面具人:「這是寒星,你先跟著她吧!」 寒星:「你好,我是寒星。」 我:「你好。」 寒星:「好,打過招呼了,那我們走囉!」 我:「欸~去哪?」 寒星拉著我的手,碰了一顆淡紫色的小球,進入一個淡紫色的空間。 我看見一個穿白衣的小女孩,抱著膝蓋坐在地板上,看著眼前的大螢幕,螢幕上是一個公園,有一群小朋友正在玩耍。 我:「這裡是哪裡?」 寒星:「這裡是人類的內心世界。」 寒星:「那個白色衣服的人,就是這個人的本心,那個螢幕顯示的,就是這個人所在的現實世界。」 白衣女孩小小的臉上看得出憂愁。 小女孩說:「我好想跟她們一起玩喔…」 周圍突然出現了很多聲音。 「你們看,她的衣服領子在後面耶!嘻嘻。」 「媽媽沒幫忙就會穿反,真是個笨蛋。」 「笨蛋。笨蛋。笨蛋。」 「我們才不跟笨蛋一起玩呢。」 「哈哈,笨死了,哈哈。」 這時從周圍淡紫色的空間中濃縮出一團淡紫色的輪廓。 淡紫色的輪廓說話了:「但是在之前的公園,因為衣服穿反了。」 「被說成是笨蛋,被笑了好久呢!」 「你還想再被笑嗎?那很丟臉耶!」 小女孩的頭更低,小小的眉心也更皺了。 我:「那是什麼?」 寒星說:「那個就是言魂,因爲以前衣服穿反了,被其他小朋友嘲笑,這個小女孩被這些語言影響,而這個影響力產生了這個言魂。」 寒星說:「本心想要去說話,言魂卻質疑她,讓本心不敢去做自己想做的事,這樣的內心拉扯會讓心的顏色變深。」 寒星說:「來考考你,我們主要的使命是什麼呢?」 我:「根據之前那個黑面具人說的,是要讓內心拉扯變小。」 寒星說:「答對了,那你知道具體要怎麼做嗎?」 我:「讓小女孩去說話嗎?」 寒星說:「是的,沒錯。」 我:「那要怎麼做呢?」 寒星說:「我們再觀察看看吧!」 在螢幕中看見一隻橘色流浪貓走向小女孩。 貓:「喵~」 小女孩說:「啊~橘子,你來了啊,我有帶你的點心喔。」 小女孩說:「我還有帶我的餅乾,我們一起吃點心吧!」 貓:「喵~」 小女孩從小包包裡拿出了一小包貓餅乾,然後小心地餵貓餅乾給流浪貓,自己也吃著自己的餅乾。 小女孩說:「還是橘子最好了,不會笑我。」 等貓吃完還整理了一下袋子和地上的碎屑。 寒星說:「嘿,有辦法了。」 寒星說:「像這種時候,就要產生新的言魂。」 寒星從口袋裡掏出一隻貓咪布偶給我。 寒星說:「我們是不能直接對本心說話的,我們只能透過言魂說話,你把這個布偶往地上丟,然後...

言魂事務所-01-序章

 言魂事務所-01-序章 「喂,醒醒。」 我張開眼睛,在黑色的空間中有許多發光的古文字向下移動,四周漂浮著許多不同顏色、不同大小的玻璃球。 一個戴著面具的人對著我,感覺不出來他是男是女。 我:「這裡是哪裡?我怎麼會在這裡?」 戴面具的人說:「這裡是語言的世界,那些是人心。」 我:「人心?」 面具人說:「每個人每天都會不斷被灌注語言,這些語言都有力量,會成為言魂,一直被灌注力量,言魂就會越來越強大,甚至會擁有形體,影響本心。」 面具人說:「當本心與言魂之間的內心拉扯越來越大時,心的顏色就會越來越深,這個人就越會陷入混亂或做出不適當的行為。」 面具人說:「我們是使用語言力量的使者,我們的使命就是用語言的力量培養或調整言魂,讓本心與言魂之間的內心拉扯變小。」 面具人說:「歡迎你來到言魂事務所。」

虛擬硬碟指令

虛擬硬碟指令 subst k: d:\HKLIB

C# 的 Dictionary

C# 的 Dictionary 與 C++ 的 map 非常相似,只是沒有排序功能 class DictionaryTest using System; using System.Collections.Generic; class DictionaryTest {     private Dictionary<int, string> _dicTest = new Dictionary<int, string>();     public DictionaryTest()     {         _dicTest.Clear();     }     public bool IsExist(int idx)     {         //TryGetValue 比 ContainsKey 還要快         string str = null;         if (_dicTest.TryGetValue(idx, out str))             return true;         return false;     }     public void AddData(int idx, string str)     {         if(!IsExist(idx))             _dicTest[idx] = str;     }     public string GetData(int idx)     {         string str = null; ...

C++ 覺得奇妙的傳陣列方法

C++ 覺得奇妙的傳陣列方法 延伸閱讀:C++ Primer(4/e) P238 7.2.4. Array 參數 #include <iostream> using namespace std; const int ARRAY_NUM = 5; void Array(int p[ARRAY_NUM]); int main() { int p1[ARRAY_NUM] = { 1, 2, 3, 4, 5 }; cout <<"sizeof(p1) = " << sizeof(p1) << endl; //20 Array(p1); system("pause"); return 0; } void Array(int p[ARRAY_NUM]) //這個陣列裡的數字其實寫什麼都沒差 { cout << "sizeof(p) = " << sizeof(p) << endl; //4(是指標) cout << endl; for (int i = 0; i < 5; i++) cout << p[i] << endl; cout << endl; for (int i = 0; i < 5; i++) cout << *(p++) << endl; }

debugnew

debugnew debugnew.h   #ifdef _DEBUG #ifndef __DEBUG_NEW_H #define __DEBUG_NEW_H #define THIS_FILE    __FILE__ void* __cdecl operator new(size_t nSize, int nType, const char* lpszFileName, int nLine); void* _cdecl operator new(size_t nSize, const char* lpszFileName, int nLine); void* __cdecl operator new[](size_t nSize, const char* lpszFileName, int nLine); void __cdecl operator delete(void* p); void __cdecl operator delete[](void* p); #define DEBUG_NEW new(THIS_FILE, __LINE__) #endif //__DEBUG_NEW_H #endif // _DEBUG   debugnew.cpp   #ifdef _DEBUG #include <crtdbg.h> #include "../include/debugnew.h" namespace {     class AutoDetectMemory     {     public:         AutoDetectMemory()         {             _CrtSetReportMode( _CRT_ERROR, _CRTDBG_MODE_DEBUG );             _CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF...

關於 Unity 粒子特效的縮放

關於 Unity 粒子特效的縮放 測試日期 2015/5/13 對於 Unity 的粒子特效 真的是....為什麼不能縮放呢..= =? 這樣使用 Asset Store 的特效包也很難用吧! 每個案子所使用的單位都不一樣啊! 而且特效也還有其他不足的部分 比方說不能在某時間插入事件或插入音效 一個爆炸的特效沒有爆炸的聲音不也很奇怪嗎? 希望他們以後可以修改 使用了第一個網頁裡的方式 不知道會不會很耗效能............... [參考網頁] http://forum.china.unity3d.com/thread-700-1-1.html http://game.ceeger.com/forum/read.php?tid=10081 http://forum.unity3d.com/threads/how-does-the-transforms-scale-work-with-a-particle-system.101964/ http://forum.unity3d.com/threads/shocked-particle-emitter-not-scalable-solved.104817/

是BUG還是Feature

是BUG還是Feature 本文來自北極熊的休閒小站 https://www.facebook.com/447574262066804/photos/a.447623198728577.1073741828.447574262066804/447584265399137/?type=1&fref=nf Tap Titans是一款需要瘋款點擊的小品遊戲。其實還挺好玩的,筆者沈迷過一段時間。不過如果你剛好在捷運上拼排行,瘋狂點擊手機的舉動可能會讓隔壁的乘客認為你是神經病(笑)。 遊戲好玩歸好玩,一直狂點可是很累人的,所以遊戲內設計了一個叫「影分身」的技能。啟動技能時,就會跳出一個黑色的小人幫你快速打擊怪物(如圖)。 大家都知道,凡是技能都會有持續時間與冷卻時間。影分身一開始的時候,持續時間30秒,冷卻10分鐘,看起來不太夠用,不過沒關係,遊戲中有各種「神器」可以來讓玩家變強。其中有兩種神器和影分身有關,一個可以增加持續時間 - 無上限,另一個可以減少冷卻時間 - 最少減到5分鐘。 所以就有玩家開發出影分身流,也就是把持續時間增強到5分鐘以上,讓持續時間 ≧ 冷卻時間,這樣無限影分身就出現了! 由於遊戲的設計是無限轉生重打,加上關卡數又多(目前版本3000關),每次轉生的時候,前面一大段輕鬆簡單的關卡,都可以靠這個無限影分身來節省大量的點擊時間,點一次技能就可以去看個電視或做其他事情,5分鐘之後回來收割,持續這樣的節奏,直到到後面影分身推不動時,再靠手動點擊這樣。 由於實在是太方便了,所以玩家們群起效尤,已經沒有玩家不點影分身的神器了。並且直接導致大部份的遊戲時間都在影分身幫打中度過,也因此被玩家戲稱Tap Titans已經是「影子傳說」了。(紅白機老玩家梗) 官方覺得這樣是不對,這個遊戲不應該是這樣玩的,因此在最近的更新中,把這個BUG修掉了。修正的方式是:無論技能持續的時間多長,冷卻時間都改從技能結束後開始計算。(也就是你放玩招後一定要等5-10分鐘的意思) 這個修正從遊戲結構上看上去是對的,畢竟遊戲就是希望玩家點,而不是希望變成影子傳說,但是包括筆者在內的許多「既得利益」的玩家來說,這個實在是不能接受的改動,除了當初為了抽到與培養影分身相關的神器,花了許多時間與資源外。更重要的是,整個遊戲的節奏會變得很漫長,而且疲勞度會大增,也因此讓筆者一度考慮棄坑... ...

最簡單的DirectX 9.0 程式

圖片
最簡單的DirectX 9.0 程式 在換電腦或是換Visual Studio版本的時候 我通常使用這小(?)程式來確認directX的設定是否正確 他應該可以說是我在 directX 上的 Hello World  環境 windows 7 64-bit Microsoft DirectX SDK (June 2010) Visual Studio 2010  首先在微軟下載DirectX SDK http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=6812   安裝完後建立專案 設定好include的header C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include    設定好Lib C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86   程式碼 main.h   #ifndef __MAIN_H #define __MAIN_H //windows 相關 #include <stdio.h> #include <windows.h> #include <tchar.h> //directx 相關 #include <d3d9.h> #include <d3dx9.h> #pragma comment(lib,"dsound.lib") #pragma comment(lib,"dinput8.lib") #pragma comment(lib,"d3dx9.lib") #pragma comment(lib,"d3d9.lib") #pragma comment(lib,"d3dxof.lib") #pragma comment(lib,"dxguid.lib") // 釋放記憶體 #define SAFE_DELETE(p)  { if(p) { delete (p);     (p)=NULL; } } #define SAFE_REL...

C++ 的 template 測試 2

C++ 的 template 測試 2 #include <iostream> using namespace std; class Point1 { public: Point1(int x, int y) { mx = x; my = y; } public: int mx; int my; }; struct Point2 { public: Point2(int x, int y) { mx = x; my = y; } public: int mx; int my; }; template<class T1, class T2> class Point3  { public: Point3(T1 x, T2 y) { mx = x; my = y; } public: T1 mx; T2 my; }; template<class T1, class T2> struct Point4 { public: Point4(T1 x, T2 y) { mx = x; my = y; } public: T1 mx; T2 my; }; int main() { Point1 *pPoint1 = new Point1(10, 20); cout << pPoint1->mx << " " << pPoint1->my << endl; delete pPoint1; Point2* pPoint2 = new Point2(100, 200); cout << pPoint2->mx << " " << pPoint2->my << endl; delete pPoint2; Point3<int, float>* pPoint3 = new Point3<int, float>(1000, 200.5); cout << pPoint3->mx << " " << pPoint3->my <...

C++ 的四捨五入

C++ 的四捨五入 日期:2015/6/12 [緣起] 之前跟企劃要升級公式,他給了我一份Excel文件,乍看覺得這數字怎麼會這麼漂亮,仔細看才發現他使用了四捨五入,這還是我第一次在C++使用四捨五入,然後才發現有那麼多的問題在裡面,處理不好的話,數值的誤差就會越來越大,所以必須好好研究才行。 [四捨五入數學上的意義] 數學問題:-2.4四捨五入是多少呢? 重點:四捨五入是取概數,所以-2.4四捨五入就是-2。 [程式上的問題] 在電腦處理四捨五入的問題時,就不得不提到電腦在處理浮點數上的誤差。浮點數的特殊存法而造成的不連續性,讓浮點數的比較和0的處理變得很麻煩。 [函式庫] C++的函式庫本身就有取概數的函式,但有些是新版的C++才有。 [自訂寫法] 網路上有太多的討論,而我認為既然數值由企畫訂,那就讓自訂函式庫的處理跟Excel相同即可。但是C++浮點數的誤差實在太大,讓我的Excel測試數值在程式裡幾乎都是錯的。因此目前還在傷腦筋中。 目前問題: 1. 浮點數的誤差,例如987654.25674無法正確顯示。 2. 必須根據需求與數值的幅度更改誤差的容忍值,所以要依真實狀況而定。 [參考資料]   浮點數的比較 http://novus.pixnet.net/blog/post/30654542-back-to-basic%3A-%E8%AB%87%E6%B5%AE%E9%BB%9E%E6%95%B8%E7%9A%84%E6%AF%94%E8%BC%83 https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/ http://zhidao.baidu.com/question/1689881511890055868.html   四捨五入 http://www.mtedu.utaipei.edu.tw/mathweb/showprint.asp?topic_id=325&forum_id=51   EXCEL http://felin0630.pixnet.net/blog/post/26209180-%E2%94%9Cexcel%E5%87%BD%E6%95%B8%E2%94%A4%E5%9B%9B...

質因數分解

質因數分解 #include <iostream> #include <vector> using namespace std; vector<int> PrimeFactor(int num); //GET Prime Factor of num. vector<int> GeneratePrime(int n); //Generate prime numbers less than num bool CheckPrime(int nCheckNum, int nPrimeArrayNowNum, vector<int> *vecPrime);//Is the number nCheckNum a prime? int GetPrime(int nIndex, vector<int> *vecPrime); //Get Prime int main() { vector<int> vecPrimeFactors = PrimeFactor(20); //GET Prime Factor of num. vector<int>::iterator it; for(it = vecPrimeFactors.begin() ; it != vecPrimeFactors.end() ; it++) { printf("%d, ", *it); } printf("\n"); system("pause"); return 0; } vector<int> GeneratePrime(int n) //Generate prime numbers less than num { vector<int> vecPrime; vecPrime.clear(); vecPrime.push_back(2); int nPrimeArrayNowNum = 1; for(int i = 3 ; i < n ; i++) { if(CheckPrime(i, nPrimeArrayNowNum, &vecPr...

輾轉相除法

輾轉相除法 unsigned int Euclidean(unsigned int a, unsigned int b) //輾轉相除法 { int k; while ((a % b) != 0) { k = a % b; a = b; b = k; } return b; }

亂數整理

亂數整理 C++ #include <iostream> #include <cstdlib> #include <ctime> int main() { srand((unsigned int)time(NULL)); int r = rand(); //其值最小是 0,最大則為 RAND_MAX(32767) } C++的部分,有新方式可以處理 https://blog.gtwang.org/programming/cpp-random-number-generator-and-probability-distribution-tutorial/ C# //https://docs.microsoft.com/zh-tw/dotnet/api/system.random?view=net-5.0 Random rnd = new Random(Guid.NewGuid().GetHashCode()); int n1 = rnd.Next(); // 傳回int數值,其範圍介於 0 - 2147483647,但不包含 2147483647(Int32.MaxValue) int n2 = rnd.Next(700);//傳回int數值,其範圍介於 0 - 700,但不包含 maxValue int n3 = rnd.Next(800, 7000); //傳回int數值,其範圍介於 800-7000,但不包含 7000 double n4 = rnd.NextDouble();  //傳回Double數值,其範圍介於0.0 - 1.0之間,但不包含1.0 python import random random.seed()   #python 的亂數種子可以不必特別去設 x1 = random.random()            #隨機浮點數,小於1,不包含1 x2 = random.uniform(-1, 3)      #隨機浮點數,(-1 <= x < 3) x3 = random.randrange(10)       #隨機整數,(0...

C++ STL vector 在迴圈中插入 iterator

C++ STL vector 在迴圈中插入 iterator 插在後面 #include <iostream> #include <vector> using namespace std; void PrintVector1(vector<int> printVector); bool NeedInsert(vector<int>* pVector, vector<int>::iterator it); bool NeedInsert2(vector<int>* pVector, vector<int>::iterator it); int ItToIndex(vector<int>* pVector, vector<int>::iterator it); void Test01(); void Test02(); int g_p = 115; int main() { Test01(); Test02(); system("pause"); return 0; } void Test02() { vector<int> myVector; for (int i = 0; i < 5; i++) myVector.push_back(i * 10); cout << "----1" << endl; PrintVector1(myVector); cout << "----2" << endl; int nIndex = 0; vector<int>::iterator it; vector<int>::iterator it2; for (it = myVector.begin(); it != myVector.end(); ) { if (NeedInsert2(&myVector, it)) { it2 = it + 1; if (it2 == myVector.end()) { myVec...

C++ 的指標陷阱

C++ 的指標陷阱 這段程式碼會印出什麼呢?   #include <iostream> using namespace std; int **g_nTest = new int*[10]; int g_nIndex = 0; void AddData(int n1); int main() { AddData(1); AddData(2); AddData(3); AddData(4); AddData(5); system("pause"); return 0; } void AddData(int n1) { g_nTest[g_nIndex] = &n1; g_nIndex++; int *n3; for(int i = 0 ; i < g_nIndex ; i++) { n3 = g_nTest[i]; cout<<"g_nTest["<<i<<"] = "<<*n3<<endl; } cout<<"--------------------"<<endl; }

最簡單的 cl

最簡單的 cl cl /EHsc helloworld.cpp

第一個C編譯器

第一個C編譯器 https://www.gushiciku.cn/pl/phZk/zh-tw

關於 Box2D

圖片
CEGUI + DirectX9 + Box2D 去年底,正在思考我的 sprite 物件該怎麼實做碰撞時,突然想到了物理引擎這東西,上網搜尋了之後,發現了Box2D,憤怒鳥就是使用了這個。   我想要把它放進我的 DirectX 製作的 2D引擎裡,結果沒想到,Box2D本身並沒有繪圖相關的 code,而官方的範例是使用 OpenGL 繪圖的,不得已,我將 Box2D 範例裡的所有跟繪圖有關的 code 全部改寫成 DirectX 的,然後放進我的 2D引擎裡,花了我非常多的時間,同時,我也發現,OpenGL 好像還是很好用,好想把他寫進我的 2D引擎裡啊。   網路上有非常多的資源,可是因為 Box2D 使用非常廣泛,我很難找到C++的適合範例,官方說明手冊在沒有範例的情況下很難理解,更不用提那些早就還給老師的物理知識了。只好用老方法,買一本書,偏偏中文版只有一本,還是用 Flash 的,沒辦法,還是硬著頭皮買了。然後這本書只能當作學習 Box2D 範例的入門,不能用來學程式語言,畢竟不是程式背景的人寫的,有許多寫作習慣讓我想撕了它。   Flash ActionScript 與 Box2D 遊戲程式設計:動手創造你的 Angry Birds 世界 http://www.books.com.tw/exep/prod/booksfile.php?item=0010575662   把 Action Script 的 code 改寫成 C++ 的過程非常的痛苦,但是經過幾個月的努力,還是把10個範例都做完了。在此同時,我也發現了我的 2D引擎的不足之處,持續地做改良。不過我到底該不該把文件看完呢?而且既然都練習完了,感覺不搞個憤怒鳥出來就好像沒完成似的...。   Box2D的相關資源 https://code.google.com/p/box2d/ http://blog.csdn.net/complex_ok/article/category/871440 http://www.iforce2d.net/b2dtut/introduction   Box2D Example https://sites.google.com/site/box2dexample/

MVC 模式(隨記)

圖片
MVC 模式(隨記) Model-View-Controller Model處理程式資料與邏輯 Model持有資料、狀態、程式邏輯,提供介面供人取得資料和狀態,也負責將改變的狀態通知觀察者。 View使用者介面 用來呈現Model,通常從Model中取得狀態與資料,以顯示出來。 Controller 取得使用者的輸入,將此輸入解讀成對model的命令。 1. 使用者和view互動 View是使用者存取Model的窗口,當使用者對View做一些事時,View就告訴Controller你做了什麼,由Controller負責處理。 2. Controller要求Model改變狀態 Controller解讀命令並告知Model如何做出對應動作。 3. Controller也可能要求View做改變 當Controller從View接收到動作,Controller也可能要View改變其結果。 4. 當Model狀態改變時,Model會通知View 使用者所進行的操作或者內部的改變,Model都會通知View改變顯示。 5. View向Model詢問狀態 View直接向Model取得狀態以便顯示。 相關的基本設計模式 觀察者 策略 合成

懶人的 set 和 get 函式

懶人的 set 和 get 函式 每次在寫 class 時一定會遇到這樣的事 //test.h class CTest { private: int m_nValue; int m_nValue2; char m_szName[256]; public: CTest(); //這堆set和get真的很刺眼 void SetValue(int n){m_nValue = n;} void SetValue2(int n){m_nValue2 = n;} void SetName(char *sz){strcpy(m_szName, sz);} int GetValue(){return m_nValue;} int GetValue2(){return m_nValue2;} char *GetName(){return m_szName;} }; 這堆 set 和 get 真的很刺眼,明明就是差不多的東西。 還好在公司裡看到特殊的用法,只是我不知道這種用法有沒有名字。 //test.h #define DECLARE_GET_FUNCTION(func_name, var_type, var_name)\ var_type Get##func_name##()\     {\         return this->var_name;\     } #define DECLARE_SET_GET_FUNCTION_STR(func_name, var_type, var_name)\ void Set##func_name##(var_type  var_name) \     { \ memcpy((void *)this->var_name, (const void *)var_name, sizeof(this->var_name));\     }\ DECLARE_GET_FUNCTION(func_name, var_type, var_name) #define DECLARE_SET_G...

物件導向程式設計守則

物件導向程式設計守則 一個好的程式,必須滿足以下條件: 1. 可以正常運作(沒有bug) 2. 程式碼夠短(技巧好) 3. 程式碼容易理解(易改寫) 4. 可以重複利用(降低開發成本) 5. 能幫上使用者(方便好用) 6大物件導向設計原則 主要目的是設計出易維護、易擴展、易重用、靈活性加的程式。 1. 單一職責原則(Single Responsibility Principle, SRP) 一個類別應該只具有一個改變的理由。 2. Liskov 替換原則(Liskov Substitution Principle, LSP) 父類別能出現的地方,子類別就可以出現,而且替換成子類別不會造成錯誤或異常。 3. 顛覆依賴原則(Dependence Inversion Principle, DIP,又譯依賴倒置原則) 依賴抽象類別,不要依賴具象類別。 4. 介面隔離原則(Interface Segregation Principle, ISP) 客戶端不應該依賴他不需要的介面,類別間的依賴關係應該建立在最小的介面上。 5. 極少化守則(Least Knowledge Principle, LKP 又稱迪米特法則Law of Demeter)) 一個物件應該對其他物件有最少的了解,只跟朋友連絡。 6. 開放-封閉原則(The Open-Closed Principle, OCP) 類別、模組、函式應該要可以擴展,但是不可修改。 其他該注意的原則 找出程式中可能需要更動之處,把他們獨立出來,不要和那些不需要更動的程式碼混在一起。 寫程式是針對介面而寫,而不是針對實踐方式而寫。簡單來說,變數的宣告型態,應該是一個抽象類別或是一個介面。 多用合成,少用繼承。 鬆耦合,高內聚。 所有的設計原則只是針對架構設計時所該注意的事,使用時也是要根據實際情況,做出適當的取捨。

pragma 指令

 pragma 指令 Each implementation of C and C++ supports some features unique to its host machine or operating system. Some programs, for instance, need to exercise precise control over the memory areas where data is placed or to control the way certain functions receive parameters. The #pragma directives offer a way for each compiler to offer machine- and operating system-specific features while retaining overall compatibility with the C and C++ languages. Pragmas are machine- or operating system-specific by definition, and are usually different for every compiler. #pragma 指令提供了一種方法,讓每個編譯器提供與機器和作業系統特定的功能,同時保留與 C 和 C++ 語言的相容性。#pragma 指令是機器或作業系統專有的,而且每個編譯器的都不一樣。 簡單來說,#pragma 是下給 compiler 看的指令,一些較常用的指令通常都支援跨平台的使用,所以大部份 compiler 都會看得懂。 對像我一樣使用 visual studio 的人來說,直接看MSDN是最快的了。 http://msdn.microsoft.com/en-us/library/d9x1s805(v=VS.71).aspx 我自己常用的 #pragma pack(1) #pragma once //寫在.h檔裡,可以只編譯一次 #pragma warning(disable : 4996) //這有很多種用法,這是我常用的 #pragma comment(lib,"Ws2_32.lib") //使用函式庫,com...

photoshop CS5 筆記-幾何工具

圖片
 photoshop CS5 筆記-幾何工具