人物-小丑: Buffoon
子彈-帽子:Missile
牆體:Wall
爆炸物:Explode
小丑:寬和高,位置(x,y),移動速度
帽子:寬和高,位置(x,y),移動速度
牆體:寬和高,位置(x,y)
爆炸物:寬和高,位置(x,y)
小丑:移動、攻擊、人物撞邊界
子彈:移動、子彈撞牆、子彈撞邊界
爆炸物:消失
public class GameClient extends Frame
通過繼承Frame類實現Java表單
public class Frame extends Window implements MenuContainer
Frame類繼承了Window類和MenuContainer介面
步驟1:建立常用工具類CommonUtils,新建getImage方法實現將圖片資源轉換為Java物件
public class CommonUtils {
/**
* 讀取圖片資源, 轉變為Java物件 Image
* @param imgPath 圖片路徑
* @return Image物件
*/
public static Image getImage(String imgPath) {
ImageIcon imageIcon = new ImageIcon(imgPath);
return imageIcon.getImage();
}
}
步驟2:呼叫getImage方法新增物件圖片
public class GameClient extends Frame {
Image bg_image = CommonUtils.getImage("images/bg.png");
Image explode = CommonUtils.getImage("images/explode.png");
Image missile = CommonUtils.getImage("images/missile.png");
Image wall_h = CommonUtils.getImage("images/wall-h.png");
Image wall_v = CommonUtils.getImage("images/wall-v.png");
Image buffoon = CommonUtils.getImage("images/body/s-left.png");
步驟3:重寫Framed的paint方法,實現表單載入圖片
@Override
public void paint(Graphics g){
//畫背景圖
g.drawImage(bg_image,0,0,1100,700,this);
//畫小丑
g.drawImage(buffoon,300,200,80,80,this);
//畫爆炸物
g.drawImage(explode,800,400,90,90,this);
//畫原諒帽
g.drawImage(missile,300,300,60,60,this);
//畫橫著的牆體
g.drawImage(wall_h,400,300,100,20,this);
//畫豎著的牆體
g.drawImage(wall_v,400,300,20,100,this);
Graphics類的drawImage方法需要提供Image類引數、表單的x引數、表單的y引數、Image類的寬度width、Image類的長度length以及observer(當轉換了更多影象時要通知的物件)
指向標的地圖,通常採用「上北下南,左西右東」的規則確定方向。移動的八個方向通常指的是北、東北、東、東南、南、西南、西、西北。因此在定義移動方向時用上、左、下、右、上右、下右、上左、下左來表示
小丑:移動 move<Orientation類傳遞方向引數>
'left向左' :x = x - this.speed;
'right向右' :x = x + this.speed;
'down向下' :y = y + this.speed;
'up向上' :y = y - this.speed;
'ur東北方向' : x = x + this.speed;
y = y - this.speed;
'ul西北方向' : x = x - this.speed;
y = y - this.speed;
'dr東南方向' : x = x + this.speed;
y = y + this.speed;
'dl西南方向' : x = x - this.speed;
y = y + this.speed;
public void start() {
//表單新增偵聽方法
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
super.windowClosing(e);
//退出遊戲
System.exit(0);
}
});
WindowAdapter類:
1.接收視窗事件的抽象介面卡類。此類中的方法為空。此類存在的目的是方便建立偵聽器物件。
2.擴充套件此類可建立 WindowEvent 偵聽器併為所需事件重寫該方法。(如果要實現 WindowListener 介面,則必須定義該介面內的所有方法。此抽象類將所有方法都定義為 null,所以只需針對關心的事件定義方法。
3.使用擴充套件的類可以建立偵聽器物件,然後使用視窗的 addWindowListener 方法向該視窗註冊偵聽器。當通過開啟、關閉、啟用或停用、圖示化或取消圖示化而改變了視窗狀態時,將呼叫該偵聽器物件中的相關方法,並將 WindowEvent 傳遞給該方法。
windowAdapter監聽器
this.addKeyListener(new KeyAdapter() {
//鍵盤按下的時候出發
@Override
public void keyPressed(KeyEvent e) {
super.keyPressed(e);
}
//鍵盤松開
@Override
public void keyReleased(KeyEvent e) {
//獲取被按下的鍵對應的數值,如,a:67,b:68
int keyCode = e.getKeyCode();
switch (keyCode){
case KeyEvent.VK_UP:
System.out.println("向上走!!!");
buffoon.setDir("UP");
break;
case KeyEvent.VK_DOWN:
System.out.println("向下走");
buffoon.setDir("DOWN");
break;
case KeyEvent.VK_RIGHT:
System.out.println("向右走");
buffoon.setDir("RIGHT");
break;
case KeyEvent.VK_LEFT:
System.out.println("向左走!!");
buffoon.setDir("LEFT");
break;
}
buffoon.move(buffoon.getDir());
}
});
要點一:‘new KeyAdapter()’ 新建一個按鍵事件的監聽器,並通過addKeyListener()向主表單註冊該監聽器;
要點二:重寫KeyAdapter的方法,分別是KeyTyped(鍵入)、KeyPresdded(按下)、KeyReleased(釋放)。這裡我們只監聽KeyPressed事件並重寫該方法,實現對人物方向狀態的改變;
要點三:KeyEvent e.getKeyCode返回的是按下按鍵對應的鍵值,參考KeyEvent的鍵值屬性。Java 8線上API
public void move(String dir){
switch (dir){
case "UP":
this.y -= this.speed;
setDir("STOP");
break;
case "DOWN":
this.y += this.speed;
setDir("STOP");
break;
case "RIGHT":
this.x += this.speed;
setDir("STOP");
break;
case "LEFT":
this.x -= this.speed;
setDir("STOP");
break;
}
物件移動的畫面也叫動畫,是在螢幕上顯示一系列連續動畫畫面的一幀一幀的圖形,然後在間隔很短的時間顯示下一幀圖形,如此反覆,利用人眼的‘視覺暫留’現象主觀感覺好像畫面的物體在運動。
FPS(Frames Per Second),是每秒鐘的幀數。一幀就是一幅靜態畫像,電影的播放速度是24FPS。幀數越多,所顯示的動作就會越流暢。通常,要避免動作不流暢的最低是30FPS。FPS百度百科
什麼是執行緒
執行緒(thread)是作業系統能夠進行運算排程的最小單位。它被包含在程序之中,是程序中的實際運作單位。一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以並行多個執行緒,每條執行緒並行執行不同的任務。
/**
* 定義一個重新繪製畫面的執行緒,相當於招一個工人專門去從事這項工作
*/
public class RePaintThread implements Runnable{
@Override
//執行緒操作的全都在run方法中
public void run() {
while (true){
//每50毫秒 執行一次
try {
Thread.sleep(20);
//重新繪製影象
gameClient.repaint();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
要點一:Runnable介面
public class RePaintThread implements Runnable
使用實現介面 Runnable 的物件建立一個執行緒時,啟動該執行緒將導致在獨立執行的執行緒中呼叫物件的 run 方法。
要點二:重寫Run方法
方法 run 的常規協定是:它可能執行任何所需的動作。
重新繪製影象
gameClient.repaint();
要點三:Thread.sleep—執行緒反覆執行的時間間隔
1、使用’While(true)'構造死迴圈
2、在死迴圈中執行repaint()重繪圖形方法
3、執行緒中斷異常(InterruptedException)是當前執行緒被中斷的表現之一。遇到這個異常時,如果你不知道如何處理,你應當向上丟擲。