⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tankclient.java

📁 基于尚学堂坦克大战的基础上开发,支持多人对战,在线聊天,坦克大战网络版.
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
import java.awt.Button;
import java.awt.Color;
import java.awt.Dialog;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Label;
import java.awt.ScrollPane;
import java.awt.TextArea;
import java.awt.TextField;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.LinkedList;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JScrollPane;

/**
 * 坦克的客户端程序
 * 
 * @author Nightelf暗夜精灵
 * 
 */
public class TankClient extends Frame {

	public static final int DEFAULT_WIDTH = 800;

	public static final int DEFAULT_HEIGHT = 600;

	Image offScreenImage = null;

	LinkedList<Missile> ms = new LinkedList<Missile>();

	Tank tank = new Tank((int) (Math.random() * 800) + 24,
			(int) (Math.random() * 600) + 24, 0, true, false, Direction.STOP,
			this);

	ArrayList<Explode> explodes = new ArrayList<Explode>();

	ArrayList<Tank> badTanks = new ArrayList<Tank>();

	ArrayList<Tank> playerTanks = new ArrayList<Tank>();

	ArrayList<Tank> deadTanks = new ArrayList<Tank>();

	private int readyer = 0; // 计算加入游戏界面有几个玩家准备就绪

	ArrayList<Wall> walls = new ArrayList<Wall>();

	ArrayList<Item> items = new ArrayList<Item>();

	ArrayList<Client> clients = new ArrayList<Client>();

	NetClient client = new NetClient(this);

	Login login = new Login();

	Join join = new Join();

	Image jointank;

	Image[] startButton;

	boolean gameStarted = false; // 判断游戏是否开始

	boolean create = false; // 判断是否已经生成过墙壁了

	private int win = 0; // 0代表无状态,1代表胜利,2代表失败

	boolean init = false;

	boolean gameOver = false;

	private int hostId; // 指定谁是主机

	private Toolkit tk = Toolkit.getDefaultToolkit();

	Image gameOverImg = tk.getImage(TankClient.class.getClassLoader()
			.getResource("images/gameOver.png"));

	Image gameWinImg = tk.getImage(TankClient.class.getClassLoader()
			.getResource("images/Win.png"));

	{
		jointank = tk.getImage(TankClient.class.getClassLoader().getResource(
				"images/jointank.gif"));
		startButton = new Image[] {
				tk.getImage(TankClient.class.getClassLoader().getResource(
						"images/start_rollout.gif")),
				tk.getImage(TankClient.class.getClassLoader().getResource(
						"images/start_pressed.gif")) };
	}

	private int badTankId = 10000;

	private boolean started = false;

	private boolean connect = false;

	int wallCount;

	private String say;

