用JAVA制作小游戏——飞机大战(二)

本篇博客是对飞机大战游戏使用代码的展示

重难点:

首先需要鼠标能够控制战机,使鼠标在窗口内时始终能够使战机的位置与鼠标相同,实现鼠标控制战斗机移动。
其次需要能够以一定的速度产生子弹和敌机,并且以一定的速度移动,为了实现这部分的功能,我们需要使用线程来完成。(Timer也可以实现这块功能,但过多使用Timer会使程序变得不稳定,会经常报错)JAVA 线程的介绍与使用
再然后就是判断子弹与敌机相撞,战机与敌机相撞,这就需要用到遍历,需要遍历的是场上的子弹与敌机,这就需要我们使用ArrayList来存储场上的敌机与子弹,当敌机与子弹离开画面使,便从ArrayList中移除,这样便可以保证遍历的是场上的敌机与子弹。

鼠标控制战机

class mouse1 extends MouseMotionAdapter{
		@Override
		public void mouseMoved(MouseEvent e) {
			X=e.getX();//得到鼠标X坐标
			Y=e.getY();//得到鼠标Y坐标
			jl2.setLocation(X-30, Y-35);
			//战机根据鼠标设置位置
			//通过监听器,只要鼠标移动就执行,
			//图片根据显示效果更改坐标值
		}
	}

子弹与敌机的产生

//敌机生成(线程代码)
class enemyCreate extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(1000);//1000毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			ImageIcon image_enemy=new ImageIcon("game_image/enemy.png");//敌机图片路径
			enemy[enemy_num]=new JLabel(image_enemy);
			Random random=new Random();
			enemy[enemy_num].setBounds(random.nextInt(image1.getIconWidth()), 0, image_enemy.getIconWidth(), image_enemy.getIconHeight());//设置敌机生成位置和大小(位置横坐标通过Random随机生成)
			layeredPane.add(enemy[enemy_num], JLayeredPane.MODAL_LAYER);
			a1.add(enemy[enemy_num]);//将每一个生成的敌机存放到ArrayList中
			enemy_num++;
			}
		}
	}
//子弹生成(线程代码)
class ammoCreate extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(1000);//1000毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				ImageIcon image_ammo=new ImageIcon("game_image/ammo.png");//子弹图片路径
				ammo[ammo_num]=new JLabel(image_ammo);
				ammo[ammo_num].setBounds(X, Y-40, image_ammo.getIconWidth(), image_ammo.getIconHeight());//子弹位置和大小(X,Y为鼠标的X,Y坐标)
				layeredPane.add(ammo[ammo_num], JLayeredPane.MODAL_LAYER);
				a2.add(ammo[ammo_num]);//将每一个生成的子弹存放到ArrayList中
				ammo_num++;
			}
		}
}

敌机与子弹的移动

//敌机移动(线程代码)
	class enemyMove extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
					a1.get(i).setLocation(a1.get(i).getX(), a1.get(i).getY()+10);//敌机移动,在原基础向下移动10
					if(a1.get(i).getY()>=image1.getIconHeight()) {//敌机移动到窗口外,变得不可见,然后从对应的ArrayList中移除
						a1.get(i).setVisible(false);
						a1.remove(i);
					}
				}
				
			}
		}
	}
	//子弹移动(线程代码)
	class ammoMove extends Thread{
		public void run() {
			while(true) {
				for(int i=0;i<a2.size();i++) {//遍历子弹的ArrayList
					a2.get(i).setLocation(a2.get(i).getX(),a2.get(i).getY()-10);//位置移动,在原基础向上移动10
					if(a2.get(i).getY()<=-30) {//子弹移动到窗口外,变得不可见,然后从对应的ArrayList中移除
						a2.get(i).setVisible(false);
						a2.remove(i);
					}
				}
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

相撞判断

//战机与敌机相撞(线程代码)
	class playerBoom extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
					if(a1.get(i).isVisible()) {//当敌机可视
						if(jl2.getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&jl2.getY()-a1.get(i).getY()>=-jl2.getHeight()) {//敌机与战机相遇
							if(jl2.getX()-a1.get(i).getX()>=-jl2.getWidth()&&jl2.getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
								a1.get(i).setVisible(false);//敌机不可视
								//游戏结束
								new game_plane_3();
								dispose();
								return;//结束该线程
							}
						}
					}
				}
			}
		}
	}
	//子弹与敌机相撞(线程代码)
	class ammoBoom extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
					for(int j=0;j<a2.size();j++) {//遍历子弹对应的ArrayList
						if(a1.get(i).isVisible()&&a2.get(j).isVisible()) {//当子弹与敌机都可视
							if(a2.get(j).getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&a2.get(j).getY()-a1.get(i).getY()>=-10) {//子弹与敌机相遇
								if(a2.get(j).getX()-a1.get(i).getX()>=-a2.get(j).getWidth()&&a2.get(j).getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
									a1.get(i).setVisible(false);//对应的敌机不可视
									a2.get(j).setVisible(false);//对应的子弹不可视
								}
							}
						}
					}
				}
			}
		}
	}

