2016-08-11 88 views
1

我製作了一個小型多人遊戲來學習多人遊戲服務器/客戶端的各個方面。當一個玩家連接時,一切都會按預期工作。然而,當第二個客戶連接時,這兩個玩家將開始閃爍。當玩家相互移動時,閃爍將停止。我已經將原始代碼壓縮成一個小例子,它仍然會重現問題。任何解釋或想法爲什麼發生這將不勝感激!處理玩家在多人遊戲中閃爍

這裏是服務器代碼:

import processing.net.*; 

Server server; 
Client client; 
int Clients; 
String Coord; 

void setup() { 
size(600, 400); 
server = new Server(this, 12345); 
} 

void getCoord() { 
    Coord = ""; 

    for (int i = 0; i < Clients ; i++) { 
     String incoming = client.readStringUntil('\n'); 
     if (incoming != null) { 
      Coord += incoming.trim() + ","; 
     } 
    } 
} 

void sendCoord() { 
    println(Coord); 
     server.write(Coord + "\n"); 
} 
void draw() { 
    client = server.available(); 
    if (client != null) { 
    getCoord(); 
    sendCoord(); 
    } 
} 

void serverEvent(Server server, Client client) { 
    String incomingMessage = "A new client has connected:" + client.ip(); 
    println(incomingMessage); 
    Clients += 1; 
} 
void disconnectEvent(Client client) { 
    Clients -= 1; 
} 

這裏是客戶端代碼:

import processing.net.*; 
Client client; 

String Coord[] = new String[100]; 

void setup() { 
size(600, 400, P3D); 
client = new Client(this, "ENTER IP HERE FOR TESTING", 12345); 
} 

class Ball { 
Float X = width/2.0; 
Float Y = height/2.0; 

void processCoord() { 
    X = parseFloat(mouseX); 
    Y = parseFloat(mouseY); 
} 

void displayBall() { 
    fill(0, 0, 0); 

    if (Coord.length > 1) { 
    if (Coord[0] != null && Coord[1] != null) { 
     ellipse(parseFloat(Coord[0]), parseFloat(Coord[1]), 30, 30); 
    } 
    } 

    if (Coord.length > 2) { 
    if (Coord[2] != null && Coord[3] != null) { 
     ellipse(parseFloat(Coord[2]), parseFloat(Coord[3]), 30, 30); 
    } 
    } 
} 
} 

class Game { 
    void mainGame() { 
    background(255, 255, 255); 
    imageMode(CENTER); 
    ball.processCoord(); 
    ball.displayBall(); 
    } 
} 

Game game = new Game(); 
Ball ball = new Ball(); 

void draw() { 
    game.mainGame(); 
    String XString = ball.X.toString() + ','; 
    String YString = ball.Y.toString() + '\n'; 
    client.write(XString); 
    client.write(YString); 

} 
void clientEvent(Client client) { 
    String inComing = client.readStringUntil('\n'); 
    if (inComing != null) { 
    inComing = inComing.substring(0, inComing.length()-1); 
    Coord = inComing.split(","); 
    println(Coord); 
    } 
} 

回答

1

當我跑到你的代碼有兩個客戶機和服務器,增加幾個打印完畢後,我意識到與每個循環中的服務器不寫:

X1,Y1,X2,Y2

這是你想要的,我認爲(x1,y1,x2,y2是兩個客戶端的x,y座標)。

而是在兩個循環就這樣寫道:

X1,Y1,X1,Y1

X2,Y2,X2,Y2

這就是說,無論客戶的座標分別發送但通過每個循環在相同的字符串中重複。因此,客戶所做的是不斷改變每個圈子的位置。一個循環 - 它們都在x1,y1。下一個循環,它們都在x2,y2。這就是爲什麼當他們在同一個地方時沒有閃爍,因爲那麼x1 = x2,y1 = y2。

你需要做的是找到一種方式,服務器在寫任何東西之前肯定會等待,直到由每個循環組成的Coord字符串由x1,y1,x2,y2,x3,y3等組成,而不是單獨的重複字符串值。

讓我知道發生了什麼,如果你不能修復它,我可以嘗試幫助你重構你的算法。

+0

你好Yigit Bireroglu,謝謝你的回覆! draw()循環是爲每個客戶端調用一次,還是爲所有客戶端調用一次。我的目標是添加一個簡單的if/else循環,其計數器在客戶端發送座標時遞增,並在接收到客戶端的所有座標後發送座標列表。它發送後,計數器將被設置爲0.但是,我不相信這將工作,如果draw()循環被調用一次爲每個客戶端。 – zerotwo77

+1

@ zerotwo77沒問題!我不認爲你應該擔心draw()以及它如何循環,因爲clientEvent()每次調用時都會干擾draw()的進程(有點像Listener)。因此,您將執行的檢查應該通過clientEvent()。你的方法聽起來合乎邏輯,然而,如果一個客戶端發送數據的速度是另一個客戶端的兩倍,那麼它仍然會導致問題,因爲在這種情況下,計數器將通過相同的特定客戶端增加兩次。我會建議的是,你應該真的檢查你是否有來自所有客戶的座標。 –

+1

@zerotwo77爲此,您可以編輯您的代碼,使其具有屬於每個客戶端的標識符,這些標識符在座標之前發送: String toSend = ClientName + x + y 您當然可以使用getIP()函數來辨別客戶端但是,由於您將從同一臺計算機運行兩個客戶端,因此它們可能具有相同的IP。 你可以做的其他事情是從服務器發送到客戶端,就像你已經做的一樣,但是讓客戶端選擇哪個座標屬於誰。另外,我認爲您不應該將數據從客戶端連續發送到服務器。只需在鼠標移動時進行。 –