Flappy bird

前言

嘛,这次是用java编写的Flappy bird,主要是本人最近新学习了多线程的使用,想试试手,变想出来做一个flappy bird的游戏,做出来后的大致效果还行吧2333但也需要进一步改进,还得多搞点事情

使用到的类

这一次使用了比较多的类,算下来好像10个(?)主要是对主要的部分都进行了一定程度的封装,虽然数量多了些,但代码更加清晰了,还算挺划算的

代码

话不多说,直接上代码吧(说太多也不知道有没有人看2333)

zhu类
因为Flappy bird 里面有障碍物,这里是用这个类来记录柱子的长度,并且在这里面执行后续话柱子的操作

public class zhu {
	int lenth;
	zhanai za;
	public zhu(int lenth,zhanai za){
		this.lenth=lenth;
		this.za=za;
	}
	public int draw(Graphics g,int width,int high,int n,int i,zhu zu){
		System.out.println("Next");
		ImageIcon ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\下柱.png");
	    Image ii = ol.getImage();
		g.drawImage(ii, width / 4 * (i + 1) - n, high - zu.lenth - 18, 30, zu.lenth, null);
		ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\上柱.png");
		ii = ol.getImage();
		g.drawImage(ii, width / 4 * (i + 1) - n, 0, 30, (high) * 2/3 - zu.lenth, null);
		for(int x=Math.max(width / 4 * (i + 1) - n,0);x<Math.min(width / 4 * (i + 1) - n+30,width);x++)
		{
			for(int y=high - zu.lenth - 18;y<high-18;y++)za.tu[x][y]=1;
			for(int y=0;y<(high) * 2/3 - zu.lenth;y++)za.tu[x][y]=1;
		}
		return 0;
	}
	
}

bird类
这个类就是对鸟的位置的一个确定,并在该类中画鸟和确定游戏是否结束。

public class Bird {
	int x;
	int y;
	int width, high;
	int zen = 0;
	newzhu k1;
	ClearScreen k2;
	JButton bu1;
	zhanai za;

	public Bird(int x, int y, JButton bu1, zhanai za, int width, int high) {
		this.x = x;
		this.y = y;
		this.width = width;
		this.high = high;
		this.bu1 = bu1;
		this.za = za;
	}

	public void draw(Graphics g) {
		y++;
		if (zen > 0) {
			y -= 4;
			zen--;
		}
		ImageIcon ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\鸟.png");
		Image ii = ol.getImage();
		g.drawImage(ii, x, y, 30, 30, null);
		for (int i = x; i < x + 30; i++)
			for (int j = y; j < y + 30; j++) {
				if (za.tu[i][j] == 1) {
					k1.change();
					k2.change();
					bu1.setText("游戏结束");
					BufferedImage bi = new BufferedImage(width, high, BufferedImage.TYPE_INT_ARGB);
					Graphics g2 = bi.getGraphics();
					ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\游戏结束.png");
					ii = ol.getImage();
					g2.drawImage(ii, 0, 0, width, high, null);
					g.drawImage(bi,350,100,width-700,high-200,null);
					return;
				}
			}
	}
}

Back类
这个就是用来画背景的,天空和陆地啥的,这样每次调用就比较方便

public class Back {
	Bird niao;
	public void draw(Graphics g,int width,int high,int n1){
		ImageIcon ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\背景.jpg");
		Image ii = ol.getImage();
		g.drawImage(ii, 0, 0, width, high, null);
		ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\陆地.png");
		ii = ol.getImage();
		g.drawImage(ii, -n1, high - 18, width + width / 4 * 3, 40, null);
	}
	public void csh(Graphics g,int width,int high,Bird niao){
		ImageIcon ol = new ImageIcon("c:\\Users\\lenovo\\Desktop\\Flappy bird\\背景.jpg");//加背景;
		Image ii = ol.getImage();
		g.drawImage(ii, 0, 0, width, high, null);
		this.niao=niao;
		niao.draw(g);
	}
}

UI类
这个就是这个程序的启动的地方了,就是对界面的一个初始化的类。

