JAVA课程设计之坦克大战

环境要求:

  • 操作系统:Windows 10
  • JAVA虚拟机:JDK1.8以上
  • 开发环境:Eclipse(4.5以上)

【功能提示】

  1. 游戏要有图形用户界面,界面能够反映游戏所有的细节。
  2. 界面中要有坦克,墙,树林,河流。
  3. 界面中要有一个“家”,“家”被攻击中则输了游戏。
  4. 坦克分两种,敌方和我方。
  5. 墙也分为两种,可以穿透的普通墙,不可以穿透的铁墙。
  6. 树和河流均只有一种,树林坦克可以通过。
  7. 坦克可以发射子弹,敌我方的子弹属性一样。
  8. 我方子弹可以杀死敌方坦克,敌方子弹也可以杀死我方坦克,但需要多枪子弹才可以杀死。
  9. 敌方之间不可以杀死对方。
  10. 子弹击中坦克要有爆炸,但击中墙不能爆炸。
  11. 我方可以吃血包增加生命。
  12. 游戏可以暂停,重新开始,游戏帮助等功能。
  13. 游戏级别分别为:级别1、级别2、级别3、级别4。

需求分析

  • 设计一个图形用户界面,将所有游戏的元素都能在此用于界面上表现出来,界面能够接受用户的操作,具有人机交互功能。用户可以选择重新开始游戏,退出游戏,暂停游戏和查找游戏帮助。
  • 界面中包含坦克,树,河流,阻挡墙和游戏用户所要保护的“家”。
  • 坦克:坦克分为两种,敌方坦克和用户控制的坦克。用户方和敌方坦克均可以发射子弹,可以改变路径的行走,且在行走过程中遇到墙等阻碍物和游戏边界时要改变方向,而不能一直顶着障碍物不放。坦克之间不能穿越,碰撞到后自动调换方向。
  • 树:界面中要包括树林,作为遮掩物体和修饰物体,以便增加游戏的元素,使得游戏更加贴切人性化。树的数目不限,以游戏整体界面清晰美观来决定数目。
  • 河流:界面中要包括河流,河流作用与树林相同,同样河流的数目不限,以游戏界面整体美观度来决定数目。
  • 墙:墙体分为两种,普通的墙和铁墙,普通的墙在受到子弹袭击时会损坏,而铁墙可以阻碍子弹的穿越。两方的坦克均不能穿越两种墙体,但都可以摧毁普通墙体。普通墙体的数目配合其他元素合理安排,铁墙则不宜过多,不然游戏难度太低甚至因为坦克不能穿越铁墙而使得游戏无法进行下去。
  • “家”:用户方除了有一辆自己的坦克外还有一个要保护的家,家由普通墙体包围,家受到子弹攻击后游戏立即结束,用户方则输了本局游戏。
  • 子弹:子弹可以由敌方和用户方发射,且发射出去的子弹可以直线移动,直到碰到障碍物就消失,子弹可以穿越树林和河流。敌方坦克受到一颗子弹攻击会爆炸从而导致死亡,死亡后坦克消失。用户方受到子弹攻击后会减少寿命,且受到四次攻击则死亡,此时如还有敌方坦克存在,则用户方输掉本次游戏。
  • 爆炸:当子弹射击到坦克身上时,要产生爆炸效果。
  • 方向:坦克和子弹都有方向,可以选择上下左右四个方向,且子弹的方向从属于坦克的方向。
     

效果如图所示:

主界面代码如下:

public TankClient() {
		// printable = false;
		// 创建菜单及菜单选项
		jmb = new MenuBar();
		jm1 = new Menu("游戏");
		jm2 = new Menu("暂停/继续");
		jm3 = new Menu("帮助");
		jm4 = new Menu("游戏级别");
		jm1.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
		jm2.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
		jm3.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体
		jm4.setFont(new Font("TimesRoman", Font.BOLD, 15));// 设置菜单显示的字体

		jmi1 = new MenuItem("开始新游戏");
		jmi2 = new MenuItem("退出");
		jmi3 = new MenuItem("暂停");
		jmi4 = new MenuItem("继续");
		jmi5 = new MenuItem("游戏说明");
		jmi6 = new MenuItem("级别1");
		jmi7 = new MenuItem("级别2");
		jmi8 = new MenuItem("级别3");
		jmi9 = new MenuItem("级别4");
		jmi1.setFont(new Font("TimesRoman", Font.BOLD, 15));
		jmi2.setFont(new Font("TimesRoman", Font.BOLD, 15));
		jmi3.setFont(new Font("TimesRoman", Font.BOLD, 15));
		jmi4.setFont(new Font("TimesRoman", Font.BOLD, 15));
		jmi5.setFont(new Font("TimesRoman", Font.BOLD, 15));

		jm1.add(jmi1);
		jm1.add(jmi2);
		jm2.add(jmi3);
		jm2.add(jmi4);
		jm3.add(jmi5);
		jm4.add(jmi6);
		jm4.add(jmi7);
		jm4.add(jmi8);
		jm4.add(jmi9);

		jmb.add(jm1);
		jmb.add(jm2);

		jmb.add(jm4);
		jmb.add(jm3);

		jmi1.addActionListener(this);
		jmi1.setActionCommand("NewGame");
		jmi2.addActionListener(this);
		jmi2.setActionCommand("Exit");
		jmi3.addActionListener(this);
		jmi3.setActionCommand("Stop");
		jmi4.addActionListener(this);
		jmi4.setActionCommand("Continue");
		jmi5.addActionListener(this);
		jmi5.setActionCommand("help");
		jmi6.addActionListener(this);
		jmi6.setActionCommand("level1");
		jmi7.addActionListener(this);
		jmi7.setActionCommand("level2");
		jmi8.addActionListener(this);
		jmi8.setActionCommand("level3");
		jmi9.addActionListener(this);
		jmi9.setActionCommand("level4");

		this.setMenuBar(jmb);// 菜单Bar放到JFrame上
		this.setVisible(true);

		for (int i = 0; i < 10; i++) { // 家的格局
			if (i < 4)
				homeWall.add(new CommonWall(350, 580 - 21 * i, this));
			else if (i < 7)
				homeWall.add(new CommonWall(372 + 22 * (i - 4), 517, this));
			else
				homeWall.add(new CommonWall(416, 538 + (i - 7) * 21, this));

		}

		for (int i = 0; i < 32; i++) {
			if (i < 16) {
				otherWall.add(new CommonWall(220 + 20 * i, 300, this)); // 普通墙布局
				otherWall.add(new CommonWall(500 + 20 * i, 180, this));
				otherWall.add(new CommonWall(200, 400 + 20 * i, this));
				otherWall.add(new CommonWall(500, 400 + 20 * i, this));
			} else if (i < 32) {
				otherWall.add(new CommonWall(220 + 20 * (i - 16), 320, this));
				otherWall.add(new CommonWall(500 + 20 * (i - 16), 220, this));
				otherWall.add(new CommonWall(220, 400 + 20 * (i - 16), this));
				otherWall.add(new CommonWall(520, 400 + 20 * (i - 16), this));
			}
		}

		for (int i = 0; i < 20; i++) { // 金属墙布局
			if (i < 10) {
				metalWall.add(new MetalWall(140 + 30 * i, 150, this));
				metalWall.add(new MetalWall(600, 400 + 20 * (i), this));
			} else if (i < 20)
				metalWall.add(new MetalWall(140 + 30 * (i - 10), 180, this));
			else
				metalWall.add(new MetalWall(500 + 30 * (i - 10), 160, this));
		}

		for (int i = 0; i < 4; i++) { // 树的布局
			if (i < 4) {
				trees.add(new Tree(0 + 30 * i, 360, this));
				trees.add(new Tree(220 + 30 * i, 360, this));
				trees.add(new Tree(440 + 30 * i, 360, this));
				trees.add(new Tree(660 + 30 * i, 360, this));
			}

		}

		theRiver.add(new River(85, 100, this));

		for (int i = 0; i < 20; i++) { // 初始化20辆坦克
			if (i < 9) // 设置坦克出现的位置
				tanks.add(new Tank(150 + 70 * i, 40, false, Direction.D, this));
			else if (i < 15)
				tanks.add(new Tank(700, 140 + 50 * (i - 6), false, Direction.D,
						this));
			else
				tanks
						.add(new Tank(10, 50 * (i - 12), false, Direction.D,
								this));
		}

		this.setSize(Fram_width, Fram_length); // 设置界面大小
		this.setLocation(280, 50); // 设置界面出现的位置
		this
				.setTitle("坦克大战——(重新开始:R键  开火:F键)");

		this.addWindowListener(new WindowAdapter() { // 窗口监听关闭
					public void windowClosing(WindowEvent e) {
						System.exit(0);
					}
				});
		this.setResizable(false);
		this.setBackground(Color.GREEN);
		this.setVisible(true);

		this.addKeyListener(new KeyMonitor());// 键盘监听
		new Thread(new PaintThread()).start(); // 线程启动
	}

	public static void main(String[] args) {
		new TankClient(); // 实例化
	}
wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==
发布了136 篇原创文章 · 获赞 198 · 访问量 15万+

猜你喜欢

转载自blog.csdn.net/qq_42680327/article/details/103650810
今日推荐