package plane.wars;
import java.awt.Color;
import java.awt.Font;
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.JPanel;
/**
* 飞机大战的主面板
* 英雄机 敌机 子弹 小蜜蜂
*
*/
public class MainPanel extends JPanel
{
private Hero hero;
/*定义计时器对象**/
private Timer timer;
/**定义保存飞行物(敌机,小蜜蜂)的数组*/
private FlyingObject[] flyings;
/**定义存子弹的数组*/
private Bullet[] bullets;
/**定义生成飞行物的计数变量*/
private int flyNewIndex;
/**定义随机数对象*/
private Random random;
/**定义发射子弹的计数变量*/
private int shootIndex;
/**定义分数*/
int score;
/**定义表示状态的变量*/
private int state ;
/**定义游戏运行的4种状态*/
public static final int START =0 ;
public static final int RUNNING = 1 ;
public static final int PAUSE =2 ;
public static final int GAME_OVER= 3;
/**初始化MainPanel的构造方法*/
public MainPanel()
{
init();
}
private void init()
{
//初始化计时器对象
timer = new Timer();
//初始化飞行物数组
flyings = new FlyingObject[2];
//多态 子类的对象 父类的类型
flyings[0] = new Airplane();
flyings[1] = new Bee();
//初始化子弹的数组
bullets = new Bullet[1];
bullets[0] = new Bullet(196,400);
//初始化英雄机
hero = new Hero();
//初始化生成飞行物的计数变量
flyNewIndex = 0;
//初始化随机数对象
random = new Random();
//初始化发射子弹的计数变量
shootIndex =0;
score=0;
state = START;
}
/**重写JPanel里面的paint方法*/
public void paint(Graphics g)
{
super.paint(g);
//画游戏背景图片
g.drawImage(Util.backGround.getImage(),0,0,this);
//画飞行物
paintFlyings(g);
//画子弹
paintBullet(g);
//画英雄机
paintHero(g);
//画分数
paintScore(g);
//画状态图
paintState(g);
}
/**画英雄机*/
private void paintHero(Graphics g)
{
g.drawImage(hero.getImageIcon().getImage(),hero.getX(),hero.getY(),this);
}
/**画子弹*/
private void paintBullet(Graphics g)
{
for(int i=0;i<bullets.length;i++)
{
Bullet bullet = bullets[i];
g.drawImage(bullet.getImageIcon().getImage(), bullet.getX(), bullet.getY(),this);
}
}
/**画飞行物*/
private void paintFlyings(Graphics g)
{
//敌机或蜜蜂
for(int i=0 ;i<flyings.length;i++)
{
FlyingObject fo = flyings[i];
g.drawImage(fo.getImageIcon().getImage(),fo.getX(),fo.getY(),this);
}
}
/**画分数*/
public void paintScore(Graphics g)
{
int x=10;
int y=25;
//设置画笔的颜色
g.setColor(new Color(0x3A3B3B));
//设置画笔的大小
g.setFont(new Font(Font.SANS_SERIF,Font.BOLD,25));
//画分数
g.drawString("SCORE:"+score, x, y);
//画英雄机生命数
g.drawString("LIFE:"+hero.getLife(),x,y+30);
}
/**画状态*/
public void paintState(Graphics g)
{
switch(state)
{
case START:
g.drawImage(Util.start.getImage(), 0, 0, this);
break;
case PAUSE:
g.drawImage(Util.pause.getImage(),0,0, this);
break;
case GAME_OVER:
g.drawImage(Util.gameOver.getImage(), 0, 0, this);
break;
}
}
/**主控制流程*/
public void action()
{
//创建鼠标的Adapter调制解调器
MouseAdapter ma = new MouseAdapter()
{
/**鼠标移动事件*/
public void mouseMoved(MouseEvent e)
{
if(state==RUNNING)
{
//获取当前鼠标所在的位置
int x = e.getX();
int y = e.getY();
//让英雄机移动到此位置
hero.moveTo(x, y);
//重绘
repaint();
}
}
/**鼠标点击事件*/
public void mouseClicked(MouseEvent e)
{
//当程序为开始状态时,改变为运行状态
if(state == START)
{
state = RUNNING;
}
else if(state == GAME_OVER)
{
//重新开始游戏
init();
}
}
/**鼠标进入事件*/
public void mouseEntered(MouseEvent e)
{
if(state == PAUSE)
{
state = RUNNING;
}
}
/**鼠标移出事件*/
public void mouseExited(MouseEvent e)
{
if(state == RUNNING)
{
state = PAUSE;
}
}
};
//给面板添加监听
this.addMouseMotionListener(ma);
this.addMouseListener(ma);
//制定计划
timer.schedule(new TimerTask() {
public void run()
{
if(state==RUNNING)
{
//飞行物入场
enteredAction();
//走一步
stepAction();
//发射子弹
shootAction();
//判断子弹是否击中飞行物
hitAction();
//判断飞行物是否越界
outOfBoundsAction();
//判断英雄机是否和飞行物相撞
heroHitFlyingObject();
//判断英雄机生命数,看是否结束游戏
isGameOver();
}
repaint();
}
}, 10,10);
}
/**飞行物入场*/
public void enteredAction()
{
//隔一段时间来一个敌机或着蜜蜂
flyNewIndex ++;
if(flyNewIndex %40 ==0)
{
//生成飞行物 小蜜蜂 敌机
FlyingObject fo = nextOne();
//数组的扩容操作
flyings = Arrays.copyOf(flyings, flyings.length+1);
flyings[flyings.length-1]=fo;
}
}
/**生成飞行物的方法*/
public FlyingObject nextOne()
{
//随机生成 敌机的几率大 蜜蜂的几率小
int index = random.nextInt(20);
if(index ==0)
{
return new Bee();//生成蜜蜂
}
else
{
return new Airplane();//生成敌机
}
}
/**飞行物走一步的方法*/
public void stepAction()
{
//英雄机走一步、切换图片
hero.step();
//飞行物走一步
for(int i=0;i<flyings.length;i++)
{
//运行时,方法是动态的绑定到对象上的。
//多态现象中,子类的对象被父类的变量引用
//但是,调用方法的时候,会按照子类的对象调用对应对象的方法,编译时根据类型来检查
// FlyingObject fo = flyings[i];
// fo.step();
flyings[i].step();
}
//子弹走一步
for(int i= 0;i<bullets.length;i++)
{
// Bullet bullet = bullets[i];
// bullet.step();
bullets[i].step();
}
//重绘
repaint();
}
/**发射子弹*/
public void shootAction()
{
if(shootIndex++%25==0)
{
//让英雄机发射子弹
Bullet[] bs = hero.shoot();
//扩容数组的长度
bullets = Arrays.copyOf(bullets, bullets.length+bs.length);
//将飞机打出去的子弹放到子弹数组中
System.arraycopy(bs, 0, bullets, bullets.length-bs.length, bs.length);
}
}
/**判断是否结束游戏*/
public void isGameOver()
{
if(hero.getLife()<=0)
{
state=GAME_OVER;
//timer.cancel();
}
}
/**判断英雄机是否与敌机相撞*/
public void heroHitFlyingObject()
{
for(int i = 0;i<flyings.length;i++)
{
// FlyingObject fo = flyings[i];
// //英雄机与敌机的碰撞检测
// boolean isHit = hero.hit(fo);
boolean isHit = hero.hit(flyings[i]);
if(isHit)
{
//英雄生命减一
hero.subLife();
//敌机消失
flyings[i] = flyings[flyings.length-1];
// flyings[flyings.length-1]= fo;
flyings[flyings.length-1]= flyings[i];
flyings = Arrays.copyOf(flyings, flyings.length-1);
return;
}
}
}
/**判断飞行物是否越界 敌机 小蜜蜂 子弹*/
public void outOfBoundsAction()
{
//循环飞行物的数组 敌机 小蜜蜂
FlyingObject[] flyLives = new FlyingObject[flyings.length];
int index = 0;
for(int i=0;i<flyings.length;i++)
{
FlyingObject fo = flyings[i];
if(!fo.outOfBounsd()) {
flyLives[index++] = fo;
}
}
//删除越界的飞行物
flyings = Arrays.copyOf(flyLives, index);
//循环子弹的 数组
Bullet[] bulletLives = new Bullet[bullets.length];
index = 0;
for(int i=0;i<bullets.length;i++)
{
Bullet bullet= bullets[i];
if(!bullet.outOfBounsd())
{
bulletLives[index++]=bullet;
}
}
//删除越界的子弹
bullets = Arrays.copyOf(bulletLives, index);
}
/**判断是否击中飞行物*/
public void hitAction()
{
//创建保存未打掉飞行物的子弹
Bullet[] bulletLives = new Bullet[bullets.length];
//定义数组计数下标
int index = 0;
//循环子弹数组,拿出每一颗子弹跟所有的飞行物比较
for