教你如何用Java一步步实现飞机大战(二)

资源交流群

资源共享学习交流群号:769674658(快满)
 
qq交流二群(296389054)
 

飞机大战第二天

1.飞行物移动的实现步骤

(1)FlyingObject------抽象方法step();

	
	/** 飞行物走一步 */
	public abstract void step();
	

 2)同理在Airplane,Bee,Bullet,Hero---重写step()

Airplane----

/** 重写step()走步 */
	public void step(){
		y+=speed; //y+(向下)
	} 

Bee---

/** 重写step()走步 */
	public void step(){
		x+=xSpeed; //x+(向左或向右)
		y+=ySpeed; //y+(向下)
		if(x>=ShootGame.WIDTH-this.width){ //若x>=(窗口宽-蜜蜂宽),则xSpeed为-1,加-1即为向左
			xSpeed=-1;
		}
		if(x<=0){ //若x<=0,则xSpeed为1,加1即为向右
			xSpeed=1;
		}
	}

Bullet---

/** 重写step()走步 */
	public void step(){
		y-=speed; //y-(向上)
	}

Hero---

/** 重写step()走步 */
	public void step(){ //10毫秒走一次
		image = images[index++/10%images.length];

ShootGame---

/** 启动程序的执行 */
	public void action(){
		//创建鼠标侦听器
		MouseAdapter l = new MouseAdapter(){
			/** 重写mouseMoved()鼠标移动事件 */
			public void mouseMoved(MouseEvent e){
				if(state==RUNNING){ //运行状态下执行
					int x = e.getX(); //获取鼠标的x坐标
					int y = e.getY(); //获取鼠标的y坐标
					hero.moveTo(x, y); //英雄机随着鼠标移动
				}
			}
			/** 重写mouseClicked()鼠标点击事件 */
			public void mouseClicked(MouseEvent e){
				switch(state){ //根据当前状态做不同的操作
				case START:        //启动状态时
					state=RUNNING; //修改为运行状态
					break;
				case GAME_OVER:  //游戏结束状态时
					score = 0;   //清理现场
					hero = new Hero();
					flyings = new FlyingObject[0];
					bullets = new Bullet[0];
					state=START; //修改为启动状态
					break;
				}
			}
			/** 重写mouseExited()鼠标移出事件 */
			public void mouseExited(MouseEvent e){
				if(state==RUNNING){ //运行状态时
					state=PAUSE;    //修改为暂停状态
				}
			}
			/** 重写mouseEntered()鼠标移入事件 */
			public void mouseEntered(MouseEvent e){
				if(state==PAUSE){  //暂停状态时
					state=RUNNING; //修改为运行状态
				}
			}
		};
		this.addMouseListener(l); //处理鼠标操作事件
		this.addMouseMotionListener(l); //处理鼠标滑动事件
		
		Timer timer = new Timer(); //创建定时器对象
		int intervel = 10; //时间间隔(以毫秒为单位)
		timer.schedule(new TimerTask(){
			public void run(){ //定时干的那个事--10毫秒走一次
				if(state==RUNNING){ //运行状态时执行
					enterAction(); //敌人(敌机+小蜜蜂)入场
					stepAction();  //飞行物(敌机+小蜜蜂+子弹+英雄机)走一步
					shootAction(); //子弹入场(英雄机发射子弹)
					outOfBoundsAction(); //删除越界的飞行物(敌机+小蜜蜂+子弹)
					bangAction();  //子弹与敌人(敌机+小蜜蜂)的碰撞
					hitAction();   //英雄机与敌人(敌机+小蜜蜂)的碰撞
					checkGameOverAction(); //判断游戏结束
				}
				repaint(); //重画(调用paint()方法)
			}
		},intervel,intervel); //定时计划
	}
	int flyIndex = 0; //敌人入场计数
	/** 敌人(敌机+小蜜蜂)入场 */
	public void enterAction(){ //10毫秒走一次
		flyIndex++; //每10毫秒增1
		if(flyIndex%40==0){ //400(10*40)毫秒走一次
			FlyingObject obj = nextOne(); //获取敌人(敌机+小蜜蜂)对象
			flyings = Arrays.copyOf(flyings,flyings.length+1); //扩容
			flyings[flyings.length-1] = obj; //将敌人添加到最后一个元素上
		}
	}
	
	/** 飞行物(敌机+小蜜蜂+子弹+英雄机)走一步 */
	public void stepAction(){ //10毫秒走一次
		hero.step(); //英雄机走一步
		for(int i=0;i<flyings.length;i++){ //遍历所有敌人
			flyings[i].step(); //敌人走一步
		}
		for(int i=0;i<bullets.length;i++){ //遍历所有子弹
			bullets[i].step(); //子弹走一步
		}
	}

2.子弹入场的实现步骤:

  1)Hero---shoot()英雄机发射子弹

