好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

Java实现简单的飞机大战游戏(敌机下落篇)

本文实例为大家分享了Java实现简单飞机大战游戏,敌机下落的具体代码,供大家参考,具体内容如下

在实现这个游戏之前,我们首先需要知道项目可能要用到哪些知识点:

重绘,线程,双缓冲,数据结构的应用

差不多是这大概有这些,如果不够的话我们再加。
首先,我们应该实现敌机下落,在这里大概思路和利用线程使小球下落差不多。不同的是,我在这里用到了三种敌机,分别为小、大、BOSS机三种。然后给予这三种敌机不同的下落规则(即速度、出现的时间、是否伴随子弹的发射等等)来给游戏适当的增加点难度。

以下是我的大概设计思路和下落规则,大家可以参考一下

1.飞机是在一开始的时候就出现的,先出现什么飞机?速度?什么位置出现?频率?

先出小飞机,再出大飞机,当所有的大小飞机都消失以后出现BOSS机.
小飞机的速度较快:8    大飞机的速度较慢:4    BOSS机的速度最慢:2
频率:每隔1秒出现一架小飞机,每出现4架小飞机后出现一架大飞机,最后出现BOSS机.
位置:在窗体的范围内,考虑到png图片的高度和宽度,所以出现的时候注意减去相应的高度和宽度.    

2.小飞机,大飞机,BOSS机需要使用不同的vector类来保存,取出的时候再使用一个vector类来保存(保存的时候应该将三个vector类中原来的飞机移除).再将保存起来的飞机依次进行画出.当出现4架小飞机的时候就出现一架大飞机,当小飞机和大飞机都出现完了以后,出现BOSS机.注意:大飞机和BOSS机的时候伴随着子弹的发出.

3.子弹:

子弹在大飞机和BOSS机出现的时候出现.且速度优于大飞机和BOSS机.因为小飞机没有子弹,在这里我们利用byte标记来区别于小飞机和其他两种飞机,另外也需要将子弹标记,以防止子弹生成子弹。    

4.使用两个线程:

(1)一个线程用来实现将不同的vector向量取出的飞机(先将大小飞机取出以后,再取出BOSS机,每取一次小飞机的时候将count记一次数,当count==4的时候,取出一架大飞机.当小飞机和大飞机全部取完以后再取出BOSS机),并保存在一个统一的vector向量中.    

(2)另一个线程用来实现画飞机和子弹并使其移动.    

5.效果图出现过于闪烁的情况可以利用双缓冲技术来减少闪烁。

以下是代码主类,主要生成窗体和敌机,并将敌机保存在不同的vector向量中。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

public class BallMain {

 

     public Graphics g;

     public Vector<Ball> vector, minVector, maxVector, bossVector;

     public ImageIcon img;

 

     public static void main(String[] args) {

         BallMain bm = new BallMain();

         bm.init();

 

     }

 

     public void init() {

         JFrame frame = new JFrame();

         frame.setTitle( "飞机大战" );

         frame.setSize( 800 , 800 );

         frame.setDefaultCloseOperation( 3 );

         frame.setLocationRelativeTo( null );

         frame.setBackground(Color.white);

         frame.setResizable( false ); // 不允许改变窗体大小

 

         frame.setVisible( true );

 

         this .g = frame.getGraphics();

 

         minVector = new Vector<Ball>();

         maxVector = new Vector<Ball>();

         bossVector = new Vector<Ball>();

         vector = new Vector<Ball>();

 

         initPlane(frame);

 

         BallThread bt = new BallThread(vector, minVector, maxVector,

                 bossVector, frame);

         bt.start();

 

         BallGraThread bll = new BallGraThread(vector, frame,

                 frame.getGraphics());

         bll.start();

     }

 

     public void initPlane(JFrame frame) {

         Random rand = new Random();

         // 小飞机的生成

         for ( int i = 0 ; i < 8 ; i++) {

             ImageIcon icon = new ImageIcon( "plane/plane0.png" );

             int r = icon.getIconWidth() / 2 ;

             int x = rand.nextInt(frame.getWidth() - icon.getIconWidth()) + r;

             int y = -icon.getIconHeight();

             int vy = 8 ;

             Ball b = new Ball(icon.getImage(), x, y, r, vy, ( byte ) 1 );

             minVector.add(b);

         }

         // 大飞机的生成

         for ( int i = 0 ; i < 2 ; i++) {

             ImageIcon icon = new ImageIcon( "plane/plane1.png" );

             int r = icon.getIconWidth() / 2 ;

             int x = rand.nextInt(frame.getWidth() - icon.getIconWidth()) + r;

             int y = -icon.getIconHeight();

             int vy = 4 ;

 

             Ball b = new Ball(icon.getImage(), x, y, r, vy, ( byte ) 2 );

             maxVector.add(b);

         }

         // Boss机的生成

         ImageIcon icon = new ImageIcon( "plane/plane2.png" );

         int r = icon.getIconWidth() / 2 ;

         int x = rand.nextInt(frame.getWidth() - icon.getIconWidth()) + r;

         int y = -icon.getIconHeight();

         int vy = 2 ;

         Ball b = new Ball(icon.getImage(), x, y, r, vy, ( byte ) 3 );

         bossVector.add(b);

     }

}