public class UI {
	Graphics g;
	int width = 1000, high = 400;
	JFrame k = new JFrame();
	JPanel j1 = new JPanel();
	JPanel j2 = new JPanel();
	JButton bu1 = new JButton("开始");
	public void show() {
		k.setSize(width, high);
		k.setLocationRelativeTo(null);
		k.add(j1, BorderLayout.CENTER);//中心画布
		k.add(j2, BorderLayout.NORTH);
		j2.add(bu1);
		k.setVisible(true);
		g = j1.getGraphics();
		zhanai za=new zhanai(width,high-90);//识别柱子
		Bird niao=new Bird(width/2,high/2-45,bu1,za,width,high-90);//鸟
		Back bg=new Back();
		bg.csh(g, width, high-90, niao);//初始化
		mouslis mou=new mouslis(niao);
		j1.addMouseListener(mou);
		java.util.ArrayList<zhu> kk = new java.util.ArrayList<zhu>();
		ButtonLis u1 = new ButtonLis(high - 90, width, g, kk,bu1,niao,j2,za);
		bu1.addActionListener(u1);//按钮监听器
	}

	public static void main(String[] args) {
		UI wor = new UI();
		wor.show();
	}
}

ButtonLis类
给按钮加的一个监听器,按下开始后游戏开始,游戏结束后点击则恢复到开始界面。

public class ButtonLis implements ActionListener {
	int high, width;
	Graphics g;
	JButton bu1, bu2 = new JButton();
	int flag = 0;
	java.util.ArrayList<zhu> kk = new java.util.ArrayList<zhu>();
	newzhu k1;
	ClearScreen k2;
	Bird niao;
	JPanel j2;
	zhanai za;
	int ci = 0;

	public ButtonLis(int high, int width, Graphics g, java.util.ArrayList<zhu> kk, JButton bu1, Bird niao, JPanel j2,
			zhanai za) {
		this.j2 = j2;
		this.za = za;
		j2.add(bu2);
		this.high = high;
		this.width = width;
		this.g = g;
		this.kk = kk;
		this.bu1 = bu1;
		k1 = new newzhu(kk, high, za);
		this.niao = niao;
		k2 = new ClearScreen(g, width, high, kk, niao, bu2, za);
		k2.csh();
		niao.k1 = k1;
		niao.k2 = k2;// 使鸟的位置可以控制游戏的结束与否
	}

	public void actionPerformed(ActionEvent e) {
		if (flag == 0) {
			bu2.setText("0");
			k1.change();
			k2.change();
			if (ci == 0) {
				k1.start();
				k2.start();
			}
			ci++;
			flag++;
			bu1.setText("暂停");
		} else if (flag % 2 == 1) {
			bu1.setText("继续");
			flag++;
			k1.change();
			k2.change();
		} else if (flag % 2 == 0) {
			bu1.setText("暂停");
			flag++;
			k1.change();
			k2.change();
		}
		String c1 = e.getActionCommand();
		if (c1.equals("游戏结束")) {
			flag = 0;
			k2.csh();
			k1.csh();
			za.csh();
			niao.y = high / 2;
			bu1.setText("开始");
			bu2.setText("0");
			Back bg=new Back();
			bg.csh(g, width, high, niao);
		}
	}
}

ClearScreen类
绘图函数,主要就是实时绘制,从而使画面更新,(丝般顺滑),这里为了解决屏幕老是乱闪的问题,还用了BufferImage,顺利搞定~这里是第一个线程

