經過2個月的d3d學習,再經過了幾個星期的開發,完成了搖搖球的初步開發,仍有許多不足之處。仍有許多地方需要進行改進與學習。尤其是碰撞測試方面。
程式簡介:該程式最初靈感來自於小時候所玩了迷宮尺子,有小球在帶有迷宮的尺子上滾動,後了解到這時著名的重力迷宮球遊戲,普及在iphone、android等手機中,通過手機的重力感應模擬小球在迷宮中的重力效果。該程式暫且開發到在乙個正方形的地板中,用滑鼠操控地板的傾斜方向與角度,模擬小球在地板上滾動及與牆面的碰撞。在此中,難點在於滑鼠旋轉演算法、重力模擬與碰撞測試。
難點一:滑鼠旋轉演算法
該演算法是通過滑鼠在視窗中的位置調整地板的旋轉方向與角度。
首先說明下理論部分,模擬乙個半徑為1的球體,初始時記錄下了正向上的法向量g_vcenterpt,通過滑鼠在視窗中的移動,計算得到新的向量g_vcurrentpt,再有這2個軸得到從g_vcenterpt旋轉到g_vcurrentpt四元數,最後由該四元數轉換得到旋轉矩陣進行繪製。
d3dxvector3 screentovector(float fscreenptx, float fscreenpty) else
y = sqrtf(1.0f - mag);
return d3dxvector3(x, y, z);
}d3dxquaternion quatfromballpoints(const d3dxvector3 &vfrom, const d3dxvector3 &vto)
screentovector(float fscreenptx, float fscreenpty):函式是獲取滑鼠的螢幕座標,返回g_pnow。(當輸入的引數是screenx/2與screeny/2時,得到的就是g_vcenterpt)
quatfromballpoints(const d3dxvector3 &vfrom, const d3dxvector3 &vto):就是調入g_vcenterpt與g_vcurrentpt得到從g_vcenterpt旋轉到g_vcurrentpt的四元數。
難點二:重力模擬
首先要得到小球的加速度方向:
再次是要讓小球跟蹤地面,再進行移動。我的辦法是:由g_vcenterpt與g_vcurrentpt叉乘得到currentaxis,再與g_vcenterpt叉乘得到predist。再通過roation(是場景的旋轉矩陣)變換predist得到balldist。d3dxvec3cross(¤taxis, &g_vcurrentpt, &g_vcenterpt);
d3dxvec3cross(&predist, &g_vcenterpt, ¤taxis);
d3dxvec3transformnormal(&balldist, &predist, &rotation); // 得到小球滾動方向
matball = matball * matprerotation * matballmove * rotation; //當前小球的偏移矩陣 = 初始位置 * 回歸旋轉矩陣 * 小球偏移矩陣 * 旋轉矩陣
matprerotation是將matball旋轉回去,回到水平位置。再由水平位置出發進行小球的偏移,最後再旋轉回去。難點三:碰撞測試matprerotation可以由之前的旋轉矩陣rotation的逆矩陣得到(在此逆矩陣與轉置矩陣是一樣的)
最後的問題是matballmove的偏移量的大小,因為加速度的方向已經確定了。偏移量可以由每次的加速度方向累加得到。
static d3dxvector3 ballmove(0.0f, 0.0f, 0.0f);
ballmove.x = ballmove.x + balldist.x * datedist;
ballmove.z = ballmove.z + balldist.z * datedist;
當然y方向上是沒有偏移的,為0;
碰撞測試還有很多bug。暫且不攻了。先再學習學習。現貼上有點問題的**(該**是由以前的打磚塊的碰撞測試改編而來)。d3dxvector3 colloding(d3dxvector3 ballmove, d3dxvector3 ballposition, d3dxvector3 balldist)
else if(collodx[12 - int(ballposition.z + ballr + 70.0f + ballmove.z + balldist.z * datedist)/wallhight]
[int(ballposition.x + 60.0f + ballmove.x + balldist.x * datedist)/wallwide]!=0
&& balldist.z > 0) // 下邊界碰撞
else if(collody[12 - int(ballposition.z + 70.0f + ballmove.z + balldist.z * datedist)/wallhight]
[int(ballposition.x + ballr + 60.0f + ballmove.x + balldist.x * datedist)/wallwide]!=0
&& balldist.x > 0) // 左邊界碰撞
else if(collody[12 - int(ballposition.z + 70.0f + ballmove.z + balldist.z * datedist)/wallhight]
[int(ballposition.x - ballr + 60.0f + ballmove.x + balldist.x * datedist)/wallwide]!=0
&& balldist.x < 0) // 右邊界碰撞
else
ballmove.y = 0;
return ballmove;
}
總結:該程式是本人的第乙個3d程式,看了龍書與《精通directx 3d圖形與動畫程式設計》。如果僅依靠這2本基礎的書籍想要開發真正的遊戲還是相當有差距的。想要開發的好,還要牢牢掌握圖形化的知識,很好的數學功底特別是矩陣,還有物理知識。因此,在今後的學習中注重實際的開發。靈活運用d3d庫,強化圖形學。暫且先讀《real-time rendering》。也好強化下英文的閱讀。
C 遊戲開發教程 D3D
本文適合有一定程式設計基礎的愛好者!本文不會涉及基本的語法等內容,本文適合所有遊戲開發初學者,本文從microsoft directx 9.0 sdk summer 2004 中的d3d下tutorials資料夾下的例子開始!關鍵字 c 遊戲開發 3d 教程 c 讀作 c sharp 是一種簡單 現...
D3D基本框架 即D3D標頭檔案分類
了dxut的結構 後,發現微軟程式設計師的編碼風格太深奧了。各種巨集定義 預編譯跳得頭暈,由於對於window api的不精通,導致寫出符合dxut風格的框架以現在的水平來看是不可能的。既然沒有弄通dxut,我也暫時不想套用了,那麼還是先自己用自己的框架來寫把。框架如下 雖然沒學會dxut,但是微軟...
d3d矩陣變換
1.d3d的繪製流水線 區域性座標系 模型空間 世界座標系 觀察座標系 背面消隱 光照 裁剪 投影 視口變化 光柵化 每個3d模型都有自己的空間,空間的中心 原點 就是模型的中心。世界空間就是物體 模型 存在的地方。世界的中心就是原點 0,0,0 注意螢幕中間的那一點不是世界空間的中心點,螢幕中間的...