第一天: 实现背景图片和小鸟的动态飞行效果

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实例解析的更多相关文章

  1. Flex通信-与Java实现Socket通信实例

    Flex通信-与Java实现Socket通信实例  转自:http://blessht.iteye.com/blog/1136888 博客分类: Flex 环境准备 [服务器端] JDK1.6,“ja ...

  2. Java的位运算符实例——与(&)、非(~)、或(|)、异或(^)

    一.Java的位运算符实例——与(&).非(~).或(|).异或(^) 1.与(&) 0 & 2 = 0 0 0 0 0 1 0 0 1 0 2.非(~) ~0 = 7 0 0 ...

  3. Java-Runoob-高级教程-实例-环境设置实例:4.Java 实例 – 如何查看当前 Java 运行的版本?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:4.Java 实例 – 如何查看当前 Java 运行的版本? 1.返回顶部 1. Java 实例 - 如何查看当前 Java 运行 ...

  4. Java-Runoob-高级教程-实例-环境设置实例:3.Java 实例 - 如何执行指定class文件目录(classpath)?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:3.Java 实例 - 如何执行指定class文件目录(classpath)? 1.返回顶部 1. Java 实例 - 如何执行指 ...

  5. Java-Runoob-高级教程-实例-环境设置实例:2.Java 实例 – Java 如何运行一个编译过的类文件?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:2.Java 实例 – Java 如何运行一个编译过的类文件? 1.返回顶部 1. Java 实例 - 如何执行编译过 Java ...

  6. Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件?

    ylbtech-Java-Runoob-高级教程-实例-环境设置实例:1.Java 实例 – 如何编译一个Java 文件? 1.返回顶部 1. Java 实例 - 如何编译 Java 文件  Java ...

  7. Java变量类型,实例变量 与局部变量 静态变量

    实例变量: 实例变量在类中声明,但在方法的外面,构造函数或任何块. 当空间分配给某个对象在堆中,插槽为每个实例变量创建值. 当一个对象与使用关键字 “new” 来创建,在对象被销毁销毁创建的实例变量. ...

  8. Java推断类和实例的关系

       通常我们使用instanceOf关键字来推断一个对象是否是类的实例,近期博主看到isInstance关键字,不解与instanceOf的差别,故度娘了一下,顺便涨了一下姿势.    Java中推 ...

  9. 关于java中构造方法、实例初始化、静态初始化执行顺序

    在Java笔试中,构造方法.实例初始化.静态初始化执行顺序,是一个经常被考察的知识点. 像下面的这道题(刚刚刷题做到,虽然做对了,但是还是想整理一下) 运行下面的代码,输出的结果是... class ...

  10. java Kafka 简单应用实例

    kafka官方中文文档  http://kafka.apachecn.org/ java Kafka 简单应用实例  下面是Linux下的单机模式:https://blog.csdn.net/fct2 ...

随机推荐

  1. 第十四章、Linux 账号管理与 ACL 权限配置

    1. Linux 的账号与群组 1.1 使用者标识符: UID 与 GID 1.2 使用者账号:/etc/passwd 文件结构, /etc/shadow 文件结构 1.3 关于群组: /etc/gr ...

  2. 图解ARP协议(四)代理ARP原理与实践(“善意的欺骗”)

    一.代理ARP概述 我:当电脑要访问互联网上的服务器,目标MAC是什么? 很多小伙伴在刚学习网络协议的时候,经常这样直接回应:不就是服务器的MAC嘛! 这时我会反问:那电脑怎么拿到这个服务器的MAC地 ...

  3. Linux 的启动流程--转

    http://cloudbbs.org/forum.php?mod=viewthread&tid=17814 半年前,我写了<计算机是如何启动的?>,探讨BIOS和主引导记录的作用 ...

  4. 动态rem解决移动前端适配

    背景 移动前端适配一直困扰很多人,我自己也是从最初的媒体查询,到后来的百分比,再到padding-top这种奇巧淫技,再到css3新单位vw这种过渡转变 但这些都或多或少会有些问题,直到使用了动态re ...

  5. SQL Serever学习15——进阶

    特别说明:在sqlserver2014中,不区分大小写,也就是说,SQL是大小写不敏感的 数据库模型3类: 层次模型 网状模型 关系模型 关系型数据库语言3种: DDL数据定义语言 CREATE(创建 ...

  6. HTTP协议状态码学习

    一直以来都在追求实战,从而忽视了对理论知识的深入学习和理解.这并不可怕,可怕的是当意识到自己的不足时,没有行动. 1xx(临时响应) 表示临时响应并需要请求者继续执行操作的状态代码. 代码   说明 ...

  7. mysql 中优化数据类型的三个原则

    数据类型越小越好 在业务够用的情况下,尽可能选取小的数据类型.不仅占用空间小,而且执行查询等操作时性能好. 越简单越好 对于简单的类型,在处理时会占用更少的 CPU 周期. 例如,整数就比字符类型简单 ...

  8. hdu 1397 (素数判定)

    一开始提交了这个,果断TLE #include <cstdio> #include <iostream> #include <string> #include &l ...

  9. IDEA 2017.2.2 环境下使用JUnit

    JUnit:单元测试框架,测试对象为一个类中的方法. JUnit不是Javase的一部分,想要使用需要导入jar包,在IntelliJ IDEA 中自带JUnit插件. JUnit 版本有3.X 4. ...

  10. 工厂方法模式(GOF23)

    耦合关系直接决定着软件面对变化时的行为 主要对模块之间的关系进行整理,依赖关系倒置(依赖反转),变化快的东西不能影响到变化慢的东西 用封装机制来隔离易变的对象,抽象部分(不易变)和细节部分(可能容易变 ...