欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

飞翔小鸟思路及代码

程序员文章站 2022-04-07 17:29:52
...

昨天跳着看视频把飞翔小鸟做出来了,下面分享一下我的思路。

先放成品图
飞翔小鸟思路及代码
飞翔小鸟思路及代码
飞翔小鸟思路及代码

和上一篇飞机大战的思路相似:

1.先把窗体做出把背景图放在面板中
2.把游戏背景中地面移动实现
3.把柱子在面板中实现进场及移动
4.把小鸟放在面板中
5.鼠标监听控制小鸟飞行轨迹
6.写判断小鸟与柱子碰撞和与地面碰撞的方法
7.添加计分和游戏结束游戏开始的画面

上面步骤最难的是写判断碰撞的方法…
——————————————————————————————————————————

首先是窗体类:
public class GameFrame extends JFrame{
	public static void main(String[] args) {
		
		GameFrame frame=new GameFrame();
		GamePanel panel =new GamePanel();
		//显示窗体
		frame.setVisible(true);
		//向窗体内添加一块画板
		frame.add(panel);	
	}
	
	public GameFrame() {
		setTitle("飞翔小鸟");// 设置标题
		setSize(432, 644);//窗体尺寸
		setLocationRelativeTo(null);// 相对于屏幕左上角居中
		setResizable(false);// 设置不允许玩家拖动界面
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//设置Logo图标 img/0.png
	  setIconImage(ImageUtil.getImage("/img/0.png"));
	}
}

这是一个获取图片字节流的工具类:
public class ImageUtil {
	public static BufferedImage getImage(String path) {
		try {
			BufferedImage image = ImageIO.read(ImageUtil.class.getResource(path));
			return image;
		} catch (IOException e) {
			// TODO 自动生成的 catch 块
			e.printStackTrace();
		}
		return null;

	}
}
地面类:
public class Ground {
	/*
	 * 定义地方的x,y坐标和宽高
	 */
	int x;
	int y;
	int w;
	int h;
	BufferedImage img;
		//地面的构造器用来构建地面对象
		public Ground() {
			img=ImageUtil.getImage("/img/ground.png");
			h=img.getHeight();
			w=img.getWidth();
			x=0;
			y=644-h;
		}
		
		public void Move() {
			//让地面能够一直往左边移动
			if(x<=-(w-432)) {
				x=25; //初始化x为25 刷新时没有明显的断层
			}else {
			x--;
			}
		}
}

这个是柱子类:
public class Column {
	/*
	 * 定义地方的x,y坐标和宽高
	 */
	int x;
	int y;
	int w;
	int h;
	Random ran = new Random();
	BufferedImage img;
	// 安全间隙
	int gap;

	// 构造器初始化构造柱子对象(i表示第几根柱子)
	public Column(int i) {
		img = ImageUtil.getImage("/img/column.png");
		h = img.getHeight() / 2;
		w = img.getWidth() / 2;
		x = 320 + (i - 1) * 245;
		y = -ran.nextInt(h + 146 - 644 + 1);
		// 初始化安全间隙
		gap = 75;
	}

	// 柱子移动
	public void Move() {
		if (x <= -w) {
			x = 432 + w;
			y = -ran.nextInt(h + 146 - 644 + 1);
		} else {
			x--;

		}
	}

}

这个是小鸟类(判断碰撞方法写在这里):
public class Bird {
	/*
	 * 定义地方的x,y坐标和宽高
	 */
	int x;
	int y;
	int w;
	int h;
	// 初速度
	double v0;
	// 时间间隔(往上移动的时间)
	double t;
	// 距离
	double s;
	// 重力
	double g;
	Random ran = new Random();
	BufferedImage img;

	List<BufferedImage> list;

	public Bird() {
		img = ImageUtil.getImage("/img/0.png");
		w = img.getWidth() / 2;
		h = img.getHeight() / 2;
		x = 100;
		y = 200;

		// 初始化初速度
		v0 = 2;
		// 时间
		t = 0.15;
		// 距离
		s = 0;
		// 重力
		g = 8;

		// 初始化装图片的容器
		list = new ArrayList<BufferedImage>();
		// 向容器中添加图片
		for (int i = 0; i < 8; i++) {
			list.add(ImageUtil.getImage("/img/" + i + ".png"));
		}
	}

	int index = 0;

	// 小鸟飞行时图片的切换效果
	public void fly() {
		if (index < 8) {
			img = list.get(index);
			index++;
		} else {
			index = 0;
		}
	}

	// 小鸟移动方法
	public void move() {
		// 计算小鸟上抛的距离
		s = v0 * t;
		// 得到小鸟上抛到最高点时的y坐标
		y = (int) (y - s);
		// 计算出小鸟到达最高点时的速度
		double v2 = v0 - g * t;
		// 最高点的速度就是小鸟下落时的初速度
		v0 = v2;
	}

