Java面向对象--飞机大战

这是一个基于Java的飞机大战游戏实现,包含敌机(小敌机AirPlane和大敌机BigPlane)、英雄机Hero、子弹Bullet以及背景Sky的类。游戏中,敌机会随机生成并移动,英雄机可跟随鼠标移动并开火,子弹与敌机碰撞后会有分数统计和奖励机制。游戏状态包括准备、运行、暂停和游戏结束。
摘要由CSDN通过智能技术生成

小敌机AirPlane.java

package PlanGame05;
import java.util.Random;

import javax.swing.ImageIcon;

public class AirPlane extends Plane implements Enemy{
	/*
	 * 添加一个无参构造器确定自己的出厂位置
	 * 
	 */
	public AirPlane() {
		super(Images.airplane[0],Images.airplane,Images.bom);
		step = Math.random()*4+1.5;
	}
	/**
	 * 自定义出厂位置
	 * @param x
	 * @param y
	 * @param step
	 */
	public AirPlane(double x, double y, double step) {
		super(x,y,Images.airplane[0],Images.airplane,Images.bom);
		this.step = step;
	}
	public int getScore() {
	return 10;	
	
	}
	}


大敌机类BigPlane

package PlanGame05;

/**
 * 大敌机
 * 
 * @author ui-cgb
 *
 */

public class BigPlane extends Plane implements Enemy{
	public BigPlane() {
		super(Images.bigplane[0],Images.bigplane,Images.bom);
		
		step  = Math.random()*3+0.5;
		life = 5;
	}
	public BigPlane(double x, double y, double step) {

		super(x,y,Images.bigplane[0],Images.bigplane,Images.bom);
		this.step = step;
		life = 5;
	}

	public int getScore() {
		return 100;
	}
	

}

英雄机Hero

package PlanGame05;

import java.awt.Graphics;

import javax.swing.ImageIcon;

public class Hero extends FlyingObject {

	public Hero(double x, double y) {
		super(x,y,Images.hero[0],Images.hero,Images.bom);

	}

	/**
	 * 将英雄机移动到鼠标位置x y
	 * 
	 * @param x 参数 鼠标的x
	 * @param y 鼠标的y
	 */
	public void move() {}
	public void move(int x, int y) {
		this.x = x-width/2;
		this.y = y-height/2;

	}


//开火方法
public Bullet fire() {
double x = this.x +width/2 - 5;
double y = this.y - 20;
Bullet bullet  = new Bullet(x,y);
return bullet;
}
private int doubleFire = 0;
public void doubleFire() {
	doubleFire = 20;
}
public Bullet[] openFire() {
	if(doubleFire>0) {
		doubleFire--;
		double x = this.x+width/2-5;
		double y = this.y -20;
		Bullet b1 = new Bullet(x+15,y);
		Bullet b2 = new Bullet(x-15,y);
		//返回两发确定了位置的子弹
		return new Bullet[] {b1,b2};//数组的静态初始化
					
	}else {
		Bullet b = fire();//一颗子弹
		return new Bullet[] {b};
		
	}
}





}

蜜蜂Bee

package PlanGame05;

import java.util.Random;

import javax.swing.ImageIcon;

/**
 * 小蜜蜂类
 * 
 * 
 * @author ui-cgb
 *
 */

public class Bee extends Plane implements Award {
	
	private int direction;
	public Bee() {
		super(Images.bee[0],Images.bee,Images.bom);
		step = Math.random()*3+1;
		direction = Math.random()>0.5?1:-1;
	}

	public Bee(double x, double y,double step) {
		super(x,y,Images.bee[0],Images.bee,Images.bom);
		this.step=step;
		direction = Math.random()>0.5?1:-1;
	}
	

	/*
	 * 重写move方法将蜜蜂方向修改为斜着飞         
	 */
	@Override
	public void move() {
		super.move();//得到父类的飞行方向
		x+=direction;
		if(x<0) {
			direction = 1;
			
		}else if (x+width>400) {
			direction = -1;
		}
	}
	/*
	 * 获取奖励
	 * 二分之一的概率
	 * 
	 * 
	 */
	@Override
	public int getAward() {
		
		return Math.random() >0.5?DOUBLE_FIRE : LIFE;
	}
	
	
}

天空类sky

package PlanGame05;

import java.awt.Graphics;

import javax.swing.ImageIcon;

public class Sky extends FlyingObject {
	// 创建一个新的y坐标y0
	private double y0;

	public Sky() {

		super(0,0,Images.sky,null,null);
		step = 0.8;
		y0=-height;
	}
	public void move() {
		y += step;
		y0 += step;
		// 当y轴的值大于或者等于图片高度时立刻回到窗口以外的上面位置等待入场
		if (y >= height) {
			y = -height;
		}
		if (y0 >= height) {
			y0 = -height;
		
		}

	}
	public void paint(Graphics g) {
		image.paintIcon(null, g, (int) x, (int) y);
		image.paintIcon(null, g, (int) x, (int) y0);
	}
}
		
	
	


	

子弹类Bullet

package PlanGame05;

import java.awt.Graphics;

import javax.swing.ImageIcon;

/**
 * 子弹类
 * 
 * @author ui-cgb
 *
 */
public class Bullet extends FlyingObject {

	public Bullet(double x, double y) {	
		super(x,y,Images.bullet,null,null);
		this.step = 4;

	}

	public void move() { 
		y -= step;
	}

}

游戏类的父类

package PlanGame05;

import java.awt.Graphics;

import javax.swing.ImageIcon;

/**
 * 所有游戏类的父类
 * 
 * @author ui-cgb 抽象类() 避免此类是一个半成品类
 */
public abstract class FlyingObject {
	
	public static final int LIVING = 1;//活着
	public static final int DEAD = 0;//死亡
	public static final int ZOMBIE = -1;//僵尸
	
	protected int state = LIVING; 
	//生命值,默认值
	//具体的飞行物的生命值可以重新设置
	protected int life = 1;
	//检测飞行物是否是活的
	protected double x;
	protected double y;
	protected double width;
	protected double height;
	protected double step;
	protected ImageIcon image;
	/*
	 * 当前的动画帧,如果没有动画帧,则值为null
	 * 如sky bullet
	 * 
	 */
	protected ImageIcon[] images;
	/*
	 * 爆炸效果的动画帧,如果没有值则是null
	 * 
	 */
	protected ImageIcon[] bom;
	/*
	 * 动画帧播放计数器
	 */
	protected int index  = 0;
	/*
	 * 动画帧播放方法
	 * 
	 */
	private int i = 0;
	
	
	
	
public FlyingObject() {
		
	}
public FlyingObject(double x, double y, ImageIcon image,ImageIcon[]images,ImageIcon []bom ) {
	
	this.x = x;
	this.y = y;
	this.image = image;
	this.images = images;
	this.bom = bom;
	width = image.getIconWidth();
	height = image.getIconHeight();
	
 }
public abstract void move();
/*
 * 
 * 定义击打方法
 * 每执行一次,生命值减少一次,返回TRUE
 * 如果生命值 = 0;则进入死亡状态,返回false
 * 如果再次执行此方法则返回false 
 * 
 * 
 * true == 1,LIVING
 * false == 0,DEAD
 * 
 */

public boolean hit() {
	if(life>0) {
		life--;
		if(life==0) {
			state = DEAD;
		}
		return true;
	}else {
		return false;
	}
}
/*
 * 飞行物去死方法
 */
public boolean goDead() {
	
	if(state==LIVING) {
		life = 0;
		state = DEAD;
		return true;
	}else {
		return false;
	}
}
 /*
  * 动画帧播放方法
  * 
  */
public void nextImage() {
	switch(state) {
	
	case LIVING:
		//没有动画帧时候,不播放动画帧图片
		if (images==null) {
			return;
		}
		
		image = images[(index++ /30) % images.length];
		break;
	case DEAD:
		int index = i++ /10;
		if(bom==null) {
			return;
		}
		
		if(index == bom.length) {
			state = ZOMBIE;
			return;
		}
		image = bom[index];
		
		
	}
}
//抽取子类对象的绘制方法
	public void paint(Graphics g) {
		nextImage();//每换一张画一次
		int x1 = (int)(x+(width-image.getIconWidth())/2);
		int y1 = (int)(y+(height-image.getIconHeight())/2);
		image.paintIcon(null, g,  x1,  y1);
		
	}
	
