BirdGame游戏

package yule_01;
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.File;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class BirdGame {

	public static void main(String[] args) throws Exception {
		JFrame frame = new JFrame();
		World world = new World();
		frame.add(world);
		frame.setSize(432+5, 644+20);
		frame.setLocation(300, 0);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		world.action();
//		bird.fly();
	}
}
class World extends JPanel{
	//在World中添加分数
	int score;
	
	Ground ground;
	Column col1,col2;
	Bird bird;
	BufferedImage bg;
	BufferedImage ready;
	BufferedImage gameOver;
	//当前的状态
	int state;
	//是state的取值。定义的状态值
	public static final int READY = 0;
	public static final int RUNNING = 1;
	public static final int GAME_OVER=2;
//	public static final int 
	
	public World() throws Exception{
		bg = ImageIO.read(new File("images/bg.png"));
		col1 = new Column(1);
		col2 = new Column(2);
		ground = new Ground();
		bird = new Bird();
		score = 0;//分数初始值是0
		//在World构造器中初始化图片和状态
		state = READY;
		ready = ImageIO.read(new File("images/start.png"));
		gameOver = ImageIO.read(new File("images/gameover.png"));
	}
	public void paint(Graphics g){
		g.drawImage(bg,0,0,null);
		g.drawImage(col1.img,col1.x-col1.width/2,col1.y-col1.height/2,null);
		g.drawImage(col2.img,col2.x-col2.width/2,col2.y-col2.height/2,null);

		Graphics2D g2 = (Graphics2D)g;//这个是在转换
		g2.rotate(bird.alpha,bird.x,bird.y);	//旋转坐标系	
		g.drawImage(bird.img,bird.x-bird.width/2,bird.y-bird.height/2,null);
		g2.rotate(-bird.alpha,bird.x,bird.y);//这句是旋转坐标系回来,不写的话后面的所有绘制都会转动
		g.drawImage(ground.img,ground.x,ground.y,null);
		//绘制碰撞的检测范围
//		g.drawRect(bird.x-bird.size/2, bird.y-bird.size/2,bird.size,bird.size);
		Font font = new Font(Font.SERIF,Font.BOLD,30);//更改画笔的字体
		g.setFont(font);
		g.drawString("score:"+score,20,40);//这个是绘制一个分数的表
		g.setColor(new Color(0xeeeeee));
		g.drawString("score:"+score,20-2,40-2);
		//往paint方法中添加根据状态绘制界面的代码
		//根据整数进行分支处理的代码是swith语句
		switch(state){
		
		case READY:
			//...1
			g.drawImage(ready,0,0,null);
			break;
		case RUNNING://这里写的是冒号不是分号
			//...2
			break;
		case GAME_OVER:
			//...3
			g.drawImage(gameOver, 0, 0, null);
			break;
		}
	}
	public void action() throws Exception{//在while之前加上
		//创建监听对象,
		MouseListener l = new MouseAdapter(){
			public void mouseClicked(MouseEvent e){
				//在鼠标单击以后执行
				//System.out.println("click");
//				bird.v0=30;
				switch(state){
				case READY:
					state=RUNNING;
//					bird.v0=40;
//					break;
					//上面的写不写都可以,在这个情况下
				case RUNNING:
					bird.v0=20;//这里的值是点击时候给鸟的力。
					break;
				case GAME_OVER:
					//清理变量的值
					score=0;
					try{//这里报错加这个
					bird =new Bird();
					col1 = new Column(1);
					col2 = new Column(2);
					}catch(Exception ex){
						
					}
					state=READY;
					break;
				}
			}
			
		};
		//this这个代表当前的这个world1面板对象
		//addxxx方法就绪 鼠标监听器对象添加到当前面板上了,当鼠标点击了面板,就执行监听器接口的方法
		this.addMouseListener(l);
		
		
		while(true){//上来就先写上这个,死循环。无线进行
//			ground.x--;
//			if(ground.x <= -108){
//				ground.x=0;
//			}
			//ground 地面 step 步伐 地面走一步
			//在step()方法中封装 地面的运动逻辑
			//简化调用代码,增加代码的可续行
//			ground.step();
//			col1.step();
//			col2.step();
//			bird.fly();
//			bird.step();
			//  ||  这个叫或者 or
//			if(bird.duang(col1)||(bird.duang(col2)||bird.duang(ground))){
//				System.out.println("疼");
//			}else{
//				System.out.println("不疼");
//			}
//			if(bird.x == col1.x+col1.width/2 + bird.size/2 ||
//					bird.x== col2.x+col2.width/2+bird.size/2){
//				score++;
//				System.out.print("分数"+score);
//			}
			switch(state){
			case READY:
				bird.fly();
				ground.step();
				break;
			case RUNNING:
				bird.fly();
				ground.step();
				col1.step();
				col2.step();
				bird.step();
				//这里面还有一个关键的数据,计分和碰撞检测
				if(bird.x==col1.x ||bird.x==col2.x){
					score++;
				}
				if(bird.duang(col1)||bird.duang(col2)||bird.duang(ground)){
					state=GAME_OVER;
				}
				break;
			case GAME_OVER:	
				
			}
			
			repaint();
			Thread.sleep(1000/30);
//			col1.x--;
//			if(col1.x<= -col1.width/2){
//				col1.x=col1.distance*2-col1.width/2;
//				Random sc = new Random();
//				col1.y= sc.nextInt(392-102)+102;
//			}
//			col2.x--;
//			if(col2.x<= -col2.width/2){
//				col2.x=col1.distance*2-col2.width/2;
//				Random sc = new Random();
//				col2.y= sc.nextInt(392-102)+102;
//		}

	}
	
}
}
class Column{
	int x,y;
	int width,height;
	int gap;
	int distance;
	BufferedImage img;
	public Column(int index) throws Exception{
		img=ImageIO.read(new File("images/column.png"));
		width = img.getWidth();
		height = img.getHeight();
		gap = 144;
		distance = 300;
		x = 432+width/2 + distance*(index-1);
		Random r = new Random();
		y = r.nextInt(398-102)+102;
	}
	//在Column类的内部
	//添加 step方法表示柱子的移动一步
	public void step(){
		x--;
		if(x<= -width/2){
			x=distance*2-width/2;
			Random sc = new Random();
			y= sc.nextInt(392-102)+102;
		}
	}
	
} 
class Ground{
	int x,y;
	BufferedImage img;
	public Ground() throws Exception{
		img = ImageIO.read(new File("images/ground.png"));
		x=0;
		y=500;
	}
	//在Ground添加step方法封装地面的运动行为
	public void step(){//行为功能,移动一步
		x--;
		if(x <= -108){
			x=0;
		}
		
	}
}
class Bird{
	int x,y;
	int width;
	int height;
	int size;//碰撞检测范围
	double g;//9.8
	double speed;
	double t;
	double v0;
	double vt;
	double s;
	double a;
	double alpha;
	double b;
	
