From 074595b3408a1323b41226d4b4259c6aff696888 Mon Sep 17 00:00:00 2001 From: kingyu Date: Sat, 11 Jul 2020 17:24:21 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=B7=BB=E5=8A=A0=E6=82=AC=E6=B5=AE?= =?UTF-8?q?=E5=9E=8B=E6=B0=B4=E7=AE=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 9 ++ README.md | 8 +- src/com/bird/main/Bird.java | 2 +- src/com/bird/main/GameElementLayer.java | 157 ++++++++++++++++++++---- src/com/bird/main/GameTime.java | 19 +-- src/com/bird/main/MovingPipe.java | 142 +++++++++++++++++++++ src/com/bird/main/Pipe.java | 22 ++-- src/com/bird/main/PipePool.java | 43 +++++-- src/com/bird/util/Constant.java | 2 + src/com/bird/util/GameUtil.java | 18 +-- src/com/bird/util/MusicUtil.java | 1 + 11 files changed, 364 insertions(+), 59 deletions(-) create mode 100644 src/com/bird/main/MovingPipe.java diff --git a/CHANGELOG.md b/CHANGELOG.md index f128794..707371a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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) diff --git a/README.md b/README.md index 6c365d0..aa48685 100644 --- a/README.md +++ b/README.md @@ -17,8 +17,14 @@ com.bird.util 自定义的工具 # Version History -1.0.0 - July 11, 2020 +1.0.0 - July 10, 2020 * 具备完整的游戏功能 +1.1.0 - July 11, 2020 +* 添加了悬浮型的水管 + +# Notes + +文本编码格式为UTF-8,若注释出现乱码请修改编译器的文本编码格式 # Contact * email: diff --git a/src/com/bird/main/Bird.java b/src/com/bird/main/Bird.java index 6451447..2d712f8 100644 --- a/src/com/bird/main/Bird.java +++ b/src/com/bird/main/Bird.java @@ -44,7 +44,7 @@ public class Bird { // 在构造器中对资源初始化 public Bird() { - timing = new GameTime(); // 计时器 + timing = GameTime.getInstance(); // 计时器 // 读取小鸟图片资源 birdImgs = new BufferedImage[STATE_COUNT][IMG_COUNT]; diff --git a/src/com/bird/main/GameElementLayer.java b/src/com/bird/main/GameElementLayer.java index b9756a2..907b0c1 100644 --- a/src/com/bird/main/GameElementLayer.java +++ b/src/com/bird/main/GameElementLayer.java @@ -17,12 +17,12 @@ public class GameElementLayer { private List 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 void draw(Graphics g, Bird bird) { */ 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 @@ private void pipeBornLogic(Bird bird) { // 若容器为空,则添加一对水管 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 boolean isCollideBird(Bird bird) { if (bird.isDead()) { return false; } - - //遍历水管容器 + + // 遍历水管容器 for (int i = 0; i < pipes.size(); i++) { Pipe pipe = pipes.get(i); // 判断碰撞矩形是否有交集 diff --git a/src/com/bird/main/GameTime.java b/src/com/bird/main/GameTime.java index f62fcd3..21aa017 100644 --- a/src/com/bird/main/GameTime.java +++ b/src/com/bird/main/GameTime.java @@ -10,16 +10,14 @@ 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; // 最高分数 - public GameTime() { + private GameTime() { timeState = STATE_READY; bestScore = -1; @@ -40,6 +38,10 @@ public GameTime() { e.printStackTrace(); } } + + public static GameTime getInstance() { + return GAME_TIME; + } // 装载最高纪录 private void loadBestTime() throws Exception { @@ -117,8 +119,8 @@ public void endTiming() { } } - private static final int FIRST_SCORE_TIME = 6700; // 从游戏开始到通过第一根水管的所需时间 - private static final int PER_SCORE_TIME = 2850; // 通过后续每一根水管的间隔的所需时间 + private static final int FIRST_SCORE_TIME = 6600; // 从游戏开始到通过第一根水管的所需时间 + private static final int PER_SCORE_TIME = 2880; // 通过后续每一根水管的间隔的所需时间 //将游戏时间转换为通过水管的数量 public long TimeToScore() { @@ -149,6 +151,7 @@ public void reset() { timeState = STATE_READY; startTime = 0; endTime = 0; + score = 0; } } diff --git a/src/com/bird/main/MovingPipe.java b/src/com/bird/main/MovingPipe.java new file mode 100644 index 0000000..ecf77c6 --- /dev/null +++ b/src/com/bird/main/MovingPipe.java @@ -0,0 +1,142 @@ +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; + + } +} diff --git a/src/com/bird/main/Pipe.java b/src/com/bird/main/Pipe.java index 71549bc..7689c8a 100644 --- a/src/com/bird/main/Pipe.java +++ b/src/com/bird/main/Pipe.java @@ -14,7 +14,7 @@ * */ 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 void draw(Graphics g, Bird bird) { 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 @@ private void drawHoverNormal(Graphics g) { 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 @@ private void pipeLogic() { if (x < -1 * PIPE_HEAD_WIDTH) {// 水管完全离开了窗口 visible = false; } - } /** diff --git a/src/com/bird/main/PipePool.java b/src/com/bird/main/PipePool.java index dde2051..92b1f1f 100644 --- a/src/com/bird/main/PipePool.java +++ b/src/com/bird/main/PipePool.java @@ -12,16 +12,21 @@ * */ public class PipePool { - private static List pool = new ArrayList<>(); // 用于管理池中所有对象的容器 + private static List pool = new ArrayList(); // 池中对象的容器 + private static List movingPool = new ArrayList(); // 池中对象的容器 + 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 = 50; // 对象池中对象的最大个数,自行定义 + public static final int MAX_PIPE_COUNT = 30; // 对象池中对象的最大个数,自行定义 - //初始化水管容器 + // 初始化水管容器 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 static Pipe get() { * @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); + } + } } } diff --git a/src/com/bird/util/Constant.java b/src/com/bird/util/Constant.java index 54de2b2..33f7721 100644 --- a/src/com/bird/util/Constant.java +++ b/src/com/bird/util/Constant.java @@ -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 = { diff --git a/src/com/bird/util/GameUtil.java b/src/com/bird/util/GameUtil.java index 921e711..fd388e5 100644 --- a/src/com/bird/util/GameUtil.java +++ b/src/com/bird/util/GameUtil.java @@ -1,15 +1,14 @@ 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 static int getRandomNumber(int min, int max) { * 获得指定字符串在指定字体的宽高 */ 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; } } diff --git a/src/com/bird/util/MusicUtil.java b/src/com/bird/util/MusicUtil.java index 10f4849..d104d12 100644 --- a/src/com/bird/util/MusicUtil.java +++ b/src/com/bird/util/MusicUtil.java @@ -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());