JAVA-制作飞机大战遇到的问题

JAVA-制作飞机大战遇到的问题

  • 问题
    • 1.闪烁
      • 解决方法
    • 2.子弹不能多发
      • 解决方法
  • 全部代码
    • 1.主菜单
    • 2.模式选择菜单
    • 3.游戏主窗口
    • 4.飞机类
    • 5.子弹类
    • 6.爆炸类
    • 7.结算界面
    • 8.工具类
    • 9.玩法窗口

这学期java最后让编一个程序,第一次写这么多行的程序,收获很大。
写的第一个博客,以后要经常写,记录自己遇到的问题和解决方法。

问题

1.闪烁

解决方法

1.使用双缓冲,但是没有效果
2. 继承JPanel类,成功

2.子弹不能多发

解决方法

建立子弹数组,由开火函数写在飞机类中,所有画图都调到游戏主窗口类的paint中。

全部代码

1.主菜单

package com.lhyltzj.www;

import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
/*
 * 主菜单,主方法类
 */
public class Welcome extends JFrame{
	
	Image background2=GameUtile.getImage("image/menuback.png");
	public Welcome() {
		//大小
		this.setSize(800,600);
		//标题
		this.setTitle("雷电");
		//窗口居中
		this.setLocationRelativeTo(null); 
		//可见
		this.setVisible(true);
		
		JButton startGame=new JButton("开始游戏");
		JButton infoGame=new JButton("玩法介绍");
		JButton endGame=new JButton("退出");
		startGame.setBounds(350, 290, 100, 50);
		infoGame.setBounds(350, 350, 100, 50);
		endGame.setBounds(350, 410, 100, 50);

		this.add(startGame);
		this.add(infoGame);
		this.add(endGame);
		this.setLayout(null);		
		
		ImageIcon img1=new ImageIcon("src/image/menuback.png");
        JLabel la3=new JLabel(img1);
	    la3.setBounds(0,0,800,600);
	    this.getLayeredPane().add(la3,new Integer(Integer.MIN_VALUE)); 
	    getContentPane().add(la3);
	    this.setResizable(false);

		
	    
		startGame.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				/*点开始游戏,销毁主菜单窗口
				 * 创建选择模式窗口
				 */
				dispose();
				ChooseModel cm=new ChooseModel();
			}
		});
		
		infoGame.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				/*
				 * 点击玩法介绍,创建玩法介绍窗口
				 */
				InfoFrame infoframe=new InfoFrame();
			}
		});
		
		endGame.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				dispose();
			}
		});
	}
	
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		
		Welcome welcome=new Welcome();
		//		GameWindow gw=new GameWindow();
		//		gw.MyWindow();
        //gw.setVisible(true);
        
	}

}

2.模式选择菜单

package com.lhyltzj.www;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
/*
 * 模式选择类
 * 
 */
public class ChooseModel extends JFrame{

	public ChooseModel(){
		
		this.setSize( 500, 400);
		this.setTitle("模式选择");
		this.setVisible(true);
		this.setLocationRelativeTo(null); 
		this.setLayout(null);
		
		
		JButton normal=new JButton("闯关模式");
		JButton endless=new JButton("无尽模式");
		normal.setBounds(200, 100, 100, 50);
		endless.setBounds(200, 200, 100, 50);
		
		this.add(normal);
		this.add(endless);
		
		ImageIcon img1=new ImageIcon("src/image/chooseback.png");
		JLabel la3=new JLabel(img1);
	    la3.setBounds(0,0,700,800);
	    this.getLayeredPane().add(la3,new Integer(Integer.MIN_VALUE)); 
	    getContentPane().add(la3);
	    this.setResizable(false);
		
		this.setLayout(null);
		normal.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				/*
				 * 闯关模式
				 * 传参数false
				 */
				dispose();
				GameWindow gw=new GameWindow();
				gw.MyWindow(false);
			}
		});
		endless.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				/*
				 * 无尽模式
				 * 传参数ture
				 */
				dispose();
				GameWindow gw=new GameWindow();
				gw.MyWindow(true);
			}
		});
		
	}
	
}

3.游戏主窗口

package com.lhyltzj.www;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.List;

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


/*
 * 游戏运行窗口
 */
public class GameWindow extends JPanel {

	//创建全局JFrame对象
	JFrame frame=new JFrame("Thunder");
	
	int j=4;
	//标记游戏失败结束,ture为游戏结束
	public  boolean GAMEOVER;
	//标记游戏胜利结束,ture为游戏结束
	public  boolean VECTORY;
	//判断游戏模式
	boolean model;
	//闯关模式关卡
	int level=1;
	//显示文字延迟
	int timeNum=0;
	//终极技能能量值
	public int power=0;
	//玩家战机初始坐标
	static int x=250;
	static int y=600;
	//窗口大小
	public static final int GAME_WIDTH=600;
	public static final int GAME_HEIGHT=750;
	//分数
	int score=0;
	
//	int enemy_x=110;
//	int enemy_y=-20;
	//子弹集合
	List<Bullet> bulletarr=new ArrayList<Bullet>();
//	List enemybulletarr=new ArrayList();
	