	@Override
	public String toString() {
		// 将toString()类信息灵活化
		String className = getClass().getName();
		return className + " [x=" + x + ", y=" + y + ", width=" + width + ", height=" + height + ""
				+ "]";
	}
	
    

	

	/**
	 * 
	 * 碰撞检测方法
	 * 1.在父类中定义的duang方法可以被任何自乐你继承,所有子类都获得了喷桩检测功能
	 * 2.将方法中的数据类型定义为FiyingObject,就可以处理各种多态参数
	 * 
	 * 
	
	 */
	public boolean duang(FlyingObject bu) {
		FlyingObject p = this;
		//计算小飞机的内切圆数据
		double r1 = Math.min(p.width,p.height)/2;
		double x1 = p.x+p.width/2;
		double y1 = p.y+p.height/2;
		//计算子弹的内切圆数据
		double r2 = Math.min(bu.width,bu.height)/2;
		double x2 = bu.x+bu.width/2;
		double y2 = bu.y+bu.height/2;
		//利用勾股定理计算圆心距离
		double a = y2-y1;
		double b = x2-x1;
		double c = Math.sqrt(a*a + b*b);
		//如果圆心距离小于半径和就表示两个圆形相交,就是发生了“碰撞”
		return c < r1+r2;
		
	}
//检测飞行物是否是活的
	public boolean isLiving() {
		return state ==LIVING;
	}
//检测飞行物是否是死的
	public boolean isDead() {
		return state == DEAD;
	}
//检测飞行物是否是僵尸	
	public boolean isZombie() {
		return state ==ZOMBIE;
	}
	public boolean outOfBounds() {
	return (y<-height-50)||(y>700+50);	
	
}
}







游戏世界类

package PlanGame05;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

/*
 * 飞机大战的游戏世界
 */
public class World extends JPanel {
	
	public static  final int READY = 0;
	public static final int RUNNING = 1;
	public static final int PAUSE = 2;
	public static final int GAME_OVER = 3;
	/*
	 * 当前状态
	 */
	private int state = READY;
	private FlyingObject[] planes;//所有的可以被打掉的敌机
	private Bullet[] bullets;
	private Sky sky;
	private Hero hero;
	private int index = 0;//计数器
	
	/**
	 * 英雄的生命值
	 */
	private int life =3;
	private int score = 0;
	/*
	 * 利用构造器初始化世界中的每个物体
	 */
	public World() {
		init();
	}
	private void init() {
		life = 3;
		score = 0;
		planes = new FlyingObject[0];//创建数组对象
		bullets = new Bullet[0];
		sky = new Sky();
		hero = new Hero(138,380);
	
	}
	public void paint(Graphics g) {
		sky.paint(g);
		hero.paint(g);
		for(int i=0;i<bullets.length;i++) {
			bullets[i].paint(g);
			
		}
		//调用每个飞机的多态方法,实现多态的绘制
		for (int i = 0;i<planes.length;i++) {
			planes[i].paint(g);
		}
		g.setColor(Color.white);
		g.drawString("SCORE:"+score, 20, 40);
		g.drawString("LIFE:"+life, 20, 60);
		g.setFont(getFont());
		switch(state) {
		case READY:
			Images.start.paintIcon(this, g, 0, 0);
			break;
		case PAUSE:
			Images.pause.paintIcon(this, g, 0, 0);
			break;
		case GAME_OVER:
			Images.gameover.paintIcon(this, g, 0, 0);		
		}		
	}
	public static void main(String[]args) {
			JFrame frame = new JFrame();
			World world = new World();
			frame.add(world);
			frame.setSize(400,700);
			frame.setLocationRelativeTo(null);
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
			//调用action 方法启动定时器
			world.action();
		
	}
	  
