本文實例為大家分享了java實現(xiàn)飛機游戲的具體代碼,供大家參考,具體內(nèi)容如下
MyGameFrame類:
主要的調(diào)用類
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
|
package sc.wh.game; import javax.swing.JFrame; import java.awt.Color; import java.awt.Font; import java.awt.Frame; import java.awt.Graphics; import java.awt.Image; import sc.wh.game.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.Date; public class MyGameFrame extends Frame { // 調(diào)用工具類的getImage方法加載圖片對象 Image planeImg = GameUtil.getImage( "images/plane.png" ); Image bg = GameUtil.getImage( "images/bg.jpg" ); // 創(chuàng)建飛機,設(shè)置初始位置 Plane plane = new Plane(planeImg, 250 , 250 ); // 創(chuàng)建炮彈組 Shell shells[] = new Shell[ 50 ]; // 設(shè)置爆炸效果類的對象的引用 Explode bao; // 游戲開始時間 Date startTime = new Date(); // 游戲結(jié)束時間 Date endTime; // 游戲進行的時間 int period; // 記錄爆炸效果顯示的圖片 int BaoCount = 0 ; // 在窗口畫圖方法,由repaint方法自動調(diào)用 @Override public void paint(Graphics g) { // 會自動被調(diào)用,g相當于一支畫筆 Color c = g.getColor(); // 畫背景 g.drawImage(bg, 0 , 0 , null ); // 調(diào)用飛機類的畫圖方法并畫飛機 plane.drawSelf(g); // 畫炮彈組中的炮彈 for ( int i= 0 ;i<shells.length;i++) { // 調(diào)用炮彈對象的draw方法 shells[i].draw(g); // 獲取炮彈所在矩形位置并調(diào)用intersects判斷兩矩形是否相交 boolean peng = shells[i].getRect().intersects(plane.getRect()); if (peng) { // 如果相交則設(shè)置飛機存活狀態(tài)為false plane.live = false ; // 如果bao對象沒有初始化過則才初始化 if (bao == null ) { bao = new Explode(plane.x, plane.y); endTime = new Date(); period = ( int )(endTime.getTime() - startTime.getTime())/ 1000 ; } if (BaoCount <= 15 ) { // 調(diào)用爆炸效果顯示類的畫圖方法,每次調(diào)用只畫一張圖 bao.draw(g); BaoCount++; } } // 如果飛機未存活則顯示游戲時間 if (!plane.live) { // 創(chuàng)建字體對象 Font f = new Font( "宋體" ,Font.BOLD, 50 ); // 設(shè)置字體 g.setFont(f); // 設(shè)置字體顏色 g.setColor(Color.RED); // 顯示游戲結(jié)束時間 g.drawString( "游戲時間:" + period + "秒" , 100 , 250 ); } } g.setColor(c); } // 繼承Thread線程類 class PaintThread extends Thread{ // 線程開始后會自動調(diào)用run方法 @Override public void run() { while ( true ) { // 調(diào)用repaint窗口畫圖方法,此方法會自動調(diào)用paint方法 repaint(); try { // 控制一秒25次在窗口畫圖的方法 Thread.sleep( 40 ); } catch (InterruptedException e) { e.printStackTrace(); } } } } // 創(chuàng)建鍵盤檢測內(nèi)部類,并繼承鍵盤監(jiān)聽類 class KeyMonitor extends KeyAdapter{ // 檢測鍵盤按下事件,調(diào)用飛機類對應(yīng)的方法 @Override public void keyPressed(KeyEvent e) { // KeyEvent鍵盤檢測類 plane.addDirection(e); } // 檢測鍵盤釋放事件,調(diào)用飛機類對應(yīng)的方法 @Override public void keyReleased(KeyEvent e) { plane.minusDirection(e); } } // 雙緩沖解決閃爍 private Image offScreenImage = null ; public void update(Graphics g) { if (offScreenImage == null ) offScreenImage = this .createImage(Constants.WIDTH,Constants.HEIGHT); //這是游戲窗口的寬度和高度 Graphics gOff = offScreenImage.getGraphics(); paint(gOff); g.drawImage(offScreenImage, 0 , 0 , null ); } public void launchFrame(){ // 標題 this .setTitle( "game fly" ); // 窗口默認不可見 this .setVisible( true ); // 窗口大小 this .setSize(Constants.WIDTH,Constants.HEIGHT); // 窗口距離左上角的坐標位置 this .setLocation( 300 , 300 ); //增加關(guān)閉窗口監(jiān)聽,這樣用戶點擊右上角關(guān)閉圖標,可以關(guān)閉游戲程序 this .addWindowListener( new WindowAdapter() { @Override public void windowClosing(WindowEvent e){ System.exit( 0 ); } }); // 創(chuàng)建在窗口中畫圖線程并調(diào)用 new PaintThread().start(); // 將KeyMonitor類的對象加入鍵盤監(jiān)控檢測,對應(yīng)的事件會自動調(diào)用此類對應(yīng)的方法 addKeyListener( new KeyMonitor()); // 創(chuàng)建炮彈,加入炮彈數(shù)組 for ( int i= 0 ;i<shells.length;i++) { shells[i] = new Shell(); } } public static void main(String[] args) { MyGameFrame f = new MyGameFrame(); // 調(diào)用畫窗口方法 f.launchFrame(); } } |
工具類(用來獲取圖片對象):
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
|
package sc.wh.game; import java.awt.Image; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import javax.imageio.ImageIO; public class GameUtil { // 工具類最好將構(gòu)造器私有化。 private GameUtil() { } public static Image getImage(String path) { BufferedImage bi = null ; try { URL u = GameUtil. class .getClassLoader().getResource(path); bi = ImageIO.read(u); } catch (IOException e) { e.printStackTrace(); } return bi; } } |
用來存儲常量的類:
1
2
3
4
5
6
|
package sc.wh.game; public class Constants { public static int WIDTH = 500 ; public static int HEIGHT = 500 ; } |
所有游戲?qū)ο蟮母割?
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
|
package sc.wh.game; import java.awt.Graphics; import java.awt.Image; import java.awt.Rectangle; // 游戲父類 public class GameObject { Image img; // 創(chuàng)建img對象 double x,y; // 坐標 int speed; // 速度 int width,height; // 寬高 // 畫圖方法 public void drawSelf(Graphics g) { g.drawImage(img,( int )x,( int )y, null ); } // 構(gòu)造方法 public GameObject(Image img, double x, double y, int speed, int width, int height) { super (); this .img = img; this .x = x; this .y = y; this .speed = speed; this .width = width; this .height = height; } public GameObject(Image img, double x, double y) { super (); this .img = img; this .x = x; this .y = y; } public GameObject() { } // 根據(jù)物體所在位置和寬度高度,返回物體所在的矩形,便與后續(xù)的碰撞檢測 public Rectangle getRect() { return new Rectangle(( int )x,( int )y,width,height); } } |
飛機類:
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
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
|
package sc.wh.game; import java.awt.Graphics; import java.awt.Image; import java.awt.event.KeyEvent; // 飛機類,繼承自游戲類,擁有游戲類對應(yīng)的方法和屬性 public class Plane extends GameObject{ // 當有鍵盤事件時,判斷飛機移動的方向 boolean left,right,up,down; // 飛機移動的速度 int speed = 5; // 用于判斷飛機是否存活 boolean live = true ; // 畫飛機的方法,可根據(jù)鍵盤事件設(shè)置(left,right...)布爾值實時調(diào)整飛機位置 public void drawSelf(Graphics g) { // 如果飛機存活,才調(diào)用畫圖方法 if (live) { if (right) { x += speed; } if (left) { x -= speed; } if (up) { y -= speed; } if (down) { y += speed; } if (x<= 0 ) { x = 0 ; } else if (x >= 460 ) { x = 460 ; } if (y <= 40 ) { y = 40 ; } else if (y >= 470 ) { y = 470 ; } // 根據(jù)位置畫圖 g.drawImage(img,( int )x,( int )y, null ); } } // 構(gòu)造方法 public Plane(Image img, double x, double y) { this .img = img; this .x = x; this .y = y; // 根據(jù)img對象的get..方法獲取圖片大小,用于矩形實現(xiàn)碰撞檢測 this .width = img.getWidth( null ); this .height = img.getHeight( null ); } // 鍵盤按下時,會調(diào)用此方法來設(shè)置移動的方向 public void addDirection(KeyEvent e) { // getKeyCode可以獲取按下鍵盤對應(yīng)特定的值 switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: left = true ; break ; case KeyEvent.VK_RIGHT: right = true ; break ; case KeyEvent.VK_UP: up = true ; break ; case KeyEvent.VK_DOWN: down = true ; break ; } } // 鍵盤松開時,會調(diào)用此方法來設(shè)置取消移動的方向 public void minusDirection(KeyEvent e) { // getKeyCode可以獲取按下鍵盤對應(yīng)特定的值 switch (e.getKeyCode()) { case KeyEvent.VK_LEFT: left = false ; break ; case KeyEvent.VK_RIGHT: right = false ; break ; case KeyEvent.VK_UP: up = false ; break ; case KeyEvent.VK_DOWN: down = false ; break ; } } } |
炮彈類:
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
|
package sc.wh.game; import java.awt.Color; import java.awt.Graphics; // 炮彈類 public class Shell extends GameObject{ double degree; // 炮彈移動角度 // 構(gòu)造方法 public Shell() { x = 200 ; // 設(shè)置炮彈的初始位置 y = 200 ; width = 10 ; // 設(shè)置炮彈的大小 height = 10 ; speed = 3 ; // 設(shè)置炮彈的速度 degree = Math.random() * Math.PI * 2 ; // 隨機設(shè)置炮彈的初始角度 } // 畫炮彈的方法 public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.YELLOW); // 設(shè)置顏色 if (x <= 0 || x >= Constants.WIDTH-width- 10 ) { degree = Math.PI - degree; // 當碰撞水平地圖邊界后,反轉(zhuǎn)角度 } if (y<= 40 || y >= Constants.HEIGHT-height) { degree = -degree; // 當碰撞垂直地圖后,反轉(zhuǎn)角度 } // 填充一個圓作為炮彈 g.fillOval(( int )x, ( int )y, width, height); // 根據(jù)角度設(shè)置炮彈移動的位置 x += speed*Math.cos(degree); y += speed*Math.sin(degree); g.setColor(c); } } |
顯示爆炸效果的類:
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
|
package sc.wh.game; import java.awt.Graphics; import java.awt.Image; public class Explode { // 記錄爆炸位置 double x,y; // 創(chuàng)建爆炸數(shù)組,static保證圖片只加載一次 static Image[] imgs = new Image[ 16 ]; // 靜態(tài)初始化塊,初始化類的時候會自動調(diào)用 static { for ( int i= 0 ;i< 16 ;i++){ // 挨個將爆炸圖片對象獲取到,并加入數(shù)組 imgs[i] = GameUtil.getImage( "images/explode/e" +(i+ 1 )+ ".gif" ); imgs[i].getWidth( null ); } } // 用來記錄當前加載的圖片 int count; // 畫爆炸效果 public void draw(Graphics g){ if (count<= 15 ){ // 輪播逐個畫爆炸的圖片 g.drawImage(imgs[count], ( int )x, ( int )y, null ); count++; } } // 構(gòu)造方法設(shè)置爆炸位置 public Explode( double x, double y){ this .x = x; this .y = y; } } |
游戲效果圖
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持服務(wù)器之家。
原文鏈接:https://blog.csdn.net/qq_46456049/article/details/108648689