成果展示

制作思路
第1步:發現類(物件)
人物-小丑: Buffoon
子彈-帽子:Missile
墻體:Wall
爆炸物:Explode
第2步:發現屬性
小丑:寬和高,位置(x,y),移動速度
帽子:寬和高,位置(x,y),移動速度
墻體:寬和高,位置(x,y)
爆炸物:寬和高,位置(x,y)
第3步:發現方法
小丑:移動、攻擊、人物撞邊界
子彈:移動、子彈撞墻、子彈撞邊界
爆炸物:消失
重難點分析
表單如何創建
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
創建物件Buffoon.move()方法
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;
}
每次監聽到按鍵事件呼叫move方法實作buffoon物件的移動

物件移動的原理
物件移動的畫面也叫影片,是在螢屏上顯示一系列連續影片畫面的一幀一幀的圖形,然后在間隔很短的時間顯示下一幀圖形,如此反復,利用人眼的‘視覺暫留’現象主觀感覺好像畫面的物體在運動,
FPS(Frames Per Second),是每秒鐘的幀數,一幀就是一幅靜態畫像,電影的播放速度是24FPS,幀數越多,所顯示的動作就會越流暢,通常,要避免動作不流暢的最低是30FPS,FPS百度百科
影片移動的搬運工-執行緒(thread)
什么是執行緒
執行緒(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)是當前執行緒被中斷的表現之一,遇到這個例外時,如果你不知道如何處理,你應當向上拋出,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/213373.html
標籤:其他