	/*
	 * 创建一个飞机
	 */
	public void createPlane() {
		if(index % 16 == 0) {
			Random random = new Random();
			int n = random.nextInt(10);
			Plane plane;
			switch(n) {
			case 8:
			case 7:
				plane = new BigPlane();
			    break;
			case 9:
				plane = new Bee();
				break;
				default:
					plane = new AirPlane();
				
			}
			//数组扩容
			planes = Arrays.copyOf(planes, planes.length+1);
			//将新飞机添加到新数组到最后位置
			planes[planes.length-1]=plane;
				
		}
		
	}
	/*
	 * 添加内部类,实现定时计划任务
	 * 为何使用内部类实现定时任务
	 * 1.隐藏定时任务到world类中
	 * 2.可以访问外部类中的数据,飞机,子弹等
	 * 
	 * 
	 * 
	 */
	private class LoopTask extends TimerTask{
		public void run() {
			index++;
			if(state == RUNNING ) {
				fireAction();
				createPlane();
				objectMove();//游戏对象的移动方法
				hitDetection();
				runAway();
				clean();

			}
			sky.move();
			//调用重写绘制方法,这个方法会自动执行paint
			repaint();			
		}		
	}
	private void objectMove(){
		//执行飞机移动方法,是多态的移动方法,每个飞机都不同
		for(int i = 0;i<planes.length;i++) {
			if(planes[i].isLiving()) {
				planes[i].move();
			}
		}
		for(int i = 0;i<bullets.length;i++) {
			if(bullets[i].isLiving()) {
				bullets[i].move();
				}
			}
	}
	/*
	 * 
	 * 定时器方法
	 * 
	 * 
	 * 创建鼠标移动事件的处理对象
	 * 创建鼠标点击事件对象
	 * 注册鼠标点击事件对象给面板
	 * 面板处理鼠标移动事件
	 * 
	 * 
	 */
			public void action() {
				Timer timer = new Timer();
				LoopTask task = new LoopTask();
				timer.schedule(task,100,1000/100);
				this.addMouseListener(new MouseAdapter() {//注册鼠标点击事件对象给面板
						@Override
						public void mouseClicked(MouseEvent e) {
						//鼠标点击执行的方法
						if(state == READY) {
							state = RUNNING;							
						}else if(state == GAME_OVER) {
							init();
							state = READY;						
						}
						}						
					@Override
					public void mouseEntered(MouseEvent e) {
						if(state == PAUSE) {
							state = RUNNING;
					}
					}					
					@Override
					public void mouseExited(MouseEvent e) {
						if(state == RUNNING) {
							state = PAUSE;
					}
					}					
				});
				this.addMouseMotionListener(new MouseAdapter() {
					@Override
					public void mouseMoved(MouseEvent e) {
						if(state == RUNNING) {
							int x = e.getX();//获取发生鼠标事件,鼠标x坐标
							int y = e.getY();//获取发生鼠标事件,鼠标x坐标
							if(hero.isLiving()) {
								hero.move(x,y);
								
							}
					}
					}
					
				});
				
				
			}
		/*
//		 * 
//		 * 分数统计方法
//		 */
			public void scores(FlyingObject obj) {
				if(obj.isDead()) {//判断飞行物是否死了
					if(obj instanceof Enemy) {
						Enemy enemy = (Enemy) obj;
						score +=enemy.getScore();
						
					}
				//处理奖励规则
					if(obj instanceof Award) {
						Award award = (Award)obj;
						int type = award.getAward();
						if(type == Award.DOUBLE_FIRE) {
							hero.doubleFire();
						}else if(type == Award.LIFE) {
							life++;
							
						}
					}
					
				}
				
			}
			public void hitDetection() {
				
				//拿到每个子弹
				for (int i=0;i<bullets.length;i++) {
					if(! bullets[i].isLiving()) {
						continue;
					}
					for(int j = 0;j<planes.length;j++) {
						if(!planes[j].isLiving()) {
							continue;
							
						}
						if(planes[j].duang(bullets[i])) {
							bullets[i].goDead();
							planes[j].hit();
							scores(planes[j]);
							
						}
						
					}
					
				}
				
				
			}
			