	//敌机,BOSS,血包 集合
	List<Plane> enemyarr=new ArrayList<Plane>();
	//爆炸集合
	List<Bomb> bombs=new ArrayList<Bomb>();
	//创建玩家战机
	Plane myplane=new Plane(x, y,true,Plane.Direction.STOP,this,100);
	//用工具类转化图片资源
	Image image=GameUtile.getImage("image/myplane.png");
	Image background=GameUtile.getImage("image/background.png");
	Image background2=GameUtile.getImage("image/background2.png");
	//背景竖坐标,用于背景图片滚动
	int back_y=-background.getHeight(null)+background.getHeight(null);
	//public GameWindow() {


	public void MyWindow(boolean model){

		
		this.setSize(GAME_WIDTH,GAME_HEIGHT);
		this.setVisible(true);
		this.model=model;
		//System.out.println("dsdkskdj");
		
		//GameWindow win=new GameWindow();
		//把GameWindow类放到全局frame里
		frame.add(this);
		//win.MyWindow();
			// 设置大小
		frame.setSize(GAME_WIDTH,GAME_HEIGHT);
        //frame.setAlwaysOnTop(true); // 设置其总在最上
		
		// 默认关闭操作
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        // 设置窗体初始位置居中
        frame.setLocationRelativeTo(null);
        //添加键盘监听器
        frame.addKeyListener(new KeyMonitor());
        //可见
        frame.setVisible(true);
        //不可改变大小
        frame.setResizable(false);
        //开启线程
		new Thread(new PaintThread()).start();
		

	public void setLevel() {
		//无尽模式
		if(model){
			for(int i = 0; i < j; i++) {
			this.enemyarr.add(new Plane(300+50*i, -200,false,Plane.Direction.D,this,20));
			
			}
			j++;
		}
		//闯关模式
		else{
		switch (level) {
		//第一关
		case 1:
//			this.enemyarr.add(new Plane(110,-150,false,Plane.Direction.D,this,1000,true));
			for(int i = 0; i < 2; i++) {
			this.enemyarr.add(new Plane(300+50*i, -200,false,Plane.Direction.D,this,20));
		 }
			break;
		//第二关
		case 2:
			this.enemyarr.add(new Plane(10, 30,false,Plane.Direction.D,this,20,false,true));
			for(int i = 0; i < 5; i++) {
			this.enemyarr.add(new Plane(-50+50*i, -50,false,Plane.Direction.D,this,20));
		 }	
			break;
		//第三关
		case 3:
			this.enemyarr.add(new Plane(300, 10,false,Plane.Direction.D,this,20,false,true));
			for(int i = 0; i < 8; i++) {
			this.enemyarr.add(new Plane(-50+50*i, -50,false,Plane.Direction.D,this,20));
		 }	
			break;	
		//第四关
		case 4:
			this.enemyarr.add(new Plane(100, 200,false,Plane.Direction.D,this,20,false,true));
			for(int i = 0; i < 11; i++) {
			this.enemyarr.add(new Plane(-50+50*i, -50,false,Plane.Direction.D,this,20));
		 }		
			break;
		//第五关(BOSS)
		case 5:
			this.enemyarr.add(new Plane(300, 100,false,Plane.Direction.D,this,20,false,true));
			this.enemyarr.add(new Plane(110,-150,false,Plane.Direction.D,this,1000,true));
			break;
		default:
			break;
		}			
	  }

	}
	@Override
	public void paint(Graphics g) {
		// TODO Auto-generated method stub
		super.paint(g);
		//失败或者胜利直接return
        if(GAMEOVER||VECTORY) {
        	
        	//myplane.setBlood(100);
        	return;
        }
        
        //使背景无限滚动
		g.drawImage(background, 0,back_y++, null);			
		g.drawImage(background, 0, back_y-background.getHeight(null), null);
		if(back_y==background.getHeight(null)) {
			back_y=0;
		}
		
		//g.drawImage(background2, 0, back_y+GAME_HEIGHT-background2.getHeight(null), null);
		//画玩家战机
		myplane.draw(g);
		//myplane.hitPlanes(enemyarr);

		//使关卡名延迟显示
		timeNum++;
		if(timeNum>0&&timeNum<=20)
		{
			if(level!=1) {
				if(!model) {
				g.setFont(new Font("宋体",Font.BOLD,100));
				g.drawString("  第"+(level-1)+"关",50,GAME_HEIGHT/2);
				}
			}
		}
		
		else if(timeNum>20) {
			if (enemyarr.size() <= 0) {
				
				setLevel();
				level++;
				timeNum=0;
			}
			
		}

		//画敌人,boss和血包
		for(int i=0;i<enemyarr.size();i++){
			Plane eP=enemyarr.get(i);
			//eP.hitPlanes(enemyarr);
			eP.draw(g);
			//如果此时集合中的是boss,而且boss死了,VECTORY为true
			if(eP.isBoss()&&!eP.isAlive()){
				System.out.println("++++++++++++++++++++++Vectory+++++++++++++++++++");
				g.setFont(new Font("宋体",Font.BOLD,100));
				g.drawString("   VECTORY!",50,GAME_HEIGHT/2);
				VECTORY=true;
			}
		}
//		enemyplane.draw(g);	
//		enemyplane02.draw(g);	
		//e.draw(g);
		//画爆炸
		for(int i=0;i<bombs.size();i++) {
			Bomb b=bombs.get(i);
			b.draw(g);
		}
		//buff.draw(g);
		//画子弹
		for(int i=0;i<bulletarr.size();i++){
			Bullet tB=bulletarr.get(i);
			tB.draw(g);	
			tB.hitPlane(myplane);
			tB.hitPlanes(enemyarr);
		}
		
		//画文字
		g.setFont(new Font("宋体",Font.BOLD,20));
		//g.drawString("missiles \t count:"+bulletarr.size(), 10, 50);
		//g.drawString("enemy \t count:"+enemyarr.size(), 10, 60);
		
		g.drawString("Score:"+score, 10, 70);
		g.drawString("HP  "+myplane.getBlood(), 0, GAME_HEIGHT-45);
		g.drawString("终极技能  "+power, GAME_WIDTH-150, GAME_HEIGHT-45);
		//如果玩家血量低于0,GAMEOVER为true
		if(myplane.getBlood()<=0) {
			g.setFont(new Font("宋体",Font.BOLD,100));
			g.drawString("GAME OVER",50,GAME_HEIGHT/2);
			GAMEOVER=true;
			//dispose();
			
		}
	}
//	private Image offScreenImage=null; 
//	private Graphics offScreenGraphics;
	
	
	
	private Image buffer;
	@Override
	public void update(Graphics g) {
		// TODO Auto-generated method stub
	    buffer=createImage(getWidth(),getHeight());//创建图片缓冲区
	    Graphics gBuffer=buffer.getGraphics();//获得图片缓冲区的画笔
			if(gBuffer!=null)
				paint(gBuffer);
			else
				paint(g);
			gBuffer.dispose();
			g.drawImage(buffer, 0, 0,null);
	}

	//游戏结束退出函数
	public void Quit() {
		//this.setVisible(false);
		//System.exit(0);
		frame.dispose();
		ReturnFrame rf=new ReturnFrame(VECTORY,model);
	}
	
	//主线程
	public class PaintThread implements Runnable{
		
		@Override
		public void run() {
			// TODO Auto-generated method stub
			//如果胜利或者失败,结束循环
			while(!GAMEOVER&&!VECTORY) {
				try {
					Thread.sleep(50);
					
				}catch(Exception e) {
					e.printStackTrace();
				}
				repaint();
			}
			Quit();
		}	
	}
	
	
	//键盘监听器
	public class KeyMonitor extends KeyAdapter{

		@Override
		public void keyPressed(KeyEvent e) {
			
			// TODO Auto-generated method stub
			super.keyPressed(e);
			myplane.KeyPressed(e);
		}

		@Override
		public void keyReleased(KeyEvent e) {
			
			// TODO Auto-generated method stub
			super.keyReleased(e);
			myplane.keyReleased(e);
		}
		
		
	}
}

4.飞机类

package com.lhyltzj.www;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random;
import java.util.Vector;

import com.lhyltzj.www.Plane.Direction;

public class Plane {
	//飞行物坐标
	int x,y;
	//用于大招发射
	int i=0;
	int j=0;
	//标记是不是活着
	private boolean isAlive=true;
	//标记是不是玩家
	private boolean good;
	//private int oldX, oldY;
	//int kind;
	//标记是不是血包
	boolean buff;