/** 英雄机发射子弹(生成子弹对象) */
	public Bullet[] shoot(){
		int xStep = this.width/4; //xStep:1/4英雄机的宽
		int yStep = 20; //yStep:固定的20
		if(doubleFire>0){ //双倍
			Bullet[] bs = new Bullet[2]; //2发子弹
			bs[0] = new Bullet(this.x+1*xStep,this.y-yStep); //x:英雄机的x+1/4英雄机的宽 y:英雄机的y-20
			bs[1] = new Bullet(this.x+3*xStep,this.y-yStep); //x:英雄机的x+3/4英雄机的宽 y:英雄机的y-20
			doubleFire-=2; //发射一次双倍火力,则火力值减2
			return bs;
		}else{ //单倍
			Bullet[] bs = new Bullet[1]; //1发子弹
			bs[0] = new Bullet(this.x+2*xStep,this.y-yStep); //x:英雄机的x+2/4英雄机的宽 y:英雄机的y-20
			return bs;
		}
	}	public Bullet[] shoot(){
		int xStep = this.width/4; //xStep:1/4英雄机的宽
		int yStep = 20; //yStep:固定的20
		if(doubleFire>0){ //双倍
			Bullet[] bs = new Bullet[2]; //2发子弹
			bs[0] = new Bullet(this.x+1*xStep,this.y-yStep); //x:英雄机的x+1/4英雄机的宽 y:英雄机的y-20
			bs[1] = new Bullet(this.x+3*xStep,this.y-yStep); //x:英雄机的x+3/4英雄机的宽 y:英雄机的y-20
			doubleFire-=2; //发射一次双倍火力,则火力值减2
			return bs;
		}else{ //单倍
			Bullet[] bs = new Bullet[1]; //1发子弹
			bs[0] = new Bullet(this.x+2*xStep,this.y-yStep); //x:英雄机的x+2/4英雄机的宽 y:英雄机的y-20
			return bs;
		}
	}

ShootGame----

	int shootIndex = 0; //射击计数
	/** 子弹入场(英雄机发射子弹) */
	public void shootAction(){ //10毫秒走一次
		shootIndex++; //每10毫秒增1
		if(shootIndex%30==0){ //300(10*30)毫秒走一次
			Bullet[] bs = hero.shoot(); //获取子弹对象
			bullets = Arrays.copyOf(bullets,bullets.length+bs.length); //扩容(bs有几个元素就扩大几个容量)
			System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length); //数组的追加
		}
	}

 

 

 

英雄机随着鼠标移动的实现步骤:

hero---

/** 英雄机随着鼠标动 x:鼠标的x y:鼠标的y*/
	public void moveTo(int x,int y){
		this.x = x-this.width/2; //英雄机的x=鼠标的x-1/2英雄机的宽
		this.y = y-this.height/2; //英雄机的y=鼠标的y-1/2英雄机的高
	}

删除越界的敌人和子弹的实现步骤:

FlyingObject---

/** 检测是否出界 */
	public abstract boolean outOfBounds();

Airplane-----

/** 重写outOfBounds()检查是否越界 */
	public boolean outOfBounds(){
		return this.y>=ShootGame.HEIGHT; //敌机的y>=窗口的高,即为越界了
	}

 

bee----

 

/** 重写outOfBounds()检查是否越界 */
	public boolean outOfBounds(){
		return this.y>=ShootGame.HEIGHT; //小蜜蜂的y>=窗口的高,即为越界了
	}

 

bullet----

 

/** 重写outOfBounds()检查是否越界 */
	public boolean outOfBounds(){
		return this.y<=-this.height; //子弹的y<=负的子弹的高,即为越界了
	}

 

Hero--

 

