JAVA学习:坦克大战(怀旧版)游戏开发代码

     这学期开了专业课《JAVA语言程序设计》,前面有一段时间跟着韩顺平老师的视频学习,顺着也把坦克大战的代码敲了出来。今天,应老汪的任务布置,在博客园上开了个人博客,主要目的在于学习交流,分享自己的点滴经验。这也是我在博客园上的第一篇随笔,罗嗦下~~~~

TankeGame1_3.java

 

/**
 * 功能:坦克大战
 * 1.画出坦克
 * 2.通过上下左右键控制坦克的移动
 * 3.增加四辆敌人的坦克
 * 4.画出了自己坦克的子弹,并能向敌人开火,子弹飞出去
 * 5.子弹可以连发
 * 6.子弹可以打死敌人的坦克,即子弹击中敌人坦克则敌人坦克消失
 * 7.敌人的坦克击中我的坦克,则我的坦克消失
 * 8.敌人的坦克运动时不能重叠在一起
 * 9.游戏可以分关
 *   9.1做一个分关panel,起提示作用
 * 10.玩家在玩游戏时可以暂停
 * 11.玩家结束游戏时可以保存游戏
 */
import java.awt.*;
import java.util.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.imageio.ImageIO;
import javax.swing.*;
import java.io.*;
//定义MyHelpPanel,提示帮助信息
class MyHelpPanel extends JPanel
{
	public void paint(Graphics g)
	{
		g.fill3DRect(0, 0, 570, 430, false);
		g.setColor(Color.blue);
		Font myfont = new Font("方正喵呜体",Font.BOLD,30);
		g.setFont(myfont);
		g.drawString("游戏帮助:", 30, 50);
		Font myfont1 = new Font("方正喵呜体",Font.BOLD,20);
		g.setFont(myfont1);
		g.drawString("1.↑,↓,←,→分别控制坦克的上下左右移动。", 38, 100);
		g.drawString("2.按下空格键可以发射子弹。", 38, 150);
		g.drawString("3.结束游戏可点击菜单栏的退出选项。", 38, 200);
		g.drawString("---稻草人工作室", 260, 260);
		
	}
}
//定义一个panel,提示首页信息
class MyStartPanel extends JPanel implements Runnable
{
	int times = 0;
	public void paint(Graphics g)
	{
		
		g.fill3DRect(0, 0, 570, 430, false);
		//信息提示
		if(times%2==0)
		{
			g.setColor(Color.blue);
			Font myfont = new Font("方正喵呜体",Font.BOLD,40);
			g.setFont(myfont);
			g.drawString("坦克大战游戏", 140, 150);
			Font myfont1 = new Font("方正喵呜体",Font.BOLD,25);
			g.setFont(myfont1);
			g.drawString("——稻草人工作室", 200, 200);
		}
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true)
		{
			//休眠一秒
			try {
				Thread.sleep(1000);
				times++;
			} catch (Exception e) {
				// TODO: handle exception
				e.printStackTrace();
			}
			//重画
			this.repaint();
		}
	}
}
//定义我的面板
class MyPanel extends JPanel implements KeyListener, Runnable {
	int x = 10, y = 10;
	
	
	
	// 定义一个我的坦克
	Hero hero = null;
	// 定义敌人的坦克组
	Vector<Enemy> en = new Vector<Enemy>();
	Vector<Node> nodes = new Vector<Node>();
	// 定义敌人的坦克数量
	int encount = 3;
	// 定义炸弹向量集合
	Vector<Bomb> bomb = new Vector<Bomb>();

	// 构造函数
	public MyPanel(String flag) {
		
		//恢复数据
		Record.getRecord();
		// 初始化我的坦克
		hero = new Hero(80, 80);
		if(flag.equals("newgame"))
		{
			System.out.println("新游戏");
			// 初始化敌人的坦克
			for (int i = 0; i < encount; i++) 
			{
				// 创建一辆坦克的对象
				Enemy e = new Enemy((i + 1) * 50, 4);
				e.setColor(3);// 给定敌人的坦克颜色
				e.setDirect(1);// 给定方向
				// 启动敌人的坦克
				Thread t = new Thread(e);
				t.start();
				// 给敌人添加一颗子弹
				Bullet b = new Bullet(e.x + 8, e.y + 35, 1);
				// 给敌人坦克加入子弹
				e.bb.add(b);
				// 启动敌人子弹启动线程
				Thread t2 = new Thread(b);
				t2.start();
				en.add(e);// 加入
				
				// 将panel里的敌人坦克向量交给敌人的坦克
				e.setEn(en);
			}
		}else if(flag.equals("con"))
		{
			
			nodes = new Record().getNodes();
			System.out.println(nodes.size()+"旧游戏");
			// 初始化敌人的坦克
			for (int i = 0; i < nodes.size(); i++) 
			{
				
				//取出节点中的一辆坦克(即是上次幸存下来的敌人坦克)
				Node node = nodes.get(i);
				// 创建一辆坦克的对象
				Enemy e = new Enemy(node.x, node.y);
				
				e.setColor(3);// 给定敌人的坦克颜色
				e.setDirect(node.direct);// 给定方向
				//将MyPanel的敌人坦克向量交给该敌人坦克
				e.setEn(en);
				// 启动敌人的坦克
				Thread t = new Thread(e);
				t.start();
				// 给敌人添加一颗子弹
				Bullet b = new Bullet(e.x + 8, e.y + 35, 1);
				// 给敌人坦克加入子弹
				e.bb.add(b);
				// 启动敌人子弹启动线程
				Thread t2 = new Thread(b);
				t2.start();
				en.add(e);// 加入
			}
		}

//		try{
//			image1 = ImageIO.read(new File("bomb_1.gif"));
//			image2 = ImageIO.read(new File("bomb_2.gif"));
//			image3 = ImageIO.read(new File("bomb_3.gif"));
//		}catch(Exception e){
//			e.printStackTrace();
//		}
		//播放开战声音
		AePlayWave apw = new AePlayWave("E:/TDDOWNLOAD/tankedazhan.wav");
		apw.start();
		// 初始化三张图片
		image1 = Toolkit.getDefaultToolkit().getImage(
				Panel.class.getResource("/bomb_1.gif"));
		image2 = Toolkit.getDefaultToolkit().getImage(
				Panel.class.getResource("/bomb_2.gif"));
		image3 = Toolkit.getDefaultToolkit().getImage(
				Panel.class.getResource("/bomb_3.gif"));
	}
	