	// 绘制出场景中的坦克,子弹,障碍物
	public void paint(Graphics g) {

		// 预加载图片,防止图片在第一次显示时,未载入完成
		if (!init) {
			Image gameOverImg = tk.getImage(TankClient.class.getClassLoader()
					.getResource("images/gameOver.png"));
			Image gameWinImg = tk.getImage(TankClient.class.getClassLoader()
					.getResource("images/gameWin.png"));
			init = true;
		}

		// 生成子弹
		for (int i = 0; i < ms.size(); i++) {
			Missile m = (Missile) ms.get(i);
			m.hitWalls(walls);
			m.hitTank(tank);
			m.hitTanks(badTanks);
			// m.hitPlayerTanks(playerTanks);
			m.drawMissile(g);
			// if(!m.isLive()) ms.remove(m)
			// else m.drawMissile(g);
		}

		// 生成障碍物
		for (int i = 0; i < walls.size(); i++) {
			Wall wall = walls.get(i);
			wall.draw(g);
		}

		// 没有连接时,生成敌方坦克,玩单机版
		int badTankscount=0;
		if (!connect) {
			for (int i = 0; i < badTanks.size(); i++) {
				Tank badtank = badTanks.get(i);
				if (badtank.isLive()) {
					badtank.drawTank(g);
					badTankscount++;
				}else
				badtank.hitWalls(walls);
				badtank.hitTanks(badTanks);
			}
		}

		// 显示玩家坦克
		int playerTankscount=1;
		if (playerTanks.size() > 0) {
			for (int i = 0; i < playerTanks.size(); i++) {
				Tank playertank = playerTanks.get(i);
				if (playertank.isLive()) {
					playertank.drawTank(g);
					playerTankscount++;
				}
				playertank.hitWalls(walls);
				playertank.hitTanks(playerTanks);
			}
		}

		// 显示道具
		for (int i = 0; i < items.size(); i++) {
			Item item = items.get(i);
			item.drawItem(g);
		}

		// 显示爆炸
		for (int i = 0; i < explodes.size(); i++) {
			Explode e = explodes.get(i);
			e.draw(g);
		}

		// 当坦克还活着时,画出坦克
		if (tank.isLive()) {
			tank.drawTank(g);
		}
		tank.hitTanks(badTanks);
		tank.hitTanks(playerTanks);
		tank.hitWalls(walls);
		tank.hitItem(items);
		g.setColor(Color.WHITE);
		g.drawString("子弹数量:" + ms.size(), 50, 60);
		g.drawString("爆炸次数:" + explodes.size(), 50, 80);
	    g.drawString("敌方坦克数量:" + badTankscount, 50, 100);
	    g.drawString("玩家坦克数量:" + playerTankscount, 50, 120);
		g.drawString("操作: 上下左右键,Ctrl发子弹,shift发超级子弹,F2复活", 50, 140);

		// 显示游戏的胜利或失败
		if (win == 1) {
			System.out.println("Win!!!!");
			g.drawImage(gameWinImg, TankClient.DEFAULT_WIDTH / 4 - 40,
					TankClient.DEFAULT_HEIGHT / 3 + 50, null);
		} else if (win == 2) {
			System.out.println("lose!!!!");
			g.drawImage(gameOverImg, TankClient.DEFAULT_WIDTH / 4 + 50,
					TankClient.DEFAULT_HEIGHT / 3 + 50, null);
		}
	}