	public void moveUp() {
		v0 = 15;
	}

	// 判断是否碰撞到天花板和地面
	public boolean hit() {
		if (y <= 0 || y >= 644 - 146 - h) {

			return true;
		}
		return false;
	}

	// 判断是否碰撞柱子
	public boolean hit(Column column) {
		if (x >= column.x - w && x <= column.x + column.w) {
			if (y > column.h / 2 + column.y - column.gap / 2 && y < column.h / 2 + column.y + column.gap / 2 - h) {
				return false;// 安全通过
			}
			return true;// 撞到了
		}
		return false;// 没撞到

	}

}

最后是画板类:
public class GamePanel extends JPanel {
	BufferedImage bg;//背景图
	/*
	 * 声明地面和柱子的对象
	 */
	Ground ground;
	Column column1;
	Column column2;
	Bird bird;//声明小鸟对象
	/*
	 * 接收三个碰撞条件的变量
	 */
	boolean bool1 ;
	boolean bool2;
	boolean bool3;
	// 游戏准备状态
	boolean start;//是否start
	boolean GameOver;//是否Gameover
	int socre;//分数

	public GamePanel() {
		bg = ImageUtil.getImage("/img/bg.png");
		ground = new Ground();
		column1 = new Column(1);
		column2 = new Column(2);
		bird = new Bird();

		// 监听鼠标
		MouseAdapter md = new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				// TODO 自动生成的方法存根
				super.mouseClicked(e);
				/*
				 * 当游戏为未开始时,点击鼠标为开始,执行start中的线程任务
				 */
				if (start == false) {
					start = true;
					start();
				} else if(GameOver){//当游戏结束时,点击鼠标为未开始,Gameover为否,并初始化画板中的各个对象
					start=false;
					GameOver=false;
					ground = new Ground();
					//初始化柱子对象
					column1 = new Column(1);//x = 300
					//初始化第二根柱子
					column2 = new Column(2);//x = 545
					//初始化鸟对象
					bird = new Bird();
					System.out.println("你的得分为 : "+socre);
					socre=0;
					repaint();
				}else{//游戏进行时,点击鼠标执行moveUp()方法
					bird.moveUp();
				}
			}

		};
		addMouseListener(md);
		addMouseMotionListener(md);
	}

	// 游戏开始的方法
	public void start() {
		MyThread mt = new MyThread();
		// 将线程所有执行的任务装入到线程对象中
		Thread t = new Thread(mt);
		// 将线程纳入线程调度
		t.start();// 告诉CPU可以给我这个线程分配时间片段了
	}

	@Override
	public void paint(Graphics g) {
		super.paint(g);
		g.drawImage(bg, 0, 0, null);// 添加背景
		g.drawImage(column1.img, column1.x, column1.y, column1.w, column1.h, null);// 添加第一根柱子
		g.drawImage(column2.img, column2.x, column2.y, column2.w, column2.h, null);// 添加第二根柱子
		g.drawImage(ground.img, ground.x, ground.y, null);// 添加地面
		g.drawImage(bird.img, bird.x, bird.y, bird.w, bird.h, null);// 添加第二根柱子
		/*
		 * 当游戏为未开始时,把准备页面画上去
		 */
		if(start==false) {
			g.drawImage(ImageUtil.getImage("/img/start.png"), 0, 0, null);
		}
		/*
		 * 当游戏为结束时,把结束页面面画上去
		 */
		if(GameOver) {
			g.drawImage(ImageUtil.getImage("/img/gameover.png"), 0, 0, null);
		}	
		//画板中字体设置
			Font f=new Font("宋体",Font.BOLD,18);
			g.setFont(f);
			g.setColor(Color.white);
			g.drawString("分数 :"+ socre, 20, 30);
	}
	//线程类
	class MyThread implements Runnable {
		//写在run()方法中,就可以用线程的方法同时进行判断
		@Override
		public void run() {
			/*
			 * 用死循环方式不断运行对象的方法
			 */
			while (true) {
				ground.Move();
				column1.Move();
				column2.Move();
				bird.fly();
				bird.move();
				bool1 = bird.hit();
				bool2 = bird.hit(column1);
				bool3 = bird.hit(column2);
				if (bool1||bool2||bool3) {
					GameOver = true;// 窗体内的对象全部静止
					break;// 结束循环
				}
				if(bird.x==column1.x+column1.w||bird.x==column2.x+column2.w) {
					socre++;//分数加一
				}
				try {
					Thread.sleep(20);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				repaint();//刷新画面
			}
		}
	}
}

需要素材或者源码的可以在下方留言哦…

相关标签: 小游戏