我目前正在尝试编写网络Tic Tac Toe游戏。网络组件正常运行。我启动服务器,然后启动2个客户端应用程序,两个客户端应用程序都连接到服务器。服务器正在接收客户端通过字符串传递的动作并传递逻辑。我不知道如何在客户端建立转弯。
此类是我希望在其中实现转弯的主要应用程序类
public class TicTacToeApplication extends Application {
private NetworkConnection client = createClient();
private ImageView icon;
private ImageView opponentIcon;
private Image cross = new Image("/Cross.png");
private Image circle = new Image("/Circle.png");
private GridPane grid;
private ArrayList<Button> buttons = new ArrayList<>();
private Text message;
@Override
public void init() throws Exception {
}
public static void main(String[] args) {
launch(args);
}
private void disableButtons(){
for(int i = 0; i < 9; i ++){
buttons.get(i).setDisable(true);
}
}
private void enableButtons(){
for(int i = 0; i < 9; i ++){
buttons.get(i).setDisable(false);
}
}
private Parent createContent(){
grid = new GridPane();
int square = 0;
for(int i = 0; i < 3; i++) {
for (int a = 0; a < 3; a++) {
Button button = new Button();
button.setMinSize(100,100);
button.setId(Integer.toString(square));
button.setOnAction(event->{
try{
client.send("MOVE" + button.getId());
System.out.println("MOVE" + button.getId());
if(client.isValidMove()){
System.out.println("wtf");
setImage(button, icon);
}
}catch(Exception e){
e.printStackTrace();
}
});
grid.add(button, i, a);
buttons.add(button);
System.out.println("Creating button " + square++);
}
}
HBox hbox = new HBox();
Button play = new Button("PLAY");
play.setAlignment(Pos.CENTER_RIGHT);
message = new Text("Press play to play");
message.setX(300);
message.setY(30);
hbox.setAlignment(Pos.TOP_CENTER);
hbox.getChildren().addAll(message,play);
play.setOnAction(event->{
try {
client.startConnection();
}catch(Exception e){
e.printStackTrace();
}
play.setDisable(true);
});
VBox root = new VBox();
root.getChildren().addAll(hbox,grid);
return root;
}
private NetworkConnection createClient(){
return new NetworkConnection("127.0.0.1",55555, data ->{
Platform.runLater(()-> {
if(client.getIcon()=='X'){
message.setText("You are X: YOUR MOVE");
icon = new ImageView(cross);
opponentIcon = new ImageView(circle);
//wait for opponents move/ set opponets move
}
else{
icon = new ImageView(circle);
opponentIcon = new ImageView(cross);
message.setText("You are O: Opponent's move");
}
message.setText(data.toString());
});
});
}
private void setImage(Button button, ImageView icon){
System.out.println("setting image");
button.setGraphic(icon);
button.setDisable(true);
}
@Override
public void start(Stage primaryStage) throws Exception{
primaryStage.setScene(new Scene(createContent()));
primaryStage.show();
}
我的NetworkConnection类负责从服务器读取信息,我开始创建getter和setter方法,以便TicTacToeApplication类可以访问某些信息。
public class NetworkConnection {
private ConnectionThread connThread = new ConnectionThread();
private Consumer<Serializable> onReceiveCallback;
private char mark;
private String ip;
private int port;
private boolean validMove = false;
private boolean won = false;
private boolean tie = false;
private boolean move;
private String message;
private int pos;
private int opponentMove;
public NetworkConnection(String ip, int port, Consumer<Serializable> onReceiveCallback){
this.onReceiveCallback = onReceiveCallback;
connThread.setDaemon(true);
this.ip = ip;
this.port = port;
}
public void startConnection() throws Exception {
connThread.start();
}
public void send(Serializable data) throws Exception{
connThread.out.writeObject(data);
}
public void closeConnection() throws Exception{
connThread.socket.close();
}
public char getIcon(){
return mark;
}
public void setIcon(char mark){
this.mark = mark;
}
public boolean isValidMove(){
return validMove;
}
public void setMove(boolean move){
this.move = true;
}
public boolean getMove(){
return true;
}
public void setVictory(boolean won){
this.won = won;
}
public boolean victory(){
return won;
}
public void setTie(boolean tie){
this.tie = tie;
}
public boolean getTie(){
return tie;
}
public void setMessage(String message){
this.message = message;
}
public String getMessage(){
return message;
}
public void setOpponentMove(int opponentMove){
this.opponentMove = opponentMove;
}
public int getOpponentMove(){
return this.opponentMove;
}
public void setPos(int pos){
this.pos = pos;
}
public int getPos(){
return pos;
}
private String getIP() {
return ip;
}
private int getPort() {
return port;
}
private class ConnectionThread extends Thread {
private Socket socket;
private ObjectOutputStream out;
@Override
public void run() {
try{
Socket socket = new Socket(getIP(), getPort());
ObjectOutputStream out = new ObjectOutputStream(socket.getOutputStream());
ObjectInputStream in = new ObjectInputStream(socket.getInputStream());
this.socket = socket;
this.out = out;
socket.setTcpNoDelay(true);
while (true) {
Serializable data = (Serializable) in.readObject();
onReceiveCallback.accept(data);
String response;
try {
response = data.toString();
if (response.startsWith("WELCOME")) {
mark = response.charAt(7);
setIcon(mark);
}
if (response.startsWith("VALID_MOVE")) {
setMessage("Valid move, please wait");
pos = Character.getNumericValue(response.charAt(10));
setMove(true);
setPos(pos);
} else if (response.startsWith("OPPONENT_MOVED")) {
int loc = Integer.parseInt(response.substring(14));
setOpponentMove(loc);
setMessage("Opponent moved, your turn");
} else if (response.startsWith("VICTORY")) {
setVictory(true);
} else if (response.startsWith("DEFEAT")) {
setVictory(false);
} else if (response.startsWith("TIE")) {
setTie(true);
} else if (response.startsWith("MESSAGE")) {
setMessage(response.substring(7));
}
}catch(Exception e){
e.printStackTrace();
}
move = false;
pos = -1;
}
}
catch (Exception e) {
onReceiveCallback.accept("Connection closed");
}
}
}
}