Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
Guangjun Jia
FlappyBird
Commits
5e5ba4bf
Commit
5e5ba4bf
authored
Jul 11, 2020
by
kingyu
Committed by
kingyuluk
Jul 11, 2020
Browse files
feat: 添加悬浮型水管
parent
d7b64a56
Changes
11
Hide whitespace changes
Inline
Side-by-side
CHANGELOG.md
View file @
5e5ba4bf
...
...
@@ -2,6 +2,15 @@
All notable changes to this project will be documented in this file. See
[
standard-version
](
https://github.com/conventional-changelog/standard-version
)
for commit guidelines.
## 1.1.0 (2020-07-11)
### Features
*
添加悬浮型水管 (
[
cc80ec9
](
https://github.com/kingyuluk/FlappyBird/commit/cc80ec9845194dc5326a8d70799b847b6821f751
)
)
*
具备原版的游戏功能 (
[
264a7c3
](
https://github.com/kingyuluk/FlappyBird/commit/264a7c320c894851aa3e6c8c30ffcddf3ce1f78a
)
)
## 1.0.0 (2020-07-10)
...
...
README.md
View file @
5e5ba4bf
...
...
@@ -17,8 +17,14 @@ com.bird.util 自定义的工具
# Version History
1.
0.0 - July 1
1
, 2020
1.
0.0 - July 1
0
, 2020
*
具备完整的游戏功能
1.
1.0 - July 11, 2020
*
添加了悬浮型的水管
# Notes
文本编码格式为UTF-8,若注释出现乱码请修改编译器的文本编码格式
# Contact
*
email:
<kingyuluk@hotmail.com>
src/com/bird/main/Bird.java
View file @
5e5ba4bf
...
...
@@ -44,7 +44,7 @@ public class Bird {
// 在构造器中对资源初始化
public
Bird
()
{
timing
=
new
GameTime
();
// 计时器
timing
=
GameTime
.
getInstance
();
// 计时器
// 读取小鸟图片资源
birdImgs
=
new
BufferedImage
[
STATE_COUNT
][
IMG_COUNT
];
...
...
src/com/bird/main/GameElementLayer.java
View file @
5e5ba4bf
...
...
@@ -17,12 +17,12 @@ import com.bird.util.GameUtil;
public
class
GameElementLayer
{
private
List
<
Pipe
>
pipes
;
// 水管的容器
//构造器
//
构造器
public
GameElementLayer
()
{
pipes
=
new
ArrayList
<>();
}
//绘制方法
//
绘制方法
public
void
draw
(
Graphics
g
,
Bird
bird
)
{
// 遍历水管容器,如果可见则绘制,不可见则归还
for
(
int
i
=
0
;
i
<
pipes
.
size
();
i
++)
{
...
...
@@ -46,7 +46,7 @@ public class GameElementLayer {
*/
public
static
final
int
VERTICAL_INTERVAL
=
Constant
.
FRAME_HEIGHT
/
5
;
public
static
final
int
HORIZONTAL_INTERVAL
=
Constant
.
FRAME_HEIGHT
>>
2
;
public
static
final
int
MIN_HEIGHT
=
(
Constant
.
FRAME_HEIGHT
)
>>
3
;
public
static
final
int
MIN_HEIGHT
=
Constant
.
FRAME_HEIGHT
>>
3
;
public
static
final
int
MAX_HEIGHT
=
((
Constant
.
FRAME_HEIGHT
)
>>
3
)
*
5
;
private
void
pipeBornLogic
(
Bird
bird
)
{
...
...
@@ -58,37 +58,152 @@ public class GameElementLayer {
// 若容器为空,则添加一对水管
int
topHeight
=
GameUtil
.
getRandomNumber
(
MIN_HEIGHT
,
MAX_HEIGHT
+
1
);
// 随机生成水管高度
Pipe
top
=
PipePool
.
get
();
Pipe
top
=
PipePool
.
get
(
"Pipe"
);
top
.
setAttribute
(
Constant
.
FRAME_WIDTH
,
-
Constant
.
TOP_PIPE_LENGTHENING
,
topHeight
+
Constant
.
TOP_PIPE_LENGTHENING
,
Pipe
.
TYPE_TOP_NORMAL
,
true
);
Pipe
bottom
=
PipePool
.
get
();
Pipe
bottom
=
PipePool
.
get
(
"Pipe"
);
bottom
.
setAttribute
(
Constant
.
FRAME_WIDTH
,
topHeight
+
VERTICAL_INTERVAL
,
Constant
.
FRAME_HEIGHT
-
topHeight
-
VERTICAL_INTERVAL
,
Pipe
.
TYPE_BOTTOM_NORMAL
,
true
);
pipes
.
add
(
top
);
pipes
.
add
(
bottom
);
}
else
{
// 判断最后一对水管是否完全进入游戏窗口
// 判断最后一对水管是否完全进入游戏窗口
,若进入则添加水管
Pipe
lastPipe
=
pipes
.
get
(
pipes
.
size
()
-
1
);
// 获得容器中最后一个水管
if
(
lastPipe
.
isInFrame
())
{
int
topHeight
=
GameUtil
.
getRandomNumber
(
MIN_HEIGHT
,
MAX_HEIGHT
+
1
);
// 随机生成水管高度
int
x
=
lastPipe
.
getX
()
+
HORIZONTAL_INTERVAL
;
//新水管的x坐标 = 最后一对水管的x坐标 + 水管的间隔
if
(
lastPipe
.
isInFrame
())
{
// 根据游戏分数难度递增
if
(
GameTime
.
getInstance
().
TimeToScore
()
<
Constant
.
HOVER_MOVING_SCORE
)
{
try
{
if
(
GameUtil
.
isInProbability
(
2
,
5
))
{
// 40%的概率生成悬浮的普通水管
addHoverPipe
(
lastPipe
);
}
else
{
addNormalPipe
(
lastPipe
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
else
{
try
{
if
(
GameUtil
.
isInProbability
(
1
,
4
))
{
// 1/4的概率生成普通水管
if
(
GameUtil
.
isInProbability
(
1
,
2
))
// 生成普通水管和悬浮水管的概率
addNormalPipe
(
lastPipe
);
else
addHoverPipe
(
lastPipe
);
}
else
{
if
(
GameUtil
.
isInProbability
(
1
,
3
))
// 生成移动水管和移动悬浮水管的概率
addMovingHoverPipe
(
lastPipe
);
else
addMovingNormalPipe
(
lastPipe
);
}
}
catch
(
Exception
e
)
{
e
.
printStackTrace
();
}
}
Pipe
top
=
PipePool
.
get
();
top
.
setAttribute
(
x
,
-
Constant
.
TOP_PIPE_LENGTHENING
,
topHeight
+
Constant
.
TOP_PIPE_LENGTHENING
,
Pipe
.
TYPE_TOP_NORMAL
,
true
);
Pipe
bottom
=
PipePool
.
get
();
bottom
.
setAttribute
(
x
,
topHeight
+
VERTICAL_INTERVAL
,
Constant
.
FRAME_HEIGHT
-
topHeight
-
VERTICAL_INTERVAL
,
Pipe
.
TYPE_BOTTOM_NORMAL
,
true
);
pipes
.
add
(
top
);
pipes
.
add
(
bottom
);
}
}
}
/**
* 添加普通水管
*
* @param lastPipe
*/
private
void
addNormalPipe
(
Pipe
lastPipe
)
{
int
topHeight
=
GameUtil
.
getRandomNumber
(
MIN_HEIGHT
,
MAX_HEIGHT
+
1
);
// 随机生成水管高度
int
x
=
lastPipe
.
getX
()
+
HORIZONTAL_INTERVAL
;
// 新水管的x坐标 = 最后一对水管的x坐标 + 水管的间隔
// 概率生成移动的水管
Pipe
top
=
PipePool
.
get
(
"Pipe"
);
top
.
setAttribute
(
x
,
-
Constant
.
TOP_PIPE_LENGTHENING
,
topHeight
+
Constant
.
TOP_PIPE_LENGTHENING
,
Pipe
.
TYPE_TOP_NORMAL
,
true
);
Pipe
bottom
=
PipePool
.
get
(
"Pipe"
);
bottom
.
setAttribute
(
x
,
topHeight
+
VERTICAL_INTERVAL
,
Constant
.
FRAME_HEIGHT
-
topHeight
-
VERTICAL_INTERVAL
,
Pipe
.
TYPE_BOTTOM_NORMAL
,
true
);
pipes
.
add
(
top
);
pipes
.
add
(
bottom
);
}
/**
* 添加悬浮水管
*
* @param lastPipe
*/
private
void
addHoverPipe
(
Pipe
lastPipe
)
{
// 随机生成水管高度,屏幕高度的[1/4,1/6]
int
topHoverHeight
=
GameUtil
.
getRandomNumber
(
Constant
.
FRAME_HEIGHT
/
6
,
Constant
.
FRAME_HEIGHT
/
4
);
int
x
=
lastPipe
.
getX
()
+
HORIZONTAL_INTERVAL
;
// 新水管的x坐标 = 最后一对水管的x坐标 + 水管的间隔
int
y
=
GameUtil
.
getRandomNumber
(
Constant
.
FRAME_HEIGHT
/
12
,
Constant
.
FRAME_HEIGHT
/
6
);
// 随机水管的y坐标,窗口的[1/6,1/12]
int
type
=
Pipe
.
TYPE_HOVER_NORMAL
;
// 生成上部的悬浮水管
Pipe
topHover
=
PipePool
.
get
(
"Pipe"
);
topHover
.
setAttribute
(
x
,
y
,
topHoverHeight
,
type
,
true
);
// 生成下部的悬浮水管
int
bottomHoverHeight
=
Constant
.
FRAME_HEIGHT
-
2
*
y
-
topHoverHeight
-
VERTICAL_INTERVAL
;
Pipe
bottomHover
=
PipePool
.
get
(
"Pipe"
);
bottomHover
.
setAttribute
(
x
,
y
+
topHoverHeight
+
VERTICAL_INTERVAL
,
bottomHoverHeight
,
type
,
true
);
pipes
.
add
(
topHover
);
pipes
.
add
(
bottomHover
);
}
/**
* 添加移动的悬浮水管
*
* @param lastPipe
*/
private
void
addMovingHoverPipe
(
Pipe
lastPipe
)
{
// 随机生成水管高度,屏幕高度的[1/4,1/6]
int
topHoverHeight
=
GameUtil
.
getRandomNumber
(
Constant
.
FRAME_HEIGHT
/
6
,
Constant
.
FRAME_HEIGHT
/
4
);
int
x
=
lastPipe
.
getX
()
+
HORIZONTAL_INTERVAL
;
// 新水管的x坐标 = 最后一对水管的x坐标 + 水管的间隔
int
y
=
GameUtil
.
getRandomNumber
(
Constant
.
FRAME_HEIGHT
/
12
,
Constant
.
FRAME_HEIGHT
/
6
);
// 随机水管的y坐标,窗口的[1/6,1/12]
int
type
=
Pipe
.
TYPE_HOVER_HARD
;
// 生成上部的悬浮水管
Pipe
topHover
=
PipePool
.
get
(
"MovingPipe"
);
topHover
.
setAttribute
(
x
,
y
,
topHoverHeight
,
type
,
true
);
// 生成下部的悬浮水管
int
bottomHoverHeight
=
Constant
.
FRAME_HEIGHT
-
2
*
y
-
topHoverHeight
-
VERTICAL_INTERVAL
;
Pipe
bottomHover
=
PipePool
.
get
(
"MovingPipe"
);
bottomHover
.
setAttribute
(
x
,
y
+
topHoverHeight
+
VERTICAL_INTERVAL
,
bottomHoverHeight
,
type
,
true
);
pipes
.
add
(
topHover
);
pipes
.
add
(
bottomHover
);
}
/**
* 添加移动的普通水管
*
* @param lastPipe
*/
private
void
addMovingNormalPipe
(
Pipe
lastPipe
)
{
int
topHeight
=
GameUtil
.
getRandomNumber
(
MIN_HEIGHT
,
MAX_HEIGHT
+
1
);
// 随机生成水管高度
int
x
=
lastPipe
.
getX
()
+
HORIZONTAL_INTERVAL
;
// 新水管的x坐标 = 最后一对水管的x坐标 + 水管的间隔
Pipe
top
=
PipePool
.
get
(
"MovingPipe"
);
top
.
setAttribute
(
x
,
-
Constant
.
TOP_PIPE_LENGTHENING
,
topHeight
+
Constant
.
TOP_PIPE_LENGTHENING
,
Pipe
.
TYPE_TOP_HARD
,
true
);
Pipe
bottom
=
PipePool
.
get
(
"MovingPipe"
);
bottom
.
setAttribute
(
x
,
topHeight
+
VERTICAL_INTERVAL
,
Constant
.
FRAME_HEIGHT
-
topHeight
-
VERTICAL_INTERVAL
,
Pipe
.
TYPE_BOTTOM_HARD
,
true
);
pipes
.
add
(
top
);
pipes
.
add
(
bottom
);
}
/**
* 判断元素和小鸟是否发生碰撞,若发生碰撞返回true,否则返回false
*
...
...
@@ -100,8 +215,8 @@ public class GameElementLayer {
if
(
bird
.
isDead
())
{
return
false
;
}
//遍历水管容器
//
遍历水管容器
for
(
int
i
=
0
;
i
<
pipes
.
size
();
i
++)
{
Pipe
pipe
=
pipes
.
get
(
i
);
// 判断碰撞矩形是否有交集
...
...
src/com/bird/main/GameTime.java
View file @
5e5ba4bf
...
...
@@ -10,16 +10,14 @@ import com.bird.util.Constant;
import
com.bird.util.MusicUtil
;
/**
* 游戏计时类
* 游戏计时类
,单例类,方便调用
*
* @author Kingyu
*
*/
public
class
GameTime
{
public
static
final
int
HOVER_BARRIER_TIME
=
10
;
// 出现悬浮管道的时间
public
static
final
int
MOVING_BARRIER_TIME
=
20
;
// 出现移动管道的时间
private
static
final
GameTime
GAME_TIME
=
new
GameTime
();
private
int
timeState
;
// 计时器的状态
public
static
final
int
STATE_READY
=
0
;
// 计时就绪
public
static
final
int
STATE_START
=
1
;
// 计时开始
...
...
@@ -30,7 +28,7 @@ public class GameTime {
private
long
score
=
0
;
// 分数
private
long
bestScore
;
// 最高分数
p
ublic
GameTime
()
{
p
rivate
GameTime
()
{
timeState
=
STATE_READY
;
bestScore
=
-
1
;
...
...
@@ -40,6 +38,10 @@ public class GameTime {
e
.
printStackTrace
();
}
}
public
static
GameTime
getInstance
()
{
return
GAME_TIME
;
}
// 装载最高纪录
private
void
loadBestTime
()
throws
Exception
{
...
...
@@ -117,8 +119,8 @@ public class GameTime {
}
}
private
static
final
int
FIRST_SCORE_TIME
=
6
7
00
;
// 从游戏开始到通过第一根水管的所需时间
private
static
final
int
PER_SCORE_TIME
=
28
5
0
;
// 通过后续每一根水管的间隔的所需时间
private
static
final
int
FIRST_SCORE_TIME
=
6
6
00
;
// 从游戏开始到通过第一根水管的所需时间
private
static
final
int
PER_SCORE_TIME
=
28
8
0
;
// 通过后续每一根水管的间隔的所需时间
//将游戏时间转换为通过水管的数量
public
long
TimeToScore
()
{
...
...
@@ -149,6 +151,7 @@ public class GameTime {
timeState
=
STATE_READY
;
startTime
=
0
;
endTime
=
0
;
score
=
0
;
}
}
src/com/bird/main/MovingPipe.java
0 → 100644
View file @
5e5ba4bf
package
com.bird.main
;
import
java.awt.Color
;
import
java.awt.Graphics
;
import
com.bird.util.Constant
;
/**
* 移动水管类,继承Pipe类
*
* @author Kingyu
*
*/
public
class
MovingPipe
extends
Pipe
{
private
int
dealtY
;
// 移动水管的坐标
public
static
final
int
MAX_DEALY
=
50
;
// 最大移动距离
private
int
dir
;
public
static
final
int
DIR_UP
=
0
;
public
static
final
int
DIR_DOWN
=
1
;
// 构造器
public
MovingPipe
()
{
super
();
}
/**
* 设置水管参数
*
* @param x
* @param y
* @param height
* @param type
* @param visible
*/
public
void
setAttribute
(
int
x
,
int
y
,
int
height
,
int
type
,
boolean
visible
)
{
this
.
x
=
x
;
this
.
y
=
y
;
this
.
height
=
height
;
this
.
type
=
type
;
this
.
visible
=
visible
;
setRectangle
(
this
.
x
,
this
.
y
,
this
.
height
);
dealtY
=
0
;
dir
=
DIR_DOWN
;
if
(
type
==
TYPE_TOP_HARD
)
{
dir
=
DIR_UP
;
}
}
// 绘制方法
public
void
draw
(
Graphics
g
,
Bird
bird
)
{
switch
(
type
)
{
case
TYPE_HOVER_HARD:
drawHoverHard
(
g
);
break
;
case
TYPE_TOP_HARD:
drawTopHard
(
g
);
break
;
case
TYPE_BOTTOM_HARD:
drawBottomHard
(
g
);
break
;
}
// 鸟死后水管停止移动
if
(
bird
.
isDead
())
{
return
;
}
pipeLogic
();
// 绘制碰撞矩形
g
.
setColor
(
Color
.
black
);
g
.
drawRect
((
int
)
pipeRect
.
getX
(),
(
int
)
pipeRect
.
getY
(),
(
int
)
pipeRect
.
getWidth
(),
(
int
)
pipeRect
.
getHeight
());
}
// 绘制移动的悬浮水管
private
void
drawHoverHard
(
Graphics
g
)
{
// 拼接的个数
int
count
=
(
height
-
2
*
PIPE_HEAD_HEIGHT
)
/
PIPE_HEIGHT
+
1
;
// 绘制水管的上顶部
g
.
drawImage
(
imgs
[
2
],
x
-
((
PIPE_HEAD_WIDTH
-
width
)
>>
1
),
y
+
dealtY
,
null
);
// 绘制水管的主体
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
g
.
drawImage
(
imgs
[
0
],
x
,
y
+
dealtY
+
i
*
PIPE_HEIGHT
+
PIPE_HEAD_HEIGHT
,
null
);
}
// 绘制水管的下底部
int
y
=
this
.
y
+
height
-
PIPE_HEAD_HEIGHT
;
g
.
drawImage
(
imgs
[
1
],
x
-
((
PIPE_HEAD_WIDTH
-
width
)
>>
1
),
y
+
dealtY
,
null
);
}
// 绘制从上往下的普通水管
private
void
drawTopHard
(
Graphics
g
)
{
// 拼接的个数
int
count
=
(
height
-
PIPE_HEAD_HEIGHT
)
/
PIPE_HEIGHT
+
1
;
// 取整+1
// 绘制水管的主体
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
g
.
drawImage
(
imgs
[
0
],
x
,
y
+
dealtY
+
i
*
PIPE_HEIGHT
,
null
);
}
// 绘制水管的顶部
g
.
drawImage
(
imgs
[
1
],
x
-
((
PIPE_HEAD_WIDTH
-
width
)
>>
1
),
height
-
Constant
.
TOP_PIPE_LENGTHENING
-
PIPE_HEAD_HEIGHT
+
dealtY
,
null
);
}
// 绘制从下往上的普通水管
private
void
drawBottomHard
(
Graphics
g
)
{
// 拼接的个数
int
count
=
(
height
-
PIPE_HEAD_HEIGHT
)
/
PIPE_HEIGHT
+
1
;
// 绘制水管的主体
for
(
int
i
=
0
;
i
<
count
;
i
++)
{
g
.
drawImage
(
imgs
[
0
],
x
,
Constant
.
FRAME_HEIGHT
-
PIPE_HEIGHT
-
i
*
PIPE_HEIGHT
+
dealtY
,
null
);
}
// 绘制水管的顶部
g
.
drawImage
(
imgs
[
2
],
x
-
((
PIPE_HEAD_WIDTH
-
width
)
>>
1
),
Constant
.
FRAME_HEIGHT
-
height
+
dealtY
,
null
);
}
/**
* 可动水管的运动逻辑
*/
private
void
pipeLogic
()
{
x
-=
speed
;
pipeRect
.
x
-=
speed
;
if
(
x
<
-
1
*
PIPE_HEAD_WIDTH
)
{
// 水管完全离开了窗口
visible
=
false
;
}
//水管上下移动
if
(
dir
==
DIR_DOWN
)
{
dealtY
++;
if
(
dealtY
>
MAX_DEALY
)
{
dir
=
DIR_UP
;
}
}
else
{
dealtY
--;
if
(
dealtY
<=
0
)
{
dir
=
DIR_DOWN
;
}
}
pipeRect
.
y
=
this
.
y
+
dealtY
;
}
}
src/com/bird/main/Pipe.java
View file @
5e5ba4bf
...
...
@@ -14,7 +14,7 @@ import com.bird.util.GameUtil;
*
*/
public
class
Pipe
{
private
static
BufferedImage
[]
imgs
;
// 水管的图片,static保证图片只加载一次
static
BufferedImage
[]
imgs
;
// 水管的图片,static保证图片只加载一次
static
{
// 静态代码块,类加载的时候,初始化图片
final
int
PIPE_IMAGE_COUNT
=
3
;
imgs
=
new
BufferedImage
[
PIPE_IMAGE_COUNT
];
...
...
@@ -29,12 +29,12 @@ public class Pipe {
public
static
final
int
PIPE_HEAD_WIDTH
=
imgs
[
1
].
getWidth
();
public
static
final
int
PIPE_HEAD_HEIGHT
=
imgs
[
1
].
getHeight
();
private
int
x
,
y
;
// 水管的坐标,相对于元素层
private
int
width
,
height
;
// 水管的宽,高
int
x
,
y
;
// 水管的坐标,相对于元素层
int
width
,
height
;
// 水管的宽,高
private
boolean
visible
;
// 水管可见状态,true为可见,false表示可归还至对象池
boolean
visible
;
// 水管可见状态,true为可见,false表示可归还至对象池
// 水管的类型
private
int
type
;
int
type
;
public
static
final
int
TYPE_TOP_NORMAL
=
0
;
public
static
final
int
TYPE_TOP_HARD
=
1
;
public
static
final
int
TYPE_BOTTOM_NORMAL
=
2
;
...
...
@@ -45,9 +45,9 @@ public class Pipe {
// 水管的速度
public
static
final
int
MIN_SPEED
=
1
;
public
static
final
int
MAX_SPEED
=
2
;
private
int
speed
;
int
speed
;
private
Rectangle
pipeRect
;
// 水管的碰撞矩形
Rectangle
pipeRect
;
// 水管的碰撞矩形
// 构造器
public
Pipe
()
{
...
...
@@ -106,10 +106,13 @@ public class Pipe {
case
TYPE_HOVER_NORMAL:
drawHoverNormal
(
g
);
break
;
}
// //绘制碰撞矩形
// g.setColor(Color.black);
// g.drawRect((int) pipeRect.getX(), (int) pipeRect.getY(), (int) pipeRect.getWidth(), (int) pipeRect.getHeight());
//鸟死后水管停止移动
if
(
bird
.
isDead
())
{
return
;
}
...
...
@@ -156,9 +159,9 @@ public class Pipe {
int
y
=
this
.
y
+
height
-
PIPE_HEAD_HEIGHT
;
g
.
drawImage
(
imgs
[
1
],
x
-
((
PIPE_HEAD_WIDTH
-
width
)
>>
1
),
y
,
null
);
}
/**
* 水管的运动逻辑
*
普通
水管的运动逻辑
*/
private
void
pipeLogic
()
{
x
-=
speed
;
...
...
@@ -166,7 +169,6 @@ public class Pipe {
if
(
x
<
-
1
*
PIPE_HEAD_WIDTH
)
{
// 水管完全离开了窗口
visible
=
false
;
}
}
/**
...
...
src/com/bird/main/PipePool.java
View file @
5e5ba4bf
...
...
@@ -12,16 +12,21 @@ import com.bird.util.Constant;
*
*/
public
class
PipePool
{
private
static
List
<
Pipe
>
pool
=
new
ArrayList
<>();
// 用于管理池中所有对象的容器
private
static
List
<
Pipe
>
pool
=
new
ArrayList
<
Pipe
>();
// 池中对象的容器
private
static
List
<
MovingPipe
>
movingPool
=
new
ArrayList
<
MovingPipe
>();
// 池中对象的容器
public
static
final
int
INIT_PIPE_COUNT
=
(
Constant
.
FRAME_WIDTH
/
(
Pipe
.
PIPE_HEAD_WIDTH
+
GameElementLayer
.
HORIZONTAL_INTERVAL
)
+
2
)
*
2
;
// 根据窗口宽度算得对象池中对象的初始个数
public
static
final
int
MAX_PIPE_COUNT
=
5
0
;
// 对象池中对象的最大个数,自行定义
public
static
final
int
MAX_PIPE_COUNT
=
3
0
;
// 对象池中对象的最大个数,自行定义
//初始化水管容器
//
初始化水管容器
static
{
for
(
int
i
=
0
;
i
<
INIT_PIPE_COUNT
;
i
++)
{
pool
.
add
(
new
Pipe
());
}
for
(
int
i
=
0
;
i
<
INIT_PIPE_COUNT
;
i
++)
{
movingPool
.
add
(
new
MovingPipe
());
}
}
/**
...
...
@@ -29,12 +34,21 @@ public class PipePool {
*
* @return
*/
public
static
Pipe
get
()
{
int
size
=
pool
.
size
();
if
(
size
>
0
)
{
return
pool
.
remove
(
size
-
1
);
// 移除并返回最后一个
public
static
Pipe
get
(
String
className
)
{
if
(
"Pipe"
.
equals
(
className
))
{
int
size
=
pool
.
size
();
if
(
size
>
0
)
{
return
pool
.
remove
(
size
-
1
);
// 移除并返回最后一个
}
else
{
return
new
Pipe
();
// 空对象池,返回一个新对象
}
}
else
{
return
new
Pipe
();
// 空对象池,返回一个新对象
int
size
=
movingPool
.
size
();
if
(
size
>
0
)
{
return
movingPool
.
remove
(
size
-
1
);
// 移除并返回最后一个
}
else
{
return
new
MovingPipe
();
// 空对象池,返回一个新对象
}
}
}
...
...
@@ -44,8 +58,15 @@ public class PipePool {
* @param pipe
*/
public
static
void
giveBack
(
Pipe
pipe
)
{
if
(
pool
.
size
()
<
MAX_PIPE_COUNT
)
{
pool
.
add
(
pipe
);
}
//判断类的类型
if
(
pipe
.
getClass
()
==
Pipe
.
class
)
{
if
(
pool
.
size
()
<
MAX_PIPE_COUNT
)
{
pool
.
add
(
pipe
);
}
}
else
{
if
(
movingPool
.
size
()
<
MAX_PIPE_COUNT
)
{
movingPool
.
add
((
MovingPipe
)
pipe
);
}
}
}
}
src/com/bird/util/Constant.java
View file @
5e5ba4bf
...
...
@@ -23,6 +23,8 @@ public class Constant {
// 图像资源路径
public
static
final
String
BG_IMG_PATH
=
"sources/img/background.png"
;
// 背景图片
public
static
final
int
HOVER_MOVING_SCORE
=
4
;
//出现移动管道的分数
// 小鸟图片
public
static
final
String
[][]
BIRDS_IMG_PATH
=
{
...
...
src/com/bird/util/GameUtil.java
View file @
5e5ba4bf
package
com.bird.util
;
import
java.awt.Font
;
import
java.awt.FontMetrics
;
import
java.awt.image.BufferedImage
;
import
java.io.FileInputStream
;
import
java.io.IOException
;
import
java.awt.font.FontRenderContext
;
import
java.awt.geom.AffineTransform
;
import
javax.imageio.ImageIO
;
import
sun.font.FontDesignMetrics
;
/**
* 工具类,游戏中用到的工具都在此类
*
...
...
@@ -71,12 +70,17 @@ public class GameUtil {
* 获得指定字符串在指定字体的宽高
*/
public
static
int
getStringWidth
(
Font
font
,
String
str
)
{
FontMetrics
fm
=
FontDesignMetrics
.
getMetrics
(
font
);
return
fm
.
stringWidth
(
str
);
AffineTransform
affinetransform
=
new
AffineTransform
();
FontRenderContext
frc
=
new
FontRenderContext
(
affinetransform
,
true
,
true
);
int
textHeight
=
(
int
)(
font
.
getStringBounds
(
str
,
frc
).
getWidth
());
return
textHeight
;
}
public
static
int
getStringHeight
(
Font
font
,
String
str
)
{
FontMetrics
fm
=
FontDesignMetrics
.
getMetrics
(
font
);
return
fm
.
getHeight
();
AffineTransform
affinetransform
=
new
AffineTransform
();
FontRenderContext
frc
=
new
FontRenderContext
(
affinetransform
,
true
,
true
);
int
textHeight
=
(
int
)(
font
.
getStringBounds
(
str
,
frc
).
getHeight
());
return
textHeight
;
}
}
src/com/bird/util/MusicUtil.java
View file @
5e5ba4bf
...
...
@@ -18,6 +18,7 @@ public class MusicUtil {
private
static
AudioClip
score
;
// 装载音乐资源
@SuppressWarnings
(
"deprecation"
)
public
static
void
load
()
{
try
{
fly
=
Applet
.
newAudioClip
(
new
File
(
"sources/wav/fly.wav"
).
toURL
());
...
...
Write
Preview
Supports
Markdown
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment