全民飞机大战(java)

目录

一、需求

二、窗体、面板、背景图的绘制

2.1  工具类

2.2  面板类

2.3  窗体类

2.4  效果图

三、英雄机的出现及移动

3.1  定义飞行父类

3.2  英雄机的出现

3.3  加入鼠标监听器

3.4  英雄机的移动

四、敌机的出现及移动

4.1  敌机类

4.2  敌机入场

4.3  敌机移动

4.4  启动一个线程

4.5  效果图

五、英雄机子弹的出现及移动

5.1  英雄机子弹类

5.2  英雄机发射子弹

5.3  英雄机子弹移动

5.4  效果图

六、敌机子弹的出现及移动

6.1  敌机子弹类

6.2  敌机发射子弹

6.3  敌机子弹移动

6.4  效果图

七、击中问题

7.1  英雄机子弹击中敌机

7.2  敌机子弹击中英雄机

7.3  敌机与英雄机相撞

7.4  效果图 

八、游戏的开始与结束

8.1  鼠标点击监听事件

8.2  开始与结束界面

8.3  效果图 

九、加入音效

9.1  音乐类

十、遇到的问题

十一、学习地址


一、需求

  • 窗体、面板、背景图的绘制
  • 英雄机的出现及移动
  • 敌机的出现及移动
  • 英雄机子弹的出现及移动
  • 敌机子弹的出现及移动
  • 英雄机子弹打中敌机
  • 敌机子弹打中英雄机
  • 敌机与英雄机相撞
  • 游戏的开始与结束界面
  • 增加背景音乐和爆炸音效

二、窗体、面板、背景图的绘制

2.1  工具类

/**
 * 这是工具类,用于获取图片
 * @author Administrator
 *
 */

import java.awt.image.BufferedImage;
import java.io.IOException;

import javax.imageio.ImageIO;

public class Tool {

	public static BufferedImage getImage(String path) {
		try {
			BufferedImage img = ImageIO.read(Tool.class.getResource(path));
			return img;
		} catch (IOException e) {
			e.printStackTrace();
		}
		return null;
	}
}

2.2  面板类

/**
 * 这是面板类,继承JPanel
 */
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;

public class GamePanel extends JPanel {
	// 定义背景图
	private BufferedImage bg;

	// 构造方法
	public GamePanel() {
		bg = Tool.getImage("../img/bg3.jpg");
	}

	// paint方法
	@Override
	public void paint(Graphics g) {
		g.drawImage(bg, 0, 0, null);
	}
}

2.3  窗体类

import javax.swing.JFrame;

/**
 * 这个类是窗体类,继承JFrame类
 * 
 * @author Administrator
 *
 */
public class GameFrame extends JFrame {

	public GameFrame() {
		setSize(512, 768);
		setLocationRelativeTo(null);// 居中
		setIconImage(Tool.getImage("../img/hero.png"));// 图标
		setTitle("飞机大战");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 关闭停止运行
	}

	public static void main(String[] args) {

		GameFrame frame = new GameFrame();
		GamePanel panel = new GamePanel();
		frame.add(panel);
		frame.setVisible(true);//窗体可见
	}
}

2.4  效果图

三、英雄机的出现及移动

3.1  定义飞行父类

import java.awt.image.BufferedImage;

/**
 * 这是飞行类,作为飞机及子弹的父类
 * @author Administrator
 *
 */
abstract class FlyObject {
	
	//图片
	BufferedImage img;
	
	//坐标
	int x;
	int y;
	
	//宽高
	int w;
	int h;
}

3.2  英雄机的出现

/**
 * 这是英雄机类
 * @author Administrator
 *
 */
public class Hero extends FlyObject {

	public Hero() {
		img = Tool.getImage("../img/hero.png");
		x = 190;
		y = 550;
		w = img.getWidth();
		h = img.getHeight();
	}

}

 

3.3  加入鼠标监听器

// 构造方法
	public GamePanel() {
		bg = Tool.getImage("../img/bg3.jpg");
		
		//创建鼠标适配器
		MouseAdapter adapter = new MouseAdapter() {
			public void mouseMoved(MouseEvent e) {
				int mx = e.getX();
				int my = e.getY();
				hero.moveToMouse(mx,my);
				repaint();
			}
		};
		//将适配器加入到监听器
		addMouseListener(adapter);
		addMouseMotionListener(adapter);
	}

3.4  英雄机的移动

	/**
	 * 英雄机跟随鼠标移动
	 * @param mx
	 * @param my
	 */
	public void moveToMouse(int mx, int my) {
		x = mx - w/2;
		y = my - h/2;
	}

四、敌机的出现及移动

4.1  敌机类

import java.util.Random;

