遊戲UI設計 2 1 視窗之父CXWnd的封裝

2021-03-31 08:56:30 字數 3878 閱讀 8057

視窗之父cxwnd的封裝

在一般的程式中的對話方塊、按鈕、編輯框等都屬於視窗。在

mfc中,類

cwnd

作為視窗類的基類,抽象出了它們的共同特徵,並由此派生出若干的子類。在普通的

windows

程式中,我們可以方便的使用

mfc為我們封裝好的這些類(

cdialog, cbutton ,cedit

等),而在遊戲程式中,由於需要與

dx/opengl

結合以及效率等原因,因此不直接使用它們,這就需要我們自己來封裝。如此之多的控制項如何封裝能?我們不妨也為所有的視窗、控制項抽象乙個基類,就叫她

cxwnd

。那就讓我們從

cxwnd

開始,一步一步來實現我們真正的

ui吧。

我們先撇開

dx具體繪製視窗的過程,看看視窗、控制項有什麼共同的特徵,以及如何在

cxwnd

中來實現。

1、

視窗的大小與位置

視窗是乙個矩形的區域,因此用兩個變數就可以表示其大小(寬:

m_wdith,

高:m_height)。

視窗的位置也可以用兩個變數表示(

x座標:

m_xpos , y

座標:m_ypos

)。但這兩個變數表示視窗的絕對座標(相對於螢幕左上角)還是相對座標(相對于父視窗的坐上角)呢?

從使用者的角度(即建立視窗)看,使用相對座標方便一點;

從程式的角度(即繪製視窗)看,使用絕對座標方便一點。

我們封裝

cxwnd

的目的在於使用,因此要從使用者的角度出發,即

m_xpos

和m_ypos

表示的是視窗的相對座標。當繪製視窗的時候,我們需要獲得視窗的絕對座標,因此需要提供乙個成員函式來轉化——

getabsolutepos(float& x, float& y)。

(圖就不用畫了吧,:))

2、

視窗之間的聯絡

為了更具代表性,想一下(就不畫了哦)乙個帶屬性頁的對話方塊的視窗層次,與它相關的視窗有乙個父視窗(不包括祖父哦),若干的子視窗(各種控制項),以及若干個同級視窗,因此就需要有乙個指向其父視窗的指標(

cxwnd* m_wndparent

),乙個指向其子視窗鍊錶的指標(

cxwnd* m_wndchild

,m_wndchild

指向視窗鍊錶的第乙個視窗,該視窗

z序在子視窗中最小,既顯示在最前面),再加上同級視窗間的指標(

cxwnd* m_wndnextsibling

指向下乙個同級視窗;

cxwnd* m_wndprevioussibling

指向前乙個同級視窗)。這麼多視窗之間用這四種指標聯絡起來,畫出來就是一棵視窗關係樹。為什麼同級視窗需要兩個指標呢?在訊息迴圈中就可以找到答案了。

對這些指標,需要哪些操作呢?

除了基本的

get***wnd()

和set***wnd()

外,還需要:

新增乙個子視窗

addchildwnd(wndchild : cxwnd*)

刪除乙個子視窗

deletechildwnd(wndchild : cxwnd*)

刪除所有的子視窗

deleteallchildwnd()

,用來釋放記憶體。

獲取子視窗個數

getchildcount()

以上幾個都是對單向鍊錶的基本操作。

3、

訊息迴圈

從經典的訊息函式

wndproc(hwnd hwnd, uint message, wparam wparam, lparam lparam)

那,得到訊息後,主視窗需要傳遞下去,於是

cxwnd

有了乙個相似的函式——

postmessage(uint msg, wparam wparam, lparam lparam, void* data);

,其中對訊息進行分類處理。

1)

滑鼠訊息

滑鼠訊息處理,當然是如下三個(不過在

cxwnd

中不需要實現它們,只是宣告為純虛函式,因為各個控制項的滑鼠處理函式都不盡相同)

virtual void onmousedown(int button, int x, int y) = null;

