Java实例---flappy-bird实例解析
第一天: 实现背景图片和小鸟的动态飞行效果
package com.ftl.flappybird.day2; import java.awt.Color;//颜色 Color.class import javax.swing.JFrame;//窗口框
import javax.swing.JPanel;//面板 底板 import java.awt.Graphics;
import java.awt.image.BufferedImage;//图片类型 import javax.imageio.ImageIO;//读取图片的工具 /**
* flappyBird
* @author Administrator
*
*/
class MyPanel extends JPanel {
// 声明了背景(background)图变量,没有图片对象
BufferedImage background;
BufferedImage bird;
BufferedImage ground;
BufferedImage column1;
BufferedImage column2;
int x1 = 100;
int y1 = -300;
int x2 = 100 + 245;
int y2 = -280;
int x = 0; // 利用“构造器”初始化变量,读取图片
// 构造器名称与类名一致
public MyPanel() throws Exception {
// 使用ImageIO的read(读)方法
// 将"bg.png"读取为一个图片类型的对象
// background 引用了这个图片对象
background = ImageIO.read(getClass().getResource("bg.png"));
bird = ImageIO.read(getClass().getResource("0.png"));
ground = ImageIO.read(getClass().getResource("ground.png"));
column1 = ImageIO.read(getClass().getResource("column.png"));
column2 = ImageIO.read(getClass().getResource("column.png"));
} // 修改JPanel的绘制方法
// Graphics 图
// paint 涂画
// draw 绘 Image图片 public void paint(Graphics g) {
// 在0,0位置绘制background图片
g.drawImage(background, 0, 0, null);
g.drawImage(bird, 100, 300, null);
g.drawImage(column1, x1, y1, null);
g.drawImage(column2, x2, y2, null);
g.drawImage(ground, x, 500, null);
// int x1 = 100;
// int y1 = -300;
// int x2 = 100 + 245;
// int y2 = -280;
// int x = 0;
} //行动
public void action() throws Exception{
while(true){
x--; //x减1
if(x == -109){
x = 0;
}
x1--;
System.out.println("x1: " + x1);
System.out.println("-colume1。getWidth" + -column1.getWidth());
if (x1 == -column1.getWidth()) {
x1 = 245 * 2 - column1.getWidth();
}
x2--;
System.out.println("x2: " + x2);
System.out.println("-colume2。getWidth" + -column2.getWidth());
if (x2 == -column2.getWidth()) {
x2 = 245 * 2 - column2.getWidth();
}
repaint();
Thread.sleep( 1000 / 30);
}
} } public class Demo2 {
public static void main(String[] args) throws Exception {
// 创建一个窗口框,被frame变量引用
JFrame frame = new JFrame();
// 创建面板,被panel变量引用
// new MyPanel()执行了构造器,装载照片
MyPanel panel = new MyPanel();
// Background 背景,设置背景色=蓝色
panel.setBackground(Color.BLUE);
// 在frame引用的框中添加panel引用的面板
// 框添加面板
frame.add(panel);
frame.setSize(432, 644 + 30);
// setVisible执行的时候,尽快的执行了
// paint 方法
frame.setVisible(true);
frame.setTitle("FlappyBird2017");
frame.setIconImage(ImageIO.read(
Demo2.class.getResource("0.png")));
panel.action();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
第二天:实现小鸟的上下飞行的小狗
package com.ftl.flappybird.day3; import java.awt.Color;//颜色 Color.class
import java.awt.Graphics;
import java.awt.image.BufferedImage;//图片类型
import java.util.Random; import javax.imageio.ImageIO;//读取图片的工具
import javax.swing.JFrame;//窗口框
import javax.swing.JPanel;//面板 底板 /**
* flappyBird
* @author Administrator
*
*/
class MyPanel extends JPanel {
// 声明了背景(background)图变量,没有图片对象
BufferedImage background;
Bird bird; //鸟
Ground ground; //MyPanel中包含地面
Column column1; //为MyPanel添加柱子
Column column2; //为MyPanel添加柱子 // 利用“构造器”初始化变量,读取图片
// 构造器名称与类名一致
public MyPanel() throws Exception {
// 使用ImageIO的read(读)方法
// 将"bg.png"读取为一个图片类型的对象
// background 引用了这个图片对象
background = ImageIO.read(getClass().getResource("bg.png"));
ground = new Ground();
//利用类来创造对象
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();
System.out.println("Demo3");
} // 修改JPanel的绘制方法
// Graphics 图
// paint 涂画
// draw 绘 Image图片 //行动
// TODO 自动生成的方法存根 public void action() throws Exception{
while(true){
this.ground.step();
this.column1.step();
this.column2.step();
this.bird.step(); repaint();
Thread.sleep( 1000 / 30);
}
} public void paint(Graphics g) {
// 在0,0位置绘制background图片
g.drawImage(background, 0, 0, null);
g.drawImage(bird.image, bird.x - bird.width/2,
bird.y - bird.height/2, 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);
g.drawImage(ground.image, ground.x, ground.y, null); }
} class Column{
public int x,y; //x,y是柱子的缝隙中心点
public int width, height; //柱子的宽, 高
public BufferedImage image; //柱子的图片
public int gap; //缝隙
public int distance; //2个柱子之间的距离 //n 代表柱子的编号,如:1,2
public Column(int n) throws Exception{
image = ImageIO.read(Demo3.class.getResource("column.png"));
this.distance = 245;
//这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432
this.x = 550 + (n - 1) * distance;
Random random = new Random();
this.y = random.nextInt(128) + 132;
this.gap = 144;
this.width = image.getWidth();
this.height = image.getHeight();
} public void step(){
this.x--;
if(this.x <= -this.width/2){
this.x = this.distance * 2 - this.width / 2;
Random random = new Random();
this.y = random.nextInt(128) + 132;
}
} } class Ground{
public BufferedImage image;
public int x,y; public Ground() throws Exception{
image = ImageIO.read(getClass().getResource("ground.png"));
this.x = 0;
this.y = 500;
}
public void step(){
this.x--; //x减1
if(this.x == -109){
this.x = 0;
} }
} class Bird{
public BufferedImage image;
public int x,y; //鸟的位置,按照鸟的中心点
public int width, height;
public int size; //鸟的大小,是鸟的碰撞检测范围
public double g; //重力加速度,是浮点类型(小数类型)
public double t; //间隔时间,两次移动的间隔时间
public double s; //两次间隔时间,移动的距离:位移
public double v0; //初始速度
public double speed; //经过时间t以后,的运动速度
public double alpha; //鸟的倾角, 以弧度制为单位 public Bird() throws Exception{
this.image = ImageIO.read(
getClass().getResource("0.png"));
this.x = 132;
this.y = 280;
this.size = 40;
this.g = 4;
this.t = 0.25;
this.v0 = 35;
this.s = 0;
this.speed = this.v0;
this.alpha = 0;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
}
public void step(){
//当前的上抛初始速度
double v0 = speed;
//计算位移
this.s = v0 * t + g * t * t / 2;
this.y = this.y - (int)s;
//计算经过时间t以后的速度,是下次计算
//的初始速度
double v = v0 - g * t;
//将经过时间t以后的速度作为下次的初始速度
this.speed = v;
// System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t + "\tspeed:" + this.speed);
if(this.y >= 280){
this.y = 280;
this.speed = 35;
}
} } public class Demo3 {
public static void main(String[] args) throws Exception {
// 创建一个窗口框,被frame变量引用
JFrame frame = new JFrame();
// 创建面板,被panel变量引用
// new MyPanel()执行了构造器,装载照片
MyPanel panel = new MyPanel();
// Background 背景,设置背景色=蓝色
panel.setBackground(Color.BLUE);
// 在frame引用的框中添加panel引用的面板
// 框添加面板
frame.add(panel);
frame.setSize(432, 644 + 30);
//居中 Location位置 Relative相对 To于 空
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("FlappyBird2017");
frame.setIconImage(ImageIO.read(
Demo3.class.getResource("0.png")));
// setVisible执行的时候,尽快的执行了
// paint 方法
frame.setVisible(true);
panel.action();
}
}
第三天: 添加小鸟飞行时候的动态表情
package com.ftl.flappybird.day4; import java.awt.Color;//颜色 Color.class
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;//图片类型
import java.util.Random; import javax.imageio.ImageIO;//读取图片的工具
import javax.swing.JFrame;//窗口框
import javax.swing.JPanel;//面板 底板 /**
* flappyBird
*
* @author Administrator
*
*/
public class Demo4 extends JPanel {
// 声明了背景(background)图变量,没有图片对象
BufferedImage background;
Bird bird; // 鸟
Ground ground; // MyPanel中包含地面
Column column1; // 为MyPanel添加柱子
Column column2; // 为MyPanel添加柱子 public Demo4() throws Exception {
background = ImageIO.read(getClass().getResource("bg.png"));
ground = new Ground();
// 利用类来创造对象
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();
} /**
* 重新复写paint,增加旋转
*/
public void paint(Graphics g) {
g.drawImage(background, 0, 0, null);
g.drawImage(bird.image, bird.x - bird.width / 2, bird.y - bird.height
/ 2, 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);
g.drawImage(ground.image, ground.x, ground.y, null);
//旋转绘图坐标系
Graphics2D g2 = (Graphics2D) g;//向下转型
g2.rotate(-this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标
g.drawImage(bird.image, bird.x - bird.width / 2,
bird.y - bird.height / 2, null);
g2.rotate(this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 } public void action() throws Exception {
while (true) {
this.ground.step();
this.column1.step();
this.column2.step();
this.bird.step();
this.bird.fly();
repaint();
Thread.sleep(1000 / 60);
}
} public static void main(String[] args) throws Exception {
// 创建一个窗口框,被frame变量引用
JFrame frame = new JFrame();
// 创建面板,被panel变量引用
// new MyPanel()执行了构造器,装载照片
Demo4 panel = new Demo4();
// Background 背景,设置背景色=蓝色
panel.setBackground(Color.BLUE);
// 在frame引用的框中添加panel引用的面板
// 框添加面板
frame.add(panel);
frame.setSize(432, 644 + 30);
//居中 Location位置 Relative相对 To于 空
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("FlappyBird2017");
frame.setIconImage(ImageIO.read(
Demo4.class.getResource("0.png")));
// setVisible执行的时候,尽快的执行了
// paint 方法
frame.setVisible(true);
panel.action(); }
} class Column {
public int x, y; // x,y是柱子的缝隙中心点
public int width, height; // 柱子的宽, 高
public BufferedImage image; // 柱子的图片
public int gap; // 缝隙
public int distance; // 2个柱子之间的距离 // n 代表柱子的编号,如:1,2
public Column(int n) throws Exception {
image = ImageIO.read(Demo4.class.getResource("column.png"));
this.distance = 245;
// 这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432
this.x = 550 + (n - 1) * distance;
Random random = new Random();
this.y = random.nextInt(128) + 132;
this.gap = 144;
this.width = image.getWidth();
this.height = image.getHeight();
} public void step() {
this.x--;
if (this.x <= -this.width / 2) {
this.x = this.distance * 2 - this.width / 2;
Random random = new Random();
this.y = random.nextInt(128) + 132;
}
} } class Ground {
public BufferedImage image;
public int x, y; public Ground() throws Exception {
image = ImageIO.read(getClass().getResource("ground.png"));
this.x = 0;
this.y = 500;
} public void step() {
this.x--; // x减1
if (this.x == -109) {
this.x = 0;
} }
} class Bird {
public BufferedImage image;
public int x, y; // 鸟的位置,按照鸟的中心点
public int width, height;
public int size; // 鸟的大小,是鸟的碰撞检测范围
public double g; // 重力加速度,是浮点类型(小数类型)
public double t; // 间隔时间,两次移动的间隔时间
public double s; // 两次间隔时间,移动的距离:位移
public double v0; // 初始速度
public double speed; // 经过时间t以后,的运动速度
public double alpha; // 鸟的倾角, 以弧度制为单位 public int index; //动画帧数组元素的小标位置
public BufferedImage images[]; //一组图片作为鸟的动画帧 public Bird() throws Exception {
this.image = ImageIO.read(getClass().getResource("0.png"));
this.images = new BufferedImage[8];
this.x = 132;
this.y = 280;
this.size = 40;
this.g = 4;
this.t = 0.25;
this.v0 = 35;
this.s = 0;
this.speed = this.v0;
this.alpha = 0;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
for(int i = 0 ; i < 8; i++){
images[i] = ImageIO.read(getClass().getResource(i + ".png"));
}
this.index = 0;
} public void fly(){
this.index++;
image = images[(index / 12) % 8];
} public void step() {
// 当前的上抛初始速度
double v0 = speed;
// 计算位移
this.s = v0 * t + g * t * t / 2;
this.y = this.y - (int) s;
// 计算经过时间t以后的速度,是下次计算
// 的初始速度
double v = v0 - g * t;
// 将经过时间t以后的速度作为下次的初始速度
this.speed = v;
// System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t +
// "\tspeed:" + this.speed);
if (this.y >= 400) {
this.y = 280;
this.speed = 35;
}
//调用Java API提供的反正切函数,计算倾角
this.alpha = Math.atan(s / 8 );
} }
第四天: 添加鼠标控制小鸟的飞行
package com.ftl.flappybird.day5; import java.awt.Color;//颜色 Color.class
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;//图片类型
import java.util.Random; import javax.imageio.ImageIO;//读取图片的工具
import javax.swing.JFrame;//窗口框
import javax.swing.JPanel;//面板 底板 /**
* flappyBird
*
* @author Administrator
*
*/
public class Demo5 extends JPanel {
// 声明了背景(background)图变量,没有图片对象
BufferedImage background;
BufferedImage gameoverImg; //游戏结束
Bird bird; // 鸟
Ground ground; // MyPanel中包含地面
Column column1; // 为MyPanel添加柱子
Column column2; // 为MyPanel添加柱子
int score; //游戏分数
boolean gameOver;
boolean started; public Demo5() throws Exception {
background = ImageIO.read(getClass().getResource("bg.png"));
gameoverImg= ImageIO.read(
getClass().getResource("gameover.png"));
ground = new Ground();
// 利用类来创造对象
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();
this.score = 0;
this.gameOver = false;
} /**
* 重新复写paint,增加旋转,增加分数
*/
public void paint(Graphics g) {
g.drawImage(background, 0, 0, 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);
g.drawImage(bird.image, bird.x - bird.width / 2, bird.y - bird.height
/ 2, null);
g.drawImage(ground.image, ground.x, ground.y, null); //增加分数算法
Font font = new Font(Font.SANS_SERIF,Font.BOLD,40);
g.setFont(font);
g.drawString("" + score, 40 , 60);
g.setColor(Color.WHITE);
g.drawString(""+score, 40-3, 60-3); g.drawImage(ground.image, ground.x,ground.y,null);
if(gameOver){
g.drawImage(gameoverImg, 0, 0, null);
return;
} //旋转绘图坐标系
Graphics2D g2 = (Graphics2D) g;//向下转型
g2.rotate(-this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标
g.drawImage(bird.image, bird.x - bird.width / 2,
bird.y - bird.height / 2, null);
g2.rotate(this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 } //增加鼠标控制
public void action() throws Exception {
MouseListener l = new MouseAdapter() {
public void mousePressed(MouseEvent e){
started = true;
bird.flappy();
}
};
this.addMouseListener(l); while (true) {
//增加积分逻辑
if(!gameOver || started){ this.ground.step();
this.column1.step();
this.column2.step();
this.bird.step();
}
this.bird.fly();
this.ground.step(); //判断是否撞了
if(this.bird.hit(ground) || this.bird.hit(column1) || this.bird.hit(column2)){
this.gameOver = true; //游戏结束
} this.bird.fly(); //增加计分操作,柱子的x坐标和鸟的x坐标重合
if(this.bird.x == this.column1.x ||
this.bird.x == this.column2.x)
{
this.score++;
}
repaint();
Thread.sleep(1000 / 60);
}
} public static void main(String[] args) throws Exception {
// 创建一个窗口框,被frame变量引用
JFrame frame = new JFrame();
// 创建面板,被panel变量引用
// new MyPanel()执行了构造器,装载照片
Demo5 panel = new Demo5();
// Background 背景,设置背景色=蓝色
panel.setBackground(Color.BLUE);
// 在frame引用的框中添加panel引用的面板
// 框添加面板
frame.add(panel);
frame.setSize(432, 644 + 30);
//居中 Location位置 Relative相对 To于 空
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("FlappyBird2017");
frame.setIconImage(ImageIO.read(
Demo5.class.getResource("0.png")));
// setVisible执行的时候,尽快的执行了
// paint 方法
frame.setVisible(true);
panel.action(); }
} class Column {
public int x, y; // x,y是柱子的缝隙中心点
public int width, height; // 柱子的宽, 高
public BufferedImage image; // 柱子的图片
public int gap; // 缝隙
public int distance; // 2个柱子之间的距离
Random random = new Random();
// n 代表柱子的编号,如:1,2
public Column(int n) throws Exception {
image = ImageIO.read(Demo5.class.getResource("column.png"));
this.distance = 245;
// 这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432
this.x = 550 + (n - 1) * distance;
this.y = random.nextInt(128) + 132;
this.gap = 144;
this.width = image.getWidth();
this.height = image.getHeight();
} public void step() {
this.x--;
if (this.x == -this.width / 2) {
this.x = this.distance * 2 - this.width / 2;
this.y = random.nextInt(128) + 132;
}
} } class Ground {
public BufferedImage image;
public int x, y;
public int width,heigth;
public Ground() throws Exception {
image = ImageIO.read(getClass().getResource("ground.png"));
this.x = 0;
this.y = 500;
this.width = image.getWidth();
this.heigth = image.getHeight();
} public void step() {
this.x--; // x减1
if (this.x == -109) {
this.x = 0;
} }
} class Bird {
public BufferedImage image;
public int x, y; // 鸟的位置,按照鸟的中心点
public int width, height;
public int size; // 鸟的大小,是鸟的碰撞检测范围
public double g; // 重力加速度,是浮点类型(小数类型)
public double t; // 间隔时间,两次移动的间隔时间
public double s; // 两次间隔时间,移动的距离:位移
public double v0; // 初始速度
public double speed; // 经过时间t以后,的运动速度
public double alpha; // 鸟的倾角, 以弧度制为单位 public int index; //动画帧数组元素的小标位置
public BufferedImage images[]; //一组图片作为鸟的动画帧 public Bird() throws Exception {
this.image = ImageIO.read(getClass().getResource("0.png"));
this.images = new BufferedImage[8];
this.x = 132;
this.y = 280;
this.size = 10;
this.g = 1;
this.t = 0.25;
this.v0 = 10;
this.s = 0;
this.speed = this.v0;
this.alpha = 0;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
for(int i = 0 ; i < 8; i++){
images[i] = ImageIO.read(getClass().getResource(i + ".png"));
}
this.index = 0;
} //实现鼠标控制
public void flappy() {
//重新设置初始速度,重新开始飞
this.speed = v0;
} //鸟的撞地检查
public boolean hit(Ground ground){
boolean hit = false;
hit = this.y + this.size / 2 > ground.y;
if(hit){
//表示撞地
this.y = ground.y - this.size / 2; //鸟儿放在地上
this.alpha = -Math.PI / 2; //鸟儿旋转效果
}
return hit;
} //鸟儿撞在柱子上
public boolean hit(Column col){
//判断鸟儿在柱子的范围内(this.x 表示主子内的中心位置)
if(this.x > col.x - col.width / 2 - this.size / 2
&& this.x < col.x + col.width / 2 + this.size / 2){
//检查是否在间隙之间
if(this.y > col.y - col.gap / 2 + this.size / 2
&& this.y < col.y + col.gap / 2 - this.size / 2){
return false;
}
return true;
}
return false;
} //实现鸟的动图
public void fly(){
this.index++;
image = images[(index / 12) % 8];
} //实现鸟儿的移动
public void step() {
// 当前的上抛初始速度
double v0 = speed;
// 计算位移
this.s = v0 * t + g * t * t / 2;
this.y = this.y - (int) s;
// 计算经过时间t以后的速度,是下次计算
// 的初始速度
double v = v0 - g * t;
// 将经过时间t以后的速度作为下次的初始速度
this.speed = v;
// System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t +
// "\tspeed:" + this.speed);
// if (this.y >= 400) {
// this.y = 280;
// this.speed = 35;
// }
//调用Java API提供的反正切函数,计算倾角
this.alpha = Math.atan(s / 8 );
} }
第五天:细节调整
package com.ftl.flappybird.day6; import java.awt.Color;//颜色 Color.class
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;//图片类型
import java.util.Random; import javax.imageio.ImageIO;//读取图片的工具
import javax.swing.JFrame;//窗口框
import javax.swing.JPanel;//面板 底板 /**
* flappyBird
*
* @author Administrator
*
*/
public class Demo6 extends JPanel {
// 声明了背景(background)图变量,没有图片对象
BufferedImage background;
BufferedImage gameStartImg; //游戏开始
BufferedImage gameoverImg; //游戏结束
Bird bird; // 鸟
Ground ground; // MyPanel中包含地面
Column column1; // 为MyPanel添加柱子
Column column2; // 为MyPanel添加柱子
int score; //游戏分数
boolean gameOver; //游戏结束
boolean started; //游戏开始 //游戏状态
int state;
public static final int START = 0;
public static final int RUNNING = 1;
public static final int GAME_OVER = 2; public Demo6() throws Exception {
state = START; //游戏一开始进入开始状态
gameStartImg = ImageIO.read(getClass().getResource("start.png"));
background = ImageIO.read(getClass().getResource("bg.png"));
gameoverImg= ImageIO.read(
getClass().getResource("gameover.png"));
ground = new Ground();
// 利用类来创造对象
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();
this.score = 0;
// this.gameOver = false;
} /**
* 重新复写paint,增加旋转,增加分数
*/
public void paint(Graphics g) {
g.drawImage(background, 0, 0, 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);
g.drawImage(bird.image, bird.x - bird.width / 2, bird.y - bird.height
/ 2, null);
g.drawImage(ground.image, ground.x, ground.y, null); //增加分数算法
Font font = new Font(Font.SANS_SERIF,Font.BOLD,40);
g.setFont(font);
g.drawString("" + score, 40 , 60);
g.setColor(Color.WHITE);
g.drawString(""+score, 40-3, 60-3); g.drawImage(ground.image, ground.x,ground.y,null);
// if(gameOver){
// g.drawImage(gameoverImg, 0, 0, null);
// return;
// }
switch (state) {
case GAME_OVER:
g.drawImage(gameoverImg, 0, 0, null);
break;
case START:
g.drawImage(gameStartImg, 0, 0, null);
break;
}
//旋转绘图坐标系
Graphics2D g2 = (Graphics2D) g;//向下转型
g2.rotate(-this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标
g.drawImage(bird.image, bird.x - bird.width / 2,
bird.y - bird.height / 2, null);
g2.rotate(this.bird.alpha, this.bird.x, this.bird.y);//设置旋转角度和坐标 } //增加鼠标控制
public void action() throws Exception {
MouseListener l = new MouseAdapter() {
public void mousePressed(MouseEvent e){ try {
switch (state) {
case GAME_OVER:
column1 = new Column(1);
column2 = new Column(2);
bird = new Bird();
score = 0;
state = START;
break;
case START:
state = RUNNING;
case RUNNING:
bird.flappy();
}
}catch (Exception e1) {
e1.printStackTrace();
}
}
};
this.addMouseListener(l); while (true) {
// //增加积分逻辑
// if(!gameOver || started){
//
// this.ground.step();
// this.column1.step();
// this.column2.step();
// this.bird.step();
// }
// this.bird.fly();
// this.ground.step();
//
// //判断是否撞了
// if(this.bird.hit(ground) || this.bird.hit(column1) || this.bird.hit(column2)){
// this.gameOver = true; //游戏结束
// }
// this.bird.fly();
// //增加计分操作,柱子的x坐标和鸟的x坐标重合
// if(this.bird.x == this.column1.x ||
// this.bird.x == this.column2.x)
// {
// this.score++;
// }
switch (state) {
case START:
bird.fly();
ground.step();
break;
case RUNNING:
column1.step();
column2.step();
bird.step(); //上下移动
bird.fly(); //动图
ground.step();
//增加计分操作,柱子的x坐标和鸟的x坐标重合
if(this.bird.x == this.column1.x ||
this.bird.x == this.column2.x)
{
this.score++;
}
//判断是否撞了
if(this.bird.hit(ground) || this.bird.hit(column1) || this.bird.hit(column2)){
state = GAME_OVER;//游戏结束
}
break;
} repaint();
Thread.sleep(1000 / 60);
}
} public static void main(String[] args) throws Exception {
// 创建一个窗口框,被frame变量引用
JFrame frame = new JFrame();
// 创建面板,被panel变量引用
// new MyPanel()执行了构造器,装载照片
Demo6 panel = new Demo6();
// Background 背景,设置背景色=蓝色
panel.setBackground(Color.BLUE);
// 在frame引用的框中添加panel引用的面板
// 框添加面板
frame.add(panel);
frame.setSize(432, 644 + 30);
//居中 Location位置 Relative相对 To于 空
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("FlappyBird2017");
frame.setIconImage(ImageIO.read(
Demo6.class.getResource("0.png")));
// setVisible执行的时候,尽快的执行了
// paint 方法
frame.setVisible(true);
panel.action(); }
} class Column {
public int x, y; // x,y是柱子的缝隙中心点
public int width, height; // 柱子的宽, 高
public BufferedImage image; // 柱子的图片
public int gap; // 缝隙
public int distance; // 2个柱子之间的距离
Random random = new Random();
// n 代表柱子的编号,如:1,2
public Column(int n) throws Exception {
image = ImageIO.read(Demo6.class.getResource("column.png"));
this.distance = 245;
// 这个不是一开始就直接小鸟进入图片,有118的距离 550 = 118 + 432
this.x = 550 + (n - 1) * distance;
this.y = random.nextInt(128) + 132;
this.gap = 144;
this.width = image.getWidth();
this.height = image.getHeight();
} public void step() {
this.x--;
if (this.x == -this.width / 2) {
this.x = this.distance * 2 - this.width / 2;
this.y = random.nextInt(128) + 132;
}
} } class Ground {
public BufferedImage image;
public int x, y;
public int width,heigth;
public Ground() throws Exception {
image = ImageIO.read(getClass().getResource("ground.png"));
this.x = 0;
this.y = 500;
this.width = image.getWidth();
this.heigth = image.getHeight();
} public void step() {
this.x--; // x减1
if (this.x == -109) {
this.x = 0;
} }
} class Bird {
public BufferedImage image;
public int x, y; // 鸟的位置,按照鸟的中心点
public int width, height;
public int size; // 鸟的大小,是鸟的碰撞检测范围
public double g; // 重力加速度,是浮点类型(小数类型)
public double t; // 间隔时间,两次移动的间隔时间
public double s; // 两次间隔时间,移动的距离:位移
public double v0; // 初始速度
public double speed; // 经过时间t以后,的运动速度
public double alpha; // 鸟的倾角, 以弧度制为单位 public int index; //动画帧数组元素的小标位置
public BufferedImage images[]; //一组图片作为鸟的动画帧 public Bird() throws Exception {
this.image = ImageIO.read(getClass().getResource("0.png"));
this.images = new BufferedImage[8];
this.x = 132;
this.y = 280;
this.size = 10;
this.g = 1;
this.t = 0.25;
this.v0 = 10;
this.s = 0;
this.speed = this.v0;
this.alpha = 0;
this.width = this.image.getWidth();
this.height = this.image.getHeight();
for(int i = 0 ; i < 8; i++){
images[i] = ImageIO.read(getClass().getResource(i + ".png"));
}
this.index = 0;
} //实现鼠标控制
public void flappy() {
//重新设置初始速度,重新开始飞
this.speed = v0;
} //鸟的撞地检查
public boolean hit(Ground ground){
boolean hit = false;
hit = this.y + this.size / 2 > ground.y;
if(hit){
//表示撞地
this.y = ground.y - this.size / 2; //鸟儿放在地上
this.alpha = -Math.PI / 2; //鸟儿旋转效果
}
return hit;
} //鸟儿撞在柱子上
public boolean hit(Column col){
//判断鸟儿在柱子的范围内(this.x 表示主子内的中心位置)
if(this.x > col.x - col.width / 2 - this.size / 2
&& this.x < col.x + col.width / 2 + this.size / 2){
//检查是否在间隙之间
if(this.y > col.y - col.gap / 2 + this.size / 2
&& this.y < col.y + col.gap / 2 - this.size / 2){
return false;
}
return true;
}
return false;
} //实现鸟的动图
public void fly(){
this.index++;
image = images[(index / 12) % 8];
} //实现鸟儿的移动
public void step() {
// 当前的上抛初始速度
double v0 = speed;
// 计算位移
this.s = v0 * t + g * t * t / 2;
this.y = this.y - (int) s;
// 计算经过时间t以后的速度,是下次计算
// 的初始速度
double v = v0 - g * t;
// 将经过时间t以后的速度作为下次的初始速度
this.speed = v;
// System.out.println("位移:" + this.s + "y:" + this.y + "\tt:" + this.t +
// "\tspeed:" + this.speed);
// if (this.y >= 400) {
// this.y = 280;
// this.speed = 35;
// }
//调用Java API提供的反正切函数,计算倾角
this.alpha = Math.atan(s / 8 );
} }
完整版:Java实例---flappy-bird实例[最终版]
源码下载:点击下载
Java实例---flappy-bird实例解析的更多相关文章
- Flex通信-与Java实现Socket通信实例
Flex通信-与Java实现Socket通信实例 转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...
- Java的位运算符实例——与(&)、非(~)、或(|)、异或(^)
一.Java的位运算符实例——与(&).非(~).或(|).异或(^) 1.与(&) 0 & 2 = 0 0 0 0 0 1 0 0 1 0 2.非(~) ~0 = 7 0 0 ...
- Java-Runoob-高级教程-实例-环境设置实例:4.Java 实例 – 如何查看当前 Java 运行的版本?
ylbtech-Java-Runoob-高级教程-实例-环境设置实例:4.Java 实例 – 如何查看当前 Java 运行的版本? 1.返回顶部 1. Java 实例 - 如何查看当前 Java 运行 ...
- Java-Runoob-高级教程-实例-环境设置实例:3.Java 实例 - 如何执行指定class文件目录(classpath)?
ylbtech-Java-Runoob-高级教程-实例-环境设置实例:3.Java 实例 - 如何执行指定class文件目录(classpath)? 1.返回顶部 1. Java 实例 - 如何执行指 ...
- Java-Runoob-高级教程-实例-环境设置实例:2.Java 实例 – Java 如何运行一个编译过的类文件?
ylbtech-Java-Runoob-高级教程-实例-环境设置实例:2.Java 实例 – Java 如何运行一个编译过的类文件? 1.返回顶部 1. Java 实例 - 如何执行编译过 Java ...
- Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件?
ylbtech-Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件? 1.返回顶部 1. Java 实例 - 如何编译 Java 文件 Java ...
- Java变量类型,实例变量 与局部变量 静态变量
实例变量: 实例变量在类中声明,但在方法的外面,构造函数或任何块. 当空间分配给某个对象在堆中,插槽为每个实例变量创建值. 当一个对象与使用关键字 “new” 来创建,在对象被销毁销毁创建的实例变量. ...
- Java推断类和实例的关系
通常我们使用instanceOf关键字来推断一个对象是否是类的实例,近期博主看到isInstance关键字,不解与instanceOf的差别,故度娘了一下,顺便涨了一下姿势. Java中推 ...
- 关于java中构造方法、实例初始化、静态初始化执行顺序
在Java笔试中,构造方法.实例初始化.静态初始化执行顺序,是一个经常被考察的知识点. 像下面的这道题(刚刚刷题做到,虽然做对了,但是还是想整理一下) 运行下面的代码,输出的结果是... class ...
- java Kafka 简单应用实例
kafka官方中文文档 http://kafka.apachecn.org/ java Kafka 简单应用实例 下面是Linux下的单机模式:https://blog.csdn.net/fct2 ...
随机推荐
- [问题解决]Fresco设置占位图不显示的问题
[问题解决]Fresco设置占位图不显示的问题 /** * Created by diql on 2017/02/15. */ 问题说明 本来设置占位图是通过以下方法: public void set ...
- Javac的命令(-Xlint)
在OptionName类中的枚举定义如下: XLINT("-Xlint"), XLINT_CUSTOM("-Xlint:"), -Xlint Enabl ...
- select2 使用教程
用了这么久的Select2插件,也该写篇文章总结总结.当初感觉Select2不是特别好用,但又找不到比它更好的下拉框插件. 在我的印象里Select2有2个版本,最新版本有一些新的特性,并且更新了一下 ...
- Redis之数据类型Sting字符串
Redis String(字符串) string是redis最基本的类型,你可以理解成与Memcached一模一样的类型,一个key对应一个value. string类型是二进制安全的.意思是redi ...
- 时间格式转换成JUN.13,2017
SimpleDateFormat sdf = new SimpleDateFormat("MMM.dd,yyyy", Locale.ENGLISH); String negotia ...
- thinkphp htmlspecialchars_decode
一 百度编辑器 与 htmlspecialchars_decode *Thinkphp百度编辑器 存的时候为了安全把进行了字符转换,数据库: <p> 测试测试</ ...
- 小程序异步处理demo计时器setInterval()
实现一个计时器/秒 其实就是要求对某字段每秒执行一次更新 这里用到了官方给的定时器 官方API 每秒刷新一次,所以用setInterval()方法 下面给出关键代码: 由于无关代码过多,这里尽可能贴出 ...
- Java 时区转换(UTC+8 到 UTC 等等)
前言:需要做时区转换,知道北京为UTC+8,东京为UTC+9,世界标准时间为UTC,所以下面的代码是只需要知道时区是+8还是+9还是0就可以了,不需要使用"CTT". " ...
- bootstrap fileinput +springmvc图片上传-krajee
引入的文件 <link href="https://cdnjs.cloudflare.com/ajax/libs/bootstrap-fileinput/4.4.9/css/filei ...
- windows操作系统用命令提示符查看占用端口号的进程
在开发中有时我们需要确定哪个占用了8080端口,在windows命令行窗口下执行: 命令执行后打印出来的结果如下所示: