您現在的位置是:首頁 > 手機遊戲首頁手機遊戲
java實現飛機大戰小遊戲(原始碼+註釋)
- 2021-08-01
飛機大戰鼠件碎片怎麼獲得
整體的思路和博主其他博文
java實現貪吃蛇小遊戲(原始碼+註釋)
和
java實現2048小遊戲(原始碼+註釋)
是一樣的,都是利用Frame建立窗體,利用Panel新增元件,提前規劃好佈局,呼叫滑鼠和鍵盤監聽,引用圖片元素。
此處的思路在於不斷的重新整理敵機集合和子彈集合來實現動態效果。
文章目錄
一。工程檔案
二。Main。java
三。GameFrame。java
四。GamePanel。java
五。FlyObject。java
六。Hero。java
七。Ep。java
八。Fire。java
九。App。java
十。效果演示
一。工程檔案
二。Main。java
主函式,實現類
package
ui
;
//主函式實現
public
class
Main
{
public
static
void
main
(
String
[
]
args
)
{
//建立窗體
GameFrame frame
=
new
GameFrame
(
)
;
//建立面板
GamePanel panel
=
new
GamePanel
(
frame
)
;
//呼叫開始遊戲的方法啟動遊戲
panel
。
action
(
)
;
//將面板加入到窗體中
frame
。
add
(
panel
)
;
//設定窗體可見
frame
。
setVisible
(
true
)
;
}
}
三。GameFrame。java
窗體類,繪製窗體
package
ui
;
import
javax
。
swing
。
*
;
//建立窗體
public
class
GameFrame
extends
JFrame
{
//構造方法,初始化窗體屬性
public
GameFrame
(
)
{
//設定標題,來源於JFrame
setTitle
(
“飛機大戰”
)
;
//設定大小
setSize
(
512
,
768
)
;
//設定居中
setLocationRelativeTo
(
null
)
;
//設定窗體可見
//setVisible(true);
//不允許玩家修改介面大小
setResizable
(
false
)
;
//設定預設的關閉選項
setDefaultCloseOperation
(
JFrame
。
EXIT_ON_CLOSE
)
;
}
}
四。GamePanel。java
畫布類,用於勾勒元素
package
ui
;
import
javax
。
swing
。
*
;
import
java
。
awt
。
*
;
import
java
。
awt
。
event
。
KeyEvent
;
import
java
。
awt
。
event
。
KeyListener
;
import
java
。
awt
。
event
。
MouseAdapter
;
import
java
。
awt
。
event
。
MouseEvent
;
import
java
。
awt
。
image
。
BufferedImage
;
import
java
。
util
。
ArrayList
;
import
java
。
util
。
List
;
import
java
。
util
。
Random
;
//自定義遊戲面板(建立畫布)
public
class
GamePanel
extends
JPanel
{
//定義背景圖
BufferedImage bg
;
//構造遊戲機
Hero hero
=
new
Hero
(
)
;
//敵機集合
List
<
Ep
>
eps
=
new
ArrayList
<
Ep
>
(
)
;
//彈藥集合
List
<
Fire
>
fs
=
new
ArrayList
<
Fire
>
(
)
;
//定義分數
int
score
;
//設定遊戲開關
Boolean gameover
=
false
;
//設定火力
int
power
=
1
;
//動作函式,描繪場景內飛行物的運動狀態
public
void
action
(
)
{
//建立執行緒(基本模板)
new
Thread
(
)
{
public
void
run
(
)
{
//無線迴圈建立
while
(
true
)
{
//判斷如果遊戲沒有失敗,則執行以下操作
if
(
!
gameover
)
{
//敵機進場
epEnter
(
)
;
//呼叫敵機移動方法
epMove
(
)
;
//發射子彈
shoot
(
)
;
//子彈移動
fireMove
(
)
;
//判斷子彈是否擊中敵機
shootEp
(
)
;
//檢測敵機是否撞到遊戲機
hit
(
)
;
}
//每執行一次,執行緒休眠一會兒
try
{
Thread
。
sleep
(
10
)
;
}
catch
(
InterruptedException
e
)
{
e
。
printStackTrace
(
)
;
}
//重繪介面
repaint
(
)
;
}
}
}
。
start
(
)
;
//讓執行緒開始執行
}
//每執行20次,釋放一個敵機,建立計數器計數
int
index
=
0
;
protected
void
epEnter
(
)
{
index
++
;
//建立敵機
if
(
index
>=
20
)
{
//建立敵機
Ep e
=
new
Ep
(
)
;
//加入集合
eps
。
add
(
e
)
;
//重置計數器
index
=
0
;
}
}
//讓敵機移動
protected
void
epMove
(
)
{
//遍歷敵機集合,依次移動
for
(
int
i
=
0
;
i
<
eps
。
size
(
)
;
i
++
)
{
//獲取集合中敵機
Ep e
=
eps
。
get
(
i
)
;
//呼叫敵機類中的移動方法
e
。
move
(
)
;
}
}
//每執行20次,建立一顆子彈,建立計數器計數
int
findex
=
0
;
protected
void
shoot
(
)
{
findex
++
;
if
(
findex
>=
20
)
{
//根據火力判斷子彈行數
//一排子彈
if
(
power
==
1
)
{
//建立子彈
Fire fire1
=
new
Fire
(
hero
。
x
+
45
,
hero
。
y
,
1
)
;
//將子彈存入子彈集合中
fs
。
add
(
fire1
)
;
}
//兩排子彈
else
if
(
power
==
2
)
{
//建立子彈
Fire fire1
=
new
Fire
(
hero
。
x
+
15
,
hero
。
y
,
0
)
;
//將子彈存入子彈集合中
fs
。
add
(
fire1
)
;
//建立子彈
Fire fire2
=
new
Fire
(
hero
。
x
+
75
,
hero
。
y
,
2
)
;
//將子彈存入子彈集合中
fs
。
add
(
fire2
)
;
}
//三排子彈
else
{
//建立子彈
Fire fire1
=
new
Fire
(
hero
。
x
+
15
,
hero
。
y
,
0
)
;
//將子彈存入子彈集合中
fs
。
add
(
fire1
)
;
//建立子彈
Fire fire2
=
new
Fire
(
hero
。
x
+
75
,
hero
。
y
,
2
)
;
//將子彈存入子彈集合中
fs
。
add
(
fire2
)
;
//建立子彈
Fire fire3
=
new
Fire
(
hero
。
x
+
45
,
hero
。
y
-
10
,
1
)
;
//將子彈存入子彈集合中
fs
。
add
(
fire3
)
;
}
//使計數器歸0
findex
=
0
;
}
}
//讓子彈移動
protected
void
fireMove
(
)
{
//遍歷子彈集合
for
(
int
i
=
0
;
i
<
fs
。
size
(
)
;
i
++
)
{
//獲取每一顆子彈位置
Fire f
=
fs
。
get
(
i
)
;
//依次移動每一顆子彈
f
。
move
(
)
;
}
}
//判斷子彈是否擊中敵機
protected
void
shootEp
(
)
{
//遍歷所有子彈
for
(
int
i
=
0
;
i
<
fs
。
size
(
)
;
i
++
)
{
//獲取每一顆子彈
Fire f
=
fs
。
get
(
i
)
;
//判斷一顆子彈是否擊中敵機
bang
(
f
)
;
}
}
//判斷一顆子彈是否擊中敵機
protected
void
bang
(
Fire f
)
{
for
(
int
i
=
0
;
i
<
eps
。
size
(
)
;
i
++
)
{
//取出每一張敵機
Ep e
=
eps
。
get
(
i
)
;
//判斷這個子彈是否擊中敵機
if
(
e
。
shootBy
(
f
)
&&
e
。
type
!=
15
)
{
//判斷遊戲機機是否擊中道具機
if
(
e
。
type
==
12
)
{
//火力增加
power
++
;
//如果火力值大於三,增加血量
if
(
power
>
3
)
{
//恢復血量
if
(
hero
。
hp
<
3
)
{
hero
。
hp
++
;
}
//使遊戲機血量不超過3
power
=
3
;
}
}
//如果敵機被子彈擊中
//敵機消失
eps
。
remove
(
e
)
;
//刪除子彈
fs
。
remove
(
f
)
;
//增加分數
score
+=
10
;
}
}
}
//檢測敵機是否撞到主機
protected
void
hit
(
)
{
for
(
int
i
=
0
;
i
<
eps
。
size
(
)
;
i
++
)
{
//獲取每一個敵機
Ep e
=
eps
。
get
(
i
)
;
//呼叫敵機的方法判斷
if
(
e
。
shootBy
(
hero
)
)
{
//刪除敵機
eps
。
remove
(
e
)
;
//主機血量減少
hero
。
hp
——
;
//火力恢復初始值
power
=
1
;
//分數增加
score
+=
10
;
//當主機血量減少到0時遊戲結束
if
(
hero
。
hp
==
0
)
{
gameover
=
true
;
}
}
}
}
//建構函式
public
GamePanel
(
GameFrame frame
)
{
//設定背景
bg
=
App
。
getImg
(
“/img/bg2。jpg”
)
;
//建立滑鼠監聽和滑鼠介面卡
MouseAdapter adapter
=
new
MouseAdapter
(
)
{
//點選滑鼠時會執行的程式碼
@Override
public
void
mouseClicked
(
MouseEvent e
)
{
//遊戲結束時候,點選螢幕時重新開始遊戲
if
(
gameover
)
{
//重新初始化主機
hero
=
new
Hero
(
)
;
//重置遊戲開關
gameover
=
false
;
//分數清0
score
=
0
;
//清空敵機集合
eps
。
clear
(
)
;
//隨機背景圖
Random random
=
new
Random
(
)
;
int
index
=
random
。
nextInt
(
5
)
+
1
;
bg
=
App
。
getImg
(
“/img/bg”
+
index
+
“。jpg”
)
;
//重新繪製
repaint
(
)
;
}
}
//確定需要監聽的事件,此處監聽滑鼠移動事件
@Override
public
void
mouseMoved
(
MouseEvent e
)
{
//讓遊戲機的橫縱座標等於滑鼠的移動座標
//獲取滑鼠的橫縱座標
int
mx
=
e
。
getX
(
)
;
int
my
=
e
。
getY
(
)
;
//傳遞座標
if
(
!
gameover
)
{
//使滑鼠座標正好位於圖片中央
hero
。
moveToMouse
(
mx
-
114
/
2
,
my
-
93
/
2
)
;
}
//重新繪製介面
repaint
(
)
;
}
}
;
//將介面卡加入到監聽器中
addMouseListener
(
adapter
)
;
addMouseMotionListener
(
adapter
)
;
//使用鍵盤監聽,建立鍵盤介面卡
KeyListener kd
=
new
KeyListener
(
)
{
@Override
public
void
keyTyped
(
KeyEvent e
)
{
}
//當鍵盤被按下是觸發
@Override
public
void
keyPressed
(
KeyEvent e
)
{
int
keyCode
=
e
。
getKeyCode
(
)
;
//上鍵
if
(
keyCode
==
KeyEvent
。
VK_UP
)
{
hero
。
y
-=
10
;
}
//下鍵
else
if
(
keyCode
==
KeyEvent
。
VK_DOWN
)
{
hero
。
y
+=
10
;
}
//左鍵
else
if
(
keyCode
==
KeyEvent
。
VK_LEFT
)
{
hero
。
x
-=
10
;
}
//右鍵
else
if
(
keyCode
==
KeyEvent
。
VK_RIGHT
)
{
hero
。
x
+=
10
;
}
repaint
(
)
;
}
@Override
public
void
keyReleased
(
KeyEvent e
)
{
}
}
;
//將介面卡加入窗體的監聽器中
frame
。
addKeyListener
(
kd
)
;
}
//畫圖方法
@Override
public
void
paint
(
Graphics g
)
{
//呼叫父類中的一些渲染方法
super
。
paint
(
g
)
;
//畫背景
g
。
drawImage
(
bg
,
0
,
0
,
null
)
;
//畫敵機
for
(
int
i
=
0
;
i
<
eps
。
size
(
)
;
i
++
)
{
Ep ep
=
eps
。
get
(
i
)
;
g
。
drawImage
(
ep
。
img
,
ep
。
x
,
ep
。
y
,
null
)
;
}
//畫子彈
for
(
int
i
=
0
;
i
<
fs
。
size
(
)
;
i
++
)
{
Fire fire
=
fs
。
get
(
i
)
;
g
。
drawImage
(
fire
。
img
,
fire
。
x
,
fire
。
y
,
fire
。
w
,
fire
。
h
,
null
)
;
}
//畫分數
g
。
setColor
(
Color
。
white
)
;
//設定字型型號,設定加粗,設定字型大小
g
。
setFont
(
new
Font
(
“\u6977\u4F53”
,
Font
。
BOLD
,
30
)
)
;
//顯示分數
g
。
drawString
(
“分數:”
+
score
,
10
,
30
)
;
//畫遊戲機
g
。
drawImage
(
hero
。
img
,
hero
。
x
,
hero
。
y
,
null
)
;
//畫遊戲機血量
for
(
int
i
=
0
;
i
<
hero
。
hp
;
i
++
)
{
g
。
drawImage
(
hero
。
img
,
380
+
i
*
35
,
5
,
30
,
30
,
null
)
;
}
//畫遊戲結束
if
(
gameover
)
{
//設定字型顏色為紅色
g
。
setColor
(
Color
。
red
)
;
//設定字型型號,設定加粗,設定字型大小
g
。
setFont
(
new
Font
(
“楷體”
,
Font
。
BOLD
,
35
)
)
;
//顯示字型
g
。
drawString
(
“GAMEOVER”
,
170
,
300
)
;
//設定字型顏色為綠色
g
。
setColor
(
Color
。
green
)
;
//設定字型型號,設定加粗,設定字型大小
g
。
setFont
(
new
Font
(
“楷體”
,
Font
。
BOLD
,
29
)
)
;
//顯示字型
g
。
drawString
(
“yh提醒你點選螢幕任意位置重新開始”
,
10
,
350
)
;
}
//重新繪製介面
repaint
(
)
;
}
}
五。FlyObject。java
飛行物類,設定飛行物特性
package
ui
;
import
java
。
awt
。
image
。
BufferedImage
;
//飛行物具有共同特點,故抽離成父類
public
class
FlyObject
{
//均採用照片素材
BufferedImage img
;
//位置的橫座標
int
x
;
//位置的縱座標
int
y
;
//圖片元素的寬度
int
w
;
//圖片元素的高度
int
h
;
}
六。Hero。java
主機類,設定遊戲時候操控的飛機屬性
package
ui
;
import
java
。
awt
。
image
。
BufferedImage
;
//遊戲機
public
class
Hero
extends
FlyObject
{
//設定遊戲機血量
int
hp
;
//建構函式
public
Hero
(
)
{
//獲取遊戲機元素
img
=
App
。
getImg
(
“/img/hero。png”
)
;
//確認初始位置
x
=
200
;
y
=
500
;
//獲取遊戲機圖片元素的寬和高
w
=
img
。
getWidth
(
)
;
h
=
img
。
getHeight
(
)
;
//設定初始血量為3
hp
=
3
;
}
//根據傳入引數移動相應位置
public
void
moveToMouse
(
int
mx
,
int
my
)
{
x
=
mx
;
y
=
my
;
}
}
七。Ep。java
敵機類
package
ui
;
import
javax
。
swing
。
*
;
import
java
。
awt
。
image
。
BufferedImage
;
import
java
。
util
。
ArrayList
;
import
java
。
util
。
List
;
import
java
。
util
。
Random
;
//敵機類
public
class
Ep
extends
FlyObject
{
//設定敵機速度
int
sp
;
//設定敵機型別,不同的敵機型別有不同的屬性
int
type
;
//建構函式
public
Ep
(
)
{
//引入隨機數隨機呼叫敵機
Random random
=
new
Random
(
)
;
//呼叫[1,15]範圍內的敵機
int
index
=
random
。
nextInt
(
15
)
+
1
;
//儲存敵機型別
type
=
index
;
//如果序號小於10,則補充前導0,實質符合圖片命名規律
String path
=
“/img/ep”
+
(
index
<
10
?
“0”
:
“”
)
+
index
+
“。png”
;
//根據路徑呼叫方法類函式獲取圖片io流
img
=
App
。
getImg
(
path
)
;
//確定敵機位置
//獲取敵機照片元素寬度引數
w
=
img
。
getWidth
(
)
;
//邊界長減去照片寬度,防止照片越界
x
=
random
。
nextInt
(
512
-
w
)
;
y
=
0
;
//設定速度
sp
=
17
-
index
;
}
//設定敵機移動方法
public
void
move
(
)
{
//如果敵機型別為5,則向左方傾斜移動
if
(
type
==
5
)
{
x
-=
5
;
y
+=
sp
;
}
//如果敵機型別為5,則向右方傾斜移動
else
if
(
type
==
6
)
{
x
+=
5
;
y
+=
sp
;
}
//如果是其他型別,則正常向下移動
else
{
y
+=
sp
;
}
}
//判斷敵機是否被子彈擊中
public
boolean
shootBy
(
Fire f
)
{
//獲取圖片元素屬性,確定相應的座標演算法,判斷是否滿足條件,滿足則被擊中
Boolean hit
=
x
<=
f
。
x
+
f
。
w
&&
x
>
f
。
x
-
w
&&
y
<=
f
。
y
+
f
。
h
&&
y
>
f
。
y
-
h
;
return
hit
;
}
//判斷敵機是否被玩家機擊中
public
boolean
shootBy
(
Hero f
)
{
//獲取圖片元素屬性,確定相應的座標演算法,判斷是否滿足條件,滿足則被擊中
Boolean hit
=
x
<=
f
。
x
+
f
。
w
&&
x
>
f
。
x
-
w
&&
y
<=
f
。
y
+
f
。
h
&&
y
>
f
。
y
-
h
;
return
hit
;
}
}
八。Fire。java
子彈類
package
ui
;
public
class
Fire
extends
FlyObject
{
//子彈當前移動方向,0為左上角飛,1垂直飛,2右上角飛
int
dir
;
//構造方法,初始化子彈
public
Fire
(
int
hx
,
int
hy
,
int
dir
)
{
//獲取子彈的圖片
img
=
App
。
getImg
(
“/img/fire。png”
)
;
//確定圖片的大小,此處把子彈大小縮小了4倍
w
=
img
。
getWidth
(
)
/
4
;
h
=
img
。
getHeight
(
)
/
4
;
//根據建構函式傳進來的引數設定子彈的位置以及子彈的方向
x
=
hx
;
y
=
hy
;
this
。
dir
=
dir
;
}
//子彈的移動方法
public
void
move
(
)
{
//左上角飛
if
(
dir
==
0
)
{
x
-=
1
;
y
-=
10
;
}
//垂直上飛
else
if
(
dir
==
1
)
{
y
-=
10
;
}
//右上角飛
else
if
(
dir
==
2
)
{
x
+=
1
;
y
-=
10
;
}
}
}
九。App。java
方法類
package
ui
;
import
javax
。
imageio
。
ImageIO
;
import
javax
。
swing
。
*
;
import
java
。
awt
。
image
。
BufferedImage
;
import
java
。
io
。
IOException
;
import
java
。
io
。
InputStream
;
//處理圖片的工具類
//此處我定義了兩種獲取圖片的方法,可以對照參考
public
class
App
{
//static可以公用所有物件都共用該方法,並且可以不依賴物件實現
public
static
BufferedImage
getImg
(
String path
)
{
//用try方法捕獲異常
try
{
//io流,輸送資料的管道
BufferedImage img
=
ImageIO
。
read
(
App
。
class
。
getResource
(
path
)
)
;
return
img
;
}
//異常處理,列印異常
catch
(
IOException
e
)
{
e
。
printStackTrace
(
)
;
}
//沒找到則返回空
return
null
;
}
//此處與貪吃蛇小遊戲的呼叫方法是一樣的
public
static
ImageIcon
getImg2
(
String path
)
{
InputStream is
;
//從主類檔案所在的路徑尋找相應路徑的圖片
is
=
App
。
class
。
getClassLoader
(
)
。
getResourceAsStream
(
path
)
;
//用try方法捕獲異常
try
{
return
new
ImageIcon
(
ImageIO
。
read
(
is
)
)
;
}
//異常處理,列印異常
catch
(
IOException
e
)
{
e
。
printStackTrace
(
)
;
}
//沒找到則返回空
return
null
;
}
}
十。效果演示
,https://blog。csdn。net/qq_50216270/article/details/116091267