天天看點

《Android遊戲開發詳解》一3.6 圖形

本節書摘來異步社群《android遊戲開發詳解》一書中的第3章,第3.6節,作者: 【美】jonathan s. harbour 譯者: 李強 責編: 陳冀康,更多章節内容可以通路雲栖社群“異步社群”公衆号檢視。

android遊戲開發詳解

基于文本的程式很容易建構,但是基于文本的遊戲已經過時了。在本節中,我們将介紹如何使用java類庫中的類(尤其是javax.swing包中的類),來建立一個圖形使用者界面(graphical user interface ,gui)。你會發現,盡管添加一個簡單的使用者界面很直接,但gui是一個很大的主題。我将隻是提供一個快速的介紹,完全隻是建立一個視窗和顯示一個基于java的遊戲所需要的基礎知識。

當在java中開發一款圖形化應用程式的時候,我們首先要建立一個叫作jframe對象(從javax.swing.jframe導入)的視窗。這個視窗中是一個内容面闆(想象一下視窗面闆),我們可以向其中添加各種ui元素,例如,按鈕、滾動條和文本區域。

内容面闆的預設布局叫作borderlayout。它允許我們将ui元素放置到5個區域中的一個,如圖3-3所示。

《Android遊戲開發詳解》一3.6 圖形

圖3-3所示的這5個區域中的每一個,都隻能容納一個ui元素,這意味着,borderlayout隻支援5個元素;然而,這對我們來說不是問題,因為我們隻需要一個名為jpanel的元素。

jpanel對象是一個簡單的、空的容器,我們可以将其添加到一個borderlayout的某個區域中。我們可以在單個的jpanel對象上繪制想要讓玩家看到的任何内容,就像是在畫布上繪圖一樣。例如,考慮一下圖3-4所示的螢幕截圖。這個螢幕截圖取自tumbl遊戲的一個正在開發的版本,這款遊戲是我所開發的第一款遊戲。你所看到的一切,從玩家的分數、暫停按鈕到角色以及加血,都繪制到一個單個的jpanel上。

《Android遊戲開發詳解》一3.6 圖形

當我們在計算機上處理圖形的時候,使用一個基于像素的x、y坐标系統。此外,我們還把左上角的像素當作原點(0, 0)。這意味着,如果螢幕上的分辨率是1 920像素×1 080像素的話,右下角的像素的坐标是(1 919, 1 079)。

現在,我們已經讨論了建構圖形化應用程式所需了解的一切内容。開始動手吧。

建立一個名為firstgraphics的java項目,并且建立一個名為firstframe的類,它帶有一個完整的main方法。然後,通過給main方法添加如下所示的代碼行(確定導入了javax.swing.jframe),我們建立了一個jframe對象。

此時,你的firstframe類應該如程式清單3.14所示。

程式清單3.14 firstframe類

運作這個firstframe類,應該會看到圖3-5所示的結果。

《Android遊戲開發詳解》一3.6 圖形

注意,所出現的視窗帶有一個“my first window”标題。顯然,這個内容面闆(圖3-5中的灰色區域)目前是空的。

在前面小節的非圖形化的示例中,隻要jvm執行了程式的最後一行代碼,程式就結束了。但圖形化應用程式并不是這樣的。jframe甚至會在最後一行代碼之後持續,就像這個視窗所展示的那樣。通過點選退出按鈕來結束該程式。

讓我們確定了解在定義jframe的4行代碼(程式清單3.14的第6行到第9行)中發生了什麼。在第6行,我們使用定制的構造方法,建立了一個名為frame的新的jframe對象。這允許我們為自己的視窗設定标題。

接下來,在第7行,我們指定了當視窗關閉的時候應該發生什麼情況。當使用者關閉視窗的時候,我們想要讓整個程式結束,是以,我們從jframe類向setdefaultcloseoperation()方法傳入了一個名為exit_on_close的公有的int(還記得吧,點運算符用來通路另一個類中的公有方法和變量)。

第8行直接告訴視窗調整其大小,以便成為480像素寬、270像素高。一旦完成了這一步,在第9行調用setvisible()方法就使得該幀出現在螢幕上。

