本文實例為大家分享了java實現飛機游戲的具體代碼,供大家參考,具體內容如下
MyGameFrame類:
主要的調用類
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 { // 調用工具類的getImage方法加載圖片對象 Image planeImg = GameUtil.getImage( "images/plane.png" ); Image bg = GameUtil.getImage( "images/bg.jpg" ); // 創建飛機,設置初始位置 Plane plane = new Plane(planeImg, 250 , 250 ); // 創建炮彈組 Shell shells[] = new Shell[ 50 ]; // 設置爆炸效果類的對象的引用 Explode bao; // 游戲開始時間 Date startTime = new Date(); // 游戲結束時間 Date endTime; // 游戲進行的時間 int period; // 記錄爆炸效果顯示的圖片 int BaoCount = 0 ; // 在窗口畫圖方法,由repaint方法自動調用 @Override public void paint(Graphics g) { // 會自動被調用,g相當于一支畫筆 Color c = g.getColor(); // 畫背景 g.drawImage(bg, 0 , 0 , null ); // 調用飛機類的畫圖方法并畫飛機 plane.drawSelf(g); // 畫炮彈組中的炮彈 for ( int i= 0 ;i<shells.length;i++) { // 調用炮彈對象的draw方法 shells[i].draw(g); // 獲取炮彈所在矩形位置并調用intersects判斷兩矩形是否相交 boolean peng = shells[i].getRect().intersects(plane.getRect()); if (peng) { // 如果相交則設置飛機存活狀態為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 ) { // 調用爆炸效果顯示類的畫圖方法,每次調用只畫一張圖 bao.draw(g); BaoCount++; } } // 如果飛機未存活則顯示游戲時間 if (!plane.live) { // 創建字體對象 Font f = new Font( "宋體" ,Font.BOLD, 50 ); // 設置字體 g.setFont(f); // 設置字體顏色 g.setColor(Color.RED); // 顯示游戲結束時間 g.drawString( "游戲時間:" + period + "秒" , 100 , 250 ); } } g.setColor(c); } // 繼承Thread線程類 class PaintThread extends Thread{ // 線程開始后會自動調用run方法 @Override public void run() { while ( true ) { // 調用repaint窗口畫圖方法,此方法會自動調用paint方法 repaint(); try { // 控制一秒25次在窗口畫圖的方法 Thread.sleep( 40 ); } catch (InterruptedException e) { e.printStackTrace(); } } } } // 創建鍵盤檢測內部類,并繼承鍵盤監聽類 class KeyMonitor extends KeyAdapter{ // 檢測鍵盤按下事件,調用飛機類對應的方法 @Override public void keyPressed(KeyEvent e) { // KeyEvent鍵盤檢測類 plane.addDirection(e); } // 檢測鍵盤釋放事件,調用飛機類對應的方法 @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 ); //增加關閉窗口監聽,這樣用戶點擊右上角關閉圖標,可以關閉游戲程序 this .addWindowListener( new WindowAdapter() { @Override public void windowClosing(WindowEvent e){ System.exit( 0 ); } }); // 創建在窗口中畫圖線程并調用 new PaintThread().start(); // 將KeyMonitor類的對象加入鍵盤監控檢測,對應的事件會自動調用此類對應的方法 addKeyListener( new KeyMonitor()); // 創建炮彈,加入炮彈數組 for ( int i= 0 ;i<shells.length;i++) { shells[i] = new Shell(); } } public static void main(String[] args) { MyGameFrame f = new MyGameFrame(); // 調用畫窗口方法 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 { // 工具類最好將構造器私有化。 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 ; } |
所有游戲對象的父類:
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; // 創建img對象 double x,y; // 坐標 int speed; // 速度 int width,height; // 寬高 // 畫圖方法 public void drawSelf(Graphics g) { g.drawImage(img,( int )x,( int )y, null ); } // 構造方法 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() { } // 根據物體所在位置和寬度高度,返回物體所在的矩形,便與后續的碰撞檢測 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; // 飛機類,繼承自游戲類,擁有游戲類對應的方法和屬性 public class Plane extends GameObject{ // 當有鍵盤事件時,判斷飛機移動的方向 boolean left,right,up,down; // 飛機移動的速度 int speed = 5; // 用于判斷飛機是否存活 boolean live = true ; // 畫飛機的方法,可根據鍵盤事件設置(left,right...)布爾值實時調整飛機位置 public void drawSelf(Graphics g) { // 如果飛機存活,才調用畫圖方法 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 ; } // 根據位置畫圖 g.drawImage(img,( int )x,( int )y, null ); } } // 構造方法 public Plane(Image img, double x, double y) { this .img = img; this .x = x; this .y = y; // 根據img對象的get..方法獲取圖片大小,用于矩形實現碰撞檢測 this .width = img.getWidth( null ); this .height = img.getHeight( null ); } // 鍵盤按下時,會調用此方法來設置移動的方向 public void addDirection(KeyEvent e) { // getKeyCode可以獲取按下鍵盤對應特定的值 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 ; } } // 鍵盤松開時,會調用此方法來設置取消移動的方向 public void minusDirection(KeyEvent e) { // getKeyCode可以獲取按下鍵盤對應特定的值 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; // 炮彈移動角度 // 構造方法 public Shell() { x = 200 ; // 設置炮彈的初始位置 y = 200 ; width = 10 ; // 設置炮彈的大小 height = 10 ; speed = 3 ; // 設置炮彈的速度 degree = Math.random() * Math.PI * 2 ; // 隨機設置炮彈的初始角度 } // 畫炮彈的方法 public void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.YELLOW); // 設置顏色 if (x <= 0 || x >= Constants.WIDTH-width- 10 ) { degree = Math.PI - degree; // 當碰撞水平地圖邊界后,反轉角度 } if (y<= 40 || y >= Constants.HEIGHT-height) { degree = -degree; // 當碰撞垂直地圖后,反轉角度 } // 填充一個圓作為炮彈 g.fillOval(( int )x, ( int )y, width, height); // 根據角度設置炮彈移動的位置 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; // 創建爆炸數組,static保證圖片只加載一次 static Image[] imgs = new Image[ 16 ]; // 靜態初始化塊,初始化類的時候會自動調用 static { for ( int i= 0 ;i< 16 ;i++){ // 挨個將爆炸圖片對象獲取到,并加入數組 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++; } } // 構造方法設置爆炸位置 public Explode( double x, double y){ this .x = x; this .y = y; } } |
游戲效果圖
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持服務器之家。
原文鏈接:https://blog.csdn.net/qq_46456049/article/details/108648689