		private void fireAction() {
			
			if(! hero.isLiving()) {
				return;
			}
			if(index % 15==0) {
				//在定时任务中执行英雄开火方法
				Bullet[] bubu = hero.openFire();
				//进行对子弹数组的扩容,添加新子弹
				int len = bullets.length;
				//子弹数组扩容
				Bullet[] arr = Arrays.copyOf(bullets, len+bubu.length);
				//将子弹添加到新数组到最后位置
				System.arraycopy(bubu, 0, arr, len, bubu.length);
				bullets = arr;
				
			}
		}
		/*
		 * 清楚僵尸的方法
		 */
		
		public void clean() {//清除僵尸不需要返回值
			
			FlyingObject[] living = new FlyingObject[planes.length];
			// 活着的数组下标
			int index = 0;
			// 遍历旧数组
			for(int i=0;i<planes.length ;i++) {
				// 挑拣活着的目标
				
				if(planes[i].isZombie()||planes[i].outOfBounds()) {
					continue;
				}
				living[index++] = planes[i];
			}
			planes = Arrays.copyOf(living,index);
			Bullet[] arr = new Bullet[bullets.length];
			index = 0;
			for(int i = 0;i<bullets.length;i++) {
				if( bullets[i].isDead()||bullets[i].outOfBounds()) {
					continue;
				}
				arr[index++] = bullets[i];
			}
			bullets = Arrays.copyOf(arr,index);
			
		}
		
		
		/*
		 * 检测英雄逃跑飞机期间,是否发生了与飞机的碰撞
		 * 
		 */
		private void runAway() {
			if(hero.isLiving()) {
				for(int i=0;i<planes.length;i++) {
					if(!planes[i].isLiving()) {
						continue;
					}
					
					if(hero.duang(planes[i])) {
						hero.goDead();
						planes[i].goDead();
						break;
					}
				}
				
			}else if (hero.isZombie()) {
				if(life>0) {
					hero = new Hero(138,380);
					for(int i = 0;i<planes.length;i++) {
						planes[i].goDead();
						
					}
					life--;
				}else {
					state = GAME_OVER;  
					
				}
			}
			
		}
		
	}




	

抽象类 Plane

package PlanGame05;

import java.util.Random;

import javax.swing.ImageIcon;

/**
 * 生成抽象类plane类继承FlyObject,实现抽象父类的方法move()
 * 
 * 
 * @author ui-cgb
 *
 */
public abstract class Plane extends FlyingObject  {

	

public Plane() {
	
	
}
/*
 * 有参构造器
 */

public Plane(double x, double y, ImageIcon image,ImageIcon[]images,ImageIcon []bom) {
	super(x,y,image,images,bom);
	
}
/*
 * 有参构造器,利用算法实现飞行物从屏幕上方入场
 * 
 */
public Plane(ImageIcon image,ImageIcon[]images,ImageIcon []bom) {
	Random random = new Random();//随机数工具类
	this.image= image;
	width = image.getIconWidth();
	height = image.getIconHeight();
	x = random.nextInt(400-(int)width);
	y = -height;
	//step的随机值	
	// 初始化飞机的动画帧
	this.images= images;
	this.bom= bom;
}
/*
 * 实现抽象父类中的抽象方法
 * move方法
 */
@Override
public void move() {
	y+=step;
	
	
}
}