	// 定义三张坦克爆炸的图片
	Image image1 = null;
	Image image2 = null;
	Image image3 = null;
	
	//画出提示信息的函数
	public void ShowInfo(Graphics g)
	{
		//画出提示信息,用于显示坦克的数量
		//画出当前敌人坦克数量
		this.drawTanke(20, 306, g, 2, 0);
		g.setColor(Color.black);
		Font myfont = new Font("方正喵呜体",Font.BOLD,20);
		g.setFont(myfont);
		g.drawString(Record.getEnNum()+"辆", 60, 325);
		//画出当前我的坦克数量
		this.drawTanke(125, 306, g, 2, 2);
		g.drawString(Record.getMyLife()+"辆", 165, 325);
		//画出玩家的总成绩
		g.setColor(Color.black);
		g.drawString("你的总成绩为:", 405, 30);
		this.drawTanke(420, 45, g, 0, 0);
		g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*100, 445, 70);
		this.drawTanke(420, 105, g, 0, 1);
		g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*200, 445, 130);
		this.drawTanke(420, 165, g, 0, 2);
		g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*300, 445, 190);
		this.drawTanke(420, 225, g, 0, 3);
		g.drawString(Record.getAllNum()+"×100="+Record.getAllNum()*400, 445, 250);
	
	}

	// 重新paint
	public void paint(Graphics g) {
		super.paint(g);
		g.fillRect(0, 0, 400, 300);// 整个画面填充成黑色
		//画出提示信息
		this.ShowInfo(g);
		// 画出自己的坦克
		if(hero.isLive)
		{
			this.drawTanke(hero.getX(), hero.getY(), g, this.hero.direct, 3);
		}else{
			//this.remove(hero);
		}
		// 画自己坦克的子弹:从bb中取出每颗子弹,并画出来
		for (int i = 0; i < hero.bb.size(); i++) {
			Bullet mybullet = hero.bb.get(i);
			// 画出子弹
			if (mybullet != null && mybullet.isLive == true) {
				g.draw3DRect(mybullet.x, mybullet.y, 2, 2, false);
			}
			// 如果子弹死亡就把子弹从bb中删除
			if (mybullet.isLive == false) {
				hero.bb.remove(mybullet);
			}
		}
		// 画出炸弹
		for (int i = 0; i < bomb.size(); i++) {
			Bomb bo = bomb.get(i);
			if (bo.Life > 6) {
				g.drawImage(image1, bo.x, bo.y, 30, 30, this);
			} else if (bo.Life > 3) {
				g.drawImage(image2, bo.x, bo.y, 30, 30, this);
			} else {
				g.drawImage(image3, bo.x, bo.y, 30, 30, this);
			}
			// 生命值减减
			bo.lifeDown();
			if (bo.Life == 0) {
				bomb.remove(bo);
			}
		}
		// 画出敌人的坦克
		for (int i = 0; i < en.size(); i++) {
			Enemy enemy = en.get(i);
			if (enemy.isLive) {
				this.drawTanke(enemy.getX(), enemy.getY(), g, enemy.getDirect(), 1);
				// 从bb中取出每颗子弹,并画出来
				for (int j = 0; j < enemy.bb.size(); j++) {
					Bullet enemybullet = enemy.bb.get(j);
					// 画出子弹
					if (enemybullet.isLive) {
						g.draw3DRect(enemybullet.x, enemybullet.y, 2, 2, false);
					} else// 如果这样就把子弹从bb中删除
					{
						enemy.bb.remove(enemybullet);
					}
				}
			}
		}
	}

	// 判断我的子弹是否击中敌人的坦克的函数
	public void ShootEnemies() {

		for (int i = 0; i < hero.bb.size(); i++) {
			// 取出子弹
			Bullet bullet1 = hero.bb.get(i);

			// 判断子弹是否击中敌人
			if (bullet1.isLive) {
				// 取出每个坦克与子弹判断是否击中
				for (int j = 0; j < en.size(); j++) {
					// 取出坦克
					Enemy enemy1 = en.get(j);
					if (enemy1.isLive) {
						if(this.ShootTanke(bullet1, enemy1))
						{
							Record.ReduceenNum();
							Record.DeadNum();
						}
					}
				}
			}

		}
	}

	// 判断敌人的子弹是否击中我的坦克的函数
	public void ShootHero()
	{
		for(int i=0;i<this.en.size();i++)
		{
			//取出敌人坦克
			Enemy e = en.get(i);
			
			//取出每颗子弹判断是否击中我的坦克
			if(e.isLive)
			{
				for(int j=0;j<e.bb.size();j++)
				{
					//取出子弹
					Bullet bullet = e.bb.get(j);
					if(hero.isLive)
					{
						if(this.ShootTanke(bullet, hero))
						{
							Record.HeroNum();
						}
					}
					
				}
			}
			
		}
	}

	// 写一个专门函数判断子弹是否击中坦克
	public boolean ShootTanke(Bullet b, Tanke ens) {
		boolean boo = false;
		// 判断坦克的方向
		switch (ens.direct) {
		// 如果敌人的坦克是向上或者向下
		case 0:
		case 1:
			if (b.x > ens.x && b.x < ens.x + 20 && b.y > ens.y
					&& b.y < ens.y + 30) {
				// 击中,子弹死亡
				b.isLive = false;
				// 敌人坦克死亡
				ens.isLive = false;
//				Record.ReduceenNum();
//				Record.DeadNum();
				boo = true;
				// 创建炸弹爆炸
				Bomb bo = new Bomb(ens.x, ens.y);
				// 放入炸弹的向量里
				bomb.add(bo);

			}
			break;
		case 2:
		case 3:
			if (b.x > ens.x && b.x < ens.x + 30 && b.y > ens.y
					&& b.y < ens.y + 20) {
				// 击中,子弹死亡
				b.isLive = false;
				// 敌人坦克死亡
				ens.isLive = false;
				boo = true;
				// 创建炸弹爆炸
				Bomb bo = new Bomb(ens.x, ens.y);
				bomb.add(bo);
			}
			break;
		}
		return boo;
	}

	// 画坦克的函数(扩展)
	public void drawTanke(int x, int y, Graphics g, int direct, int type) {
		// 判断什么类型的坦克
		switch (type) {
		case 0:
			g.setColor(Color.gray);
			break;
		case 1:
			g.setColor(Color.green);
			break;
		case 2:
			g.setColor(Color.blue);
			break;
		case 3:
			g.setColor(Color.red);
			break;
		}
		// 判断方向
		switch (direct) {
		// 坦克向上移动
		case 0:
			// 1.画左边的矩形框
			g.fill3DRect(x, y, 5, 30, false);
			// 2.画右边的矩形框
			g.fill3DRect(x + 15, y, 5, 30, false);
			// 画出中间矩形
			g.fill3DRect(x + 5, y + 5, 10, 20, false);

			// 画圆
			g.fillOval(x + 4, y + 10, 10, 10);
			// 画线(炮筒向上)
			g.drawLine(x + 9, y + 10, x + 9, y - 7);
			g.drawLine(x + 10, y + 10, x + 10, y - 7);
			// 画左链条
			g.drawLine(x, y + 5, x + 4, y + 5);
			g.drawLine(x, y + 10, x + 4, y + 10);
			g.drawLine(x, y + 15, x + 4, y + 15);
			g.drawLine(x, y + 20, x + 4, y + 20);
			g.drawLine(x, y + 25, x + 4, y + 25);
			// 画右边的链条
			g.drawLine(x + 15, y + 5, x + 19, y + 5);
			g.drawLine(x + 15, y + 10, x + 19, y + 10);
			g.drawLine(x + 15, y + 15, x + 19, y + 15);
			g.drawLine(x + 15, y + 20, x + 19, y + 20);
			g.drawLine(x + 15, y + 25, x + 19, y + 25);
			break;

		// 坦克向下移动
		case 1:
			// 1.画左边的矩形框
			g.fill3DRect(x, y, 5, 30, false);
			// 2.画右边的矩形框
			g.fill3DRect(x + 15, y, 5, 30, false);
			// 画出中间矩形
			g.fill3DRect(x + 5, y + 5, 10, 20, false);

			// 画圆
			g.fillOval(x + 4, y + 10, 10, 10);
			// 画线(炮筒向下)
			g.drawLine(x + 9, y + 10, x + 9, y + 37);
			g.drawLine(x + 10, y + 10, x + 10, y + 37);
			// 画左链条
			g.drawLine(x, y + 5, x + 4, y + 5);
			g.drawLine(x, y + 10, x + 4, y + 10);
			g.drawLine(x, y + 15, x + 4, y + 15);
			g.drawLine(x, y + 20, x + 4, y + 20);
			g.drawLine(x, y + 25, x + 4, y + 25);
			// 画右边的链条
			g.drawLine(x + 15, y + 5, x + 19, y + 5);
			g.drawLine(x + 15, y + 10, x + 19, y + 10);
			g.drawLine(x + 15, y + 15, x + 19, y + 15);
			g.drawLine(x + 15, y + 20, x + 19, y + 20);
			g.drawLine(x + 15, y + 25, x + 19, y + 25);
			break;

		// 坦克向左移动
		case 2:
			// 1.画上边的矩形框
			g.fill3DRect(x, y, 30, 5, false);
			// 2.画下边的矩形框
			g.fill3DRect(x, y + 15, 30, 5, false);
			// 画出中间矩形
			g.fill3DRect(x + 5, y + 5, 20, 10, false);

			// 画圆
			g.fillOval(x + 10, y + 4, 10, 10);

			// 画线(炮筒向左)
			g.drawLine(x + 15, y + 9, x - 7, y + 9);
			g.drawLine(x + 15, y + 10, x - 7, y + 10);

			// 画上边的链条
			g.drawLine(x + 5, y, x + 5, y + 4);
			g.drawLine(x + 10, y, x + 10, y + 4);
			g.drawLine(x + 15, y, x + 15, y + 4);
			g.drawLine(x + 20, y, x + 20, y + 4);
			g.drawLine(x + 25, y, x + 25, y + 4);
			// 画下边的链条
			g.drawLine(x + 5, y + 15, x + 5, y + 19);
			g.drawLine(x + 10, y + 15, x + 10, y + 19);
			g.drawLine(x + 15, y + 15, x + 15, y + 19);
			g.drawLine(x + 20, y + 15, x + 20, y + 19);
			g.drawLine(x + 25, y + 15, x + 25, y + 19);
			break;

		// 坦克向右移动
		case 3:
			// 1.画上边的矩形框
			g.fill3DRect(x, y, 30, 5, false);
			// 2.画下边的矩形框
			g.fill3DRect(x, y + 15, 30, 5, false);
			// 画出中间矩形
			g.fill3DRect(x + 5, y + 5, 20, 10, false);

			// 画圆
			g.fillOval(x + 10, y + 4, 10, 10);

			// 画线(炮筒向右)
			g.drawLine(x + 15, y + 9, x + 35, y + 9);
			g.drawLine(x + 15, y + 10, x + 35, y + 10);

			// 画上边的链条
			g.drawLine(x + 5, y, x + 5, y + 4);
			g.drawLine(x + 10, y, x + 10, y + 4);
			g.drawLine(x + 15, y, x + 15, y + 4);
			g.drawLine(x + 20, y, x + 20, y + 4);
			g.drawLine(x + 25, y, x + 25, y + 4);
			// 画下边的链条
			g.drawLine(x + 5, y + 15, x + 5, y + 19);
			g.drawLine(x + 10, y + 15, x + 10, y + 19);
			g.drawLine(x + 15, y + 15, x + 15, y + 19);
			g.drawLine(x + 20, y + 15, x + 20, y + 19);
			g.drawLine(x + 25, y + 15, x + 25, y + 19);
			break;
		}
	}

	// 按下某一个键
	public void keyPressed(KeyEvent e) {
		if (e.getKeyCode() == KeyEvent.VK_UP)// 上移
		{
			this.hero.setDirect(0);
			this.hero.moveUp();
			// 调用repaint()函数来重绘界面
			this.repaint();
		} else if (e.getKeyCode() == KeyEvent.VK_RIGHT)// 右移
		{
			this.hero.setDirect(3);
			this.hero.moveRight();
			// 调用repaint()函数来重绘界面
			this.repaint();
		} else if (e.getKeyCode() == KeyEvent.VK_LEFT)// 左移
		{
			this.hero.setDirect(2);
			this.hero.moveLeft();
			// 调用repaint()函数来重绘界面
			this.repaint();
		} else if (e.getKeyCode() == KeyEvent.VK_DOWN)// 下移
		{
			this.hero.setDirect(1);
			this.hero.moveDown();
			// 调用repaint()函数来重绘界面
			this.repaint();
		}
		// 判断玩家是否按下空格键,是否发出子弹
		if (e.getKeyCode() == KeyEvent.VK_SPACE) {
			// 此时玩家按下空格键,则开火
			if (this.hero.bb.size() < 5) {
				this.hero.Fire();
			}

		}
		// 必须重新绘制Panel
		this.repaint();

	}

	// 松开某一个键
	public void keyReleased(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	// 键的值被输出
	public void keyTyped(KeyEvent e) {
		// TODO Auto-generated method stub

	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (true) {
			try {
				Thread.sleep(100);// 每隔100毫秒重绘
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//我打敌人
			this.ShootEnemies();
			//敌人打我
			this.ShootHero();

			// 重绘
			this.repaint();
		}
	}
}

public class TankeGame1_4 extends JFrame implements ActionListener{

	//定义游戏面板
	MyPanel mp = null;
	//定义一个开始面板
	MyStartPanel msp = null;
	MyHelpPanel mhp = null;
	//定义菜单和菜单选项
	JMenuBar jmb = null;
	JMenu jm1 = null,jm2 = null,jm3 = null;
	JMenuItem jmi1 = null, jmi2 = null,jmi3 = null, jmi4 = null,
	          jmi5 = null,jmi6 = null,jmi7 = null;
	// 构造函数
	public TankeGame1_4() {

		//创建菜单及菜单选项
		jmb = new JMenuBar();
		jm1 = new JMenu("游戏(G)");
		jm2 = new JMenu("暂停/继续(Q)");
		jm3 = new JMenu("帮助(H)");
		jm1.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体
		jm1.setMnemonic('G');//设置快捷方式
		jm2.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体
		jm2.setMnemonic('Q');//设置快捷方式
		jm3.setFont(new Font("方正喵呜体",Font.BOLD,15));//设置菜单显示的字体
		jm3.setMnemonic('H');//设置快捷方式
		
		jmi1 = new JMenuItem("开始新游戏(N)");
		jmi2 = new JMenuItem("继续旧游戏(J)");
		jmi3 = new JMenuItem("保存游戏(B)");
		jmi4 = new JMenuItem("退出(E)");
		jmi5 = new JMenuItem("暂停(S)");
		jmi6 = new JMenuItem("继续(C)");
		jmi7 = new JMenuItem("游戏制作");
		jmi1.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi2.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi3.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi4.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi5.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi6.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi7.setFont(new Font("方正喵呜体", Font.BOLD, 15));
		jmi1.setMnemonic('N');//设置快捷键
		jmi2.setMnemonic('J');//设置快捷键
		jmi3.setMnemonic('B');//设置快捷键
		jmi4.setMnemonic('E');//设置快捷键
		jmi5.setMnemonic('S');//设置快捷键
		jmi6.setMnemonic('C');//设置快捷键
		jm1.add(jmi1);
		jm1.add(jmi2);
		jm1.add(jmi3);
		jm1.add(jmi4);
		jm2.add(jmi5);
		jm2.add(jmi6);
		jm3.add(jmi7);
		jmb.add(jm1);
		jmb.add(jm2);
		jmb.add(jm3);
		//注册菜单项的监听
		jmi1.addActionListener(this);
		jmi1.setActionCommand("newgame");
		jmi2.addActionListener(this);
		jmi2.setActionCommand("jixu");
		jmi3.addActionListener(this);
		jmi3.setActionCommand("save");
		
		jmi4.addActionListener(this);
		jmi4.setActionCommand("exit");
		
		jmi7.addActionListener(this);
		jmi7.setActionCommand("help");
		
		msp = new MyStartPanel();
		
    	// 启动mp线程
		Thread t = new Thread(msp);
		t.start();
		this.setJMenuBar(jmb);//菜单Bar放到JFrame上
		this.add(msp);
		this.setTitle("坦克大战");
		this.setSize(570, 430);
		this.setLocation(300, 100);//设置游戏框在屏幕上出现的位置
		this.setResizable(false);//游戏框不能修改大小
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setVisible(true);
	}

	public static void main(String[] args) {

		TankeGame1_4 tankegame1_1 = new TankeGame1_4();

	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		//对监听到的用户的动作作出反应
		if(e.getActionCommand().equals("newgame"))
		{
			//创建真正游戏面板
			
			mp = new MyPanel("newgame");
			Thread tt = new Thread(mp);
			tt.start();
			this.remove(msp);//移除旧的MyStartPanel面板
			this.add(mp);//添加游戏面板MyPanel
			
			// 注册监听
			this.addKeyListener(mp);
			//显示一下新添加的面板,这样才能看到新面板。
			this.setVisible(true);
		}
		else if(e.getActionCommand().equals("save"))
		{
			//保存当前游戏状态
			System.out.println("保存");
			Record record = new Record();
			record.setEn(mp.en);
			record.keepEnemyRecord();
		}
		else if(e.getActionCommand().endsWith("jixu"))
		{
			
			//创建真正游戏面板
			mp = new MyPanel("con");
			
			Thread tt = new Thread(mp);
			tt.start();
			this.remove(msp);//移除旧的MyStartPanel面板
			this.add(mp);//添加游戏面板MyPanel
			
			// 注册监听
			this.addKeyListener(mp);
			//显示一下新添加的面板,这样才能看到新面板。
			this.setVisible(true);
		}
		else if(e.getActionCommand().equals("exit"))
		{
			//退出前先保存游戏
			Record record = new Record();
			record.setEn(mp.en);
			record.keepEnemyRecord();
			System.exit(0);
		}
		else if(e.getActionCommand().equals("help"))
		{
			mhp = new MyHelpPanel();
			this.remove(msp);
			this.add(mhp);
			this.setVisible(true);
		}
	}

}


Material.java

 

import java.util.Vector;
import java.io.*;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.SourceDataLine;

//播放声音的类
class AePlayWave extends Thread {

	private String filename;
	public AePlayWave(String wavfile) {
		filename = wavfile;

	}

	public void run() {

		File soundFile = new File(filename);

		AudioInputStream audioInputStream = null;
		try {
			audioInputStream = AudioSystem.getAudioInputStream(soundFile);
		} catch (Exception e1) {
			e1.printStackTrace();
			return;
		}

		AudioFormat format = audioInputStream.getFormat();
		SourceDataLine auline = null;
		DataLine.Info info = new DataLine.Info(SourceDataLine.class, format);

		try {
			auline = (SourceDataLine) AudioSystem.getLine(info);
			auline.open(format);
		} catch (Exception e) {
			e.printStackTrace();
			return;
		}

		auline.start();
		int nBytesRead = 0;
		//这是缓冲
		byte[] abData = new byte[512];

		try {
			while (nBytesRead != -1) {
				nBytesRead = audioInputStream.read(abData, 0, abData.length);
				if (nBytesRead >= 0)
					auline.write(abData, 0, nBytesRead);
			}
		} catch (IOException e) {
			e.printStackTrace();
			return;
		} finally {
			auline.drain();
			auline.close();
		}

	}

	
}



class Node
{
	int x;
	int y;
	int direct;
	public Node(int x,int y,int direct)
	{
		this.x = x;
		this.y = y;
		this.direct = direct;
	}
	
}
//记录类,记录玩家的各种信息和设置
class Record
{
	//从文件中读取记录点
	static Vector<Node> nodes = new Vector<Node>();
	//记录每关有多少敌人
	private static int enNum = 20;
	//我的生命值
	private static int myLife = 3;
	
	private static int allNum = 0;
	private static FileWriter fw = null;
	private static BufferedWriter bw = null;
	private static FileReader fr = null;
	private static BufferedReader br = null;
	private static Vector<Enemy> en = new Vector<Enemy>();
	public Vector<Enemy> getEn() {
		return en;
	}
	public void setEn(Vector<Enemy> en1) {
		this.en = en1;
	}
	//写一个函数读取文件里的信息(敌人坦克数量、坐标、方向)
	public Vector<Node> getNodes()
	{
		try {
			fr = new FileReader("d:\\mykeepRecord.txt");
			br = new BufferedReader(fr);
			String str = "";
			str = br.readLine();
			allNum = Integer.parseInt(str);
			while((str = br.readLine())!=null)
			{
				String string[] = str.split(" ");
				Node node = new Node(Integer.parseInt(string[0]), Integer.parseInt(string[1]),Integer.parseInt(string[2]));
				nodes.add(node);
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			try {
				br.close();
				fr.close();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();		
			}
		}
		return nodes;
	}
	//退出保存我消灭的敌人坦克数量的记录
	public static void keepRecord()
	{
		try {
			//创建txt文件
			fw = new FileWriter("d:\\mykeepRecord.txt");
			bw = new BufferedWriter(fw);
			bw.write(allNum+"\r\n");
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			try {
				//关闭流,谁先开就后关,后开先关
				bw.close();
				fw.close();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();
			}
		}
	}
	public void keepEnemyRecord()
	{
		try {
			//创建txt文件,保存被消灭的敌人坦克数
			fw = new FileWriter("d:\\mykeepRecord.txt");
			bw = new BufferedWriter(fw);
			bw.write(allNum+"\r\n");
			
			//记录敌人活着的坦克的坐标、方向,为恢复游戏做准备。
			for(int i = 0; i<en.size();i++)
			{
				//取出一辆坦克
				Enemy e = en.get(i);
				if(e.isLive)//坦克还活着
				{
					String enemyrecord = e.x+" "+e.y+" "+e.direct;
					//写入
					bw.write(enemyrecord+"\r\n");
				}
			}
			
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			try {
				//关闭流,谁先开就后关,后开先关
				bw.close();
				fw.close();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();
			}
		}
	}
	//读取击毁的敌人坦克数量记录
	public static void getRecord()
	{
		try {
			fr = new FileReader("d:\\mykeepRecord.txt");
			br = new BufferedReader(fr);
			String str = br.readLine();
			allNum = Integer.parseInt(str);
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
		}finally{
			try {
				br.close();
				fr.close();
			} catch (Exception e2) {
				// TODO: handle exception
				e2.printStackTrace();		
			}
		}
	}
	public static int getAllNum() {
		return allNum;
	}
	public static void setAllNum(int allNum) {
		Record.allNum = allNum;
	}
	public static int getEnNum() {
		return enNum;
	}
	public static void setEnNum(int enNum) {
		Record.enNum = enNum;
	}
	public static int getMyLife() {
		return myLife;
	}
	public static void setMyLife(int myLife) {
		Record.myLife = myLife;
	}	
	//减少敌人数量
	public static void ReduceenNum()
	{
		enNum--;
	}
	//被消灭的敌人的坦克
	public static void DeadNum()
	{
		allNum++;
	}
	//若我被击中,我的坦克数量减少
	public static void HeroNum()
	{
		myLife--;
	}
}
//炸弹类
class Bomb
{
	int x, y;
	int Life = 9;
	boolean isLive = true;
	public Bomb(int x,int y)
	{
		this.x = x;
		this.y = y;
	}
	//减少生命值
	public void lifeDown()
	{
		if(Life > 0)
		{
			Life--;
		}else{
			this.isLive = false;
		}
	}
}
//子弹类
class Bullet implements Runnable 
{
	int x, y,direct=0;
	boolean isLive = true;
	int speed = 3;//子弹的速度
	public Bullet(int x, int y,int direct)
	{
		this.x = x;
		this.y = y;
		this.direct = direct;
	}
	 public void run()
	 {
		 

		 while(isLive){
			 //子弹先休息50毫秒
			 try {
				 Thread.sleep(50);
				 } catch (InterruptedException e) {
					 e.printStackTrace();
				 }
			 switch(direct)
			 {
			 //子弹向上飞
			 case 0:
				 y-=speed;
				 break;
			 //子弹向下飞
		     case 1:
		    	 y+=speed;
		    	 break;
		     //子弹向左飞
		     case 2:
		    	 x-=speed;
		    	 break;
		     //子弹向右飞
		     case 3:
		    	 x+=speed;
		    	 break;
		     }
			 //子弹何时死亡,判断子弹是否到达边缘
			 if(x < -2 || x > 400 || y < -2 || y > 296)
			 {
				 this.isLive = false;
				 break;
			 }
		 }
	 }
	
}
//坦克类
class Tanke{
	int x = 0;//横坐标
	int y = 0;//纵坐标
	boolean isLive = true;
	int direct = 0; //0表示向上,1表示向下,2表示向左,3表示向右
	int speed = 3;//定义速度
	int type = 0;//坦克类型:0表示灰色,打一次就死;1表示绿色,打两次才死;2表示蓝色,打三次才死;3表示红色,打四次才死。
	int color;//坦克颜色
	public int getColor() {
		return color;
	}
	public void setEn(Vector<Enemy> vv) {
		// TODO Auto-generated method stub
		
	}
	public void setColor(int color) {
		this.color = color;
	}
	public int getType() {
		return type;
	}
	public void setType(int type) {
		this.type = type;
	}
	public int getSpeed() {
		return speed;
	}
	public void setSpeed(int speed) {
		this.speed = speed;
	}
	public int getDirect() {
		return direct;
	}
	public void setDirect(int direct) {
		this.direct = direct;
	}
	public int getX() {
		return x;
	}
	public void setX(int x) {
		this.x = x;
	}
	public int getY() {
		return y;
	}
	public void setY(int y) {
		this.y = y;
	}
	
	public Tanke(int x, int y){
		this.x = x;
		this.y = y;	
	}	
}
//我的坦克
class Hero extends Tanke{
	//子弹
    //子弹向量组
	Vector<Bullet> bb = new Vector<Bullet>();
	Bullet b = null;
	
	//坦克
	public Hero(int x,int y){
		super(x,y);	
	}
	//开火
	public void Fire()
	{
		
		switch(this.direct)
		{
		//子弹向上
		case 0:
			//创建一颗子弹
			b = new Bullet(x+8, y-8,0);
			//把子弹加入到向量中
			bb.add(b);
			break;
		 //子弹向下 
		case 1:
			//创建一颗子弹
			b = new Bullet(x+8, y+35,1);
			//把子弹加入到向量中
			bb.add(b);
			break;
		//子弹向左
		case 2:
			b = new Bullet(x-8,y+9,2);
			bb.add(b);
			break;
		//子弹向右
		case 3:
			b = new Bullet(x+35, y+9,3);
			bb.add(b);
			break;
		}
		//启动子弹线程
		Thread t = new Thread(b);
		t.start();
	}
	//我的坦克向上移动
	public void moveUp(){
		if(y>0){
			y-=speed;
		}
		
	}
	//我的坦克向下移动
	public void moveDown(){
		if(y<228){
		    y+=speed;
		}
	}
	//我的坦克向左移动
	public void moveLeft(){
		if(x>0){
			x-=speed;
		}
	}
	//我的坦克向右移动
	public void moveRight(){
		if(x<350){
			x+=speed;
		}
	}
	public void MyType(){
		
	}
}

//敌人的坦克
class Enemy extends Tanke implements Runnable{
	//定义敌人的坦克组,定义向量,可以访问到panel里敌人的坦克
	
	Vector<Enemy> en = new Vector<Enemy>();
    //定义敌人的子弹向量组
	Vector<Bullet> bb = new Vector<Bullet>();
	public Enemy(int x,int y)
	{
		super(x,y);	
	}
	//得到panel里的敌人坦克向量
	public void setEn(Vector<Enemy> vv)
	{
		this.en = vv;
	}
	//判断是否碰到了别的坦克
	public boolean isTouchOtherEnemy()
	{
		boolean b = false;
		switch(this.direct)
		{
		case 0:
			//坦克向上,取出所有的敌人坦克
			for(int i=0;i<en.size();i++)
			{
				//取出每一辆坦克
				Enemy e = en.get(i);
				//如果不是自己的坦克
				if(e!=this)
				{
					//如果敌人的坦克向上或者向下
					if(e.direct==0||e.direct==1)
					{
						if(this.x>=e.x&&this.x<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
						{
							return true;
						}
						if(this.x+20>=e.x&&this.x+20<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
						{
							return true;
						}
					}
					//如果敌人的坦克向左或者向右
					if(e.direct==2||e.direct==3)
					{
						if(this.x>=e.x&&this.x<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
						{
							return true;
						}
						if(this.x+20>=e.x&&this.x+20<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
						{
							return true;
						}
					}
				}
			}
			break;
		case 1:
			//坦克向下,取出所有的敌人坦克
			for(int i=0;i<en.size();i++)
			{
				//取出每一辆坦克
				Enemy e = en.get(i);
				//如果不是自己的坦克
				if(e!=this)
				{
					//如果敌人的坦克向上或者向下
					if(e.direct==0||e.direct==1)
					{
						if(this.x>=e.x&&this.x<=e.x+20&&this.y+30>=e.y&&this.y+30<=e.y+30)
						{
							return true;
						}
						if(this.x+20>=e.x&&this.x+20<=e.x+20&&this.y+30>=e.y&&this.y+30<=e.y+30)
						{
							return true;
						}
					}
					//如果敌人的坦克向左或者向右
					if(e.direct==2||e.direct==3)
					{
						if(this.x>=e.x&&this.x<=e.x+30&&this.y+30>=e.y&&this.y+30<=e.y+20)
						{
							return true;
						}
						if(this.x+20>=e.x&&this.x+20<=e.x+30&&this.y+30>=e.y&&this.y+30<=e.y+20)
						{
							return true;
						}
					}
				}
			}
			break;
		case 2:
			//坦克向左,取出所有的敌人坦克
			for(int i=0;i<en.size();i++)
			{
				//取出每一辆坦克
				Enemy e = en.get(i);
				//如果不是自己的坦克
				if(e!=this)
				{
					//如果敌人的坦克向上或者向下
					if(e.direct==0||e.direct==1)
					{
						if(this.x>=e.x&&this.x<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
						{
							return true;
						}
						if(this.x>=e.x&&this.x<=e.x+20&&this.y+20>=e.y&&this.y+20<=e.y+30)
						{
							return true;
						}
					}
					//如果敌人的坦克向左或者向右
					if(e.direct==2||e.direct==3)
					{
						if(this.x>=e.x&&this.x<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
						{
							return true;
						}
						if(this.x>=e.x&&this.x<=e.x+30&&this.y+20>=e.y&&this.y+20<=e.y+20)
						{
							return true;
						}
					}
				}
			}
			break;
		case 3:
			//坦克向上,取出所有的敌人坦克
			for(int i=0;i<en.size();i++)
			{
				//取出每一辆坦克
				Enemy e = en.get(i);
				//如果不是自己的坦克
				if(e!=this)
				{
					//如果敌人的坦克向上或者向下
					if(e.direct==0||e.direct==1)
					{
						if(this.x+30>=e.x&&this.x+30<=e.x+20&&this.y>=e.y&&this.y<=e.y+30)
						{
							return true;
						}
						if(this.x+30>=e.x&&this.x+30<=e.x+20&&this.y+20>=e.y&&this.y+20<=e.y+30)
						{
							return true;
						}
					}
					//如果敌人的坦克向左或者向右
					if(e.direct==2||e.direct==3)
					{
						if(this.x+30>=e.x&&this.x+30<=e.x+30&&this.y>=e.y&&this.y<=e.y+20)
						{
							return true;
						}
						if(this.x+30>=e.x&&this.x+30<=e.x+30&&this.y+20>=e.y&&this.y+20<=e.y+20)
						{
							return true;
						}
					}
				}
			}
			break;
		}
		return b;
	}

	public void run() {
		// TODO Auto-generated method stub
		while(true)
		{
			//坦克休息80毫秒
			try {
				Thread.sleep(80);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			switch(this.direct)
			{
			//坦克向上
			case 0:
				for(int i=10;i>0;i--){
					try {
						Thread.sleep(40);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
					        e.printStackTrace();
						}
						if(y>0&&!this.isTouchOtherEnemy()){
							y-=speed;
						}
				}
				
				break;
			//下
			case 1:
				for(int i=10;i>0;i--){
					try {
						Thread.sleep(80);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if(y<228&&!this.isTouchOtherEnemy()){
					    y+=speed;
					}
				}
				
				break;
		    //左
			case 2:
				for(int i=10;i>0;i--){
					try {
						Thread.sleep(80);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if(x>0&&!this.isTouchOtherEnemy()){
						x-=speed;
					}
					
				}
				break;
			//右
			case 3:
				for(int i=10;i>0;i--){
					try {
						Thread.sleep(80);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					if(x<333&&!this.isTouchOtherEnemy()){
						x+=speed;
					}
					
				}
				
				break;
				
			}
			//为敌人的坦克添加子弹连发
			if(isLive)
			{
				if(bb.size()<3)
				{
					Bullet b = null;
					//没有子弹 ,则添加子弹
					switch(this.direct)
					{
					//子弹向上
					case 0:
						//创建一颗子弹
						b = new Bullet(x+8, y-8,0);
						//把子弹加入到向量中
						bb.add(b);
						break;
					 //子弹向下 
					case 1:
						//创建一颗子弹
						b = new Bullet(x+8, y+35,1);
						//把子弹加入到向量中
						bb.add(b);
						break;
					//子弹向左
					case 2:
						b = new Bullet(x-8,y+9,2);
						bb.add(b);
						break;
					//子弹向右
					case 3:
						b = new Bullet(x+35, y+9,3);
						bb.add(b);
						break;
					}
					//启动子弹线程
					Thread t = new Thread(b);
					t.start();
				}
			}
			//让坦克随机产生一个数,来确定坦克的方向

		    this.direct =(int)(Math.random()*4);

			//判断坦克是否死亡
			if(this.isLive == false){
				break;
			}
			
		}
		
	}
}

运行截图:

2011062119144666.jpg

2011062119150660.jpg


转载于:https://www.cnblogs.com/wangdaobin/archive/2011/06/21/2086323.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值