	BufferedImage img;//这个不能少。表示是当前的动画帧
	//数组:存储一个组一样的物体
	//声明images数组存储8张图片(动画帧)
	BufferedImage[] images= new BufferedImage[8];
	int index = 0;//用来标记放映到 那个动画帧
	//images[index % 8]图片周期性更换,能够实现图片的循环播放!
	public Bird() throws Exception{
		//凡是固定次序循环操作室友for循环!
		for(int i=0;i<8;i++){
			images[i]=ImageIO.read(new File("images/"+i+".png"));
		}
		img = images[0];
		x = 132;
		y = 280;
		t = 1.0/5;//写1/30得到的是0,整数除以整数得到整数,小数除以整数得到小数
		v0 = 35;
		s = 0;
		g = 8;
		width=56;
		//在Bird的构造器中:初始化Bird的宽和高;
		height=48;
		a=20;//调整a的值可以改变鸟头的摆动角度大小
		width = 56;
		height=48;
		//在鸟的构造器中。初始化size,碰撞检测范围
		size=40;
		
//      读取8张图片然后写下面的话
//		images[0]=ImageIO.read(new File("images/0.png"));
	}//构造器结束
	
	//在鸟的类中添加方法
	//检测当前鸟与柱子是否发生碰撞,ture撞上,false没撞上。
	public boolean duang(Ground ground){
		//方法的重载:同一个类中出现了两个名字一样的方法
		//方法的参数一定不同,名字一样的不同方法
		return y >=500-size/2;
	}
	
	
	
	public boolean duang(Column col){
		//在柱子范围内,但是不在缝隙中,就发生了碰撞。
		//当前在鸟中的X.Y是鸟的X.Y
		return
		x >col.x-col.width/2-size/2   && 
		x<col.x+col.width/2+size/2    &&
		!( y >col.y-col.gap/2+size/2  &&  y<col.y+col.gap/2-size/2);//括号里面写在缝隙中
		

	}
	//鸟移动有步以后的情况
	public void step(){//在action 方法中调用
		s = v0*t+g*t*t/2;//这个是位移
//		System.out.print("s+"+s+"t+"+t);测试参数
		y = y - (int)s;//强制转换
		vt = v0-g*t;
		v0=vt;
		if(y>500){
//			y=0;
			v0=50;
		}
		//计算鸟的倾角
		b=s;
		alpha = -Math.atan(b/a);
		//java中的角都是弧度制
//		System.out.println("alpha="+alpha);
	}
	//在world构造器添加bird = new Bird();
	//在action()方法中添加bird.fly();
	//在paint()方法中添加g.drawimage(bird.img..)
	public void fly(){
		index++;
		img = images[index/4 % images.length];
	}
	
	
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值