/**
 * 这是敌机类
 * @author Administrator
 */
public class Enemy extends FlyObject{
	//敌机速度
	int sp;
	
	public Enemy() {
		
		Random num = new Random();
		int index = num.nextInt(11)+1;//生成1~11的随机数
		img = Tool.getImage("../img/ep"+index+".png");
		
		w = img.getWidth();
		h = img.getHeight();
		x = num.nextInt(512 - w);
		y = -h;
		sp = 11 - index;
	}
	
	//敌机移动
	public void move() {
		y += sp;
	}
}

4.2  敌机入场

// 敌机入场
	public void epEnter() {
		epcount++;
		if (epcount > 10) {
			Enemy ep = new Enemy();
			eps.add(ep);
			epcount = 0;
		}
	}

4.3  敌机移动

//敌机移动
	public void epMove() {
		for(int i = 0; i < eps.size(); i++) {
			Enemy ep = eps.get(i);
			ep.move();
		}
	}

4.4  启动一个线程

//游戏启动方法
	public void action() {
		new Thread() {
			public void run() {
				while(true) {
				    epEnter();
				    epMove();
				    try {
						Thread.sleep(20);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				    repaint();
				}
			}
		}.start();
	}

4.5  效果图

五、英雄机子弹的出现及移动

5.1  英雄机子弹类

/**
 * 这是英雄机子弹类
 * @author Administrator
 *
 */
public class HeroFire extends FlyObject{
	
	public HeroFire(int hx,int hy) {
		img = Tool.getImage("../img/herofire.png");
		x = hx;
		y = hy;
		w = img.getWidth()/3;
		h = img.getHeight()/3;
	}
	
	//英雄机子弹的移动
	public void move() {
		y -= 10;
	}
}

5.2  英雄机发射子弹

//英雄机发射子弹
	public void heroShoot() {
		hero_fire_count++;
		if(hero_fire_count > 5) {
			HeroFire hf = new HeroFire(hero.x+43,hero.y);
			hfs.add(hf);
			hero_fire_count = 0;
		}
	}

5.3  英雄机子弹移动

//英雄机子弹移动
	public void heroFireMove() {
		for(int i = 0; i < hfs.size(); i++) {
			HeroFire hf = hfs.get(i);
			hf.move();
		}
	}

5.4  效果图

 

六、敌机子弹的出现及移动

6.1  敌机子弹类

/**
 * 这是敌机子弹类
 * @author Administrator
 *
 */
public class EnemyFire extends FlyObject{
	
	int sp;
	
	public EnemyFire(int ex,int ey) {
		img = Tool.getImage("../img/fire.png");
		x = ex;
		y = ey;
		w = img.getWidth()/5;
		h = img.getHeight()/5;
	}
	
	//敌机子弹移动
	public void move() {
		y += sp+5;
	}
}

6.2  敌机发射子弹

//敌机发射子弹
	public void enemyShoot() {
		enemy_fire_count++;
		if (enemy_fire_count > 10) {
			for (int i = 0; i < eps.size(); i++) {
				Enemy ep = eps.get(i);
				EnemyFire ef = new EnemyFire(ep.x+55, ep.y+120);
				ef.sp = ep.sp;
				efs.add(ef);
			}
			enemy_fire_count = 0;
		}
	}

6.3  敌机子弹移动

//敌机子弹移动
	public void enemyFireMove() {
		for(int i = 0; i < efs.size(); i++) {
			EnemyFire ef = efs.get(i);
			ef.move();
		}
	}

6.4  效果图

七、击中问题

7.1  英雄机子弹击中敌机

       //英雄机子弹击中敌机
	public void heroFireHitEnemy() {
		for(int i = 0; i < hfs.size(); i++) {
			HeroFire hf = hfs.get(i);
			enemyBang(hf);
		}
	}
	
	//敌机被击中后消失
	public void enemyBang(HeroFire hf) {
		for(int i = 0; i < eps.size(); i++) {
			Enemy ep = eps.get(i);
			if(ep.enemyshootBy(hf)) {
				ep.hp--;
				if(ep.hp <= 0) {
					eps.remove(ep);
				}
				hfs.remove(hf);
			}
		}
	}

7.2  敌机子弹击中英雄机

//3.敌机子弹击中英雄机
	public void enemyFireHitHero() {
		for(int i = 0; i < efs.size(); i++) {
			EnemyFire ef = efs.get(i);
			heroBang(ef);
		}
	}
	
	//4.英雄机被敌机击中后,游戏结束
	public void heroBang(EnemyFire ef) {
		if(hero.heroshootBy(ef)) {
			hero.hp--;
			if(hero.hp <= 0) {
				gameover = true;
			}
			efs.remove(ef);
		}
	}

7.3  敌机与英雄机相撞

//7.敌机与英雄机相撞
	public void enemyBumpHero() {
		for(int i = 0; i < eps.size(); i++) {
			Enemy ep = eps.get(i);
			if(ep.bumpByHero(hero)) {
				eps.remove(ep);
				//hero.hp--;
				if(hero.hp <= 0) {
					gameover = true;
				}
			}
		}
	}

7.4  效果图 

八、游戏的开始与结束

8.1  鼠标点击监听事件

//鼠标点击监听
			@Override
			public void mouseClicked(MouseEvent e) {
				if (!start) {
					hero = new Hero();
					gameover = false;
					start = true;
					score = 0;
					eps.clear();
					hfs.clear();
					efs.clear();
					repaint();
				}
				if (gameover) {
					start = false;
					repaint();
				}
			}

8.2  开始与结束界面

//绘制结束界面
		if(gameover) {
			g.drawImage(over, 60, 200, over.getWidth() * 2, over.getHeight() * 2, null);
			g.drawImage(again_img,190,450,null);
		}
		//绘制开始界面
		if(!start) {
			g.drawImage(begin_img,0,0,null);
			g.drawImage(title_img,-30,10,title_img.getWidth(),title_img.getHeight(),null);
			g.drawImage(start_img,180,400,null);
		}

8.3  效果图 

 

九、加入音效

9.1  音乐类

/**
 * 这是音乐类,用于播放音乐
 * @author Administrator
 *
 */
public class Sound {
	
	private AudioClip bang;
	private AudioClip music;
	
	public Sound() {
		String fileName = "E:\\learning\\Program\\img\\bang.wav";
		String fileName2 = "E:\\learning\\Program\\img\\bgm.wav";
		try {
			bang = JApplet.newAudioClip(new URL("file:"+fileName));
			music = JApplet.newAudioClip(new URL("file:"+fileName2));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	
	//播放飞机爆炸的声音
	public void bangVoice() {
		new Thread() {
			public void run() {
				bang.play();;
			}
		}.start();
	}
	
	//播放背景音乐
	public void bgm() {
		new Thread() {
			public void run() {
				music.loop();
			}
		}.start();
	}
	
	//停止播放背景音乐
	public void stop() {
		music.stop();
	}
}

十、遇到的问题

1.  明明没有敌机出现,可是子弹却一直不停的从上方发出,一开始我总把注意力放在敌机和子弹的出现频率上,后来更改敌机的

     初始贴图位置后,发现敌机速度为0,所以一直在发射子弹。不同的敌机拥有不同的速度,其中有一种设为0了。

2.  关于鼠标点击监听,游戏结束后,点击后应该重新开始游戏,结果游戏并未运行,只贴出了背景图和英雄机,于是又把注意

     力放在了gameover上,因为游戏不运行,就是某个地方gameover=true了,找了很久发现action函数中if把异常中的睡眠也包

     括进去了,包括睡眠与不包括睡眠这两者的区别我还不明白

3.  关于加入敌机爆炸特效,不知道怎么加。 

4.  关于背景图的循环滚动,不知道怎么加。

十一、学习地址

----------------------------------------------------------------------更新bug及功能-------------------------------------------------------------------------------

  • 关于开始界面,简介界面,结束界面之间存在bug,更正监听代码如下
//鼠标点击监听
			@Override
			public void mouseClicked(MouseEvent e) {
				
				boolean clickstartgame = e.getX() >= 160 && e.getX() <= 349 && e.getY() >= 400 && e.getY() <= 462;
				boolean clickregame = e.getX() >= 190 && e.getX() <= 332 && e.getY() >= 450 && e.getY() <= 501;
				boolean clickbrief = e.getX() >= 160 && e.getX() <= 349 && e.getY() >= 480 && e.getY() <= 542;
				boolean clickreturn = e.getX() >= 160 && e.getX() <= 349 && e.getY() >= 620 && e.getY() <= 682;
				
				if(clickbrief && !gameover) {
					playbrief = true;
				}
				if(playbrief && clickreturn) {
					start = false;
					playbrief = false;
				}
				if (!start && clickstartgame) {
					hero = new Hero();
					gameover = false;
					start = true;
					score = 0;
					eps.clear();
					hfs.clear();
					efs.clear();
					sound.bgm();
					repaint();
				}
				if (gameover && clickregame) {
					start = false;
					gameover = false;
					repaint();
				}
			}
  • 关于背景的循环滚动
//背景图的移动,画两张相同的背景图
	public void bgMove() {
		y1++;
		y2++;
		if(y1 == 0) {
			y2 = -game_bg.getHeight();
		}
		if(y2 == 0) {
			y1 = -game_bg.getHeight();
		}
	}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值