	public boolean isAlive() {
		return isAlive;
	}
	public void setAlive(boolean isAlive) {
		this.isAlive = isAlive;
	}
	
	public boolean isGood() {
		return good;
	}
	public void setGood(boolean good) {
		this.good = good;
	}

	
	//Vector bulletarr=new Vector();
	//飞机速度
	public static final int XSPEED=10;
	public static final int YSPEED=8;
	
//	public static final int WIDTH=147;
//	public static final int HEIGHT=104;
	
	private boolean bL=false,bU=false,bR=false,bD=false;
	//枚举
	enum Direction{L, LU, U, RU, R, RD, D, LD, STOP};
	//开始默认停止
	private Direction dir=Direction.STOP;
	//拿权限
	GameWindow gw;
	//血量
	private int blood;
	//标记是否为boss
	private boolean boss;
	
	public boolean isBoss() {
		return boss;
	}
	public void setBoss(boolean boss) {
		this.boss = boss;
	}
	public int getBlood() {
		return blood;
	}
	public void setBlood(int blood) {
		this.blood = blood;
	}
	//随机数用于随机产生图片
	Random ran=new Random();
	int ranNum=ran.nextInt(4);
	private int step=ran.nextInt(12)+3;
	
	Image enemy;
	
	Image enemyA=GameUtile.getImage("image/enemyA.png");
	Image enemyB=GameUtile.getImage("image/enemyB.png"); 
	Image enemyC=GameUtile.getImage("image/enemyC.png");
	Image enemyD=GameUtile.getImage("image/enemyD.png");
	Image enemyboss=GameUtile.getImage("image/BOSS.png");
	
	Image lifeBuff=GameUtile.getImage("image/lifebuff.png");
	
	Image image=GameUtile.getImage("image/myplane.png");
	
	Image img=GameUtile.getImage("image/bullet.png");
	Image Eimg=GameUtile.getImage("image/enemybullet.png");
	
	//随机产生不同样子的敌机
	public void ranPlane() {
		switch(ranNum) {
		case 0:
			enemy=enemyA;
			break;
		case 1:
			enemy=enemyB;
			break;
		case 2:
			enemy=enemyC;
			break;
		case 3:
			enemy=enemyD;
			break;
		}

	}
	
//	public Plane(int x,int y,int kind,boolean buff) {
//		this.x=x;
//		this.y=y;
//		this.kind=kind;
//		this.buff=buff;
//	}
	
	public Plane(int x, int y,boolean good) {
		super();
		this.x = x;
		this.y = y;
		this.good=good;
	}
	
	public Plane(int x,int y,boolean good,Direction dir,GameWindow gw,int blood) {
		this(x,y,good);
		this.dir=dir;
		this.gw=gw;
//		this.oldX=x;//
//		this.oldY=y;//
		this.ranPlane();
		this.blood=blood;
	}
	
	public Plane(int x,int y,boolean good,Direction dir,GameWindow gw,int blood,boolean boss) {
		this(x,y,good,dir,gw,blood);
		this.boss=boss;
	}
	
	public Plane(int x,int y,boolean good,Direction dir,GameWindow gw,int blood,boolean boss,boolean buff) {
		this(x,y,good,dir,gw,blood,boss);
		this.buff=buff;
	}
	
	public void draw(Graphics g){
		//画血包
		if(buff) {
			g.drawImage(lifeBuff, x, y, null);
			//System.out.println("++++++++++++++++++++++++++++++");
		}
		if(!isAlive) {
				//如果飞机死了并且不是玩家,就从移除移除
			if(!good) {
				gw.enemyarr.remove(this);

			}
			return;
		}
		

		if(good&&!buff) {
			//玩家血条
			Color c=g.getColor();
			g.setColor(Color.red);
			g.fillRect(0, gw.GAME_HEIGHT-60, this.getBlood(), 20);
			g.setColor(c);

			//能量条
			g.setColor(Color.blue);
			g.fillRect(gw.GAME_WIDTH-gw.power, gw.GAME_HEIGHT-60, gw.GAME_WIDTH, 20);
			g.setColor(c);
			g.drawImage(image, x, y,null);			
		}
		else if(!good&&!buff) {
			if(this.isBoss()==true) {
				g.drawImage(enemyboss, x, y,null);
				//boss血条
				Color c=g.getColor();
				g.setColor(Color.red);
				g.fillRect(0,0 , this.getBlood()*enemyboss.getWidth(null)/1000+1, 30);
				g.setColor(c);	
				g.setFont(new Font("宋体",Font.BOLD,20));
				g.drawString("BOSS HP  "+this.getBlood(), 0, 20);
				//System.out.println("BOSS出现");
			}
			else if(this.isBoss()==false) {
		g.drawImage(enemy, x, y,null);
		//小怪血条
		Color c=g.getColor();
		g.setColor(Color.red);
		g.fillRect(x,y-15 , this.getBlood()*enemy.getWidth(null)/20+1, 10);
		g.setColor(c);					
			}

		}

		//System.out.println("飞机"+x+","+y);
		move();
	}
	public void move() {
		// TODO Auto-generated method stub
//		this.oldX=x;//
//		this.oldY=y;//
		switch (dir) {
		case L:
			x-=XSPEED;
			break;
		case LU:
			x-=XSPEED;
			y-=YSPEED;
			break;
		case U:
			y-=YSPEED;
			break;
		case RU:
			x+=XSPEED;
			y-=YSPEED;
			break;
		case R:
			x+=XSPEED;
			break;
		case RD:
			x+=XSPEED;
			y+=YSPEED;
			break;
		case D:
			y+=YSPEED;
			break;
		case LD:
			x-=XSPEED;
			y+=YSPEED;
			break;
		case STOP:
			break;
		}
		//是敌机小怪
		if(!boss&&!good&&!buff) {
			if(x<30){
				x=30;
			}
			if(y<30){
				y=30;
			}
			if(x+enemy.getWidth(null)>gw.GAME_WIDTH){
				x=gw.GAME_WIDTH-enemy.getWidth(null);
			}
			if(y+enemy.getHeight(null)>gw.GAME_HEIGHT){
				y=gw.GAME_HEIGHT-enemy.getHeight(null);
			}
		}
		
		//是玩家
		else if(good&&!buff) {
			if(x<10){
				x=10;
			}
			if(y<10){
				y=10;
			}
			if(x+image.getWidth(null)>gw.GAME_WIDTH){
				x=gw.GAME_WIDTH-image.getWidth(null);
			}
			if(y+image.getHeight(null)>gw.GAME_HEIGHT){
				y=gw.GAME_HEIGHT-image.getHeight(null);
			}
		}
		
		//是血包
		if(buff) {
			y++;

			//if(x)
			if(x<0||y<0||x>GameWindow.GAME_WIDTH||y>GameWindow.GAME_HEIGHT){
				isAlive=false;
				//gw.arr.remove(this);
			}	   
		}
		
		//是boss,或者小怪
		if(!good&&!buff) {
			if(boss) {
				if(y>=0) {
//				j++;
//				if(j%2==0){
//				x+=5;					
//				}
//				else{
//				x-=5;					
//				}

				dir=Direction.STOP;					
				}

			}
			else if(!boss&&!buff) {
			Direction[] dirs=Direction.values();
			if(step==0) {
				step=ran.nextInt(12)+3;
				int ranMove=ran.nextInt(dirs.length);
				dir=dirs[ranMove];
			}
			step--;				
			}

			//随机开火
			if(ran.nextInt(40)>38) {
				if(boss) {
					BossSkill();
					}
				else
				this.fire();
			}	
		}
		
	}
	