virtual void onmousemove(int x, int y) = null;

virtual void onmouseup(int button, int x, int y) = null;

如何得知是哪個視窗得到了滑鼠訊息呢?那就需要挨個搜尋各個視窗,看滑鼠當前的座標(注意是絕對座標)在哪個視窗上。因此加入函式

cursorintersect(float x, float y)

來完成此功能。

滑鼠訊息是如何在視窗樹中傳遞的呢?範圍肯定是從大到小掃瞄,即先看是否在某視窗上,若在則看是否在該視窗的子視窗上……,終於找到最上的最底層的視窗,於是子視窗先處理滑鼠訊息,即最上的子視窗具有處理滑鼠訊息的優先權

。因此訊息的傳遞是從上而下,就稱之為正序訊息傳遞吧——

postmsgtochildren

(……)負責把訊息正序傳給每乙個子視窗。

2)

鍵盤訊息

同滑鼠訊息一樣,鍵盤訊息的處理有如下兩個純虛成員函式:

virtual void onkeydown(wparam key, lparam extended) = null;

virtual void onkeyup(wparam key, lparam extended) = null;

鍵盤訊息的處理的特殊之處在於處理它的視窗(控制項)需要獲得焦點(原因很簡單),因此每個窗體需要乙個存放其獲取焦點的子窗體的指標成員變數(

cxwnd* m_wndfocus

)和乙個判斷其是否獲得焦點的

bool

成員變數(

bool m_bfocus

),從而就有了

setfocuswnd

(……)和

getfocus()

成員函式。

鍵盤訊息的傳遞與滑鼠訊息的傳遞一樣。

3)

視窗繪製訊息

視窗的繪製是與具體的視窗物件相關的,因此在

cxwnd

中不予實現,但視窗繪製的訊息是要傳遞的,那該訊息是如何傳遞的呢?

每個視窗都有自己的

z序,最後面的要先繪製,最前面的要後繪製(要不就被當住了),對應與視窗樹就是,父視窗要先繪製,然後最下子視窗後繪製,最後是最上的子視窗。因此最下的視窗具有處理視窗繪製訊息的優先權

。而最上的子視窗排在子視窗鍊錶的最前面,因此該訊息需要逆序從後往前傳遞。因此需要乙個專門的傳遞該訊息的成員函式——

postmsgtochildrenreverse

(……)。

視窗的z序不是固定的,因此需要乙個函式來改變它們的z序

——movetofront

(……)。

至此,cxwnd

的主體功能已經完成了,看看它有那些成員吧:

遊戲ui設計,遊戲ui設計需要學什麼

一.什麼是遊戲ui?ui設計大體可以分為應用ui和遊戲ui兩個方向。應用ui多指的是網頁 安卓 ios圖示介面設計等內容,也是現在普遍培訓機構的課程。而遊戲ui設計則是在應用ui的基礎上,主要針對遊戲介面 遊戲道具 圖示設計 登陸介面等方面,很少有培訓機構去統一培訓。其中遊戲介面又包含頁遊 客戶端介...

移動遊戲ui設計(一)

遊戲世界 遊戲介面就是根據遊戲特性,把必要的資訊展現在遊戲主介面,操控介面和彈出界面上,通過合理的設計引導使用者進行人機互動操作 1,遊戲介面設計原則 互動設計盡量不要繁瑣,用最簡單的方式引導使用者即可 把控好遊戲的介面風格,注意色彩對介面的影響 引導介面的設計應言簡意賅 遊戲設計師要懂得很多客觀知...

如何設計21點遊戲

21點遊戲的設計能夠充分體現c語言結構化程式設計的思想,如果你是c語言的初學者,本文對你一定有幫助.21點遊戲的規則如下 撲克牌a 2 3 4 10 j q k 大小鬼分別代表數字1 2 3 4 10 11 12 13 21 人和電腦輪流坐莊,莊家先發牌。勝利條件 將所取牌點數相加湊成 和 是21,...