/** 重写outOfBounds()检查是否越界 */
	public boolean outOfBounds(){
		return false; //永不越界
	}

shootGame---outOfBoundsAction(){
      1)声明活着的数组
      2)遍历flyings/bullets数组
        判断对象是否不越界:
        若true:
          将对象添加到活着的数组中
      3)将活着的数组复制到flyings/bullets数组中
    }

/** 删除越界的飞行物(敌机+小蜜蜂+子弹) */
	public void outOfBoundsAction(){ //10毫秒走一次
		int index = 0; //1)不越界敌人数组下标  2)不越界敌人个数
		FlyingObject[] flyingLives = new FlyingObject[flyings.length]; //不越界敌人数组
		for(int i=0;i<flyings.length;i++){ //遍历所有敌人
			FlyingObject f = flyings[i]; //获取每一个敌人
			if(!f.outOfBounds()){ //不越界
				flyingLives[index] = f; //将不越界敌人对象添加到不越界敌人数组中
				index++; //1)不越界敌人数组下标增一  2)不越界敌人个数增一
			}
		}
		flyings = Arrays.copyOf(flyingLives,index); //将不越界敌人数组复制到flyings中,flyings的长度为index(不越界敌人个数)
		
		index = 0; //1)不越界子弹数组下标归零  2)不越界子弹个数归零
		Bullet[] bulletLives = new Bullet[bullets.length]; //不越界子弹数组
		for(int i=0;i<bullets.length;i++){ //遍历所有子弹
			Bullet b = bullets[i]; //获取每一个子弹
			if(!b.outOfBounds()){ //不越界
				bulletLives[index] = b; //将不越界子弹对象添加到不越界子弹数组中
				index++; //1)不越界子弹数组下标增一  2)不越界子弹个数增一
			}
		}
		bullets = Arrays.copyOf(bulletLives,index); //将不越界子弹数组复制到bullets中,bullets的长度为index(不越界子弹个数)
		
	}

子弹和敌人碰撞的实现步骤:

 

1)FlyingObject---shootBy(Bullet b)--

/** 检测敌人(敌机+小蜜蜂)是否被子弹击中 this:敌人 bullet:子弹 */
	public boolean shootBy(Bullet bullet){
		int x1 = this.x;             //x1:敌人的x
		int x2 = this.x+this.width;  //x2:敌人的x+敌人的宽
		int y1 = this.y;             //y1:敌人的y
		int y2 = this.y+this.height; //y2:敌人的y+敌人的高
		int x = bullet.x;            //x:子弹的x
		int y = bullet.y;            //y:子弹的y
		
		return x>=x1 && x<=x2
			   &&
			   y>=y1 && y<=y2; //x在x1与x2之间,并且,y在y1与y2之间,即为撞上了
	}

 

  2)Hero----addDoubleFire(),addLife()--

 

/** 英雄机增命 */
	public void addLife(){
		life++; //命数增1
	}
	
	/** 获取英雄机的命 */
	public int getLife(){
		return life; //返回命数
	}
	
	/** 英雄机减命 */
	public void subtractLife(){
		life--; //命数减1
	}
	
	/** 英雄机增火力 */
	public void addDoubleFire(){
		doubleFire+=40; //火力值增40
	}
	
	/** 清空英雄机的火力值 */
	public void clearDoubleFire(){
		doubleFire = 0; //火力值归零
	}


  3)action(){
      run(){
        ...
    bangAction(); //检查碰撞
    repaint();
      }
    }
  4)bangAction(){ //所有子弹与所有敌人撞
      遍历所有子弹,将子弹传给bang()方法
    }
  5)bang(Bullet b){ //1发子弹与所有敌人撞
      遍历所有敌人,获取每一个敌人f
      判断f是否与b撞上了
      若撞上了:
        5.1)得分或得奖励
      5.1.1)得到被撞敌人对象
      5.1.2)判断是敌人还是奖励
             若是敌人则增分
         若是奖励则得奖励类型
            判断不同的奖励类型:
              增命或增火力值
    5.2)将被撞对象从flyings中删除
      5.2.1)将被撞敌人与最后一个元素交换(追尾并绕圈)
      5.2.2)缩容---删除最后一个元素(被撞的对象)
    }

 

 

 

 

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 技术黑板 设计师:CSDN官方博客 返回首页