現在,我們有了一個jframe,是時候添加其内容面闆了。要做到這一點,我們将建立一個名為mypanel的新類。該類将會是使用繼承建立的jpanel的一個定制版本,是以,我們必須擴充jpanel,先導入java.swing.jpanel。

将程式清單3.15所示的代碼複制到你的mypanel類中。一旦運作了該程式,我們将讨論它。别忘了如第1行、第2行和第4行所示,添加适當的導入。

程式清單3.15 mypanel類

現在必須回頭看看firstframe類,構造mypanel的一個執行個體,并且将其添加到内容面闆的一個區域中。通過在main方法的底部添加如下所示的代碼行,來做到這一點。

更新後的firstframe類應該如程式清單3.16所示(注意第1行的import語句)。

程式清單3.16 更新後的firstframe類

運作firstframe,将會看到圖3-6所示的界面。

《Android遊戲開發詳解》一3.6 圖形

在讨論發生了什麼之前,我們需要先解釋一些術語。還記得吧,我們可以在jframe的内容面闆區域添加各種圖形化的元素。這些圖形化的元素叫作微件(widget),它們屬于一類叫作jcomponent的泛型對象。這意味着,jpanel以及在基于swing的圖形化應用程式中使用的其他的圖形化元素,都是一種類型的部件(component)。

3.6.6 了解mypanel

我現在要解釋當運作程式的時候發生了什麼,首先來說明mypanel類。回頭去看看程式清單3.15,你還會記得mypanel擴充了jpanel(程式清單3.15的第6行)。這就是說,mypanel是jpanel的一個子類;換句話說,它是泛型的jpanel類的一個更加具體的版本。也就是說,mypanel繼承了屬于jpanel的所有共有的方法(由此,mypanel通過繼承成為jpanel的一個特定類型)。

有一個繼承的方法名為paintcomponent()。它是描述部件應該如何渲染的一個方法。我們想要控制這個方法,以便可以告訴程式一個mypanel對象應該如何顯示。為了做到這點,我們在自己的mypanel類中聲明了paintcomponent()方法,并且添加了一個@override修飾符(在第8行),通過這種方法,讓編譯器知道我們要使用自己的方法來替代已有的paintcomponent()方法。

在這個方法paintcomponent()内部,我們使用所提供的graphic對象g,調用了8個方法(程式清單3.15中的第10行到第20行)。

graphics對象每次可以繪制一項内容,并且它像筆刷一樣工作。首先使用setcolor()方法選擇一種顔色,并且告訴graphics對象,使用幾個繪制和填充方法之一來繪制什麼。

setcolor()方法接受一個color對象,我們可以通過color類來擷取該對象(這個類儲存了很多color對象作為公有變量,我們可以使用點運算符來引用它)。注意,對于每種顔色有兩個變量,一個全部都是大寫,一個全部都是小寫。它們總是為你傳回相同的 顔色。

作為一般性的規則,以單詞draw開頭的方法隻是繪制想要的形狀的架構。另一方面,以單詞fill開頭的方法,将會繪制整個形狀。例如,g.drawrect(50, 50, 100, 100)将會繪制一個方形的邊框,其左上角位于(50, 50),并且其邊長為100個像素。

現在,我們來解釋在mypanel中發生了什麼,讓我們先來讨論在程式清單3.16中添加到firstframe類中的兩行代碼。

mypanel panel = new mypanel(); // creates new mypanel object.

frame.add(borderlayout.center, panel); // adds panel to center region.

第一行代碼使用熟悉的文法建立了一個新的mypanel對象。然後,第二行将其添加到圖3-3所示的中心區域(center)。注意,空的區域并不占用空間。

一旦mypanel對象添加到了jframe,其paintcomponent方法就會自動調用。這意味着,我們不必明确地要求panel來繪制自己。這就是為什麼我們能夠看到圖3-6所示的各種圖形。

確定自己再次回顧代碼,以了解如何能夠得到甚至讓畢加索感到驕傲的驚人的藝術品。