	public void update(Graphics g) {
		// 当图像为空时,创建图片对象
		if (offScreenImage == null) {
			offScreenImage = this.createImage(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		}
		Graphics gImage = offScreenImage.getGraphics(); // 得到图片的画笔
		Color c = gImage.getColor();
		gImage.setColor(Color.BLACK); // 设置画笔颜色
		gImage.fillRect(0, 0, DEFAULT_WIDTH, DEFAULT_WIDTH); // 用一个矩形覆盖窗口
		Toolkit tk = Toolkit.getDefaultToolkit();
		Image map = tk.getImage(Tank.class.getClassLoader().getResource(
				"images/map.jpg"));
		gImage.drawImage(map, 0, 30, null);
		paint(gImage); // 画出图片
		g.drawImage(offScreenImage, 0, 0, null); // 一次性画出图像
	}

	/**
	 * 开始时游戏的主界面
	 * 
	 */
	public void lauchFrame() {

		login.setVisible(true);

		this.setTitle("坦克大战");

		setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT);
		setResizable(false);
		setLocation(270, 240);

		// 添加窗口关闭事件
		this.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				TankClient.this.exitGame();
				dispose();
				System.exit(0);
			}

		});

		this.addMouseListener(new MouseAdapter() {

			public void mouseClicked(MouseEvent e) {
				// 坦克活着的时候才进行键盘响应,死了就不管他了
				if (tank.isLive()) {
					tank.mouseEvent(e);
				}
			}
		});
		setBackground(Color.BLACK);
		this.addKeyListener(new TankMonitor());
		new TankThread();

		join.setVisible(true);
		// playerTanks.add(new Tank(50,50,false,Tank.Direction.STOP,this));
	}

	// 创建敌方坦克的方法
	public void createBadTanks() {

		if (badTanks.size() <= 0 && started) { // 当坦克小于指定值时,再生成一批坦克 if
			{
				int repaintTankCount = Integer.parseInt(TankMgr
						.getProperty("repaintTankCount"));
				for (int i = 0; i < repaintTankCount; i++) {
					int ranx = (int) (Math.random() * 1000) % 800;
					int rany = (int) (Math.random() * 1000) % 800;
					Tank tank = new Tank(ranx, rany, badTankId++, false, true,
							Direction.D, this);
					while (tank.hitWalls(walls)) {
						ranx += 50;
						rany += 50;
						tank = new Tank(ranx, rany, badTankId++, false, true,
								Direction.D, this);
					}
				}
			}
		}

	}

	// 当没有连接服务器的情况下,打单机版的
	public void createSingleTankandWall() {

		// 创建墙
		walls.removeAll(walls);
		wallCount = (int) (Math.random() * 100) + 10;
		for (int i = 0; i < wallCount; i++) {
			int x = (int) (Math.random() * 780 + 20);
			int y = (int) (Math.random() * 560 + 40);
			int style = (int) (Math.random() * 10) % 3;

			// 使程序随机到3的机率小一点,类型3的障碍物是,油桶
			if (style == 3) {
				if ((int) (Math.random() * 10) != 0) {
					style = (int) (Math.random() * 10) % 3;
				}
			}
			Wall wall = new Wall(x, y, style, this);
			if (!wall.isHitTanks()) {
				walls.add(wall);
			}
		}
		
		//让主坦克尽量避免生成在墙上
		
		while(TankClient.this.tank.hitWalls(walls)){
			System.out.println("重定向坦克!!"+tank.x+tank.y);
			if(tank.x>DEFAULT_WIDTH-24){
			tank.x-=50;
			}else{
			tank.x+=50;
			}
		}

		int initTankCount = Integer.parseInt(TankMgr
				.getProperty("initTankCount"));
		// 当客户端是第一个创建的,则让客户端生成电脑控制的坦克
		badTanks.removeAll(badTanks);
		for (int i = 0; i < initTankCount; i++) {
			// 生成的时候避免生成墙上
			int ranx = (int) (Math.random() * 800);
			int rany = (int) (Math.random() * 600);
			Tank tank = new Tank(ranx, rany, badTankId++, false, true,
					Direction.D, this);
			while (tank.hitWalls(walls)) {
				ranx += 50;
				rany += 50;
				tank = new Tank(ranx, rany, badTankId++, false, true,
						Direction.D, this);
			}
			// 随机从tank中升级成飞机
			int Airplane = (int) (Math.random() * 10) % 2;
			if (Airplane == 0) {
				tank.isAirplane = true;
			}
			badTanks.add(tank);
			System.out.println("造出第" + i + "辆坦克");

		}
	}

	/**
	 * TankClient的内部线程类,用于不断的repaint()面板
	 */
	private class TankThread implements Runnable {

		public TankThread() {
			new Thread(this).start();
		}

		public void run() {
			while (true) {
				repaint();
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

	/**
	 * 登陆窗体
	 * 
	 * @author Nightelf暗夜精灵
	 * 
	 */
	class Login extends Dialog {

		ImageIcon icon; // 背景图片

		TextField username, IP, Port, udpPort;

		private ScrollPane scrollPane = new ScrollPane();

		Button button;

		boolean init = true; // 预加载的控制变量

		public Login() {
			super(TankClient.this, true);
			Toolkit tk = Toolkit.getDefaultToolkit();
			icon = new ImageIcon(tk.getImage(Login.class.getClassLoader()
					.getResource("images/TankUI.jpg")));
			setLayout(null);
			username = new TextField("坦克新兵", 40);
			username.setLocation(50, 40);
			username.setLocation(120, 529);
			username.setSize(100, 24);
			IP = new TextField("127.0.0.1", 40);
			IP.setLocation(260, 529);
			IP.setSize(100, 24);
			Port = new TextField("8888", 15);
			Port.setLocation(440, 529);
			Port.setSize(70, 24);
			String udpport = String
					.valueOf((int) (Math.random() * 10000) + 1024);
			udpPort = new TextField(udpport, 15);
			udpPort.setLocation(600, 529);
			udpPort.setSize(70, 24);
			button = new Button("登陆");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -