package cn.tedu.shoot;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
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 ShootMain extends JPanel {
public static final int SCREEN_WIDTH = 400;
public static final int SCREEN_HEIGHT = 700;
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;
private int state = START;
private static BufferedImage start;
private static BufferedImage pause;
private static BufferedImage gameover;
static{//静态初始化图片资源
start = FlyingObject.loadImage("start.png");
pause = FlyingObject.loadImage("pause.png");
gameover = FlyingObject.loadImage("gameover.png");
}
private FlyingObject[] flys = {};// 敌人(小敌机,大敌机,蜜蜂)数组
private Bullet[] bullets = {};// 子弹数组
private Hero hero = new Hero();
private Sky sky = new Sky();
// 1.新建子弹 大敌机的数组,获取每一个对象。step()方法
// 2.思考:继承 建的类中能否使用继承,代码复用?
/** 生成敌人对象 */
public FlyingObject nextOne() {
Random rand = new Random();
int type = rand.nextInt(20);// 0-19
if (type < 5) {// 0-4随机产生蜜蜂对象
return new Bee();
} else if (type < 15) {// 5-14随机产生小敌机对象
return new Airplane();
} else {// 15-19随机产生大敌机对象
return new BigAirplane();
}
}
int enterIndex = 0;
/** 敌人入场 */
public void enterAction() {
enterIndex++;
if (enterIndex % 20 == 0) {
// 获取到敌人对象
FlyingObject f = nextOne();
// 数组的扩容
flys = Arrays.copyOf(flys, flys.length + 1);
// 将产生的敌人放到数组的最后一个位置上
flys[flys.length - 1] = f;
}
}
/** 子弹入场 */
int shootIndex = 0;
public void shootAction() {
shootIndex++;
if (shootIndex % 10 == 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 stepAction() {
sky.step();// 天空移动
// 遍历出所有敌人,让每个敌人移动
for (int i = 0; i < flys.length; i++) {
flys[i].step();
}
for (int i = 0; i < bullets.length; i++) {
bullets[i].step();
}
}
/**删除越界的飞行物*/
public void outOfBoundsAction(){
int index = 0;//充当不越界的敌人的数组下标,用来记录不越界的敌人
//设置一个不越界的数组
FlyingObject[] flysLive = new FlyingObject[flys.length];
//遍历每一个敌人
for(int i=0;i< flys.length;i++){
//获取每一个敌人
FlyingObject f = flys[i];//0-1-2-3-4
if(!f.outOfBounds()){//不越界 1,3,这些不越界敌人的下标放入flysLive中需要重排
flysLive[index] = f;
index++;//不越界的数组下标增加1,不越界的敌人个数增加1
}
}
flys = Arrays.copyOf(flysLive, index);
index = 0;
//删除越界的子弹对象
Bullet[] bulletLive = new Bullet[bullets.length];
for (int i = 0; i< bullets.length;i++){
Bullet b = bullets[i];
if(!b.outOfBounds()&& !b.isRemove()){
bulletLive[index] = b;
index++;
}
}
bullets = Arrays.copyOf(bulletLive, index);
}
/**子弹与敌人发生碰撞*/
int score = 0;
public void bulletBangAction(){
//遍历所有的子弹
for (int i=0; i < bullets.length;i++){
//获取到每一个子弹
Bullet b = bullets[i];
for (int j = 0;j < flys.length;j++){//遍历所有敌人
FlyingObject f = flys[j];//获取每一个敌人
if (f.isLife() && b.isLife() && f.hit(b)){//判断是否撞上,敌人和子弹必须都是活着的
f.goDead();//敌人over,子弹over
b.goDead();
//如果被撞上的的对象是敌人能得分
if(f instanceof Enemy){
Enemy e = (Enemy)f;
score += e.getScore();//玩家得分
}
//如果被撞上的对象是奖励,得火力、得生命
if(f instanceof Award){
Award a = (Award)f;
int type = a.getAwardType();
switch(type){
case Award.DOUBLE_FIRE:
hero.addDoubleFire();//得火力
break;
case Award.LIFE:
hero.addLife();//得生命
break;
}
}
}
}
}
}
/**英雄机与敌人发生碰撞*/
public void heroBangAction(){
//遍历所有敌人
for(int i = 0;i< flys.length;i++){
//获取到每一个敌人
FlyingObject f = flys[i];
//碰撞--英雄机是活着的,敌人也是活着的
if (hero.isLife() && f.isLife() && f.hit(hero)){
//如果撞上了,敌人over,英雄机减少生命,清空火力
f.goDead();
hero.subtractlife();
hero.clearDoubleFire();
}
}
}
/**检测游戏结束*/
public void checkGameOverAction(){
if (hero.getLife() <= 0){
state=GAME_OVER;
}
}
/**测试方法 */
public void action() {
//侦听器对象
MouseAdapter l = new MouseAdapter() {
public void mouseMoved(MouseEvent e) {
super.mouseMoved(e);
int x = e.getX();
int y = e.getY();
hero.moveTo(x, y);
}
/**鼠标的点击事件*/
public void mouseClicked(MouseEvent e){
super.mouseClicked(e);
switch (state) {
case START:
state = RUNNING;
break;
case GAME_OVER:
score = 0;
sky = new Sky();
hero = new Hero();
flys = new FlyingObject[0];
bullets = new Bullet[0];
state = START;
break;
}
}
/**鼠标的移入移出*/
public void mouseEntered(MouseEvent e){
super.mouseEntered(e);
if (state == PAUSE){
state = RUNNING;
}
}
public void mouseExited(MouseEvent e){
super.mouseExited(e);
if (state == RUNNING){
state = PAUSE;
}
}
};
this.addMouseListener(l);// 处理鼠标的操作事件
this.addMouseMotionListener(l);// 处理鼠标的滑动
Timer timer = new Timer();
int inter = 10;// 定时间隔(以毫秒为单位)
timer.schedule(new TimerTask() {
public void run() {// 定时去干一件事--每隔10毫秒
if(state==RUNNING){
enterAction(); // 敌人入场
shootAction();// 子弹入场
stepAction();// 飞行物移动
outOfBoundsAction();//删除越界飞行物
bulletBangAction();//子弹与敌人发生碰撞
heroBangAction();//英雄机与敌人发生碰撞
checkGameOverAction();//检测游戏结束
}
repaint();// 重画(调用paint方法)
}
}, inter, inter);
}
/** paint方法 Graphics g:画笔 */
public void paint(Graphics g) {
super.paint(g);
sky.paintObject(g);
hero.paintObject(g);
//遍历每一个敌人对象
for (int i = 0; i < flys.length; i++) {
flys[i].paintObject(g);//将每一个敌人对象画出来
}
for (int i = 0; i < bullets.length; i++) {
bullets[i].paintObject(g);
}
g.drawString("得分:" +score,30,50);
g.drawString("生命:" +hero.getLife(),30,80);
//根据不同状态画不同的状态图
switch (state){
case START://启动状态
g.drawImage(start, 0, 0, null);
break;
case PAUSE://暂停状态
g.drawImage(pause, 0, 0, null);
break;
case GAME_OVER://游戏结束状态
g.drawImage(gameover, 0, 0, null);
break;
}
}
/**主函数:程序的入口*/
public static void main(String[] args) {
ShootMain sm = new ShootMain();
JFrame frame = new JFrame();
frame.setSize(ShootMain.SCREEN_WIDTH, ShootMain.SCREEN_HEIGHT);
frame.setTitle("飞机大战1.0");
//设置退出的时候进行关闭,减少内存的占用
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);//设置居中显示
sm.setBackground(Color.BLACK);//设置底部背景颜色
frame.add(sm);// 添加画布到窗口中
frame.setVisible(true);//展示出来
sm.action();
}
}