版本0.1java
功能: 產生一個窗口ide
掌握: 經過Eclipse創建新的項目 爲新的項目指定不一樣的源代碼和輸出目錄 指定項目所用的JDK版本 經過Eclipse創建新的類函數
注意: 類名和方法名的命名可以見名知意,類名首字母大寫,方法名、變量名首字母小寫,應用駝峯標識(多個單詞組成第一個單詞小寫,其餘單詞首字母大寫)this
具體代碼實現:spa
1 import java.awt.Frame; 2 3 public class TankClient extends Frame{ 4 5 public static void main(String[] args) { 6 TankClient tc=new TankClient(); 7 tc.launchFrame(); 8 } 9 public void launchFrame(){ 10 this.setLocation(400,300); 11 this.setSize(800, 600); 12 setVisible(true); 13 } 14 }
版本0.2線程
功能: 添加關閉窗口的事件處理,不容許窗口的大小改動code
掌握: 匿名類的用法 思考:匿名類的應用場合? 類短小、不涉及未來的擴展、不涉及重要的業務邏輯 經過Eclipse重寫父類的方法對象
注意: 沒掌握匿名類的先照抄,不寫也行 不影響最後的運行效果blog
具體代碼實現:事件
1 import java.awt.Frame; 2 import java.awt.event.WindowAdapter; 3 import java.awt.event.WindowEvent; 4 5 public class TankClient extends Frame{ 6 7 public static void main(String[] args) { 8 TankClient tc=new TankClient(); 9 tc.launchFrame(); 10 } 11 public void launchFrame(){ 12 this.setLocation(400,300); 13 this.setSize(800, 600); 14 this.addWindowListener(new WindowAdapter() { 15 16 @Override 17 public void windowClosing(WindowEvent e) { 18 19 System.exit(0); 20 } 21 22 }); 23 setResizable(false); 24 setVisible(true); 25 } 26 }
版本0.3
功能: 畫出表明坦克的實心圓
掌握: 如何重寫paint方法
注意: 不要改變原來的前景色
回顧: paint(Graphics g)方法,窗口重畫時自動調用 x軸、y軸的方向(X向右遞增、Y向下遞增)
具體代碼實現:
1 import java.awt.Color; 2 import java.awt.Frame; 3 import java.awt.Graphics; 4 import java.awt.event.WindowAdapter; 5 import java.awt.event.WindowEvent; 6 7 public class TankClient extends Frame{ 8 9 //重寫paint方法 10 @Override 11 public void paint(Graphics g) { 12 System.out.println(g.getColor()); 13 //不要改變原來的前景色,先拿出來,使用之後再改回去 14 //getClolor返回的是this graphics context's current color 15 Color c=g.getColor(); 16 g.setColor(Color.RED); 17 //四個參數分別表明Frame的左上角的x、y座標,實心圓的寬width和高height 18 g.fillOval(50,50,30,30); 19 g.setColor(c); 20 21 } 22 public static void main(String[] args) { 23 TankClient tc=new TankClient(); 24 tc.launchFrame(); 25 } 26 public void launchFrame(){ 27 this.setLocation(400,300); 28 this.setSize(800, 600); 29 this.addWindowListener(new WindowAdapter() { 30 31 @Override 32 public void windowClosing(WindowEvent e) { 33 34 System.exit(0); 35 } 36 37 }); 38 setResizable(false); 39 //設置背景色 40 this.setBackground(Color.GREEN); 41 setVisible(true); 42 } 43 }
版本0.4
功能: 讓坦克運動起來
步驟: 將位置改變爲變量 啓動線程不斷重畫
思考:爲何使用線程重畫,而不是每按下一個鍵進行一次重畫?
由於線程重畫更均勻,更能控制重畫的速度。 按鍵重畫不能解決子彈自動飛行的問題。 每次重畫改變Tank位置
掌握: 內部類的使用 思考:內部類有哪些好處?何時使用內部類? 能夠方便的訪問包裝類的方法。不方便公開的,只爲包裝類服務的類應當定義爲內部類。
注意: x, y值得含義,指的是小方塊的左上角點
具體代碼實現:
1 import java.awt.Color; 2 import java.awt.Frame; 3 import java.awt.Graphics; 4 import java.awt.event.WindowAdapter; 5 import java.awt.event.WindowEvent; 6 7 public class TankClient extends Frame{ 8 //將坦克的位置設置爲變量 9 int x=50; 10 int y=50; 11 12 //重寫paint方法 13 @Override 14 public void paint(Graphics g) { 15 //不要改變原來的前景色,先拿出來,使用之後再改回去 16 //getClolor返回的是this graphics context's current color 17 Color c=g.getColor(); 18 g.setColor(Color.RED); 19 //四個參數分別表明Frame的左上角的x、y座標,實心圓的寬width和高 20 g.fillOval(x,y,30,30); 21 g.setColor(c); 22 y+=5; 23 } 24 public static void main(String[] args) { 25 TankClient tc=new TankClient(); 26 tc.launchFrame(); 27 } 28 public void launchFrame(){ 29 //窗體位置 30 this.setLocation(400,300); 31 //窗體尺寸大小 32 this.setSize(800, 600); 33 //窗體title名稱 34 this.setTitle("TankWar"); 35 this.addWindowListener(new WindowAdapter() { 36 37 @Override 38 public void windowClosing(WindowEvent e) { 39 40 System.exit(0); 41 } 42 43 }); 44 setResizable(false); 45 //設置背景色 46 this.setBackground(Color.GREEN); 47 setVisible(true); 48 new Thread(new PaintThread()).start(); 49 } 50 //使用內部類,只爲包裝類復位 51 private class PaintThread implements Runnable{ 52 53 @Override 54 public void run() { 55 //重畫,內部會自動調用paint(Graphics g)方法 56 repaint(); 57 try { 58 Thread.sleep(100); 59 } catch (InterruptedException e) { 60 e.printStackTrace(); 61 } 62 } 63 64 } 65 }
版本0.4.1
功能:使用雙緩衝消除閃爍現象
緣由:刷新重畫頻率太快,paint方法尚未完成 逐條顯示
解決辦法:將全部東西畫在虛擬圖片上,一次性顯示出來
注意:若是不能理解透徹就照抄本版本代碼,不影響對J2SE的練習功效
具體代碼實現:
1 import java.awt.Color; 2 import java.awt.Frame; 3 import java.awt.Graphics; 4 import java.awt.Image; 5 import java.awt.event.WindowAdapter; 6 import java.awt.event.WindowEvent; 7 8 public class TankClient extends Frame { 9 // 將坦克的位置設置爲變量 10 int x = 50; 11 int y = 50; 12 Image offScreenImage = null; 13 14 // 重寫paint方法 15 @Override 16 public void paint(Graphics g) { 17 // 不要改變原來的前景色,先拿出來,使用之後再改回去 18 // getClolor返回的是this graphics context's current color 19 Color c = g.getColor(); 20 g.setColor(Color.RED); 21 // 四個參數分別表明Frame的左上角的x、y座標,實心圓的寬width和高 22 g.fillOval(x, y, 30, 30); 23 g.setColor(c); 24 y += 50; 25 } 26 27 @Override 28 public void update(Graphics g) { 29 if (offScreenImage == null) { 30 // 建立的虛擬圖片大小 31 offScreenImage = this.createImage(800, 600); 32 } 33 Graphics gOffScreen = offScreenImage.getGraphics(); 34 Color c=gOffScreen.getColor(); 35 gOffScreen.setColor(Color.GREEN); 36 gOffScreen.fillRect(0, 0, 800, 600); 37 gOffScreen.setColor(c); 38 paint(gOffScreen); 39 g.drawImage(offScreenImage, 0, 0, null); 40 } 41 42 public static void main(String[] args) { 43 TankClient tc = new TankClient(); 44 tc.launchFrame(); 45 } 46 47 public void launchFrame() { 48 // 窗體位置 49 this.setLocation(400, 300); 50 // 窗體尺寸大小 51 this.setSize(800, 600); 52 // 窗體title名稱 53 this.setTitle("TankWar"); 54 this.addWindowListener(new WindowAdapter() { 55 56 @Override 57 public void windowClosing(WindowEvent e) { 58 59 System.exit(0); 60 } 61 62 }); 63 setResizable(false); 64 // 設置背景色 65 this.setBackground(Color.GREEN); 66 setVisible(true); 67 new Thread(new PaintThread()).start(); 68 } 69 70 // 使用內部類,只爲包裝類復位 71 private class PaintThread implements Runnable { 72 73 @Override 74 public void run() { 75 // 重畫,內部會自動調用paint(Graphics g)方法 76 repaint(); 77 try { 78 Thread.sleep(50); 79 } catch (InterruptedException e) { 80 e.printStackTrace(); 81 } 82 } 83 84 } 85 }
版本0.5
功能: 代碼重構,將之後可能須要多處改變的量定義爲常量,Frame的寬度和高度(常量名通常大寫)
注意: 常量通常是public static final的。
具體代碼實現:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class TankClient extends Frame { 5 public static final int GAME_WIDTH = 800; 6 public static final int GAME_HEIGHT = 600; 7 8 int x = 50, y = 50; 9 10 Image offScreenImage = null; 11 12 public void paint(Graphics g) { 13 Color c = g.getColor(); 14 g.setColor(Color.RED); 15 g.fillOval(x, y, 30, 30); 16 g.setColor(c); 17 18 y += 5; 19 } 20 21 public void update(Graphics g) { 22 if(offScreenImage == null) { 23 offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); 24 } 25 Graphics gOffScreen = offScreenImage.getGraphics(); 26 Color c = gOffScreen.getColor(); 27 gOffScreen.setColor(Color.GREEN); 28 gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); 29 gOffScreen.setColor(c); 30 paint(gOffScreen); 31 g.drawImage(offScreenImage, 0, 0, null); 32 } 33 34 public void lauchFrame() { 35 this.setLocation(400, 300); 36 this.setSize(GAME_WIDTH, GAME_HEIGHT); 37 this.setTitle("TankWar"); 38 this.addWindowListener(new WindowAdapter() { 39 public void windowClosing(WindowEvent e) { 40 System.exit(0); 41 } 42 }); 43 this.setResizable(false); 44 this.setBackground(Color.GREEN); 45 setVisible(true); 46 47 new Thread(new PaintThread()).start(); 48 } 49 50 public static void main(String[] args) { 51 TankClient tc = new TankClient(); 52 tc.lauchFrame(); 53 } 54 55 private class PaintThread implements Runnable { 56 57 public void run() { 58 while(true) { 59 repaint(); 60 try { 61 Thread.sleep(50); 62 } catch (InterruptedException e) { 63 e.printStackTrace(); 64 } 65 } 66 } 67 } 68 69 }
版本0.6
功能: 讓坦克遵從咱們的指揮,添加鍵盤監聽器類KeyMonitor TankCient添加鍵盤監聽器,針對不一樣的鍵改變坦克的位置,與重畫線程結合產生不一樣方向運動
注意: switch case語句中break語句的運用,寫程序要按部就班
具體代碼實現:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class TankClient extends Frame { 5 public static final int GAME_WIDTH = 800; 6 public static final int GAME_HEIGHT = 600; 7 8 int x = 50, y = 50; 9 10 Image offScreenImage = null; 11 12 public void paint(Graphics g) { 13 Color c = g.getColor(); 14 g.setColor(Color.RED); 15 g.fillOval(x, y, 30, 30); 16 g.setColor(c); 17 } 18 19 public void update(Graphics g) { 20 if(offScreenImage == null) { 21 offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); 22 } 23 Graphics gOffScreen = offScreenImage.getGraphics(); 24 Color c = gOffScreen.getColor(); 25 gOffScreen.setColor(Color.GREEN); 26 gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); 27 gOffScreen.setColor(c); 28 paint(gOffScreen); 29 g.drawImage(offScreenImage, 0, 0, null); 30 } 31 32 public void lauchFrame() { 33 this.setLocation(400, 300); 34 this.setSize(GAME_WIDTH, GAME_HEIGHT); 35 this.setTitle("TankWar"); 36 this.addWindowListener(new WindowAdapter() { 37 public void windowClosing(WindowEvent e) { 38 System.exit(0); 39 } 40 }); 41 this.setResizable(false); 42 this.setBackground(Color.GREEN); 43 44 this.addKeyListener(new KeyMonitor()); 45 46 setVisible(true); 47 48 new Thread(new PaintThread()).start(); 49 } 50 51 public static void main(String[] args) { 52 TankClient tc = new TankClient(); 53 tc.lauchFrame(); 54 } 55 56 private class PaintThread implements Runnable { 57 58 public void run() { 59 while(true) { 60 repaint(); 61 try { 62 Thread.sleep(50); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 } 67 } 68 } 69 70 private class KeyMonitor extends KeyAdapter { 71 72 public void keyPressed(KeyEvent e) { 73 int key = e.getKeyCode(); 74 switch(key) { 75 case KeyEvent.VK_LEFT : 76 x -= 5; 77 break; 78 case KeyEvent.VK_UP : 79 y -= 5; 80 break; 81 case KeyEvent.VK_RIGHT : 82 x += 5; 83 break; 84 case KeyEvent.VK_DOWN : 85 y += 5; 86 break; 87 } 88 } 89 90 } 91 }
版本0.7
功能: 將坦克單獨包裝成類(Tank)
步驟: 創建Tank類;爲Tank類添加成員變量x、y;添加draw方法,使Tank類獨立控制本身的畫法;添加Tank類處理按鍵的方法;根據Tank類修改TankClient類
掌握: 面向對象的思考方法,細節隱藏、構建單獨的類、首先考慮系統中有哪些類?合適的方法應該出如今合適的類中;
具體代碼實現:
Tank:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class Tank { 5 int x; 6 int y; 7 public Tank(int x, int y) { 8 this.x = x; 9 this.y = y; 10 } 11 public void draw(Graphics g){ 12 Color c=g.getColor(); 13 g.setColor(Color.RED); 14 g.fillOval(x, y, 30, 30); 15 g.setColor(c); 16 } 17 //坦克本身向哪一個方向移動,它本身最清楚; 18 public void KeyPressed(KeyEvent e){ 19 //得到所按下的鍵所對應的虛擬碼: 20 //Returns the integer keyCode associated with the key in this event 21 int key = e.getKeyCode(); 22 //判斷不一樣的按鍵,指揮坦克的運動方向 23 switch(key) { 24 case KeyEvent.VK_LEFT : 25 x -= 5; 26 break; 27 case KeyEvent.VK_UP : 28 y -= 5; 29 break; 30 case KeyEvent.VK_RIGHT : 31 x += 5; 32 break; 33 case KeyEvent.VK_DOWN : 34 y += 5; 35 break; 36 } 37 } 38 }
TankClient:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class TankClient extends Frame { 5 //設置成常量,方便之後的改動 6 public static final int GAME_WIDTH = 800; 7 public static final int GAME_HEIGHT = 600; 8 Tank myTank=new Tank(50, 50); 9 10 //定義虛擬圖片,方便後期的一次性顯示 11 Image offScreenImage = null; 12 13 public void paint(Graphics g) { 14 //不改變前景色 15 myTank.draw(g); 16 } 17 18 //刷新操做 19 public void update(Graphics g) { 20 if(offScreenImage == null) { 21 offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); 22 } 23 Graphics gOffScreen = offScreenImage.getGraphics(); 24 Color c = gOffScreen.getColor(); 25 gOffScreen.setColor(Color.GREEN); 26 gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); 27 gOffScreen.setColor(c); 28 paint(gOffScreen); 29 g.drawImage(offScreenImage, 0, 0, null); 30 } 31 32 public void lauchFrame() { 33 this.setLocation(400, 300); 34 this.setSize(GAME_WIDTH, GAME_HEIGHT); 35 this.setTitle("TankWar"); 36 this.addWindowListener(new WindowAdapter() { 37 public void windowClosing(WindowEvent e) { 38 System.exit(0); 39 } 40 }); 41 this.setResizable(false); 42 this.setBackground(Color.GREEN); 43 44 this.addKeyListener(new KeyMonitor()); 45 46 setVisible(true); 47 48 new Thread(new PaintThread()).start(); 49 } 50 51 public static void main(String[] args) { 52 TankClient tc = new TankClient(); 53 tc.lauchFrame(); 54 } 55 56 private class PaintThread implements Runnable { 57 58 public void run() { 59 while(true) { 60 repaint(); 61 try { 62 Thread.sleep(50); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 } 67 } 68 } 69 70 //建立鍵盤時間監聽 71 private class KeyMonitor extends KeyAdapter { 72 73 //直接調用myTank本身的方法根據相應的按鍵信息進行移動 74 public void keyPressed(KeyEvent e) { 75 myTank.KeyPressed(e); 76 } 77 78 } 79 }
版本0.8
功能: 讓主戰坦克向8個方向行走(左、右、上、下、左上、左下、右上、右下)
步驟: 添加記錄按鍵狀態的布爾量;添加表明方向的量(使用枚舉);根據按鍵狀態肯定Tank方向;根據方向進行下一步的移動(move);
Tank:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class Tank { 5 // 方便後期更改 6 public static final int XSPEED = 5; 7 public static final int YSPEED = 5; 8 private int x; 9 private int y; 10 // 添加記錄按鍵狀態的布爾量 11 private boolean bL = false; 12 private boolean bR = false; 13 private boolean bU = false; 14 private boolean bD = false; 15 16 // 添加表明方向的量(使用枚舉) 17 enum Direction { 18 L, R, U, D, LU, LD, RU, RD, STOP 19 }; 20 21 private Direction dir = Direction.STOP; 22 23 public Tank(int x, int y) { 24 this.x = x; 25 this.y = y; 26 } 27 28 // Tank對象的draw方法 29 public void draw(Graphics g) { 30 Color c = g.getColor(); 31 g.setColor(Color.RED); 32 g.fillOval(x, y, 30, 30); 33 g.setColor(c); 34 move(); 35 } 36 37 public void move() { 38 switch (dir) { 39 case L: 40 x -= XSPEED; 41 break; 42 case R: 43 x += XSPEED; 44 break; 45 case U: 46 y -= YSPEED; 47 break; 48 case D: 49 y += YSPEED; 50 break; 51 case LU: 52 x -= XSPEED; 53 y -= YSPEED; 54 break; 55 case LD: 56 x -= XSPEED; 57 y += YSPEED; 58 break; 59 case RU: 60 x += XSPEED; 61 y -= YSPEED; 62 break; 63 case RD: 64 x += XSPEED; 65 y += YSPEED; 66 break; 67 68 case STOP: 69 break; 70 } 71 } 72 73 public void locateDirection() { 74 if (bL && !bU && !bR && !bD) 75 dir = Direction.L; 76 else if (bL && bU && !bR && !bD) 77 dir = Direction.LU; 78 else if (!bL && bU && !bR && !bD) 79 dir = Direction.U; 80 else if (!bL && bU && bR && !bD) 81 dir = Direction.RU; 82 else if (!bL && !bU && bR && !bD) 83 dir = Direction.R; 84 else if (!bL && !bU && bR && bD) 85 dir = Direction.RD; 86 else if (!bL && !bU && !bR && bD) 87 dir = Direction.D; 88 else if (bL && !bU && !bR && bD) 89 dir = Direction.LD; 90 else if (!bL && !bU && !bR && !bD) 91 dir = Direction.STOP; 92 93 } 94 95 // 坦克本身向哪一個方向移動,它本身最清楚; 96 public void KeyPressed(KeyEvent e) { 97 // 得到所按下的鍵所對應的虛擬碼: 98 // Returns the integer keyCode associated with the key in this event 99 int key = e.getKeyCode(); 100 // 判斷不一樣的按鍵,指揮坦克的運動方向 101 switch (key) { 102 case KeyEvent.VK_LEFT: 103 bL = true; 104 break; 105 case KeyEvent.VK_UP: 106 bU = true; 107 break; 108 case KeyEvent.VK_RIGHT: 109 bR = true; 110 break; 111 case KeyEvent.VK_DOWN: 112 bD = true; 113 break; 114 } 115 locateDirection(); 116 } 117 }
TankClient:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class TankClient extends Frame { 5 // 設置成常量,方便之後的改動 6 public static final int GAME_WIDTH = 800; 7 public static final int GAME_HEIGHT = 600; 8 Tank myTank = new Tank(50, 50); 9 10 // 定義虛擬圖片,方便後期的一次性顯示 11 Image offScreenImage = null; 12 13 public void paint(Graphics g) { 14 // 不改變前景色 15 myTank.draw(g); 16 } 17 18 // 刷新操做 19 public void update(Graphics g) { 20 if (offScreenImage == null) { 21 offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); 22 } 23 Graphics gOffScreen = offScreenImage.getGraphics(); 24 Color c = gOffScreen.getColor(); 25 gOffScreen.setColor(Color.GREEN); 26 gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); 27 gOffScreen.setColor(c); 28 paint(gOffScreen); 29 g.drawImage(offScreenImage, 0, 0, null); 30 } 31 32 public void lauchFrame() { 33 this.setLocation(400, 300); 34 this.setSize(GAME_WIDTH, GAME_HEIGHT); 35 this.setTitle("TankWar"); 36 this.addWindowListener(new WindowAdapter() { 37 public void windowClosing(WindowEvent e) { 38 System.exit(0); 39 } 40 }); 41 this.setResizable(false); 42 this.setBackground(Color.GREEN); 43 44 this.addKeyListener(new KeyMonitor()); 45 46 setVisible(true); 47 48 new Thread(new PaintThread()).start(); 49 } 50 51 public static void main(String[] args) { 52 TankClient tc = new TankClient(); 53 tc.lauchFrame(); 54 } 55 56 private class PaintThread implements Runnable { 57 58 public void run() { 59 while (true) { 60 repaint(); 61 try { 62 Thread.sleep(50); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 } 67 } 68 } 69 70 // 建立鍵盤時間監聽 71 private class KeyMonitor extends KeyAdapter { 72 73 // 直接調用myTank本身的方法根據相應的按鍵信息進行移動 74 public void keyPressed(KeyEvent e) { 75 myTank.KeyPressed(e); 76 } 77 78 } 79 }
按下按鍵->KeyPressed監聽->按鍵狀態發生改變->locateDirection()函數->dir的值會發生改變->進而當調用move方法的時候執行相應的操做;
版本0.9
咱們在版本0.8中,按下某個鍵的時候,記錄按鍵狀態的布爾量一直是true,咱們沒法改變坦克的移動方向了,在版本0.9中咱們作下處理
功能: 讓主戰坦克向8個方向行走
步驟: 處理鍵擡起的消息 修改TankClient相關代碼
Tank:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class Tank { 5 // 方便後期更改 6 public static final int XSPEED = 5; 7 public static final int YSPEED = 5; 8 private int x; 9 private int y; 10 // 添加記錄按鍵狀態的布爾量 11 private boolean bL = false; 12 private boolean bR = false; 13 private boolean bU = false; 14 private boolean bD = false; 15 16 // 添加表明方向的量(使用枚舉) 17 enum Direction { 18 L, R, U, D, LU, LD, RU, RD, STOP 19 }; 20 21 private Direction dir = Direction.STOP; 22 23 public Tank(int x, int y) { 24 this.x = x; 25 this.y = y; 26 } 27 28 // Tank對象的draw方法 29 public void draw(Graphics g) { 30 Color c = g.getColor(); 31 g.setColor(Color.RED); 32 g.fillOval(x, y, 30, 30); 33 g.setColor(c); 34 move(); 35 } 36 37 public void move() { 38 switch (dir) { 39 case L: 40 x -= XSPEED; 41 break; 42 case R: 43 x += XSPEED; 44 break; 45 case U: 46 y -= YSPEED; 47 break; 48 case D: 49 y += YSPEED; 50 break; 51 case LU: 52 x -= XSPEED; 53 y -= YSPEED; 54 break; 55 case LD: 56 x -= XSPEED; 57 y += YSPEED; 58 break; 59 case RU: 60 x += XSPEED; 61 y -= YSPEED; 62 break; 63 case RD: 64 x += XSPEED; 65 y += YSPEED; 66 break; 67 68 case STOP: 69 break; 70 } 71 } 72 73 public void locateDirection() { 74 if (bL && !bU && !bR && !bD) 75 dir = Direction.L; 76 else if (bL && bU && !bR && !bD) 77 dir = Direction.LU; 78 else if (!bL && bU && !bR && !bD) 79 dir = Direction.U; 80 else if (!bL && bU && bR && !bD) 81 dir = Direction.RU; 82 else if (!bL && !bU && bR && !bD) 83 dir = Direction.R; 84 else if (!bL && !bU && bR && bD) 85 dir = Direction.RD; 86 else if (!bL && !bU && !bR && bD) 87 dir = Direction.D; 88 else if (bL && !bU && !bR && bD) 89 dir = Direction.LD; 90 else if (!bL && !bU && !bR && !bD) 91 dir = Direction.STOP; 92 93 } 94 95 // 坦克本身向哪一個方向移動,它本身最清楚; 96 public void KeyPressed(KeyEvent e) { 97 // 得到所按下的鍵所對應的虛擬碼: 98 // Returns the integer keyCode associated with the key in this event 99 int key = e.getKeyCode(); 100 // 判斷不一樣的按鍵,指揮坦克的運動方向 101 switch (key) { 102 case KeyEvent.VK_LEFT: 103 bL = true; 104 break; 105 case KeyEvent.VK_UP: 106 bU = true; 107 break; 108 case KeyEvent.VK_RIGHT: 109 bR = true; 110 break; 111 case KeyEvent.VK_DOWN: 112 bD = true; 113 break; 114 } 115 locateDirection(); 116 } 117 118 public void keyReleased(KeyEvent e) { 119 int key = e.getKeyCode(); 120 // 判斷不一樣的按鍵,指揮坦克的運動方向 121 // 哪一個鍵按下了,就把對應方向的布爾類型置爲false 122 switch (key) { 123 case KeyEvent.VK_LEFT: 124 bL = false; 125 break; 126 case KeyEvent.VK_UP: 127 bU = false; 128 break; 129 case KeyEvent.VK_RIGHT: 130 bR = false; 131 break; 132 case KeyEvent.VK_DOWN: 133 bD = false; 134 break; 135 } 136 // 從新定位一下 137 locateDirection(); 138 } 139 }
TankClient:
1 import java.awt.*; 2 import java.awt.event.*; 3 4 public class TankClient extends Frame { 5 // 設置成常量,方便之後的改動 6 public static final int GAME_WIDTH = 800; 7 public static final int GAME_HEIGHT = 600; 8 Tank myTank = new Tank(50, 50); 9 10 // 定義虛擬圖片,方便後期的一次性顯示 11 Image offScreenImage = null; 12 13 public void paint(Graphics g) { 14 // 不改變前景色 15 myTank.draw(g); 16 } 17 18 // 刷新操做 19 public void update(Graphics g) { 20 if (offScreenImage == null) { 21 offScreenImage = this.createImage(GAME_WIDTH, GAME_HEIGHT); 22 } 23 Graphics gOffScreen = offScreenImage.getGraphics(); 24 Color c = gOffScreen.getColor(); 25 gOffScreen.setColor(Color.GREEN); 26 gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT); 27 gOffScreen.setColor(c); 28 paint(gOffScreen); 29 g.drawImage(offScreenImage, 0, 0, null); 30 } 31 32 public void lauchFrame() { 33 this.setLocation(400, 300); 34 this.setSize(GAME_WIDTH, GAME_HEIGHT); 35 this.setTitle("TankWar"); 36 this.addWindowListener(new WindowAdapter() { 37 public void windowClosing(WindowEvent e) { 38 System.exit(0); 39 } 40 }); 41 this.setResizable(false); 42 this.setBackground(Color.GREEN); 43 44 this.addKeyListener(new KeyMonitor()); 45 46 setVisible(true); 47 48 new Thread(new PaintThread()).start(); 49 } 50 51 public static void main(String[] args) { 52 TankClient tc = new TankClient(); 53 tc.lauchFrame(); 54 } 55 56 private class PaintThread implements Runnable { 57 58 public void run() { 59 while (true) { 60 repaint(); 61 try { 62 Thread.sleep(50); 63 } catch (InterruptedException e) { 64 e.printStackTrace(); 65 } 66 } 67 } 68 } 69 70 // 建立鍵盤時間監聽 71 private class KeyMonitor extends KeyAdapter { 72 73 // 直接調用myTank本身的方法根據相應的按鍵信息進行移動 74 public void keyPressed(KeyEvent e) { 75 myTank.KeyPressed(e); 76 // 添加了處理鍵擡起的事件,能夠控制坦克起步之後的狀態 77 // 而不是一直按照一個方向走下去 78 } 79 public void keyReleased(KeyEvent e){ 80 myTank.keyReleased(e); 81 } 82 83 } 84 }
未完待續。。。。。。