	//判断方向
	private void locateDirection() {
		// TODO Auto-generated method stub
		if(bL&&!bU&&!bR&&!bD) dir=Direction.L;
		if(bL&&bU&&!bR&&!bD) dir=Direction.LU;
		if(!bL&&bU&&!bR&&!bD) dir=Direction.U;
		if(!bL&&bU&&bR&&!bD) dir=Direction.RU;
		if(!bL&&!bU&&bR&&!bD) dir=Direction.R;
		if(!bL&&!bU&&bR&&bD) dir=Direction.RD;
		if(!bL&&!bU&&!bR&&bD) dir=Direction.D;
		if(bL&&!bU&&!bR&&bD) dir=Direction.LD;
		if(!bL&&!bU&&!bR&&!bD) dir=Direction.STOP;
	}
	
	//抬起
	public void keyReleased(KeyEvent e) {
		int key=e.getKeyCode();
		if(key==KeyEvent.VK_UP) {
			bU=false;
		}
		if(key==KeyEvent.VK_DOWN) {
			bD=false; 
		}
		if(key==KeyEvent.VK_LEFT) {
			bL=false;
		}
		if(key==KeyEvent.VK_RIGHT) {
			bR=false;
		}
		if(key==KeyEvent.VK_Z) {
			fire();
		}
		locateDirection();
	}
	
	//按下
	public void KeyPressed(KeyEvent e) {
		int key=e.getKeyCode();
		if(key==KeyEvent.VK_UP&&y>0) {
			//System.out.println("dddd");
			bU=true;
		}
		if(key==KeyEvent.VK_DOWN&&y<615) {
			bD=true;
		}
		if(key==KeyEvent.VK_LEFT&&x>0) {
			bL=true;
		}
		if(key==KeyEvent.VK_RIGHT&&x<480) {
			bR=true;
		}
		if(key==KeyEvent.VK_X) {
			//new Thread(new MyBullet()).start();
				if(gw.power>=100) {
					ultimateSkill();	
					gw.power=0;
				}
				
				

		}
		locateDirection();
	}
//	private void stay(){ //一旦撞墙,把撞墙时的位置赋值为原始的位置,即正确的最后一步位置
//		x=oldX;
//		y=oldY;
//	}
	
	//碰撞检测
	public Rectangle getRect(){
		if(buff) {
			return new Rectangle(x,y,lifeBuff.getWidth(null),lifeBuff.getHeight(null));
		}
		if(!good) {
			if(boss) {
				return new Rectangle(x,y,enemyboss.getWidth(null),enemyboss.getHeight(null));
			}
			return new Rectangle(x,y,enemy.getWidth(null),enemy.getHeight(null));
		}
		return new Rectangle(x,y,image.getWidth(null),image.getHeight(null));
	}
	
	
	//开火
	public Bullet fire() {
			int x = this.x + image.getWidth(null)/2 - img.getWidth(null)/2; //让子弹从中心打出
		if(!good) {
			x = this.x + enemy.getWidth(null)/2 - img.getWidth(null)/2; 
			if(boss) {
				 x = this.x + enemyboss.getWidth(null)/2 - img.getWidth(null)/2; 
				 int y=this.y+enemyboss.getHeight(null)/2-img.getHeight(null)/2;
			}
		}

		//Bullet tB=new Bullet(x-image.getWidth(null)/2,y,dir.LU,good,this.gw,10);
		
		Bullet ttB=new Bullet(x,y,dir,good,this.gw,good?10:5);
		//Bullet tttB=new Bullet(x+image.getWidth(null)/2,y,dir.RU,good,this.gw,10);
		//gw.bulletarr.add(tB);
		
		gw.bulletarr.add(ttB);
		//gw.bulletarr.add(tttB);
		return ttB;
	}
	
	//玩家大招
	public Bullet ultimateSkill() {
		int x = this.x + image.getWidth(null)/2 - img.getWidth(null)/2;
			Bullet L1=new Bullet(x-image.getWidth(null)/2,y,dir.LU,good,this.gw,10);
			Bullet L2=new Bullet(x,y,dir.LU,good,this.gw,10);
			Bullet m=new Bullet(x,y,dir.U,good,this.gw,10);
			Bullet R1=new Bullet(x+image.getWidth(null)/2,y,dir.RU,good,this.gw,10);
			Bullet R2=new Bullet(x,y,dir.RU,good,this.gw,10);
			m.XSPEED=0;
			gw.bulletarr.add(m);
			L1.XSPEED=5;
			gw.bulletarr.add(L1);
			L2.XSPEED=10;
			gw.bulletarr.add(L2);
			R1.XSPEED=5;
			gw.bulletarr.add(R1);
			R2.XSPEED=10;
			gw.bulletarr.add(R2);
			//tB.XSPEED=0;
		
		
		//tB.YSPEED=speed;
		return null;	
	}
	
	//Boss 攻击方式
	public Bullet BossSkill() {
		int x = this.x + enemyboss.getWidth(null)/2 - Eimg.getWidth(null)/2;
			Bullet L1=new Bullet(x-image.getWidth(null)/2,y,dir.LD,good,this.gw,10);
			Bullet L2=new Bullet(x,y,dir.LD,good,this.gw,10);
			Bullet m=new Bullet(x,y,dir.D,good,this.gw,10);
			Bullet R1=new Bullet(x+image.getWidth(null)/2,y,dir.RD,good,this.gw,10);
			Bullet R2=new Bullet(x,y,dir.RD,good,this.gw,10);
			
			if(i%2==0) {
				m.eXSPEED=0;
				gw.bulletarr.add(m);
				L1.eXSPEED=-1;
				gw.bulletarr.add(L1);
				L2.eXSPEED=-2;
				gw.bulletarr.add(L2);
				R1.eXSPEED=1;
				gw.bulletarr.add(R1);
				R2.eXSPEED=2;
				gw.bulletarr.add(R2);
			}
			else {
				m.eXSPEED=0;
				gw.bulletarr.add(m);
				L1.eXSPEED=0;
				gw.bulletarr.add(L1);
				L2.eXSPEED=0;
				gw.bulletarr.add(L2);
				R1.eXSPEED=0;
				gw.bulletarr.add(R1);
				R2.eXSPEED=0;
				gw.bulletarr.add(R2);
			}
			i++;
			
		return null;
		
	}
}


5.子弹类

package com.lhyltzj.www;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.util.List;

import com.lhyltzj.www.Plane.Direction;

/*
 * 
 * 子弹类
 * 
 */
public class Bullet {
	int x,y;
	private boolean  isAlive=true;
	
	public boolean isAlive() {
		return isAlive;
	}
	
	public void setAlive(boolean isAlive) {
		this.isAlive = isAlive;
	}
	
	Image img=GameUtile.getImage("image/bullet.png");
	Image Eimg=GameUtile.getImage("image/enemybullet.png");
	
	Plane.Direction dir;
	
	//玩家子弹速度
	public static  int XSPEED=0;
	public static int YSPEED=50;
	//敌人子弹速度
	public static  int eXSPEED=0;
	public static final int eYSPEED=-7;
	
	public int att;
	private GameWindow gw;
	private boolean good;
	
	public Bullet(int x, int y, Plane.Direction dir) {
		super();
		this.x = x;
		this.y = y;
		this.dir = dir;
	}
	
