## How to start
– Please run the `TankServer` first, you may need to close the firewall before playing with friends on different computers, otherwise they can not connect to your `TankServer` (You needn’t to do this if you just want to Test on the local machince).
– Then run the `TankClient`, you need to fill the `server IP` to connect to the machine which running the `TankServer`. the default value `127.0.0.1` can be used if you just test the game on your own PC.
## Game Operation
– You control it with `W`(up), `S`(down), `A`(left), `D`(right) and `J`(fire).
– you can restart the `TankClient` to return to the game if your tank was defeated.
package client.client;
import client.bean.Dir;
import client.bean.Explode;
import client.bean.Missile;
import client.bean.Tank;
import client.protocol.MissileDeadMsg;
import client.protocol.TankDeadMsg;
import server.TankServer;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
public class TankClient extends Frame {
public static final int GAME_WIDTH = 800;
public static final int GAME_HEIGHT = 600;
private Image offScreenImage = null;
private Tank myTank;//客户端的坦克
private NetClient nc = new NetClient(this);
private ConDialog dialog = new ConDialog();
private GameOverDialog gameOverDialog = new GameOverDialog();
private UDPPortWrongDialog udpPortWrongDialog = new UDPPortWrongDialog();
private ServerNotStartDialog serverNotStartDialog = new ServerNotStartDialog();
private List<Missile> missiles = new ArrayList<>();//存储游戏中的子弹集合
private List<Explode> explodes = new ArrayList<>();//爆炸集合
private List<Tank> tanks = new ArrayList<>();//坦克集合
@Override
public void paint(Graphics g) {
g.drawString("missiles count:" missiles.size(), 10, 50);
g.drawString("explodes count:" explodes.size(), 10, 70);
g.drawString("tanks count:" tanks.size(), 10, 90);
for(int i = 0; i < missiles.size(); i ) {
Missile m = missiles.get(i);
if(m.hitTank(myTank)){
// TankDeadMsg msg = new TankDeadMsg(myTank.getId());
// nc.send(msg);
MissileDeadMsg mmsg = new MissileDeadMsg(m.getTankId(), m.getId());
nc.send(mmsg);
// nc.sendClientDisconnectMsg();
// gameOverDialog.setVisible(true);
}
m.draw(g);
}
for(int i = 0; i < explodes.size(); i ) {
Explode e = explodes.get(i);
e.draw(g);
}
for(int i = 0; i < tanks.size(); i ) {
Tank t = tanks.get(i);
t.draw(g);
}
if(null != myTank){
myTank.draw(g);
}
}
@Override
public void update(Graphics g) {
if(offScreenImage == null) {
offScreenImage = this.createImage(800, 600);
}
Graphics gOffScreen = offScreenImage.getGraphics();
Color c = gOffScreen.getColor();
gOffScreen.setColor(Color.LIGHT_GRAY);
gOffScreen.fillRect(0, 0, GAME_WIDTH, GAME_HEIGHT);
gOffScreen.setColor(c);
paint(gOffScreen);
g.drawImage(offScreenImage, 0, 0, null);
}
public void launchFrame() {
this.setLocation(400, 300);
this.setSize(GAME_WIDTH, GAME_HEIGHT);
this.setTitle("TankClient");
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
nc.sendClientDisconnectMsg();//关闭窗口前要向服务器发出注销消息.
System.exit(0);
}
});
this.setResizable(false);
this.setBackground(Color.LIGHT_GRAY);
this.addKeyListener(new KeyMonitor());
this.setVisible(true);
new Thread(new PaintThread()).start();
dialog.setVisible(true);
}
public static void main(String[] args) {
TankClient tc = new TankClient();
tc.launchFrame();
}
/**
* 重画线程
*/
class PaintThread implements Runnable {
public void run() {
while(true) {
repaint();
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class KeyMonitor extends KeyAdapter {
@Override
public void keyReleased(KeyEvent e) {
myTank.keyReleased(e);
}
@Override
public void keyPressed(KeyEvent e) {
myTank.keyPressed(e);
}
}
/**
* 游戏开始前连接到服务器的对话框
*/
class ConDialog extends Dialog{
Button b = new Button("connect to server");
TextField tfIP = new TextField("127.0.0.1", 15);//服务器的IP地址
TextField tfTankName = new TextField("myTank", 8);
public ConDialog() {
super(TankClient.this, true);
this.setLayout(new FlowLayout());
this.add(new Label("server IP:"));
this.add(tfIP);
this.add(new Label("tank name:"));
this.add(tfTankName);
this.add(b);
this.setLocation(500, 400);
this.pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
setVisible(false);
System.exit(0);
}
});
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String IP = tfIP.getText().trim();
String tankName = tfTankName.getText().trim();
myTank = new Tank(tankName, 50 (int)(Math.random() * (GAME_WIDTH - 100)),
50 (int)(Math.random() * (GAME_HEIGHT - 100)), true, Dir.STOP, TankClient.this);
nc.connect(IP);
setVisible(false);
}
});
}
}
/**
* 坦克死亡后退出的对话框
*/
class GameOverDialog extends Dialog{
Button b = new Button("exit");
public GameOverDialog() {
super(TankClient.this, true);
this.setLayout(new FlowLayout());
this.add(new Label("Game Over~"));
this.add(b);
this.setLocation(500, 400);
this.pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
}
/**
* UDP端口分配失败后的对话框
*/
class UDPPortWrongDialog extends Dialog{
Button b = new Button("ok");
public UDPPortWrongDialog() {
super(TankClient.this, true);
this.setLayout(new FlowLayout());
this.add(new Label("something wrong, please connect again"));
this.add(b);
this.setLocation(500, 400);
this.pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
}
/**
* 连接服务器失败后的对话框
*/
class ServerNotStartDialog extends Dialog{
Button b = new Button("ok");
public ServerNotStartDialog() {
super(TankClient.this, true);
this.setLayout(new FlowLayout());
this.add(new Label("The server has not been opened yet..."));
this.add(b);
this.setLocation(500, 400);
this.pack();
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
b.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
}
}
public void gameOver(){
this.gameOverDialog.setVisible(true);
}
public List<Missile> getMissiles() {
return missiles;
}
public void setMissiles(List<Missile> missiles) {
this.missiles = missiles;
}
public List<Explode> getExplodes() {
return explodes;
}
public void setExplodes(List<Explode> explodes) {
this.explodes = explodes;
}
public List<Tank> getTanks() {
return tanks;
}
public void setTanks(List<Tank> tanks) {
this.tanks = tanks;
}
public Tank getMyTank() {
return myTank;
}
public void setMyTank(Tank myTank) {
this.myTank = myTank;
}
public NetClient getNc() {
return nc;
}
public void setNc(NetClient nc) {
this.nc = nc;
}
public UDPPortWrongDialog getUdpPortWrongDialog() {
return udpPortWrongDialog;
}
public ServerNotStartDialog getServerNotStartDialog() {
return serverNotStartDialog;
}
}
资源文件列表
TankOnline-master/TankOnline-master/README.md , 1129
TankOnline-master/TankOnline-master/src/client/bean/Dir.java , 103
TankOnline-master/TankOnline-master/src/client/bean/Explode.java , 1995
TankOnline-master/TankOnline-master/src/client/bean/Missile.java , 4016
TankOnline-master/TankOnline-master/src/client/bean/Tank.java , 10958
TankOnline-master/TankOnline-master/src/client/client/NetClient.java , 6085
TankOnline-master/TankOnline-master/src/client/client/TankClient.java , 9179
TankOnline-master/TankOnline-master/src/client/event/TankHitEvent.java , 332
TankOnline-master/TankOnline-master/src/client/event/TankHitListener.java , 184
TankOnline-master/TankOnline-master/src/client/images/explode/explode1.png , 19330
TankOnline-master/TankOnline-master/src/client/images/explode/explode2.png , 18796
TankOnline-master/TankOnline-master/src/client/images/explode/explode3.png , 19627
TankOnline-master/TankOnline-master/src/client/images/explode/explode4.png , 19821
TankOnline-master/TankOnline-master/src/client/images/explode/explode5.png , 19816
TankOnline-master/TankOnline-master/src/client/images/explode/explode6.png , 19631
TankOnline-master/TankOnline-master/src/client/images/explode/explode7.png , 19351
TankOnline-master/TankOnline-master/src/client/images/missile/m.png , 18211
TankOnline-master/TankOnline-master/src/client/images/missile/n.png , 20021
TankOnline-master/TankOnline-master/src/client/images/tank/eD.png , 17369
TankOnline-master/TankOnline-master/src/client/images/tank/eL.png , 17371
TankOnline-master/TankOnline-master/src/client/images/tank/eLD.png , 17353
TankOnline-master/TankOnline-master/src/client/images/tank/eLU.png , 17351
TankOnline-master/TankOnline-master/src/client/images/tank/eR.png , 17326
TankOnline-master/TankOnline-master/src/client/images/tank/eRD.png , 17360
TankOnline-master/TankOnline-master/src/client/images/tank/eRU.png , 17158
TankOnline-master/TankOnline-master/src/client/images/tank/eU.png , 16941
TankOnline-master/TankOnline-master/src/client/images/tank/tD.png , 17327
TankOnline-master/TankOnline-master/src/client/images/tank/tL.png , 17330
TankOnline-master/TankOnline-master/src/client/images/tank/tLD.png , 17334
TankOnline-master/TankOnline-master/src/client/images/tank/tLU.png , 17327
TankOnline-master/TankOnline-master/src/client/images/tank/tR.png , 17235
TankOnline-master/TankOnline-master/src/client/images/tank/tRD.png , 17295
TankOnline-master/TankOnline-master/src/client/images/tank/tRU.png , 17138
TankOnline-master/TankOnline-master/src/client/images/tank/tU.png , 16855
TankOnline-master/TankOnline-master/src/client/protocol/MissileDeadMsg.java , 1983
TankOnline-master/TankOnline-master/src/client/protocol/MissileNewMsg.java , 2168
TankOnline-master/TankOnline-master/src/client/protocol/Msg.java , 609
TankOnline-master/TankOnline-master/src/client/protocol/TankAlreadyExistMsg.java , 2460
TankOnline-master/TankOnline-master/src/client/protocol/TankDeadMsg.java , 1791
TankOnline-master/TankOnline-master/src/client/protocol/TankMoveMsg.java , 2387
TankOnline-master/TankOnline-master/src/client/protocol/TankNewMsg.java , 2223
TankOnline-master/TankOnline-master/src/client/protocol/TankReduceBloodMsg.java , 2097
TankOnline-master/TankOnline-master/src/client/strategy/Fire.java , 150
TankOnline-master/TankOnline-master/src/client/strategy/FireAction.java , 123
TankOnline-master/TankOnline-master/src/client/strategy/NormalFireAction.java , 670
TankOnline-master/TankOnline-master/src/server/TankServer.java , 7323
TankOnline-master/TankOnline-master/TankClient.jar , 154688
TankOnline-master/TankOnline-master/TankServer.jar , 154686