奖励类

package PlanGame05;

public interface Award {

	int DOUBLE_FIRE = 1;
	int LIFE = 2;
	int getAward();
}

敌人类

package PlanGame05;

public interface Enemy {
/*
 * 敌人接口
 */
	int getScore();
}

照片类

package PlanGame05;

import javax.swing.ImageIcon;

/**
 * 
 * 图片信息的静态资源管理器
 * @author ui-cgb
 *
 */
public class Images {
	public static ImageIcon[] airplane;
	public static ImageIcon[] bigplane;
	public static ImageIcon[] bee;
	public static ImageIcon[] hero;
	public static ImageIcon[] bom;
	public static ImageIcon bullet;
	public static ImageIcon sky;
	public static ImageIcon start;
	public static ImageIcon pause;
	public static ImageIcon gameover;
	
	//静态代码块加载静态变量
	static {
		airplane = new ImageIcon[2];
		airplane[0] = new ImageIcon("images/airplane0.png");
		airplane[1] = new ImageIcon("images/airplane1.png");
		
		bigplane = new ImageIcon[2];
		bigplane[0] = new ImageIcon("images/bigairplane0.png");
		bigplane[1] = new ImageIcon("images/bigairplane1.png");
		
		
		
		bee = new ImageIcon[2];
		bee[0] = new ImageIcon("images/bee0.png");
		bee[1] = new ImageIcon("images/bee1.png");
		
		
		hero = new ImageIcon[2];
		hero[0] = new ImageIcon("images/hero0.png");
		hero[1] = new ImageIcon("images/hero1.png");
		
		bom = new ImageIcon[4];
		bom[0] = new ImageIcon("images/bom4.png");
		bom[1] = new ImageIcon("images/bom3.png");
		bom[2] = new ImageIcon("images/bom2.png");
		bom[3] = new ImageIcon("images/bom1.png");
		
		
		bullet = new ImageIcon("images/bullet.png");
		sky = new ImageIcon("images/background.png");
		start = new ImageIcon("images/start.png");
		pause = new ImageIcon("images/pause.png");
		gameover = new ImageIcon("images/gameover.png");
		
		
		
		
	}
public static void main(String[] args) {
	System.out.println(airplane[0].getImageLoadStatus());
	System.out.println(airplane[0].getImageLoadStatus());
	System.out.println(bigplane[0].getImageLoadStatus());
	System.out.println(bigplane[0].getImageLoadStatus());
	System.out.println(bee[1].getImageLoadStatus());
	System.out.println(bee[1].getImageLoadStatus());
	System.out.println(bullet.getImageLoadStatus());
	System.out.println(hero[0].getImageLoadStatus());
	System.out.println(hero[1].getImageLoadStatus());
	System.out.println(bom[0].getImageLoadStatus());
	System.out.println(bom[1].getImageLoadStatus());
	System.out.println(bom[2].getImageLoadStatus());
	System.out.println(bom[3].getImageLoadStatus());
	System.out.println(sky.getImageLoadStatus());
	System.out.println(start.getImageLoadStatus());
	System.out.println(pause.getImageLoadStatus());
	System.out.println(gameover.getImageLoadStatus());	
	
}
	
	}


游戏世界

package PlanGame05;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;

/*
 * 飞机大战的游戏世界
 */
public class World extends JPanel {
	
	public static  final int READY = 0;
	public static final int RUNNING = 1;
	public static final int PAUSE = 2;
	public static final int GAME_OVER = 3;
	/*
	 * 当前状态
	 */
	private int state = READY;
	private FlyingObject[] planes;//所有的可以被打掉的敌机
	private Bullet[] bullets;
	private Sky sky;
	private Hero hero;
	private int index = 0;//计数器
	
