}
import java.awt.Color;
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.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
//继承JPanel,由于原生的JPanel无法完成我们想要的功能
public class BirdGame extends JPanel {
BufferedImage bg,startImage,gameOverImage;
//创建背景,开始,结束的图片对象
Bird bird;
//创建小鸟对象
Column column1,column2;
//创建柱子对象
int score;
//创建分数
boolean startgame,gameover;
//创建开始结束的boolean值
Ground ground;
//创建地面对象
public BirdGame() throws IOException{
//构造方法,初始化各个参数
bg=ImageIO.read(getClass().getResource("bg.png"));
//实例化(读入)背景图片对象
startImage=ImageIO.read(getClass().getResource("start.png"));
//实例化(读入)开始图片对象
gameOverImage=ImageIO.read(getClass().getResource("gameover.png"));
//实例化(读入)结束图片对象
ground=new Ground();
//实例化地面对象
column1=new Column(1);
//实例化柱子对象1
column2=new Column(2);
//实例化柱子对象2
bird=new Bird();
//实例化小鸟对象
score=0;
//初始化
startgame=false;
//初始化开始游戏的booelan值
gameover=false;
//初始化结束游戏的值
}
@Override
public void paint(Graphics g) {
//绘图方法,继承过来的
g.drawImage(bg, 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);
//绘制两根柱子对象,这也说明其实我们只有两根柱子
Font f=new Font(Font.SANS_SERIF, Font.BOLD, 40);
//实例化一个字体对象
g.setFont(f);
//绘制的字的字体为f
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);
//绘制地面
Graphics2D g2=(Graphics2D)g;
//实例化一个g2的2d效果对象
g2.rotate(-bird.aphal, bird.x, bird.y);
//绘制小鸟的倾斜角度
g.drawImage(bird.image, bird.x-bird.width/2,bird.y-bird.height/2, null);
//绘制小鸟
g2.rotate(bird.aphal, bird.x, bird.y);
//配合上面的控制小鸟的倾斜角度
if(gameover){
//开始gameover为false所以不绘制结束的图像
g.drawImage(gameOverImage, 0, 0, null);
//从点(0,0)的地方开始绘制
}
if(!startgame){
//还没点击开始是为false所以先绘制开始状态的图片,覆盖上面的所有图片
g.drawImage(startImage, 0, 0,null);
//从点(0,0)的地方开始绘制
}
}
//小鸟游戏运动的最重要的方法
public void BirdAction() throws IOException{
MouseListener m=new MouseAdapter() {
//添加鼠标点击的监听事件
@Override
public void mousePressed(MouseEvent e) {
//触发事件
if(gameover){
//如果gameover为true说明游戏结束,重新初始化各个参数
try {
column1=new Column(1);
column2=new Column(2);//实例化两根柱子
bird=new Bird();//实例化小鸟对象
ground=new Ground();//实例化地面对象
startgame=false;//开始状态改为false重新回到最初的开始界面
gameover=false;//结束状态改为false
score=0;//分数重置为0
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}else{//如果结束boolean值为false,那么设置开始状态为true,点击小鸟就开始飞
startgame=true;
bird.hitfly();//小鸟的点击飞起方法
}
}
};
this.addMouseListener(m);
//添加鼠标点击监听事件
while(true){
//死循环
if(!gameover&&startgame){
//如果游戏开始了,且没有死,柱子地面开始自己运动,否则停止所有移动
ground.step();//地面运动方法
column1.step();//柱子运动的方法
column2.step();
bird.step();//小鸟运动的方法
bird.fly();//小鸟飞翔的方法,确定是否掉落到地面
if(bird.x==column1.x||bird.x==column2.x){
score++;
//如果过了一根柱子,分数就加1
}
}
synchronized(BirdGame.this){//同步
if(ground.higround(bird)||column1.hitColumn(bird)||column2.hitColumn(bird)){
gameover=true;
//如果掉落到地上游戏结束,触发结束图片显示,停止所有运动
}
}
repaint();
try {
Thread.sleep(1000/60);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
//地面类
public class Ground {
BufferedImage image;
//创建地面图片
int x,y;
//定义图片的坐标
public Ground() throws IOException{
//构造方法初始化各参数
image=ImageIO.read(getClass().getResource("ground.png"));
//读取地面图片
x=0;
//初始化x坐标为0
y=500;
//初始化y坐标为500
}
public void step(){
//地面运动方法
x--;
if(x<=-108){
x=0;
}
}
public boolean higround(Bird bird){
//判断是否碰到地面方法
if(bird.y>=500-bird.width/2){
bird.aphal = -3.14159265358979323/2;
//改变为小鸟为垂直状态
return true;//撞击到地面
}
return false;
}
}
import java.awt.AlphaComposite;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
//小鸟类
public class Bird {
BufferedImage[] images;
//定义图片集
BufferedImage image;
//小鸟当前的图片
int x,y,index;
//小鸟当前坐标和图片的下标
int width,height;
//图片的宽度和高度
double v0,v,t;
//初始速度,实时速度,时间间隔
double g,s;
//重力加速度,运动距离
double aphal;
//小鸟图片倾斜角度
public Bird() throws IOException{
//构造方法初始化各个参数
index=0;
//第一张图片
images=new BufferedImage[8];
for(int i=0;i
images[i]=ImageIO.read(getClass().getResource(i+".png"));
}
//图片的宽度和高度
width=images[0].getWidth();
height=images[0].getHeight();
v0=20;
//促使速度为20
x=132;
y=250;
//坐标为(132,250)
g=4.5;
//重力加速度为4.5(因为9.8太快这里不适合,所以改小了)
t=0.25;
//时间间隔为0.25秒
s=0;
//初始运动距离
v=v0;
//吧初始速度给v(实时速度)
}
public void step(){
//小鸟展翅的效果方法,原理就是切换图片
index++;
image=images[index/8%8];
}
public void fly(){
//小鸟飞的方法
s=v*t-g*t*t/2;
//垂直的运动距离
v=v-g*t;
//实时速度,这是物理公式,实时速度等于初始速度-加速度*时间
y=(int)(y-s);
//算出小鸟的y坐标
aphal = Math.atan(s/8);
//算出倾角
if(y>=500-width/2){
y=500-width/2;
}
//如果掉到地上,就死
}
public void hitfly(){
//点击就飞,其实就是再给一个促使速度
v=20;
}
}
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;
//柱子类
public class Column {
BufferedImage image;
//创建图片对象
int x,y;
//定义柱子的坐标
int width,height;
//定义柱子的高度和宽度
int distance;
//柱子之间的距离
int gap;
//柱子之间的间隙
public Column(int n) throws IOException{
//构造方法,初始化各个参数
image=ImageIO.read(getClass().getResource("column.png"));
//读取柱子图片
distance=240;
//两根柱子之间的距离设置为240
gap=144;
//间隙设置为144
x=500+(n-1)*distance;
//柱子的x坐标,这里以图片中心的坐标为准
Random r=new Random();
//随机生成柱子的y坐标
y=40+gap/2+r.nextInt(460-gap/2-(40+gap/2));
//保证柱子在40+gap/2~460-gap/2
width=image.getWidth();
//获得柱子的宽度
height=image.getHeight();
//获得柱子的高度
}
public void step(){
//柱子运动
x--;
if(x<=-width/2){//当柱子移除界面
x=2*distance-width/2;//初始化下一次柱子的坐标
Random r=new Random();
y=40+gap/2+r.nextInt(460-gap/2-(40+gap/2));
}
}
public boolean hitColumn(Bird bird){
//小鸟是否闯到柱子
int x1=x-width/2-bird.width/2;//得x最小界限
int x2=x+width/2+bird.width/2;//得到x最大范围
int y1=y-gap/2+bird.height/2;//得到y的最小值
int y2=y+gap/2-bird.height/2;//得到y的最大值
//上述是在柱子之间的临界值
if(bird.x>x1&&bird.x
if(bird.y>y1&&bird.y
return false;
}else{
//撞到
return true;
}
}else{
//在柱子之外没有碰到
return false;
}
}
}