📄 tankclient.java
字号:
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 + -