完整代码

import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.*;
public class game_plane_2 extends JFrame{
	ImageIcon image1=new ImageIcon("game_image/background.png");//背景图片路径
	ImageIcon image2=new ImageIcon("game_image/player1.png");//战机图片路径

	JLabel[] enemy=new JLabel[50000];
	ArrayList<JLabel> a1=new ArrayList<JLabel>();//存放敌机
	JLabel[] ammo=new JLabel[50000];
	ArrayList<JLabel> a2=new ArrayList<JLabel>();//存放子弹
	
	JLabel jl1=new JLabel(image1);
	JLabel jl2=new JLabel(image2);
	JLayeredPane layeredPane=new JLayeredPane(); 
	int X=200,Y=500;//记录鼠标位置X,Y
	int enemy_num=0,ammo_num=0;
	public game_plane_2() {
		jl1.addMouseMotionListener(new mouse1());//添加监听器
		jl2.setBounds(X, Y, image2.getIconWidth(), image2.getIconHeight());//战机位置和大小
		jl1.setBounds(0, 0, image1.getIconWidth(), image1.getIconHeight());//背景位置和大小
		layeredPane.add(jl1, JLayeredPane.DEFAULT_LAYER);
		layeredPane.add(jl2, JLayeredPane.MODAL_LAYER);
		
		new enemyCreate().start();//敌机生成的线程启动
		new ammoCreate().start();//子弹生成的线程启动
		new enemyMove().start();//敌机移动的线程启动
		new ammoMove().start();//子弹移动的线程启动
		new ammoBoom().start();//子弹与敌机相撞的线程启动
		new playerBoom().start();//战机与敌机相撞的线程启动
		this.setLayeredPane(layeredPane);
		this.setTitle("飞机大战");//窗体标题
		this.setResizable(false);//窗体不可最大化
		this.setSize(image1.getIconWidth(),image1.getIconHeight());//设置大小
		this.setLocationRelativeTo(null);//窗体位置
		this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);//窗体关闭
		this.setVisible(true);//窗体可视
	}
	class mouse1 extends MouseMotionAdapter{
		@Override
		public void mouseMoved(MouseEvent e) {
			X=e.getX();//得到鼠标X坐标
			Y=e.getY();//得到鼠标Y坐标
			jl2.setLocation(X-30, Y-35);
			//战机根据鼠标设置位置
			//通过监听器,只要鼠标移动就执行,
			//图片根据显示效果更改坐标值
		}
	}
	//战机与敌机相撞(线程代码)
	class playerBoom extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
					if(a1.get(i).isVisible()) {//当敌机可视
						if(jl2.getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&jl2.getY()-a1.get(i).getY()>=-jl2.getHeight()) {//敌机与战机相遇
							if(jl2.getX()-a1.get(i).getX()>=-jl2.getWidth()&&jl2.getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
								a1.get(i).setVisible(false);//敌机不可视
								//游戏结束
								new game_plane_3();
								dispose();
								return;//结束该线程
							}
						}
					}
				}
			}
		}
	}
	//子弹与敌机相撞(线程代码)
	class ammoBoom extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
					for(int j=0;j<a2.size();j++) {//遍历子弹对应的ArrayList
						if(a1.get(i).isVisible()&&a2.get(j).isVisible()) {//当子弹与敌机都可视
							if(a2.get(j).getY()-a1.get(i).getY()<=a1.get(i).getHeight()&&a2.get(j).getY()-a1.get(i).getY()>=-10) {//子弹与敌机相遇
								if(a2.get(j).getX()-a1.get(i).getX()>=-a2.get(j).getWidth()&&a2.get(j).getX()-a1.get(i).getX()<=a1.get(i).getWidth()) {
									a1.get(i).setVisible(false);//对应的敌机不可视
									a2.get(j).setVisible(false);//对应的子弹不可视
								}
							}
						}
					}
				}
			}
		}
	}
	//敌机移动(线程代码)
	class enemyMove extends Thread{
		public void run() {
			while(true) {
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				for(int i=0;i<a1.size();i++) {//遍历敌机对应的ArrayList
					a1.get(i).setLocation(a1.get(i).getX(), a1.get(i).getY()+10);//敌机移动,在原基础向下移动10
					if(a1.get(i).getY()>=image1.getIconHeight()) {//敌机移动到窗口外,变得不可见,然后从对应的ArrayList中移除
						a1.get(i).setVisible(false);
						a1.remove(i);
					}
				}
				
			}
		}
	}
	//子弹移动(线程代码)
	class ammoMove extends Thread{
		public void run() {
			while(true) {
				for(int i=0;i<a2.size();i++) {//遍历子弹的ArrayList
					a2.get(i).setLocation(a2.get(i).getX(),a2.get(i).getY()-10);//位置移动,在原基础向上移动10
					if(a2.get(i).getY()<=-30) {//子弹移动到窗口外,变得不可见,然后从对应的ArrayList中移除
						a2.get(i).setVisible(false);
						a2.remove(i);
					}
				}
				try {
					this.sleep(100);//100毫秒执行一次
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	//敌机生成(线程代码)
	class enemyCreate extends Thread{
			public void run() {
				while(true) {
					try {
						this.sleep(1000);//1000毫秒执行一次
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				ImageIcon image_enemy=new ImageIcon("game_image/enemy.png");//敌机图片路径
				enemy[enemy_num]=new JLabel(image_enemy);
				Random random=new Random();
				enemy[enemy_num].setBounds(random.nextInt(image1.getIconWidth()), 0, image_enemy.getIconWidth(), image_enemy.getIconHeight());//设置敌机生成位置和大小(位置横坐标通过Random随机生成)
				layeredPane.add(enemy[enemy_num], JLayeredPane.MODAL_LAYER);
				a1.add(enemy[enemy_num]);//将每一个生成的敌机存放到ArrayList中
				enemy_num++;
				}
			}
		}
	//子弹生成(线程代码)
	class ammoCreate extends Thread{
			public void run() {
				while(true) {
					try {
						this.sleep(1000);//1000毫秒执行一次
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					ImageIcon image_ammo=new ImageIcon("game_image/ammo.png");//子弹图片路径
					ammo[ammo_num]=new JLabel(image_ammo);
					ammo[ammo_num].setBounds(X, Y-40, image_ammo.getIconWidth(), image_ammo.getIconHeight());//子弹位置和大小(X,Y为鼠标的X,Y坐标)
					layeredPane.add(ammo[ammo_num], JLayeredPane.MODAL_LAYER);
					a2.add(ammo[ammo_num]);//将每一个生成的子弹存放到ArrayList中
					ammo_num++;
				}
			}
	}
}

如有错误
欢迎指出

下一篇:用JAVA制作小游戏——飞机大战(三)(待发布)

上一篇:打飞机


下一篇:测试面试题集-Python三局两胜小游戏