	/**
	 * 英雄的生命值
	 */
	private int life =3;
	private int score = 0;
	/*
	 * 利用构造器初始化世界中的每个物体
	 */
	public World() {
		init();
	}
	private void init() {
		life = 3;
		score = 0;
		planes = new FlyingObject[0];//创建数组对象
		bullets = new Bullet[0];
		sky = new Sky();
		hero = new Hero(138,380);
	
	}
	public void paint(Graphics g) {
		sky.paint(g);
		hero.paint(g);
		for(int i=0;i<bullets.length;i++) {
			bullets[i].paint(g);
			
		}
		//调用每个飞机的多态方法,实现多态的绘制
		for (int i = 0;i<planes.length;i++) {
			planes[i].paint(g);
		}
		g.setColor(Color.white);
		g.drawString("SCORE:"+score, 20, 40);
		g.drawString("LIFE:"+life, 20, 60);
		g.setFont(getFont());
		switch(state) {
		case READY:
			Images.start.paintIcon(this, g, 0, 0);
			break;
		case PAUSE:
			Images.pause.paintIcon(this, g, 0, 0);
			break;
		case GAME_OVER:
			Images.gameover.paintIcon(this, g, 0, 0);		
		}		
	}
	public static void main(String[]args) {
			JFrame frame = new JFrame();
			World world = new World();
			frame.add(world);
			frame.setSize(400,700);
			frame.setLocationRelativeTo(null);
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.setVisible(true);
			//调用action 方法启动定时器
			world.action();
		
	}
	  
	/*
	 * 创建一个飞机
	 */
	public void createPlane() {
		if(index % 16 == 0) {
			Random random = new Random();
			int n = random.nextInt(10);
			Plane plane;
			switch(n) {
			case 8:
			case 7:
				plane = new BigPlane();
			    break;
			case 9:
				plane = new Bee();
				break;
				default:
					plane = new AirPlane();
				
			}
			//数组扩容
			planes = Arrays.copyOf(planes, planes.length+1);
			//将新飞机添加到新数组到最后位置
			planes[planes.length-1]=plane;
				
		}
		
	}
	/*
	 * 添加内部类,实现定时计划任务
	 * 为何使用内部类实现定时任务
	 * 1.隐藏定时任务到world类中
	 * 2.可以访问外部类中的数据,飞机,子弹等
	 * 
	 * 
	 * 
	 */
	private class LoopTask extends TimerTask{
		public void run() {
			index++;
			if(state == RUNNING ) {
				fireAction();
				createPlane();
				objectMove();//游戏对象的移动方法
				hitDetection();
				runAway();
				clean();

			}
			sky.move();
			//调用重写绘制方法,这个方法会自动执行paint
			repaint();			
		}		
	}
	private void objectMove(){
		//执行飞机移动方法,是多态的移动方法,每个飞机都不同
		for(int i = 0;i<planes.length;i++) {
			if(planes[i].isLiving()) {
				planes[i].move();
			}
		}
		for(int i = 0;i<bullets.length;i++) {
			if(bullets[i].isLiving()) {
				bullets[i].move();
				}
			}
	}
	/*
	 * 
	 * 定时器方法
	 * 
	 * 
	 * 创建鼠标移动事件的处理对象
	 * 创建鼠标点击事件对象
	 * 注册鼠标点击事件对象给面板
	 * 面板处理鼠标移动事件
	 * 
	 * 
	 */
			public void action() {
				Timer timer = new Timer();
				LoopTask task = new LoopTask();
				timer.schedule(task,100,1000/100);
				this.addMouseListener(new MouseAdapter() {//注册鼠标点击事件对象给面板
						@Override
						public void mouseClicked(MouseEvent e) {
						//鼠标点击执行的方法
						if(state == READY) {
							state = RUNNING;							
						}else if(state == GAME_OVER) {
							init();
							state = READY;						
						}
						}						
					@Override
					public void mouseEntered(MouseEvent e) {
						if(state == PAUSE) {
							state = RUNNING;
					}
					}					
					@Override
					public void mouseExited(MouseEvent e) {
						if(state == RUNNING) {
							state = PAUSE;
					}
					}					
				});
				this.addMouseMotionListener(new MouseAdapter() {
					@Override
					public void mouseMoved(MouseEvent e) {
						if(state == RUNNING) {
							int x = e.getX();//获取发生鼠标事件,鼠标x坐标
							int y = e.getY();//获取发生鼠标事件,鼠标x坐标
							if(hero.isLiving()) {
								hero.move(x,y);
								
							}
					}
					}
					
				});
				
				
			}
		/*
//		 * 
//		 * 分数统计方法
//		 */
			public void scores(FlyingObject obj) {
				if(obj.isDead()) {//判断飞行物是否死了
					if(obj instanceof Enemy) {
						Enemy enemy = (Enemy) obj;
						score +=enemy.getScore();
						
					}
				//处理奖励规则
					if(obj instanceof Award) {
						Award award = (Award)obj;
						int type = award.getAward();
						if(type == Award.DOUBLE_FIRE) {
							hero.doubleFire();
						}else if(type == Award.LIFE) {
							life++;
							
						}
					}
					
				}
				
			}
			public void hitDetection() {
				
				//拿到每个子弹
				for (int i=0;i<bullets.length;i++) {
					if(! bullets[i].isLiving()) {
						continue;
					}
					for(int j = 0;j<planes.length;j++) {
						if(!planes[j].isLiving()) {
							continue;
							
						}
						if(planes[j].duang(bullets[i])) {
							bullets[i].goDead();
							planes[j].hit();
							scores(planes[j]);
							
						}
						
					}
					
				}
				
				
			}
			
