2.Direct2D 捕魚遊戲開發-渲染類content.h的封裝
環境:
編輯器:VS2015
系統:win10 專業版
碰撞:aabb obb盒模型(obb採用分離軸進行判斷)
渲染:direct2d
幀的概念
幀:在一個動畫裡面我們把每個畫面叫做幀
動畫:一個連續不間斷的幀就是一個動畫(這裡可以理解到後面封裝動畫精靈的時候會用到)
幀的間隔:兩個幀之間的間隔就表示一個幀的間隔 我們遊戲裡面的幀的間隔為1000/60ms即我們遊戲所用到的幀為一秒60幀
為什麼取這個值:
因為人眼看到的最大幀就是60幀再大也是和這個幀一樣
Direct2D說明:
開發公司:微軟
主要功能:通過呼叫gpu實現的非常快的圖形渲染相對於gdi與gdi+來說d2d的渲染是非常快的
封裝用到的Direct2D物件:
渲染工廠類:
ID2D1Factory * m_fac;
提供:
建立渲染目標類方法(可以是視窗為渲染目標,點陣圖為渲染目標) CreateHwndRenderTarget
建立邊框樣式類方法 (讓繪製的路徑是虛線還是實線) CreateStrokeStyle
建立路徑繪製類方法(繪製圓形,矩形,橢圓,不規則形狀) CreatePathGeometry,CreateEllipseGeometry
渲染目標類
ID2D1HwndRenderTarget * m_render
提供各種繪製方法的一個類
繪製不規則路徑的方法 (DrawGeometry)
填充不規則路徑的方法(FillGeometry)
開始繪製 (BeginDraw)
結束繪製 (EndDraw)
填充矩形(FillRectangle)
設定變換 (SetTransform)
建立點陣圖 (CreateBitmapFromWicBitmap)
繪製點陣圖 (DrawBitmap)
建立點陣圖畫刷 (CreateBitmapBrush)
繪製文字 (DrawText)
畫刷畫線的類(我們這裡定義pen的作用為畫線的)
ID2D1SolidColorBrush * pen
一切畫線的方法都會用到這個畫刷
在封裝中用到的方法:
content::drawText 繪製文字
content::stroke 將我們的beginPath和closePath的路徑繪製為不規則圖形
content::strokeStyle 設定繪製的顏色
content::drawArc 繪製沒有背景顏色的圓形
content::drawLine 繪製一根線條
畫刷畫背景的類(我們這裡定義brush的作用為畫線的)
ID2D1SolidColorBrush * brush
在封裝中用到的方法:
content::fill() 將我們的beginPath和closePath的路徑填充為有背景顏色的不規則圖形
content::fillStyle() 設定填充的顏色
content::fillRect() 填充矩形
content::fillArc() 填充圓形
畫刷畫背景圖的類(我們這裡定義bitmapBrush的作用為畫背景圖的)
ID2D1BitmapBrush * bitmapBrush
在封裝中用到的方法:
content::fillImage 填充背景 這裡主要是繪製重複的背景用的
影象類(WIC類)
IWICImagingFactory * m_imgFac;
提供讀取影象的方法(這裡只是將圖片讀取了還不是能用的點陣圖) CreateDecoderFromFilename
我們需要對讀取的內容進行轉碼具體看下面程式碼
content.cpp
文字工廠類:
IDWriteFactory * m_writeFac;
提供建立文字繪製物件的方法 CreateTextFormat
文字樣式類:
IDWriteTextFormat * m_forMat
這個類主要用於繪製文字的字型和大小
在我們的封裝裡面主要用於
content::drawText
封裝思路:
我們這裡就不詳細介紹direct2d的各種api了因為api(提供程式呼叫的方法)估計得有好幾千個
我們這裡就說一下這個捕魚遊戲需要的渲染工具(即這個程式用到的direct2D物件)
1.圖片繪製方法 content::drawImage
思路:這裡我們重寫了多種引數但是最主要的目的還是要讓圖片通過一個路徑直接繪製出來
我們的getSource方法會將傳入的引數進行快取起來 當下一次呼叫的時候就不需要再去呼叫com元件來處理圖片了
核心方法: content.cpp
2.重複圖形繪製方法 content::fillImage
思路:這裡我們在填充矩形的時候通過呼叫點陣圖畫刷進行繪製這樣就會填充多個圖片了
核心方法:content.cpp
setExtendmodeX是設定x軸的填充重複模式
setExtendmodeY是設定y軸的填充重複模式
3.獲取圖片資源方法 content::getSoucre
思路:這裡我們通過兩個陣列 一個位圖vector另一個string vector進行快取
我們先檢索string裡面是否有重複的 如果有我們就直接返回快取的點陣圖資源 如果沒有我們就載入並且將載入好的存在數組裡面
核心方法:
content.cpp
4.繪製文字的方法 content::drawText //
思路:我們通過非常簡單的傳入文字和座標就繪製文字
核心程式碼:content.cpp
5.獲取文字寬度與高度的方法 content::getTextInfo
思路:通過傳入的字串將當前繪製環境的字串繪製寬度與高度快取到第二個引數裡面
核心程式碼:content.cpp
6.變換相關的方法
content::rotate(int angle,int x =0,int y = 0); //提供旋轉變換的方法
content::scale(int zoom, int x = 0, int y = 0);//提供縮放變換的方法
content::skew(int angleX, int angleY, int x = 0, int y = 0);//提供扭曲(傾斜)變換的方法
content::trisition(int x, int y);//提供位移變換的方法
content::save();//將上一次變換的變換矩陣儲存到記憶體中
content::restore();//將上一次變換的變換矩陣重新放出來渲染
思路:這裡我們要儲存兩個矩陣變數
D2D1_MATRIX_3X2_F m1;
D2D1_MATRIX_3X2_F bufM1;
我們在呼叫save方法的時候我們就將bufM1的值設定為m1
然後我們在呼叫restore的時候我們將快取的矩陣變數釋放出來 這樣我們在save和resore之間就可以進行任意的變換從而不用擔心在繪製之後不能繪製其他的圖形
核心程式碼:content.cpp
7.開始一幀的繪製 content::beginDraw
思路:beginDraw開始一幀的繪製
8.結束一幀的繪製 content::closeDraw
思路:closeDraw結束一幀的繪製
closeDraw和beginDraw在訊息迴圈的時候進過測試貌似是已經有一個時間間隔了間隔為1000/60ms即60幀
因為我手動在peekmessage裡面加了sleep就出現了畫面閃爍的問題
這裡就不詳細說其他在這個遊戲裡面沒有用到的方法了
drawImage:
可以看到在原始碼裡面我們重寫了非常多的引數情況
content.h
因為這個方法非常常用所以我們會重寫這麼多
這是我們要做的目標:
專案開源地址:
https://github.com/yinhui1129754/fishing