zoukankan      html  css  js  c++  java
  • 坦克大战(版本0.1-版本0.9)

    版本0.1

    功能: 产生一个窗口

    掌握: 通过Eclipse建立新的项目 为新的项目指定不同的源代码和输出目录 指定项目所用的JDK版本 通过Eclipse建立新的类

    注意: 类名和方法名的命名能够见名知意,类名首字母大写,方法名、变量名首字母小写,应用驼峰标识(多个单词组成第一个单词小写,其他单词首字母大写)

    具体代码实现:

     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

    功能: 添加关闭窗口的事件处理,不允许窗口的大小改动

    掌握: 匿名类的用法 思考:匿名类的应用场合? 类短小、不涉及将来的扩展、不涉及重要的业务逻辑 通过Eclipse重写父类的方法

    注意: 没掌握匿名类的先照抄,不写也行 不影响最后的运行效果

    具体代码实现:

     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 }
    View Code

    版本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 }
    View Code

    版本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 }
    View Code

    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 }
    View Code

    版本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 }
    View Code

    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 }
    View Code

    按下按键->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 }
    View Code

    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 }
    View Code

    未完待续。。。。。。

  • 相关阅读:
    面试题目-atof与ftoa
    数据结构-List
    数据结构-Vector
    面试题目-计算最大公约数
    数据结构-二分查找
    面试题目-用递归通过单字符输出打印多位的数字
    Linux-守护进程的实现
    面试题目-链表反转
    Linux-C程序的存储空间布局
    Linux-如何添加路由表
  • 原文地址:https://www.cnblogs.com/ysw-go/p/5503281.html
Copyright © 2011-2022 走看看