	public Bullet(int x,int y ,Plane.Direction dir,boolean good,GameWindow gw,int att){
		this(x,y,dir);
		this.good=good;
		this.gw=gw;
		this.att=att;
		//this.good=good;
	}
	
	
	public void draw(Graphics g) {
		if(!isAlive) {
			//如果死亡,从集合中移除
			gw.bulletarr.remove(this);
			return;
		}
//		 if(isAlive==false){
//			 gw.bulletarr.remove(this);
//			 return;
//		 }
		//g.drawImage(img, this.x+174, this.y, null);
		//g.drawImage(img, this.x+87, this.y, null);
		//System.out.println("子弹"+x+","+y);
		if(good) {
			//玩家子弹
			g.drawImage(img, this.x, this.y, null);	
			//g.drawImage(img, this.x+50, this.y, null);
			mymove();
		}
		if(!good) {
			//敌人子弹
			g.drawImage(Eimg, this.x, this.y, null);
			enemymove();
		}
		

	}
	
	//玩家子弹移动
	void mymove() {
		switch (dir) {
		case L:
			//x-=XSPEED;
			y-=YSPEED;
			break;
		case LU:
			x-=XSPEED;
			//y-=YSPEED;
			y-=YSPEED;
			break;
		case U:
			y-=YSPEED;
			break;
		case RU:
			x+=XSPEED;
			//y-=YSPEED;
			y-=YSPEED;
			break;
		case R:
			//x+=XSPEED;
			y-=YSPEED;
			break;
		case RD:
			//x+=XSPEED;
			//y+=YSPEED;
			y-=YSPEED;
			break;
		case D:
			//y+=YSPEED;
			y-=YSPEED;
			break;
		case LD:
			//x-=XSPEED;
			//y+=YSPEED;
			y-=YSPEED;
			break;
		case STOP:
			y-=YSPEED;
			break;
		}
		
		//如果超出屏幕,标记死亡
		if(x<0||y<0||x>GameWindow.GAME_WIDTH||y>GameWindow.GAME_HEIGHT){
			isAlive=false;
			//gw.bulletarr.remove(this);
		}
	}
	
	//敌方子弹移动
   void enemymove() {
		switch (dir) {
		case L:
			//x-=XSPEED;
			y-=eYSPEED;
			break;
		case LU:
			//x-=XSPEED;
			//y-=YSPEED;
			y-=eYSPEED;
			break;
		case U:
			y-=eYSPEED;
			break;
		case RU:
			//x+=XSPEED;
			//y-=YSPEED;
			y-=eYSPEED;
			break;
		case R:
			//x+=XSPEED;
			y-=eYSPEED;
			break;
		case RD:
			x+=eXSPEED;
			//y+=YSPEED;
			y-=eYSPEED;
			break;
		case D:
			//y+=YSPEED;
			y-=eYSPEED;
			break;
		case LD:
			x-=eXSPEED;
			//y+=YSPEED;
			y-=eYSPEED;
			break;
		case STOP:
			y-=eYSPEED;
			break;
		}
		if(x<0||y<0||x>GameWindow.GAME_WIDTH||y>GameWindow.GAME_HEIGHT){
			isAlive=false;
			//gw.bulletarr.remove(this);
		}	   
   }
	
   //碰撞检测
	public Rectangle getRect(){
		if(!good) {
			return new Rectangle(x,y,Eimg.getWidth(null),Eimg.getHeight(null));
		}
		return new Rectangle(x,y,img.getWidth(null),img.getHeight(null));
	}
//	public boolean hitBuff(Plane buff){
//		if(this.good&&this.isAlive&&buff.buff&&this.getRect().intersects(buff.getRect())) {
//			gw.myplane.setBlood(100);
//			System.out.println("+++++++++++++++++++++++++++");
//			return true;
//		}
//		return false;
//	}
	
	//击中
	public boolean hitPlane(Plane p){
		if(this.isAlive&&this.getRect().intersects(p.getRect())&&p.isAlive()&&this.good==true&&p.buff==true){
			//如果是血包
			gw.myplane.setBlood(100);
			System.out.println("++++++++++++++++++++++++++");
			p.setAlive(false);
			this.isAlive=false;
		}
		if(this.isAlive&&this.getRect().intersects(p.getRect())&&p.isAlive()&&this.good!=p.isGood()){
			//如果击中的是玩家或者小怪或者boss
			int nextBlood=p.getBlood()-this.att;
			if(p.getBlood()>0) {
				//如果没死
				p.setBlood(nextBlood);
				//加能量
				gw.power+=5;
				
				this.isAlive=false;
			}
			else if(p.getBlood()<=0) {
				//如果死了
			//p.setPower(nextPower);
				p.setAlive(false);
				this.isAlive=false;
				//爆炸
			Bomb b=new Bomb(x,y,gw);
			gw.bombs.add(b);
			if(!p.isGood()) {
				//如果死亡的不是玩家
				//加分,加能量
				gw.score++;
				gw.power+=10;
				//p.buff=true;	
			  }
			}
			return true;
		}
		return false;
	}
	
