java小游戏-ava小游戏-飞翔的小鸟

  • 1 游戏窗口的显示
  • 2 游戏背景添加
  • 3 背景颜色的添加
  • 4 屏幕中绘制小鸟
  • 5 实现小鸟上下移动
  • 6 解决屏幕闪烁问题
  • 7 云彩的添加与移动
  • 8 云彩的自动生成与销毁
  • 9 绘制从上向下的障碍物
  • 10 绘制从下往上的障碍物
  • 11 障碍物的自动生成
  • 12 障碍物对象池
  • 13 障碍物归还对象池
  • 14 判断小鸟与障碍物发生碰撞
  • 15 小鸟与碰撞物碰撞后处理
  • 16 计时器
  • 17 添加障碍物
  • 18 按下空格键查询开始游戏
  • 19 记录持久化
  • 20 游戏优化

连接视频

1 游戏窗口的显示

创建Constant类

/*** 常量*/
public class Constant {//窗口的大小public static final int FRAME_WIDTH = 600;public static final int FRAME_HEIGHT = 500;//窗口的标题public static final String FRAME_TITLE = "飞翔的小鸟";//窗口的初始化位置public static final int FRAME_X = 200;public static final int FRAME_Y = 200;}

创建GameFrame类

/*** 游戏的主窗口,所有的关于游戏中绘制的内容都在此类中完成。* 游戏开发:基本都是底层界面的绘制,而不是用jdk通过的各种组件*/
public class GameFrame extends Frame {//构造方法中初始化一些参数public GameFrame() {//窗口是否可见setVisible(true);//窗口大小setSize(FRAME_WIDTH, FRAME_HEIGHT);//窗口标题setTitle(FRAME_TITLE);//窗口的初始化位置setLocation(FRAME_X, FRAME_Y);//窗口的大小不可变setResizable(false);//窗口的关闭事件addWindowListener(new WindowAdapter() {@Overridepublic void windowClosing(WindowEvent e) {System.exit(0);//结束程序}});}}

创建GameApp类

public class GameApp {public static void main(String[] args) {new GameFrame();}
}

2 游戏背景添加

先把准备的图片放入项目中

在Constant类添加常量

//图片路径
public static final String BK_IMG_PATH = "birdimg/ground.png";

创建GameUtil类

/*** 工具类*/
public class GameUtil {//加载图片public static BufferedImage loadBufferedImage(String imgPath){try {return ImageIO.read(new FileInputStream(imgPath));} catch (IOException e) {e.printStackTrace();}return null;}
}

创建GameBackGround类

/*** 游戏背景类*/
public class GameBackGround {//背景需要的资源图片private BufferedImage bkimg;//构造器初始化资源public GameBackGround(){bkimg = GameUtil.loadBufferedImage(Constant.BK_IMG_PATH);}//绘制图片public void draw(Graphics g){//得到图片的高度和宽度int height = bkimg.getHeight();int wight = bkimg.getWidth();//循环次数int count = Constant.FRAME_WIDTH/wight + 1;for (int i = 0; i < count; i++) {g.drawImage(bkimg,wight*i,Constant.FRAME_HEIGHT-height,null);}}
}

在GameFrame类添加方法

public class GameFrame extends Frame {//实例化gameBackGround类private GameBackGround gameBackGround;//构造方法中初始化一些参数public GameFrame() {...//初始化游戏对象initGamg();new run().start();}//对游戏中对象初始化public void initGamg(){gameBackGround = new GameBackGround();}//创建线程class run extends Thread{@Overridepublic void run() {repaint();try {Thread.sleep(33);} catch (InterruptedException e) {e.printStackTrace();}}}/*** 所有我们需要绘制的内容都在此方法中进行调用绘制*/@Overridepublic void update(Graphics g){gameBackGround.draw(g);}}

3 背景颜色的添加

在Constant类添加常量

//游戏背景颜色
public static final Color BK_COLOR = new Color(0x4B4CF);

在GameBackGround类draw方法添加绘制

//绘制图片
public void draw(Graphics g){//填充背景色g.setColor(BK_COLOR);g.fillRect(0,0,FRAME_WIDTH,FRAME_HEIGHT);g.setColor(Color.black);//得到图片的高度和宽度...
}

4 屏幕中绘制小鸟

在Constant类中添加常量

//小鸟的图片资源
public static final String[] BIRD_IMG ={"birdimg/00.png","birdimg/01.png","birdimg/02.png"};

创建Bird类

/*** 小鸟类*/
public class Bird {//存放小鸟图片private BufferedImage[] images;private static final int BIRD_IMG_COUNT = 3;//鸟的状态private int state;private static final int STATE_NORMAR = 0;//平着飞private static final int STATE_UP = 1;//向上飞private static final int STATE_DOWN = 2;//向下飞//构造方法中对资源初始化public Bird(){images = new BufferedImage[BIRD_IMG_COUNT];for (int i = 0; i < BIRD_IMG_COUNT; i++) {images[i] = GameUtil.loadBufferedImage(BIRD_IMG[i]);}}//绘制小鸟public void draw(Graphics g){g.drawImage(images[state],200,200,null);}}

在GameFrame类中添加bird对象

//实例化Bird类
private Bird bird;//对游戏中对象初始化
public void initGamg(){gameBackGround = new GameBackGround();bird = new Bird();
}/*** 所有我们需要绘制的内容都在此方法中进行调用绘制*/
@Override
public void update(Graphics g){gameBackGround.draw(g);bird.draw(g);
}

5 实现小鸟上下移动

在Bird类添加小鸟移动参数

//小鸟的位置
private int x = 200, y = 200;//小鸟移动方向 上下
private boolean up = false, down = false;//小鸟移动速度
private int speed = 4;
//绘制小鸟
public void draw(Graphics g) {flyLogic();g.drawImage(images[state], x, y, null);
}//控制小鸟移动方向
public void flyLogic() {if (up) {y -= speed;if (y < 20) {y = 20;}}if (!up) {y += speed;if (y > 470) {y = 470;}}
}public void fly(int fly) {switch (fly) {case 1:state = 1;up = true;break;case 5:state = 2;up = false;break;}
}

在GameFrame类添加小鸟移动监听事件

//构造方法中初始化一些参数
public GameFrame() {...//初始化游戏对象initGamg();new run().start();//添加按键监听事件addKeyListener(new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {add(e);}@Overridepublic void keyReleased(KeyEvent e) {minu(e);}});
}//创建线程
class Run extends Thread {@Overridepublic void run() {while (true) {repaint();try {Thread.sleep(33);} catch (InterruptedException e) {e.printStackTrace();}}}
}//按键
public void add(KeyEvent e){switch (e.getKeyCode()){case KeyEvent.VK_UP:bird.fly(1);break;}
}//抬键
public void minu(KeyEvent e){switch (e.getKeyCode()){case KeyEvent.VK_UP:bird.fly(5);break;}
}

6 解决屏幕闪烁问题

在GameFrame类添加缓存图片对象

//存放屏幕图片
private BufferedImage buffimg = new BufferedImage(FRAME_WIDTH, FRAME_HEIGHT, BufferedImage.TYPE_4BYTE_ABGR);/*** 所有我们需要绘制的内容都在此方法中进行调用绘制*/
@Override
public void update(Graphics g) {//得到图片的画笔Graphics graphics = buffimg.getGraphics();gameBackGround.draw(graphics);bird.draw(graphics);//一次性的将图片绘制到屏幕中g.drawImage(buffimg, 0, 0, null);
}

7 云彩的添加与移动

创建Cloud类

/*** 云彩类*/
public class Cloud {//云彩图片private BufferedImage img;//云彩的速度private int speed;//云彩的位置private int x,y;public Cloud(){}public Cloud(BufferedImage img, int speed, int x, int y) {this.img = img;this.speed = speed;this.x = x;this.y = y;}public void draw(Graphics g){x-=speed;g.drawImage(img,x,y,null);}
}

创建GameFrontGround类

/*** 游戏的前景类*/
public class GameFrontGround {//云彩的个数private static final int CLOUD_COUNT = 2;//存放云彩的容器private List<Cloud> clouds;//云彩的飞行速度private static final int CLOUD_SPEED = 1;//使用到的图片资源资源private BufferedImage[] images;//构造器初始化数据public GameFrontGround(){clouds = new ArrayList<>();images = new BufferedImage[CLOUD_COUNT];//容器中添加云彩图片for (int i = 0; i < CLOUD_COUNT; i++) {images[i] = GameUtil.loadBufferedImage("birdimg/cloud" + i +".png");}}//绘制云彩public void draw(Graphics g){Cloud cloud = new Cloud(images[1], CLOUD_SPEED, 300, 100);clouds.add(cloud);clouds.get(0).draw(g);}}

在GameFrame类绘制云彩

//实例化GameFrontGround类
private GameFrontGround gameFrontGround;//对游戏中对象初始化
public void initGamg() {gameBackGround = new GameBackGround();bird = new Bird();gameFrontGround = new GameFrontGround();
}@Override
public void update(Graphics g) {//得到图片的画笔Graphics graphics = buffimg.getGraphics();gameBackGround.draw(graphics);bird.draw(graphics);gameFrontGround.draw(graphics);//一次性的将图片绘制到屏幕中g.drawImage(buffimg, 0, 0, null);
}

8 云彩的自动生成与销毁

在GameFrontGround添加云彩随机数

//用于产生随机数
private Random random;
//构造器初始化数据
public GameFrontGround() {clouds = new ArrayList<>();images = new BufferedImage[CLOUD_COUNT];//容器中添加云彩图片for (int i = 0; i < CLOUD_COUNT; i++) {images[i] = GameUtil.loadBufferedImage("birdimg/cloud" + i + ".png");}random = new Random();
}//绘制云彩
public void draw(Graphics g) {logic();for (int i = 0; i < clouds.size(); i++) {clouds.get(i).draw(g);}
}//用于云彩个数控制
public void logic() {if ((500 * Math.random()) < 5) {Cloud cloud = new Cloud(images[random.nextInt(CLOUD_COUNT)],CLOUD_SPEED,600,random.nextInt(150));clouds.add(cloud);}for (int i = 0; i < clouds.size(); i++) {Cloud cloud = clouds.get(0);if (cloud.isOutFrame()) {clouds.remove(cloud);i--;System.out.println("云彩移除:" + cloud);}}
}

在Cloud类添加判断

//用于判断云彩是否飞出屏幕之外
public boolean isOutFrame(){if(x < -50){return true;}return false;
}

9 绘制从上向下的障碍物

在Constant类添加障碍物资源

//障碍物的图片资源
public static final String[] BARRIER_IMG_PATH ={"birdimg/barrier.png","birdimg/barrier_up.png","birdimg/barrier_down.png"};

创建Barrier类

/*** 障碍物类*/
public class Barrier {//障碍物所需三个图片private static BufferedImage[] images;static {final int COUNT = 3;//类加载的时候将三个图片初始化images = new BufferedImage[COUNT];for (int i = 0; i < COUNT; i++) {images[i] = GameUtil.loadBufferedImage(Constant.BARRIER_IMG_PATH[i]);}}//位置private int x, y;//宽度和高度private int width, height;//障碍物的类型private int type;private static final int TYPE_TOP_NORMAL = 0;private static final int TYPE_BOTTOM_NORMAL = 2;private static final int TYPE_HOVER_NORMAL = 4;//获取障碍物的高度和宽度public static final int BARRIER_WIDTH = images[0].getWidth();public static final int BARRIER_HEIGHT = images[0].getHeight();public static final int BARRIER_HEAD_WIDTH = images[1].getWidth();public static final int BARRIER_HEAD_HEIGHT = images[1].getHeight();public Barrier() {}public Barrier(int x, int y, int height, int type) {this.x = x;this.y = y;this.width = BARRIER_WIDTH;this.height = height;this.type = type;}//根据不同的类型绘制障碍物public void draw(Graphics g) {drawToNormal(g);}//绘制从上向下障碍物private void drawToNormal(Graphics g) {//求出所需要的障碍物的块数int count = (height - BARRIER_HEAD_HEIGHT) / BARRIER_HEIGHT + 1;//for循环绘制障碍物for (int i = 0; i < count; i++) {g.drawImage(images[0], x, y + i * BARRIER_HEIGHT, null);}//绘制头int y = height - BARRIER_HEAD_HEIGHT;g.drawImage(images[2], x - (BARRIER_HEAD_WIDTH - BARRIER_WIDTH) / 2, y, null);}
}

创建GameBarrierLayer类

/*** 游戏中的障碍物层*/
public class GameBarrierLayer {//存放障碍物private List<Barrier> barriers;public GameBarrierLayer(){barriers = new ArrayList<>();}//绘制障碍物public void draw(Graphics g){Barrier barrier = new Barrier(200, 0, 200, 0);barriers.add(barrier);barriers.get(0).draw(g);}
}

在GameFrame类创建GameBarrierLayer 对象

//实例化GameBarrierLayer类
private GameBarrierLayer gameBarrierLayer;//对游戏中对象初始化
public void initGamg() {gameBackGround = new GameBackGround();bird = new Bird();gameFrontGround = new GameFrontGround();gameBarrierLayer = new GameBarrierLayer();
}/*** 所有我们需要绘制的内容都在此方法中进行调用绘制*/
@Override
public void update(Graphics g) {//得到图片的画笔Graphics graphics = buffimg.getGraphics();gameBackGround.draw(graphics);bird.draw(graphics);gameFrontGround.draw(graphics);gameBarrierLayer.draw(graphics);//一次性的将图片绘制到屏幕中g.drawImage(buffimg, 0, 0, null);
}

10 绘制从下往上的障碍物

在Barrier类添加方法

//根据不同的类型绘制障碍物
public void draw(Graphics g) {switch (type){case TYPE_TOP_NORMAL:drawToNormal(g);break;case TYPE_BOTTOM_NORMAL:drawNormalTop(g);break;}
}//绘制从下向上的障碍物
public void drawNormalTop(Graphics g) {//求出所需要的障碍物的块数int count = height / BARRIER_HEIGHT + 1;//for循环绘制障碍物for (int i = 0; i < count; i++) {g.drawImage(images[0], x, Constant.FRAME_HEIGHT - i * BARRIER_HEIGHT, null);}//绘制头int y = Constant.FRAME_HEIGHT - height;g.drawImage(images[1], x - (BARRIER_HEAD_WIDTH - BARRIER_WIDTH) / 2, y, null);
}

在GameBarrierLayer类修改draw方法

//绘制障碍物
public void draw(Graphics g){Barrier barrier = new Barrier(200, 0, 200, 0);barriers.add(barrier);barriers.get(0).draw(g);Barrier barrier1 = new Barrier(300, 0, 300, 2);barriers.add(barrier1);barriers.get(1).draw(g);
}

11 障碍物的自动生成

在GameBarrierLayer添加障碍物的自动生成

private Random random = new Random();//绘制障碍物
public void draw(Graphics g){for (int i = 0; i < barriers.size(); i++) {Barrier barrier = barriers.get(i);barrier.draw(g);}logic();
}public void logic(){if(barriers.size() == 0){ran();Barrier top = new Barrier(600,0,numberTop,0);barriers.add(top);Barrier down = new Barrier(600,500-numberDown,numberDown,2);barriers.add(down);}else {//判断最后一个障碍物是否完全进入屏幕内Barrier last = barriers.get(barriers.size() - 1);if(last.isInFrame()){ran();Barrier top = new Barrier(600,0,numberTop,0);barriers.add(top);Barrier down = new Barrier(600,500-numberDown,numberDown,2);barriers.add(down);}}
}//上方障碍物高度
private int numberTop;
//下方障碍物高度
private int numberDown;
//产生两个100-500之间的随机高度
public void ran(){numberTop = random.nextInt(400) + 100;numberDown = random.nextInt(400) + 100;//如果管道重合,则重新随机if(numberTop + numberDown > 450){ran();}}

在Barrier类添加判断

//障碍物移动速度
private int speed = 3;//绘制从上向下障碍物
private void drawToNormal(Graphics g) {//求出所需要的障碍物的块数int count = (height - BARRIER_HEAD_HEIGHT) / BARRIER_HEIGHT + 1;//for循环绘制障碍物for (int i = 0; i < count; i++) {g.drawImage(images[0], x, y + i * BARRIER_HEIGHT, null);}//绘制头int y = height - BARRIER_HEAD_HEIGHT;g.drawImage(images[2], x - (BARRIER_HEAD_WIDTH - BARRIER_WIDTH) / 2, y, null);x-=speed;
}//绘制从下向上的障碍物
public void drawNormalTop(Graphics g) {//求出所需要的障碍物的块数int count = height / BARRIER_HEIGHT + 1;//for循环绘制障碍物for (int i = 0; i < count; i++) {g.drawImage(images[0], x, Constant.FRAME_HEIGHT - i * BARRIER_HEIGHT, null);}//绘制头int y = Constant.FRAME_HEIGHT - height;g.drawImage(images[1], x - (BARRIER_HEAD_WIDTH - BARRIER_WIDTH) / 2, y, null);x-=speed;
}//判断什么时候绘制下一组障碍物
public boolean isInFrame(){return 600-x>150;
}

12 障碍物对象池

创建BarrierPool对象

/*** 为了避免反复创建和销毁对象,使用对象池来提前创建一些好的对象。* 使用的时候从池子中获取,使用完毕后,归还*/
public class BarrierPool {//用于管理池中所有对象的容器private static List<Barrier> pool = new ArrayList<>();//池中初始化的对象个数public static final int initCount = 16;//对象池中最大数public static final int maxCount = 20;static {//初始化池中对象for (int i = 0; i < initCount; i++) {pool.add(new Barrier());}}//从池中获取一个对象public static Barrier getPool(){int size = pool.size();//如果池中有对象才可以拿if(size > 0){//移除数据System.out.println("拿走一个");return pool.remove(size-1);}else {//池中没有对象 只能newSystem.out.println("新的对象");return new Barrier();}}//将对象归还容器中public static void setPool(Barrier barrier){if(pool.size() < maxCount){pool.add(barrier);System.out.println("容器归还了");}}
}

在Barrier类添加get和set方法

public int getX() { return x; }
public void setX(int x) { this.x = x; }
public int getY() { return y; }
public void setY(int y) { this.y = y; }
public int getHeight() { return height; }
public void setHeight(int height) { this.height = height; }
public int getType() { return type; }
public void setType(int type) { this.type = type; }

在GameBarrierLayer类添加对象池方法

public void logic(){if(barriers.size() == 0){ran();
//            Barrier top = new Barrier(600,0,numberTop,0);
//            barriers.add(top);
//            Barrier down = new Barrier(600,500-numberDown,numberDown,2);
//            barriers.add(down);insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}else {//判断最后一个障碍物是否完全进入屏幕内Barrier last = barriers.get(barriers.size() - 1);if(last.isInFrame()){ran();
//                Barrier top = new Barrier(600,0,numberTop,0);
//                barriers.add(top);
//                Barrier down = new Barrier(600,500-numberDown,numberDown,2);
//                barriers.add(down);insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}}
}//用于从池中获取对象,并把参数封装成barrier,存入barriers数组中
public void insert(int x,int y,int height,int type){Barrier pool = BarrierPool.getPool();pool.setX(x);pool.setY(y);pool.setHeight(height);pool.setType(type);barriers.add(pool);
}

13 障碍物归还对象池

在Barrier类添加存活判断

//障碍物存活状态
private boolean visible;//绘制从上向下障碍物
private void drawToNormal(Graphics g) {....x-=speed;if(x < -50){visible = false;}
}//绘制从下向上的障碍物
private void drawNormalTop(Graphics g) {....x-=speed;if(x < -50){visible = false;}
}
public boolean isVisible() { return visible; }
public void setVisible(boolean visible) { this.visible = visible; }

在GameBarrierLayer类设置存活状态

//绘制障碍物
public void draw(Graphics g){for (int i = 0; i < barriers.size(); i++) {Barrier barrier = barriers.get(i);if (barrier.isVisible()) {barrier.draw(g);}else {Barrier remove = barriers.remove(i);BarrierPool.setPool(remove);i--;}}logic();
}//用于从池中获取对象,并把参数封装成barrier,存入barriers数组中
public void insert(int x,int y,int height,int type){Barrier pool = BarrierPool.getPool();pool.setX(x);pool.setY(y);pool.setHeight(height);pool.setType(type);pool.setVisible(true);barriers.add(pool);
}

14 判断小鸟与障碍物发生碰撞

在Bird类添加矩形对象

//小鸟矩形对象
private Rectangle rect;//构造方法中对资源初始化
public Bird() {images = new BufferedImage[BIRD_IMG_COUNT];for (int i = 0; i < BIRD_IMG_COUNT; i++) {images[i] = GameUtil.loadBufferedImage(BIRD_IMG[i]);}int w = images[0].getWidth();int h = images[0].getHeight();rect = new Rectangle(w,h);
}//绘制小鸟
public void draw(Graphics g) {flyLogic();g.drawImage(images[state], x, y, null);//绘制小鸟的矩形g.drawRect(x,y,(int)rect.getWidth(),(int)rect.getHeight());rect.x = this.x;rect.y = this.y;
}public Rectangle getRect() {return rect;
}

在Barrier类添加矩形对象

//矩形参数
private Rectangle rect;public Barrier() {rect = new Rectangle();
}//绘制从上向下障碍物
private void drawToNormal(Graphics g) {...rect(g);
}//绘制从下向上的障碍物
public void drawNormalTop(Graphics g) {...rect(g);
}//绘制障碍物碰撞矩形
public void rect(Graphics g){int x1 = this.x;int y1 = this.y;int w1 = images[0].getWidth();g.setColor(Color.blue);g.drawRect(x1,y1,w1,height);setRecyangle(x1,y1,w1,height);
}//障碍物的碰撞矩形参数
public void setRecyangle(int x,int y,int width,int height){rect.x = x;rect.y = y;rect.width = width;rect.height = height;
}public Rectangle getRect() {return rect;
}

在GameBarrierLayer类添加碰撞判断

//绘制障碍物
public void draw(Graphics g,Bird bird){for (int i = 0; i < barriers.size(); i++) {Barrier barrier = barriers.get(i);if (barrier.isVisible()) {barrier.draw(g);}else {Barrier remove = barriers.remove(i);BarrierPool.setPool(remove);i--;}}collideBird(bird);logic();
}//判断障碍物和小鸟发生碰撞
public boolean collideBird(Bird bird){for (int i = 0; i < barriers.size(); i++) {Barrier barrier = barriers.get(i);//判断是否相交if(barrier.getRect().intersects(bird.getRect())){System.out.println("碰撞上了");}}return false;
}

在GameFrame 类修改update方法

public void update(Graphics g) {//得到图片的画笔Graphics graphics = buffimg.getGraphics();gameBackGround.draw(graphics);bird.draw(graphics);gameFrontGround.draw(graphics);gameBarrierLayer.draw(graphics,bird);//一次性的将图片绘制到屏幕中g.drawImage(buffimg, 0, 0, null);
}

15 小鸟与碰撞物碰撞后处理

在Bird类添加小鸟状态

//小鸟的生命
public boolean life = true;

在GameBarrierLayer类修改collideBird方法

//判断障碍物和小鸟发生碰撞
public boolean collideBird(Bird bird){for (int i = 0; i < barriers.size(); i++) {Barrier barrier = barriers.get(i);//判断是否相交if(barrier.getRect().intersects(bird.getRect())){System.out.println("碰撞上了");bird.life = false;}}return false;
}

在GameFrame 类修改update方法

/*** 所有我们需要绘制的内容都在此方法中进行调用绘制*/
@Override
public void update(Graphics g) {if (bird.life) {//得到图片的画笔Graphics graphics = buffimg.getGraphics();gameBackGround.draw(graphics);bird.draw(graphics);gameFrontGround.draw(graphics);gameBarrierLayer.draw(graphics,bird);//一次性的将图片绘制到屏幕中g.drawImage(buffimg, 0, 0, null);}else {String over = "游戏结束";g.setColor(Color.red);g.setFont(new Font("微软雅黑",1,60));g.drawString(over,300,250);}
}

16 计时器

创建GameTime类

/*** 游戏计时*/
public class GameTime {//开始private long beginTime;//结束private long endTime;//时间差private long differ;public GameTime(){}//开始计时public void begin(){beginTime = System.currentTimeMillis();}//计算时间差public long differ(){endTime = System.currentTimeMillis();return differ = (endTime-beginTime) / 1000;}}

在GameBarrierLayer类引用计时对象

private GameTime gameTime;public GameBarrierLayer(){barriers = new ArrayList<>();gameTime = new GameTime();
}//绘制障碍物
public void draw(Graphics g,Bird bird){....logic(g);
}public void logic(Graphics g){if(barriers.size() == 0){ran();gameTime.begin();insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}else {long differ = gameTime.differ();g.setColor(Color.white);g.setFont(new Font("微软雅黑",1,20));g.drawString("您坚持了:" + differ+"秒",20,50);//判断最后一个障碍物是否完全进入屏幕内Barrier last = barriers.get(barriers.size() - 1);if(last.isInFrame()){ran();insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}}
}

17 添加障碍物

在GameBarrierLayer添加中间障碍物

//中间障碍物
private int number;public void ran(){number = random.nextInt(500);...
}public void logic(Graphics g){if(barriers.size() == 0){ran();gameTime.begin();insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}else {long differ = gameTime.differ();g.setColor(Color.white);g.setFont(new Font("微软雅黑",1,20));g.drawString("您坚持了:" + differ+"秒",20,50);//判断最后一个障碍物是否完全进入屏幕内Barrier last = barriers.get(barriers.size() - 1);if(last.isInFrame()){ran();if (number < 50) {insert(600,32,440,4);}else if (number > 450){insert(600,125,200,6);}else {insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}}}
}

在Barrier类添加绘制中间障碍物和移动障碍物

private static final int TYPE_MOBILE = 6;private boolean mob = true;//根据不同的类型绘制障碍物
public void draw(Graphics g) {switch (type){case TYPE_TOP_NORMAL:drawToNormal(g);break;case TYPE_BOTTOM_NORMAL:drawNormalTop(g);break;case TYPE_HOVER_NORMAL:drawHoverNormal(g);break;case TYPE_MOBILE:drawMobile(g);break;}
}//绘制中间的障碍物
public void drawHoverNormal(Graphics g) {//求出所需要的障碍物的块数int count = (height - BARRIER_HEAD_HEIGHT)/ BARRIER_HEIGHT;//绘制上头g.drawImage(images[1],x,y,null);//for循环绘制障碍物for (int i = 0; i < count; i++) {g.drawImage(images[0], x, y+BARRIER_HEAD_HEIGHT+i*BARRIER_HEIGHT, null);}rect(g);//绘制下头int y1 = y+height-BARRIER_HEAD_HEIGHT;g.drawImage(images[2], x, y1, null);x-=speed;if(x < -50){visible = false;}
}//绘制移动的障碍物
public void drawMobile(Graphics g) {//求出所需要的障碍物的块数int count = (height - BARRIER_HEAD_HEIGHT)/ BARRIER_HEIGHT;//绘制上头g.drawImage(images[1],x,y,null);//for循环绘制障碍物for (int i = 0; i < count; i++) {g.drawImage(images[0], x, y+BARRIER_HEAD_HEIGHT+i*BARRIER_HEIGHT, null);}rect(g);//绘制下头int y1 = y+height-BARRIER_HEAD_HEIGHT;g.drawImage(images[2], x, y1, null);x-=speed;if(x < -50){visible = false;}if(mob){y+=5;if(y >= 250){mob = false;}}else if(!mob){y-=5;if(y <= 100){mob = true;}}
}

18 按下空格键查询开始游戏

在GameBarrierLayer类添加方法

//用于清空障碍物的池子
public void restant(){barriers.clear();
}

在Bird类添加方法

//重新绘制小鸟的位置
public void restartDraw(){life = true;x = 200;y = 200;
}

在GameFrame类添加按键事件

@Override
public void update(Graphics g) {if (bird.life) {//得到图片的画笔Graphics graphics = buffimg.getGraphics();gameBackGround.draw(graphics);bird.draw(graphics);gameFrontGround.draw(graphics);gameBarrierLayer.draw(graphics,bird);//一次性的将图片绘制到屏幕中g.drawImage(buffimg, 0, 0, null);}else {String over = "游戏结束";g.setColor(Color.red);g.setFont(new Font("微软雅黑",1,60));g.drawString(over,300,250);String reset = "Space Reset Game";g.drawString(reset,25,350);}
}//按键
public void add(KeyEvent e) {switch (e.getKeyCode()) {case KeyEvent.VK_UP:bird.fly(1);break;case KeyEvent.VK_SPACE:if (bird.life == false) {restart();}break;}
}//重置游戏
public void restart(){gameBarrierLayer.restant();bird.restartDraw();
}

19 记录持久化

先创建一个txt文件,然后写入一条数据

在GameBarrierLayer类创建文件对象

//存储飞行时间
private int txt;File file = new File("birdimg/bird.txt");
//用于得到文件中数据
public int getTxt(){try {BufferedReader in = new BufferedReader(new FileReader(file));int read = Integer.parseInt(in.readLine());in.close();return read;} catch (IOException e) {e.printStackTrace();}return 0;
}//用于存储数据
public void setTxt(String str){try {FileWriter writer = new FileWriter(file);writer.write(str);writer.close();} catch (IOException e) {e.printStackTrace();}
}public void logic(Graphics g){if(barriers.size() == 0){ran();gameTime.begin();insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}else {long differ = gameTime.differ();g.setColor(Color.white);g.setFont(new Font("微软雅黑",1,20));g.drawString("您坚持了:" + differ+"秒",20,50);txt = getTxt();if(differ <= txt){g.drawString("最高成绩:" + txt,200,50);}else {setTxt(differ+"");g.drawString("最高成绩:" + getTxt(),200,50);}//判断最后一个障碍物是否完全进入屏幕内Barrier last = barriers.get(barriers.size() - 1);if(last.isInFrame()){ran();if (number < 50) {insert(600,32,440,4);}else if (number > 450){insert(600,125,200,6);}else {insert(600,0,numberTop,0);insert(600,500-numberDown,numberDown,2);}}}
}

20 游戏优化

在Bird类修改

//小鸟加速度
private int acceleration;//绘制小鸟
public void draw(Graphics g) {flyLogic();g.drawImage(images[state], x, y, null);//绘制小鸟的矩形// g.drawRect(x,y,(int)rect.getWidth(),(int)rect.getHeight());rect.x = this.x;rect.y = this.y;
}//控制小鸟移动方向
public void flyLogic() {if (up) {acceleration--;y+=acceleration;if(acceleration < -10){acceleration = -10;}if (y < 20) {y = 20;acceleration = 0;}}if (!up) {acceleration++;y+=acceleration;if(acceleration > 10){acceleration=10;}if (y > 470) {y = 470;acceleration = 0;}}
}

在Barrier类修改

//绘制障碍物碰撞矩形
public void rect(Graphics g){int x1 = this.x;int y1 = this.y;int w1 = images[0].getWidth();
//        g.setColor(Color.blue);
//        g.drawRect(x1,y1,w1,height);setRecyangle(x1,y1,w1,height);
}

java小游戏-飞翔的小鸟相关推荐

  1. java小游戏——飞翔的小鸟(java初学作品)

    注:学习了java基础后,做出来的一个小作品,可以用来巩固学习 概述: 飞翔的小鸟能够作为Java基础的收官之作,包涵了Java很多的基础知识,在学习完Java基础后,尝试编写一些东西,能够起到很好的 ...

  2. java小游戏 飞翔的小鸟,校园新手入门,分分钟带你玩转编程

    本课程讲解了飞翔的小鸟游戏的详细编写流程,即使你是刚入门java的新手,只要你简单掌握了该游戏所需要的javase基础知识,便可以跟随教程视频完成属于你自己的飞翔的小鸟游戏!同时还可以加深和巩固你对面 ...

  3. Java小游戏------飞翔的小鸟

    我们要做出这个样子的游戏 首先就要分析我们需要创建几个类,有鸟类.柱子类.地面类,然后就是游戏判定.我的思路就是,先创建这几个类,然后把这些类,对应的东西,画到游戏界面上,再确定游戏碰撞机制,当小鸟碰 ...

  4. Java小游戏-飞翔小鸟

    摘 要 Eclipse 是一个开放源代码的.基于Java的可扩展开发平台.就其本身而言,它只是一个框架和一组服务,用于通过插件组件构建开发环境.幸运的是,Eclipse 附带了一个标准的插件集,包括J ...

  5. unity2D小游戏---飞翔的小鸟

    飞翔的小鸟 一.柱子的移动 二.小鸟的控制 三.游戏暂停开始 一.柱子的移动 1.制作柱子:新建空物体,包含上方柱子,下方柱子和空物体(用于计算得分) 2.给柱子和空物体加上适合大小的碰撞体 空物体需 ...

  6. java小游戏------Flappy Bird(飞翔的小鸟含源码)

    前言:本小游戏可作为java入门阶段收尾创作. 需:掌握面向对象的使用,了解多线程和异常处理等知识. 如上图所示:我们需要绘制背景,小鸟,障碍物,当然也包括游戏开始界面以及死亡界面. 一:思路解析: ...

  7. Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码

    源码介绍 Java SpringMVC+H5飞翔的小鸟游戏微信小程序源码 试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏. 包含一些基本的功能:躲避障碍物.计分.排 ...

  8. 【源码+图片素材】Java开发经典游戏飞翔的小鸟_Java游戏项目Flappy Bird像素鸟游戏_Java小游戏_Java初级项目_Java课程设计项目

    开发环境: jdk1.8 开发工具: IDEA JavaEE基础: 变量.数据类型.判断语句.循环结构.数组.集合.简单窗口创建.图形图片绘制.双缓存技术.事件-键盘事件.物体的碰撞检测.File [ ...

  9. 【源码+图片素材+详细教程】Java游戏开发_Java开发经典游戏飞翔的小鸟_飞扬的小鸟_Java游戏项目Flappy Bird像素鸟游戏_Java课程设计项目

    课程目标: 1.通过本课程的学习巩固Java的相关基础知识,例如循环判断,数组和集合的使用,对象的继承,接口的实现,窗口的创建,事件监听,图形绘制. 2.完成小鸟的移动,管道自动生成.碰撞死亡,计分系 ...

最新文章

  1. 卖了5个月水果之后再看互联网思维
  2. confluence添加用户_玩转Confluence插件开发插件模块配置文件介绍(04)
  3. centos 下安装配置nfs服务器
  4. LeetCode 1880. 检查某单词是否等于两单词之和
  5. Android总结篇系列:Activity中几个主要函数详解
  6. 440.字典序中的第K小数字
  7. 如何减小电压跟随器输出电阻_电压跟随器秘笈:LM358电压跟随器+运放问题
  8. 网络知识之----http七层协议
  9. Uclinux、Linux区别
  10. 我在b站上推荐一个看小电影的网站,结果被骂了
  11. 微信授权文件放到域名根目录下
  12. 荣耀4a鸿蒙,华为荣耀4A上手评测:599元也可以很拉轰
  13. python简易自动化之pyautogui 2020-12-19
  14. ATF:Gicv源码文件系列-gicv2.h
  15. S3C22440 JTAG连接不上
  16. 这里记录几个国外的网站
  17. Pytorch下transforms.ToTensor(),transforms.Normalize()详解,及代码实现和复原
  18. 微信小程序底部菜单详解
  19. 1205: 你爱我么?
  20. NOIP2016 天天爱跑步(线段树/桶)

热门文章

  1. Python开发qq批量登陆
  2. cad记忆口诀_42条简单易记的CAD口诀,一天精通入门,七天上手绘图!
  3. trickle_ice 原理
  4. 牛顿迭代法(牛顿-拉弗森方法(Newton-Raphson method))
  5. Java数组讲解(数组,字符串数组,多态数组)
  6. QT中的setAttribute()用法
  7. Advice(通知)的类别有哪些?
  8. rarlinux(rar\unrar在linux使用)
  9. 解决Vmware虚拟机下运行Linux电脑发出声音
  10. 解决ERROR: distribution port 25672 in use by another node: rabbit@