項(xiàng)目源碼
游戲配置信息類
Config.java 沒(méi)什么解釋的痊班。
package config;
public class Config {
public final static String TITEL = "fight_to_the_end";
public final static String VERSION = "v1.0";
public final static byte BUFFERS = 2;
public final static int FPS = 60;
public final static boolean DEBUG = true;
}
主函數(shù)Main.java
package main;
public class Main
{
public static void main(String [] args)
{
GameApp app = new GameApp();
}
}
創(chuàng)建了一個(gè)GameApp對(duì)象辩块,GameApp對(duì)象是我們游戲的主循環(huán)荆永。
package main;
import config.Config;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferStrategy;
public class GameApp {
private boolean _gameRunning = true;
private Frame _frm;
public GameApp(){
try{
_frm = new Frame();
_frm.setUndecorated(true);
_frm.setIgnoreRepaint(true);
_frm.setTitle("");
JButton button = new JButton("close");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_gameRunning = false;
_frm.dispose();
}
});
_frm.add(button);
_frm.setSize(800,600);
_frm.setLocation(100, 100);
_frm.setVisible(true);
_frm.setResizable(false);
_frm.createBufferStrategy(Config.BUFFERS);
_gameLoop();
}catch (Exception e) {
e.printStackTrace();
}finally{
System.exit(0);
}
}
GameApp構(gòu)造函數(shù)主要做了2件事:
1.創(chuàng)建游戲窗口具钥;
2.啟動(dòng)game主循環(huán)_gameLoop()
_frm = new Frame();
_frm.setUndecorated(true);
_frm.setIgnoreRepaint(true);
_frm.setTitle("");
JButton button = new JButton("close");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
_gameRunning = false;
_frm.dispose();
}
});
_frm.add(button);
_frm.setSize(800,600);
_frm.setLocation(100, 100);
_frm.setVisible(true);
_frm.setResizable(false);
_frm.createBufferStrategy(Config.BUFFERS);
_gameLoop();
創(chuàng)建窗體骂删,設(shè)置窗體大小,位置宁玫,可見(jiàn)性欧瘪,窗口上添加了一個(gè)大按鈕,點(diǎn)擊后可以關(guān)閉本窗體佛掖。
其中比較重要的一行代碼是:
_frm.createBufferStrategy(Config.BUFFERS);
設(shè)置窗體的緩沖策略為雙緩沖芥被。就是我們先將游戲每一幀(包含很多圖片,我們下一節(jié)詳細(xì)介紹)的全部數(shù)據(jù)冗茸,先全部畫(huà)在內(nèi)存中匹中,再一次性的粘貼到屏幕上。這樣可以提高繪制效率麻蹋,減少屏幕閃爍焊切。
想象一下,有一個(gè)雙面白板刹勃,可以翻轉(zhuǎn)顯示一側(cè)或另一側(cè)嚎尤。前面是顯示器(玩家看到的屏幕),而背面是隱藏的乏梁,只有計(jì)算機(jī)可以“看到”它。每一幀卖毁,都在背面(內(nèi)存中)繪制所有圖畫(huà) - 每個(gè)角色落萎,每個(gè)子彈,每個(gè)閃耀的光線等等翔脱。然后媒鼓,當(dāng)完成后隶糕,將白板翻轉(zhuǎn)并顯示(將所有圖片數(shù)據(jù)從內(nèi)存拷貝到屏幕上)。
接下來(lái)我們看_gameLoop()方法:
private void _gameLoop(){
BufferStrategy buff = _frm.getBufferStrategy();
while(_gameRunning){
Graphics2D g = (Graphics2D)buff.getDrawGraphics();
// Rendering
_initRendering(g);
if(Config.DEBUG){
_displayInfoText(g);
}
g.dispose();
if (!buff.contentsLost())
{
buff.show();
}
Toolkit.getDefaultToolkit().sync();
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void _initRendering(Graphics2D g){
g.setColor(Color.black);
g.fillRect(0, 0, 800, 600);
}
private void _displayInfoText(Graphics2D g){
g.setColor(Color.white);
g.drawString(Config.TITEL+ " "+ Config.VERSION, 20, 20);
}
該方法整體結(jié)構(gòu)是一個(gè)死循環(huán)濒旦,每次循環(huán)Thread.sleep(1); 讓主線程睡眠1毫秒尔邓,讓出cpu時(shí)間片锉矢;讓其他進(jìn)程得到執(zhí)行,防止cpu使用率過(guò)高灯节。
Graphics2D g = (Graphics2D)buff.getDrawGraphics();
// Rendering
_initRendering(g);
if(Config.DEBUG){
_displayInfoText(g);
}
g.dispose();
在內(nèi)存中描畫(huà):填充一個(gè)黑色矩形绵估,并且顯示一個(gè)白色的字符串。
if (!buff.contentsLost())
{
buff.show();
}
Toolkit.getDefaultToolkit().sync();
將內(nèi)存中的圖像形入,粘貼到屏幕上缝左。
本節(jié)最終效果
運(yùn)行程序,顯示一個(gè)黑窗體蛇数,點(diǎn)擊任意位置苞慢,窗體關(guān)閉英妓。