		private void fireAction() {
			
			if(! hero.isLiving()) {
				return;
			}
			if(index % 15==0) {
				//在定时任务中执行英雄开火方法
				Bullet[] bubu = hero.openFire();
				//进行对子弹数组的扩容,添加新子弹
				int len = bullets.length;
				//子弹数组扩容
				Bullet[] arr = Arrays.copyOf(bullets, len+bubu.length);
				//将子弹添加到新数组到最后位置
				System.arraycopy(bubu, 0, arr, len, bubu.length);
				bullets = arr;
				
			}
		}
		/*
		 * 清楚僵尸的方法
		 */
		
		public void clean() {//清除僵尸不需要返回值
			
			FlyingObject[] living = new FlyingObject[planes.length];
			// 活着的数组下标
			int index = 0;
			// 遍历旧数组
			for(int i=0;i<planes.length ;i++) {
				// 挑拣活着的目标
				
				if(planes[i].isZombie()||planes[i].outOfBounds()) {
					continue;
				}
				living[index++] = planes[i];
			}
			planes = Arrays.copyOf(living,index);
			Bullet[] arr = new Bullet[bullets.length];
			index = 0;
			for(int i = 0;i<bullets.length;i++) {
				if( bullets[i].isDead()||bullets[i].outOfBounds()) {
					continue;
				}
				arr[index++] = bullets[i];
			}
			bullets = Arrays.copyOf(arr,index);
			
		}
		
		
		/*
		 * 检测英雄逃跑飞机期间,是否发生了与飞机的碰撞
		 * 
		 */
		private void runAway() {
			if(hero.isLiving()) {
				for(int i=0;i<planes.length;i++) {
					if(!planes[i].isLiving()) {
						continue;
					}
					
					if(hero.duang(planes[i])) {
						hero.goDead();
						planes[i].goDead();
						break;
					}
				}
				
			}else if (hero.isZombie()) {
				if(life>0) {
					hero = new Hero(138,380);
					for(int i = 0;i<planes.length;i++) {
						planes[i].goDead();
						
					}
					life--;
				}else {
					state = GAME_OVER;  
					
				}
			}
			
		}
		
	}




	
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值