	//击中敌机小怪,boss,血包
	public boolean hitPlanes(List<Plane> enemyarr) {
		for (int i = 0; i < enemyarr.size(); i++) {
			if (hitPlane(enemyarr.get(i))) {
				//gw.enemyarr.remove(i);	
				return true;
			}
		}
		return false;
	}
}

6.爆炸类

package com.lhyltzj.www;

import java.awt.Color;
import java.awt.Graphics;

public class Bomb {
	
	int x,y;
	GameWindow gw;
	private boolean isAlive=true;
	int[] diameter=new int[]{4,7,12,18,26,32,49,30,14,6};
	int step=0;
	public Bomb(int x, int y, GameWindow gw) {
		
		super();
		this.x = x;
		this.y = y;
		this.gw = gw;
		
	}
	
	public void draw(Graphics g){
		
		if(!isAlive) {
			gw.bombs.remove(this);
			return;
		}
		if(step==diameter.length){
			isAlive=false;
			step=0;
			return;
		}
		Color c=g.getColor();
		g.setColor(Color.orange);
		g.fillOval(x, y, diameter[step], diameter[step]);
		g.setColor(c);
		step++;
	}
}

7.结算界面

package com.lhyltzj.www;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JLabel;

public class ReturnFrame extends JDialog{
	//GameWindow gw;
	 boolean VECTORY;
	 //boolean model;
	public ReturnFrame(boolean VECTORY,final boolean model) {
		
		this.setSize(800,550);
		this.setLocationRelativeTo(null);
		this.setVisible(true);
		JButton returnMenu=new JButton("返回主菜单");
		JButton replay=new JButton("重新开始");
		JButton endGame=new JButton("退出");
		returnMenu.setBounds(600, 290, 100, 50);
		replay.setBounds(600, 350, 100, 50);
		endGame.setBounds(600, 410, 100, 50);
		this.add(returnMenu);
		this.add(replay);
		this.add(endGame);
		this.setLayout(null);
		//this.model=model;
		ImageIcon img1;
		if(VECTORY) {
			this.setTitle("胜利");
		img1=new ImageIcon("src/image/returnV.png");			
		}
		else {
			this.setTitle("失败");
		img1=new ImageIcon("src/image/returnD.png");		
		}

        JLabel la3=new JLabel(img1);
	    la3.setBounds(0,0,800,550);
	    this.getLayeredPane().add(la3,new Integer(Integer.MIN_VALUE)); 
	    getContentPane().add(la3);
	    this.setResizable(false);
		
	    //this.gw=gw;
		returnMenu.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				//gw.dispose();
				//gw.frame.dispose();
				dispose();
				new Welcome();
			}
		});
		replay.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				dispose();
				GameWindow gw=new GameWindow();
				gw.MyWindow(model);
				
			}
		});
		endGame.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				// TODO Auto-generated method stub
				dispose();
			}
		});
	}
}

8.工具类

package com.lhyltzj.www;

import java.awt.Image;
import java.awt.image.BufferedImage;
import java.net.URL;

import javax.imageio.ImageIO;
/*
 * 游戏工具类
 * 用于加载图片为Image格式
 */
public class GameUtile {
	public static Image getImage(String path) {
		URL url=GameUtile.class.getClassLoader().getResource(path);
		BufferedImage image=null;
		try {
			image=ImageIO.read(url);
		}catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}
		return image;
		
	}
}

9.玩法窗口

package com.lhyltzj.www;

import java.awt.FlowLayout;
import java.awt.GridLayout;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

public class InfoFrame extends JFrame{
	public InfoFrame(){
		
		this.setSize( 300, 600);
		this.setTitle("玩法介绍");
		this.setVisible(true);
		this.setLocationRelativeTo(null); 
		
		JLabel text1=new JLabel("按 上 ,下,左,右 键移动, 空格 发射子弹");
		JLabel text2=new JLabel("闯关模式  一共有5关,第五关会出现BOSS");
		JLabel text3=new JLabel("玩家初始血量为100,击中绿色血包可以回满HP");
		JLabel text4=new JLabel("玩家会有一个充能条,会显示玩家当前的能量");
		JLabel text5=new JLabel("击中或击杀敌机和玩家受到伤害,都会增加能量");
		JLabel text6=new JLabel("当能量达到100之后,按X释放终极技能");
		this.add(text1);
		this.add(text2);
		this.add(text3);
		this.add(text4);
		this.add(text5);
		this.add(text6);
		this.setLayout(new GridLayout(6,1));
	}
}

你可能感兴趣的:(JAVA-制作飞机大战遇到的问题)