public class ClearScreen extends Thread {
	Graphics g2;
	int width, high;
	int qi;
	int score=0;
	boolean flag=false;
	java.util.ArrayList<zhu> k = new java.util.ArrayList<zhu>();
	Bird niao;
	JButton bu2=new JButton();
	zhanai za;
	int n = -width / 4 * 3;
	int n2= -width / 4; 
	int n1 = 0, ci = 0;
	public ClearScreen(Graphics g, int width, int high, java.util.ArrayList<zhu> k,Bird niao,JButton bu2,zhanai za) {
		this.g2 = g;
		this.width = width;
		this.high = high;
		this.k = k;
		this.niao=niao;
		this.za=za;
		this.bu2=bu2;
	}
	public void csh(){
		n = -width / 4 * 3;
		n2= -width / 4; 
		n1 = 0;ci = 0;
		flag=false;
		score=0;
	}
	public void run() {
		while (true) {
			String s=""+score;
			bu2.setText(s);
			BufferedImage bi = new BufferedImage(width, high, BufferedImage.TYPE_INT_ARGB);
			Graphics g = bi.getGraphics();
			try {
				Thread.sleep(3);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			if (flag == true) {
				ci++;
				Back jj = new Back();
				jj.draw(g, width, high, n1);
				za.csh();//绘图前清空
				for (int i = 0; i < k.size() && i <= 4; i++) {
					zhu zu = k.get(i);
					zu.draw(g, width, high, n, i, zu);//画出柱子并且加上标记
				}
				if (n >= width / 4)// 柱子动
				{
					k.remove(0);
					n = 0;
				}
				if(n2>=width/4)
				{
					n2=0;
					score++;
					music df=new music(1);
					df.start();
				}
				if (n1 >= width / 4)// 陆地动
					n1 = 0;
				if (ci >= 11) {
					n += 10;
					n1 += 10;
					n2+=10;
					ci = 0;
				}
				niao.draw(g);
				g2.drawImage(bi, 0, 0, width, high, null);// 整个画上去;
			}
		}
	}
	public void change(){
		flag=!flag;
	}
}

newzhu类
创建新的柱子加到队列中,使其可以顺利的继续下去,这是第二个线程。

public class newzhu extends Thread {// 添加新柱子
	private java.util.ArrayList<zhu> k;
	int high;
	boolean flag=false;
	zhanai za;
	public newzhu(java.util.ArrayList<zhu> k, int high,zhanai za) {
		this.k = k;
		this.high = high;
		this.za=za;
	}
	public void csh(){
		 flag=false;
	}
	public void run() {
		while (true) {
			int lenth = (int) (Math.random() * high / 2) + 10;
			zhu zz = new zhu(lenth,za);
			if(flag==true)
				k.add(zz);
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public void change(){
		flag=!flag;
	}
}

mouslis类
这个类主要是作为鼠标监听器使用,每次点击使鸟向上飞一段距离,完成跳跃的效果。

public class mouslis implements MouseListener,MouseMotionListener{
	Bird niao;
	public mouslis(Bird niao){
		this.niao=niao;
	}
    public void mouseClicked(MouseEvent e){
    }
    public void mousePressed(MouseEvent e){
    	//music fly=new music(2);
    	niao.zen+=20;
    //	fly.start();
    }
    public void mouseReleased(MouseEvent e){
    	niao.zen=0;
    }
    public void mouseEntered(MouseEvent e){
    }
    public void mouseExited(MouseEvent e){
    }
    public void mouseDragged(MouseEvent e){
    }
    public void mouseMoved(MouseEvent e){
    }
}

zhanai类
这个类用来存个二维数组,从而来判定是否出现了碰撞。

public class zhanai {
	int width, high;
	int[][] tu = new int[2000][2000];// 储存当前的障碍
	public zhanai(int width,int high){
		this.high=high;
		this.width=width;
	}
	public void csh()// 初始化
	{
		for (int i = 0; i <= width; i++) {
			for (int j = 0; j <= high; j++) {
				tu[i][j]=0;
			}
			tu[i][0] = tu[i][high - 18] = 1;
		}
	}
}

music类
顾名思义,放音乐用的~

public class music extends Thread{
	int n;
	File f = new File("c:\\Users\\lenovo\\Desktop\\Flappy bird\\fly.wav");
	File f2 = new File("c:\\Users\\lenovo\\Desktop\\Flappy bird\\得分.wav");
	URL sy;
	public music(int n){
		this.n=n;
	}
	public void run(){
		if(n==1)this.df();
		if(n==2)this.fly();
	}
	private void fly() {
		try {
			sy = f.toURL();
			AudioClip aau;
			aau = Applet.newAudioClip(sy);// 播放声音文件
			aau.play();
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			aau.stop();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	private void df() {
		try {
			sy = f2.toURL();
			AudioClip aau;
			aau = Applet.newAudioClip(sy);// 播放声音文件
			aau.play();
			try {
				Thread.sleep(2000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			aau.stop();
		} catch (MalformedURLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
}

和之前的国际跳棋不大同,这次算是我做的第一个灵活性较高的游戏了,下一步准备继续玩些大的23333

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值