我正在尝试在 Greenfoot 中为学校项目制作一个简单的多人游戏。
如果我删除“updatePosition();”在播放器脚本中,服务器可以移动,客户端获取数据。但是,当我尝试从客户端获取数据并调用 updatePosition(); 时在播放器脚本中,当服务器尝试调用 receiveInt() 时,它会停止。终端显示“Works Server”,但在脚本后面的几行中不显示“1”或“2”。
“游戏管理器”:
import greenfoot.*;
import java.io.*;
import java.net.*;
import javax.swing.JOptionPane;
import java.util.ArrayList;
public class MyWorld extends World
{
public Server server;
public Client client;
public boolean Server = false;
/**
* Constructor for objects of class MyWorld.
*
*/
public MyWorld()
{
super(600, 400, 1);
Player player = new Player(this);
addObject(player, getWidth()/2, getHeight()/2);
}
public void act()
{
if(Greenfoot.isKeyDown("q"))
{
if(Server)
{
server.close();
}else
{
client.close();
}
}
}
public void init()
{
Object[] options = {"Server","Client"};
int i = JOptionPane.showOptionDialog(null, "Host as server or join as client?", "Selection", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, options, options[0]);
if(i == 0)
{
server = new Server(this);
Server = true;
Player2 player2 = new Player2();
addObject(player2, 0, 0);
}else if(i == 1)
{
client = new Client(this);
Player2 player2 = new Player2();
addObject(player2, 0, 0);
}
}
public class Server
{
MyWorld myWorld;
public ServerSocket serverSocket;
public Socket skt;
private ObjectInputStream inServer;
private ObjectOutputStream outServer;
public Server(MyWorld myWorl)
{
this.myWorld = myWorl;
try
{
serverSocket = new ServerSocket(8888);
skt = serverSocket.accept();
inServer = new ObjectInputStream(skt.getInputStream());
outServer = new ObjectOutputStream(skt.getOutputStream());
}catch(IOException e)
{
close();
}
}
public void sendInts(int ...arr) {
try {
outServer.writeObject(arr);
Greenfoot.delay(1);
outServer.flush();
}
catch(NullPointerException ex) {
}
catch(IOException ex) {
}
}
public int[] receiveInts() {
int[] datServer = null;
try {
datServer = (int[])inServer.readObject();
}
catch(ClassNotFoundException ex) {
ex.printStackTrace();
close();
}
catch(NullPointerException ex) {
close();
}
catch(IOException ex) {
close();
}
return datServer;
}
public void close()
{
try {
outServer.close();
inServer.close();
skt.close();
serverSocket.close();
}
catch(IOException ex) {
throw new RuntimeException("Error closing streams...");
}
}
}
public class Client
{
MyWorld myWorld;
private ObjectOutputStream outClient;
private ObjectInputStream inClient;
public Socket clientSocket;
public Client(MyWorld myWorl)
{
this.myWorld = myWorl;
try
{
clientSocket = new Socket("localhost",8888);
outClient = new ObjectOutputStream(clientSocket.getOutputStream());
inClient = new ObjectInputStream(clientSocket.getInputStream());
}catch(IOException e)
{
close();
}
}
public void sendInts(int ...arr) {
try {
outClient.writeObject(arr);
Greenfoot.delay(1);
outClient.flush();
}
catch(NullPointerException ex) {
}
catch(IOException ex) {
}
}
public int[] receiveInts() {
int[] datClient = null;
try {
datClient = (int[])inClient.readObject();
}
catch(ClassNotFoundException ex) {
ex.printStackTrace();
}
catch(NullPointerException ex) {
}
catch(IOException ex) {
close();
}
return datClient;
}
public void close()
{
try {
outClient.close();
inClient.close();
clientSocket.close();
}
catch(IOException ex) {
throw new RuntimeException("Error closing streams...");
}
}
}
}
玩家:
import greenfoot.*;
public class Player extends Actor
{
private MyWorld myWorld;
private Player2 player2;
public Player(MyWorld myWorl)
{
myWorld = myWorl;
}
private boolean startSelectionBool = false;
public void act()
{
if(!startSelectionBool)
{
if(Greenfoot.getMouseInfo() != null)
{
if(Greenfoot.mouseClicked(this))
{
myWorld.init();
startSelectionBool = true;
}
}
}
else
{
if(myWorld.Server == true)
{
updateServer();
//System.out.println("Server");
}else
{
updateClient();
//System.out.println("Client");
}
}
}
public void updateServer()
{
if(Greenfoot.isKeyDown("w"))
{
setLocation(this.getX(), this.getY()-1);
}
if(Greenfoot.isKeyDown("s"))
{
setLocation(this.getX(), this.getY()+1);
}
if(Greenfoot.isKeyDown("a"))
{
setLocation(this.getX()-1, this.getY());
}
if(Greenfoot.isKeyDown("d"))
{
setLocation(this.getX()+1, this.getY());
}
myWorld.server.sendInts(this.getX(), this.getY());
updatePosition();
}
public void updatePosition()
{
if (myWorld.server.receiveInts() != null)
{
System.out.println("Works Server");
int[] w1 = myWorld.server.receiveInts();
//System.out.println("1");
player2 = getWorld().getObjects(Player2.class).get(0);
player2.setLocation(w1[0], w1[1]);
//System.out.println("2");
}
else
{
System.out.println("1");
}
}
public void updateClient()
{
if(Greenfoot.isKeyDown("w"))
{
setLocation(this.getX(), this.getY()-1);
}
if(Greenfoot.isKeyDown("s"))
{
setLocation(this.getX(), this.getY()+1);
}
if(Greenfoot.isKeyDown("a"))
{
setLocation(this.getX()-1, this.getY());
}
if(Greenfoot.isKeyDown("d"))
{
setLocation(this.getX()+1, this.getY());
}
myWorld.client.sendInts(this.getX(), this.getY());
if (myWorld.client.receiveInts() == null)
{
System.out.println("Return Client");
return;
}
else
{
player2 = getWorld().getObjects(Player2.class).get(0);
int[] w2 = myWorld.client.receiveInts();
System.out.println("Position: " + w2[0] + " - " + w2[1]);
player2.setLocation(w2[0], w2[1]);
}
}
}
看起来奇怪的一件事是,在
updatePosition()
中,您调用 receiveInts()
两次,因此第一个将从套接字读取然后丢弃它,第二个将不得不等待下一个相应的 sendInts()
调用。我怀疑您希望在 w1
中的 if 语句之前对 updatePosition()
进行赋值,然后检查 w1
是否为空。