Flapper Bird

目录

一、前言

二、素材准备

1.背景图片

2.背景音乐

三、建立工程

四、代码实现

1.小鸟类

2. 地面类

3.  柱子类

4.  音乐类

5. 游戏类

五、效果展示

六、注意事项

七、心得体会


一、前言

断断续续java学了一个月,想找个项目练练手,于是打算跟着大佬们一起写个《Flapper Bird》小游戏。以下只是我对自己研究该项目的一个小结,记录一下也希望对读者有一定的帮助。

原文链接:

JavaSE实战项目:飞翔的小鸟(完整版)_zjdzka的博客-CSDN博客_javase实战项目

Java小游戏中加背景音乐--有图有真相_一如既往的博客-CSDN博客_java给游戏添加背景音乐

与原文的区别在于:简单设置了游戏等级,添加了背景音乐(由于时间有限,仅任意找了一首歌转换格式导入),以及本人完成该项目的效果展示。

二、素材准备

    1.背景图片

在开发此项目之前,需要先下载一些关于flapper bird的素材图片
        ①开始结束图片
        ②小鸟的飞翔图片
        ③地面背景图片
        ④柱子图片

网盘链接:百度网盘 请输入提取码
        提取码:zjd8

        2.背景音乐

给游戏添加一个背景音乐,因为时间有限,我只是任意找了一首歌转换格式后导入。此项目采用的是.wav格式音频(注意:不可直接更改音频文件后缀名!!!)
        ①背景音乐

音频格式转换网站:在线转换为音频-免费的在线音频转换器

三、建立工程

        1. 创建一个项目工程: Flapper_Bird

        2. 工程下新建一个包:ui

        3. 包下新建五个类: Bird、Ground、Column、Music、Game

        4. 在该工程下导入: ①图片素材②.wav格式背景音乐

四、代码实现

        1.小鸟类

package ui;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;public class Bird {//图片BufferedImage image;//位置int x,y;//宽,高int width,height;//大小int size;//重力加速度double g;//位移的间隔时间double t;//最初上抛速度double v0;//当前上抛速度double speed;//经过时间t后的位移double s;//小鸟的倾角double alpha;//一组图片,记录小鸟的动画帧BufferedImage[] images;//动画帧数组的下标int index;//初始化小鸟public  Bird() throws Exception{//初始化基本参数image = ImageIO.read(new File("0.png"));width = image.getWidth();height = image.getHeight();x=132;y=280;size =40;//初始化位移参数g=8;//4v0=35;//20t=0.2;//0.25speed = v0;s = 0;alpha = 0;//初始化动画帧参数images = new BufferedImage[8];for(int i = 0;i<8;i++){images[i] = ImageIO.read(new File(i+".png"));}index = 0;}//飞行动作(变化一帧)public void fly(){index++;image = images[(index/12)%8];//image = images[(index/12)%8];}//移动一步public void step(){double v0 =speed;//计算上抛运动位移s=v0*t/1.5 + g*t*t/2;// s=v0*t + g*t*t/2;//计算小鸟的坐标位置y=y-(int)s;//计算下次移动速度double v = v0 -g*t;speed = v;//计算倾角alpha = Math.atan(s/15);//alpha = Math.atan(s/8);}//向上飞翔public void flappy(){//重叠速度speed =v0;}//检查小鸟是否碰撞到地面public boolean hit(Ground ground ){boolean hit = y+size/2 > ground.y;if(hit){y = ground.y - size/2;alpha = -3.14159265358979323 / 2;}return hit;}//检查小鸟是否碰到柱子public boolean hit(Column column){//先检测是否在柱子范围内if(x>column.x - column.width /2 - size /2&& x<column.x + column.width/2 + size/2){//检查是否在柱子的缝隙种if(y>column.y - column.gap/2 + size /2&& y<column.y + column.gap /2 -size/2){return false;}return true;}return false;}
}

        2. 地面类

package ui;import java.awt.image.BufferedImage;import javax.imageio.ImageIO;
import java.io.File;public class Ground {//图片BufferedImage image;//位置int x,y;//宽高int width,height;//初始化地面public Ground() throws Exception {image = ImageIO.read(new File("ground.png"));width = image.getWidth();height = image.getHeight();x=0;y=500;}//向左移动一步public void step(){x--;if(x==-100){x = 0;}}
}

        3.  柱子类

package ui;import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Random;public class Column {//图片BufferedImage image;//位置int x,y;//宽高int width,height;//柱子间缝隙int gap;//柱子间距离int distance;//随机数工具Random random = new Random();/*** 初始化第n个柱子*/public Column(int n) throws  Exception{image = ImageIO.read(new File("column.png"));width = image.getWidth();height = image.getHeight();gap = 144;distance = 245;x= 550 + (n-1) * distance;y = random.nextInt(218)+132;}/** 向左移动一步*/public void step(){x--;if(x==-width/2){x = distance * 2 - width/2;y = random.nextInt(218) + 132;}}
}

        4.  音乐类

package ui;import java.io.File;
import java.io.IOException;import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.FloatControl;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;public class Music extends Thread {private String fileName;private final int EXTERNAL_BUFFER_SIZE = 524288;public Music(String wavFile) {this.fileName = wavFile;}@SuppressWarnings("unused")public void run() {File soundFile = new File(fileName); // 播放音乐的文件名if (!soundFile.exists()) {System.err.println("Wave file not found:" + fileName);return;}while (true) { // 设置循环播放AudioInputStream audioInputStream = null; // 创建音频输入流对象try {audioInputStream = AudioSystem.getAudioInputStream(soundFile); // 创建音频对象} catch (UnsupportedAudioFileException e1) {e1.printStackTrace();return;} catch (IOException e1) {e1.printStackTrace();return;}AudioFormat format = audioInputStream.getFormat(); // 音频格式SourceDataLine auline = null; // 源数据线DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);try {auline = (SourceDataLine) AudioSystem.getLine(info);auline.open(format);} catch (LineUnavailableException e) {e.printStackTrace();return;} catch (Exception e) {e.printStackTrace();return;}if (auline.isControlSupported(FloatControl.Type.PAN)) {FloatControl pan = (FloatControl) auline.getControl(FloatControl.Type.PAN);}auline.start();int nBytesRead = 0;byte[] abData = new byte[EXTERNAL_BUFFER_SIZE];try {while (nBytesRead != -1) {nBytesRead = audioInputStream.read(abData, 0, abData.length);if (nBytesRead >= 0)auline.write(abData, 0, nBytesRead);}} catch (IOException e) {e.printStackTrace();return;} finally {auline.drain();
// auline.close();}}}
}

        5. 游戏类

package ui;import javax.imageio.ImageIO;
import javax.swing.*;import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;public class Game  extends JPanel {private static final long serialVersionUID = 1L;//背景图片BufferedImage background;//开始图片BufferedImage startImage;//结束图片BufferedImage gameOverImage;//地面Ground ground;//柱子Column column1,column2;//小鸟Bird bird;//游戏分数int score;//游戏等级int degree;//游戏状态int state;//状态常量public  static  final int START = 0;//开始public  static  final int RUNNING = 1;//运行public  static  final int GAME_OVER = 2;//结束/*** 初始化游戏*/public Game() throws Exception{//初始化background = ImageIO.read(new File("bg.png"));startImage = ImageIO.read(new File("start.png"));gameOverImage = ImageIO.read(new File("gameover.png"));//初始化地面,柱子,小鸟ground = new Ground();column1 = new Column(1);column2 = new Column(2);bird = new Bird();//初始化分数score = 0;//初始化等级degree = 0;//初始化状态state = START;}/*** 绘制界面*/public void paint(Graphics g){//绘制背景g.drawImage(background,0,0,null);//绘制地面g.drawImage(ground.image,ground.x,ground.y,null);//绘制柱子g.drawImage(column1.image,column1.x - column1.width/2,column1.y-column1.height/2,null);g.drawImage(column2.image,column2.x - column2.width/2,column2.y-column2.height/2,null);//绘制小鸟Graphics2D g2 = (Graphics2D) g;g2.rotate(-bird.alpha,bird.x,bird.y);g2.drawImage(bird.image,bird.x - bird.width/2,bird.y-bird.height/2,null);g2.rotate(bird.alpha,bird.x,bird.y);//绘制分数Font f = new Font(Font.SANS_SERIF,Font.BOLD,40);g.setFont(f);g.drawString(""+score,40,60);g.setColor(Color.WHITE);g.drawString(""+score,40-3,60-3);//绘制等级Font d = new Font(Font.SANS_SERIF,Font.BOLD,40);g.setFont(d);for(int i=0;i<degree;i++){g.drawString("*",250+i*20,60);g.setColor(Color.BLUE);g.drawString("*",250+i*20-1,60-1);}//绘制开始和结束界面switch (state) {case START:g.drawImage(startImage, 0, 0, null);break;case GAME_OVER:g.drawImage(gameOverImage, 0, 0, null);break;}}// 开始游戏public void action() throws Exception {// 鼠标监听器MouseListener l = new MouseAdapter() {// 鼠标按下事件public void mousePressed(MouseEvent e) {try {switch (state) {case START:// 在开始状态,按下鼠标则转为运行状态。state = RUNNING;break;case RUNNING:// 在运行状态,按下鼠标则小鸟向上飞行。bird.flappy();break;case GAME_OVER:// 在结束状态,按下鼠标则重置数据,再次转为开始态。column1 = new Column(1);column2 = new Column(2);bird = new Bird();score = 0;degree = 0;state = START;break;}} catch (Exception ex) {ex.printStackTrace();}}};// 将监听器添加到当前的面板上addMouseListener(l);// 不断的移动与重绘while (true) {double grade = 1.0;switch (state) {case START:// 小鸟做出飞行动作bird.fly();// 地面向左移动一步ground.step();break;case RUNNING:if(score > 2){grade = (double)(score *1.0) / 2;degree = (int)grade;}while(grade > 0){// 地面向左移动一步ground.step();// 柱子向左移动一步column1.step();column2.step();grade--;}                     // 小鸟做出飞行动作bird.fly();// 小鸟上下移动一步bird.step();// 计算分数if (bird.x == (column1.x + column1.width/2) || bird.x == (column2.x + column2.width/2)) {score++;}// 检测是否发生碰撞if (bird.hit(ground) || bird.hit(column1) || bird.hit(column2)) {state = GAME_OVER;}break;}// 重新绘制界面repaint();// 休眠 1000/60 毫秒Thread.sleep(1000 / 60);}}/*** 启动方法*/public static void main(String[] args) throws Exception {//背景音乐启动Music audioPlayWave = new Music("intuition.wav");// 开音乐 音樂名audioPlayWave.start();@SuppressWarnings("unused")int musicOpenLab = 1;JFrame frame = new JFrame();Game game = new Game();frame.add(game);frame.setSize(440, 670);frame.setLocationRelativeTo(null);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.setVisible(true);game.action();}}

五、效果展示

1. 开始运行(背景音乐随之播放)

2. 开始游戏                                        3. 游戏结束

六、注意事项

1. 代码中添加的图片与音频必须与导入的路径名一致

2. 报错:Wave file not found:intuition.wav

未导入.wav音频

3. 报错:javax.sound.sampled.UnsupportedAudioFileException: could not get audio input stream from input file at javax.sound.sampled.AudioSystem.getAudioInputStream (AudioSystem.java:1189) at ui.Music.run(Music.java:33)
        导入音频格式有误,不可直接更改音频文件后缀名得到.wav格式音频!

七、心得体会

java小白首次体验了一下小游戏的开发,受益匪浅。在添加图片和音乐上也费了些时间,开始是完全不知道图片和音乐应该加在哪里,接着是音乐格式一直有误,总之实属不易。新手上路,欢迎各位读者留言指导!

Java实战小游戏《flapper Bird》完整版,含源码相关推荐

  1. 【Java实现小游戏】飞翔的小鸟(源码)

    游戏玩法:通过鼠标点击使小鸟上下移动穿过柱子并完成得分,小鸟碰到柱子或掉落到地面上都会结束游戏. (游戏内图片) 下面是实现这个游戏的代码: Brid类: package bird;import or ...

  2. C++小游戏笔记——射击小行星(附源码)

    C++小游戏笔记--射击小行星(附源码) 游戏展示图 一.飞船 1.飞船的绘制 2.飞船的角度 二.小行星 1.小行星的绘制 2."凹凸不平"效果的形成 3.小行星的分裂 三.子弹 ...

  3. 微信小游戏《飞机打方块》源码分享

    微信小游戏<飞机打方块>源码分享 游戏使用CocosCreator v2.4.2开发 源码:https://gitee.com/propertygame/cocos-creator3.x- ...

  4. FC小游戏合集网页版HTML源码

    FC小游戏合集网页版HTML源码,上传到服务器即可访问,包含游戏文件在里面,操作键网页上有列出. 源码下载:FC小游戏合集网页版HTML源码-小程序文档类资源-CSDN下载

  5. cocos creator 2.4.5消除小游戏新玩法消星星源码H5+安卓+IOS三端源码

    cocos creator 2.4.5消除小游戏新玩法消星星源码H5+安卓+IOS三端源码,开发脚本为typeScript方便扩展和阅读,支持cocos creator2.X版本,完整的源码可直接运营 ...

  6. QT界面免费版开源图片转文字工具程序完整版附源码

    QT界面免费版开源图片转文字工具程序完整版附源码 需求源码的朋友请留言 操作步骤如下:

  7. 【新手上路】Java必备小游戏——Flappy Bird(飞翔的小鸟)

    <飞翔的小鸟>是一款曾经比较火热的小游戏,本文可以带你你从零开始,一步一步的开发出这款小游戏.如果你只是刚入门java的新手,不用担心,只要你简单掌握了该游戏所需要的javase基础知识, ...

  8. C语言小游戏之扫雷完整版

    C语言小游戏之扫雷 一.游戏介绍 二.游戏步骤及实现的功能 1.初始化雷盘 2.打印雷盘 3.随机布置雷 4.玩家排雷 5.防止玩家第一次被炸死 6.统计所选位置周围八个位置中雷的个数 7.递归拓展已 ...

  9. Java开发的船体程序 超级玛丽小游戏 411 功能非常齐全 完整源码

    今天为大家继续分享泡泡堂小游戏的开发与制作 410,目前系统已经完成了初步功能,后续会进一步完善.整个系统界面漂亮,有完整得源码,希望大家可以喜欢.喜欢的帮忙点赞和关注.一起编程.一起进步!! 开发环 ...

最新文章

  1. 【代码保留】表删除/重命名(含中文与空格)
  2. 使用数字示波器DS6104测量交流信号的幅值和相位
  3. linux 新开窗口到最前,怎么设置一个窗口总是在电脑桌面的最前
  4. Android webservice的用法详细讲解
  5. P3157-[CQOI2011]动态逆序对【CDQ分治,树状数组】
  6. hessian学习笔记
  7. linux基础应用和常用技巧
  8. Zernike函数拟合曲面--MATLAB实现
  9. python-类的装饰器
  10. (55)Verilog HDL双沿采样设计
  11. xenserver 突破VID 2T限制
  12. XenServer 6.5实战:Creating a Storage Repository (CIFS)
  13. 基于QT的超市信息管理系统
  14. openbmc开发29:开关机管理
  15. Ubuntu下deb文件安装方法图文详解
  16. css preserve-3d 使用
  17. arm嵌入式led灯闪烁实验报告_嵌入式ARM键盘控制LED灯实验报告
  18. 项目管理知识体系指南 (四)
  19. android bootload漏洞,一加6手机的Bootloader漏洞可让攻击者控制设备
  20. 蓝桥杯试题 基础练习 数列特征python

热门文章

  1. qt客户端显示服务器发送的图片,qt客户端显示服务器发送的图片
  2. 豪斯医生改名换姓上演《我的“钱”半生》?
  3. 《深入理解Java虚拟机》知识点目录
  4. 2011年网页设计发展趋势
  5. 1824. Minimum Sideway Jumps 贪心和DP方法
  6. Ubuntu 安装截图软件
  7. 之于图片主色调提取算法
  8. 老有所依,得上点技术
  9. 深度学习主机环境配置: Ubuntu16.04+Nvidia GTX 1080i+CUDA8.0+CUDDN6
  10. LightOJ 1079 Just another Robbery