以下为飞机的下落规则:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

public BallThread(Vector<Ball> vector, Vector<Ball> minVector,

             Vector<Ball> maxVector, Vector<Ball> bossVector, JFrame frame) {

         this .vector = vector;

         this .minVector = minVector;

         this .maxVector = maxVector;

         this .bossVector = bossVector;

 

         this .frame = frame;

     }

 

     public void run() {

         int count = 0 ;

         while ( true ) {

             if (minVector.size() > 0 ) {

                 vector.add(minVector.remove( 0 ));

                 ++count;

                 if (count == 4 ) {

                     if (maxVector.size() > 0 ) {

                         vector.add(maxVector.remove( 0 ));

                         count = 0 ;

                     }

                 }

             }

             if (vector.size() == 0 ) {

                 vector.add(bossVector.remove( 0 ));

                 break ;

             }

             try {

                 Thread.sleep( 1000 );

             } catch (InterruptedException e) {

                 e.printStackTrace();

             }

         }

     }

}

利用双缓冲减少闪烁,画出飞机并擦除,使其不断更新位置:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

public class BallGraThread extends Thread {

 

     public Vector<Ball> vector;

     public JFrame frame;

     public Graphics g;

     public BufferedImage image;

     public Graphics ig;

 

     public BallGraThread(Vector<Ball> vector, JFrame frame, Graphics g) {

         this .vector = vector;

         this .frame = frame;

         this .g = g;

     }

 

     public void run() {

         if (image == null ) {

            

             //创建一个带透明色的BufferedImage对象

             image = new BufferedImage(frame.getWidth(), frame.getHeight(),

                     BufferedImage.TYPE_INT_ARGB);

             //获取画笔对象.

             ig = image.getGraphics();

         }

         while ( true ) {

             //擦除.

             ig.setColor(frame.getContentPane().getBackground());

             ig.fillRect( 0 , 0 , frame.getWidth(), frame.getHeight());

 

             for ( int i = 0 ; i < vector.size(); i++) {

                 Ball ball = vector.get(i);

                 ball.draw(ig);

                 ball.move(vector, frame, ig);

             }

 

             g.drawImage(image, 0 , 0 , frame);

 

             try {

                 Thread.sleep( 100 );

             } catch (InterruptedException e) {

                 e.printStackTrace();

             }

 

         }

     }

}

子弹类,标记子弹来区分三种敌机,当飞机和子弹飞出窗体外后将其移除与vector:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

public class Ball {

     public int x, y;

     public int flag = 1 ;

     public Color color;

     public Image img;

     public BulletThread ba;

     int r;

     int vy;

     byte type;

     Random random = new Random();

 

     public Ball(Image img, int x, int y, int r, int vy, byte type) {

         this .img = img;

         this .x = x;

         this .y = y;

         this .r = r;

         this .vy = vy;

         this .type = type;

     }

 

     public void move(Vector<Ball> vector, JFrame frame, Graphics g) {

         if (y >= 0 && flag == 1 ) {

             // 如果是大飞机或者BOSS机的话,就发射子弹.

             if (type == 2 || type == 3 ) {

                 ba = new BulletThread(vector, this );

                 ba.start();

                 flag = 2 ;

                 System.out.println(ba);

             }

         }

 

         if (y >= frame.getHeight()) {

             img = new ImageIcon( "planne/bullet.png" ).getImage();

             g.drawImage(img, x, y, 2 * r, 2 * r, null );

             System.out.println(ba);

             if (type == 2 || type == 3 )

                 ba.stopFlag = false ;

             vector.remove( this );

         }

         y = y + vy;

     }

 

     public void draw(Graphics g) {

         // 需要将ImageIcon转为Image类型的.

         g.drawImage(img, x, y, 2 * r, 2 * r, null );

 

     }

 

}

画出子弹并添加于vector向量中,使其移动:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

public class BulletThread extends Thread {

     public Vector<Ball> vector;

     public Ball ball; // 大飞机的数据来生成子弹

     public boolean stopFlag = true ;

     public boolean pauseFlag = true ;

 

     public BulletThread(Vector<Ball> vector, Ball ball) {

         this .vector = vector;

         this .ball = ball;

     }

 

     public void run() {

         while (stopFlag) {

             if (pauseFlag) {

                 int x = ball.x + ball.r;

                 int y = ball.y + 2 * ball.r;

                 int r = 20 ;

                 Image img = new ImageIcon( "plane/bullet.png" ).getImage();

                 int vy = ball.vy + 4 ;

                 Ball bullet = new Ball(img, x, y, r, vy, ( byte ) 0 );

                 vector.add(bullet);

             }

             try {

                 Thread.sleep( 4000 );

             } catch (InterruptedException e) {

                 e.printStackTrace();

             }

         }

     }

}

以上差不多就是敌机的下落,其他的一些功能尚未完善,比如可以给敌机添加不同的血量再来增加难度,大家可以根据自己的发挥来写出属于自己的飞机大战游戏。

希望这篇文章对大家的学习有所帮助,也希望大家多多支持。

原文链接:https://blog.csdn.net/weixin_42331530/article/details/89383000

查看更多关于Java实现简单的飞机大战游戏(敌机下落篇)的详细内容...

  阅读:21次