The Basic Window 基本窗口
Our basic window is going to be created and maintained by a central class, Game. The following sections cover the initial sections of code in the main class.
譯:Game類實現基本窗口的創建和維護。下面的章節包括主窗口類的的初始化代碼:
Game Entry Point
游戲入口點
In java our entry point is "public static void main(String arg[])". This is where the application starts when its run. From here we're going to create an instance of our main class which will start everything else running. Game will be a subclass of Canvas, since it will be the main element displaying the graphics. Note, that it needs to be a subclass of Canvas since its one of the only components that supports using accelerated graphics.
譯:在Java中,啟動應用程序的入口點是“public static void main(String arg[])”。在這里我們要創建一個主類的對象實例使整個程序運行起來。Game類是 Canvas類的子類,主要用于把游戲圖形在界面上顯示出來。請注意,它必須是一個Canvas(畫布,Canvas 組件表示屏幕上一個空白矩形區域,應用程序可以在該區域內繪圖,或者可以從該區域捕獲用戶的輸入事件。),因為它是唯一支持圖形加速的組件。
public static void main(String argv[]) {
Game g = new Game();
g.gameLoop();
}
Creating the window
創建窗口
First we need to create our window and configure its contents. We're going to fix our resolution to 800x600. However, since the window may have decoration the content must be set to 800x600 and we must rely on pack() (shown a little later) to actually size the window appropriately.
譯:首先,我們需要創建并配置我們的窗口。我們將設置屏幕分辨率為800*600。 然而因為窗口包含的一些內容必須被設置成800*600的分辨率,所以必須依靠pack()方法(稍后介紹,調整此窗口的大小,以適合其子組件的首選大小和布局)來合適地設置窗口的實際大小。
// create a frame to contain our game
//創建一個 frame 包含我們的游戲
JFrame container = new JFrame("Space Invaders 101");
// get hold the content of the frame and set up the
// resolution of the game
//獲得frame(窗口)的內容面板。設置游戲分辨率
JPanel panel = (JPanel) container.getContentPane();
panel.setPreferredSize(new Dimension(800,600));
panel.setLayout(null);
// setup our canvas size and put it into the content of the frame
//設置畫布尺寸并將其添加到frame(窗口)的內容面板
setBounds(0,0,800,600);
panel.add(this);
Since the canvas we're working with is going to be actively redrawn (i.e. accelerated graphics) we need to prevent Java AWT attempting to redraw our surface. Finally, we get the window to resolve its size, prevent the user resizing it and make it visible.
譯:由于畫布會被頻繁的重繪(即加速圖形),我們需要阻止Java AWT重繪我們的界面。最后,我們設置好窗口的大小,并且不允許用戶重置窗口大小,然后顯示此窗口。
// Tell AWT not to bother repainting our canvas since we're
// going to do that our self in accelerated mode
setIgnoreRepaint(true);//設置是否應該忽略從操作系統接受的繪制消息。
// finally make the window visible //最后顯示該窗口
container.pack();
container.setResizable(false);
container.setVisible(true); //根據參數的值顯示或隱藏此 Window。
Accelerated Graphics 圖形加速
To manage our accelerated graphics canvas we're going to rely on a class provided from the JDK. The BufferStrategy is named that because its a strategy for managing buffers, or rather the swapping of buffers. This supports us using page flipping and accelerated graphics.
譯:我們需要依靠JDK提供的BufferStrategy 類在 canvas (畫布)上使用緩沖區管理策略,如稱為翻頁的緩沖區交換策略,來支持圖形加速。
Creating a BufferStrategy couldn't be simpler. We simply ask the Canvas to do it for us. The only thing that needs to be specified is how many buffers to use to manage the screen, in this case we're going to use just 2.
譯:構造一個BufferStrategy本身不是一件簡單的事情。我們可以簡單地調用Canvas 的方法來創建。唯一需要指定的是需要多少緩沖區用來管理屏幕,我們將只使用2個緩沖區。
// create the buffering strategy which will allow AWT
// to manage our accelerated graphics 創建緩沖策略,讓AWT管理我們的圖形加速
createBufferStrategy(2);
strategy = getBufferStrategy();
The Game Loop 游戲循環
The game loop is a remarkably important part of any game. Client side games tend to be single threaded. This helps prevent a whole bunch of complexities synchronising game updates and game drawing. Generally this results in more stable and maintainble code. There are good arguments to use threading, however for the purposes of this tutorial we're not going to consider it.
譯:游戲循環是任何游戲顯著的重要組成部分。客戶端游戲往往是單線程的。這有助于避免大量復雜的同步游戲更新和游戲圖形繪制。通常來說,這樣的代碼更加穩定和易于維護。有很多好處促使我們使用線程,然而,出于本教程的目的,我們將不討論它了。
The normal game loop runs something like this:
· Work out how long its been since we last looped
· Process any input from the user/player
· Move everything based on the time since last loop
· Draw everything on screen
· Swap the buffers over to make the new image visible
· Wait for a set period
譯:一般的游戲循環是這樣運行的:
· 計算出從游戲重新開始運行已經多長時間了
· 處理用戶/玩家的任何輸入
· 基于上一次循環結束的時間移動所有游戲實體
· 在屏幕上繪制游戲實體
· 交換緩沖區,加速新圖片顯示
· 等待一個規定的時間
At this stage we're just interested in getting the screen swap and timing done, so we add a function called gameLoop that does this:
譯:在這個階段,我們僅僅對屏幕切換(重繪)和逝去時間感興趣,所以我們添加一個叫gameLoop函數來實現:
long lastLoopTime = System.currentTimeMillis(); // 上一次循環的時間
while (gameRunning) {
// work out how long its been since the last update, this
// will be used to calculate how far the entities should
// move this loop 計算從上一次更新到現在已經過去多長時間了,
//逝去時間值將用于計算本次循環所有實體對象應該移動多遠
long delta = System.currentTimeMillis() - lastLoopTime;
lastLoopTime = System.currentTimeMillis();
// Get hold of a graphics context for the accelerated
// surface and blank it out 獲得一個加速圖形上下文,并讓它的表面空著
Graphics2D g = (Graphics2D) strategy.getDrawGraphics();
g.setColor(Color.black);
g.fillRect(0,0,800,600);
// finally, we've completed drawing so clear up the graphics
// and flip the buffer over 最后,我們已經完成繪圖,因此釋放此圖形的上下文以及它使用的所有系統資源,翻轉緩沖區(將顯示指針指向緩沖區,此緩沖區變為顯示區,舊的顯示區變為緩沖區),顯示圖形
g.dispose();
strategy.show();
// finally pause for a bit. Note: this should run us at about
// 100 fps but on windows this might vary each loop due to
// a bad implementation of timer 最好,暫停一會兒。注意:大約是100幀,但在windows下面會有所不同,因為定時器實現不同。
try { Thread.sleep(10); } catch (Exception e) {}
}
Finally we call gameLoop from the bottom of the constructor of Game. This just starts the game loop running around. If you've been following this code you should be able to run what you currently have and a window should be displayed with an accelerated canvas that shows a black screen.
譯:最后,我們在Game類的構造器函數中調用 gameLoop 方法,啟動游戲。如果你已經寫好這些代碼了,你可以運行它們,會彈出一個采用了硬件加速的黑色屏幕窗口。
學軟件開發,到蜂鳥科技!
超強的師資力量 、完善的課程體系 、超低的培訓價格 、真實的企業項目。
網址:www.ntcsoft.com
電話:0371-63839606
鄭州軟件開發興趣小組群:38236716
posted on 2010-11-25 23:43
whistler 閱讀(276)
評論(0) 編輯 收藏