Hallo,
ich versuche gerade ein 2D-Spiel von mir netzwerkfähig zu machen. Ich versende verschiedene Klassen über einen ObjecOutputStream, für Sounds, Statusänderungen, Positionen usw.
Mit Abstand am öftesten versendet wird ein Array aus SpriteMessage, die lediglich drei Integer-Werte speichert.
Allerdings bekomme ich früher oder später jedes Mal eine ArrayStore- oder StreamCorruptedException. Mal läuft es nur einige Sekunden, mal eine Minute.
Die StreamCorruptedExceptions haben verschiedene Fehlercodes, z.b. 00 oder 6C.
Alle Exceptions treten beim Lesen auf:
[JAVA=37]message = inputStream.readObject();[/code]
Sehr merkwürdig: Schreibe ich für jedes empfangene Objekt eine Nachricht in System.out (s. Senden Z. 37) funktioniert alles, läuft nur langsamer...
Verbindung herstellen:
[JAVA=83]//Stellt eine Verbindung zum angegebenen Socket her und gibt den Erfolg zurück
public boolean connect(Socket socket, boolean toHost) {
this.socket = socket;
try {
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
gameListener = new GameListener(main, inputStream);
gameListener.start();
if(toHost) main.setProgrammeStatus(ProgrammeStatus.NETWORK_CLIENT);
else {
main.setProgrammeStatus(ProgrammeStatus.NETWORK_HOST);
sendDisplayMode();
}
main.setStatus(GameStatus.MULTIPLAYER_GAME);
} catch (IOException e) {e.printStackTrace(); return false;}
return true;
}[/code]
Senden:
[JAVA=35]public void sendObject(Object object) {
//Löscht man die print-Befehle klappt gar nichts mehr. Warum weiß niemand.
//main.print("Sende " + object);
if(isConnected()) {
try {
outputStream.writeObject(object);
//main.print("Übertragung erfolgreich.");
} catch(SocketException e) {
if(e.getLocalizedMessage().equals("Connection reset")) {
main.getCommunicationManager().closeConnection();
main.getComponentHandler().showPopUp("Verbindung unterbrochen!");
}else e.printStackTrace();
}
catch (IOException e) {e.printStackTrace();}
}
}[/code]
Empfangene Nachrichten auswerten:
[JAVA=29]@Override
public void listen() {
Object message = null;
try {
message = inputStream.readObject();
} catch(SocketException e) {
if(e.getLocalizedMessage().equals("Connection reset") || e.getLocalizedMessage().equals("socket closed")) {
main.getCommunicationManager().closeConnection();
main.getComponentHandler().showPopUp("Verbindung unterbrochen!");
}else e.printStackTrace();
}
catch (IOException e) {e.printStackTrace();}
catch (ClassNotFoundException e) {e.printStackTrace();}
if(message != null) {
//main.print("Objekt erhalten: " + message);
if(message instanceof SpriteMessage[]) {
SpriteMessage[] sprites = (SpriteMessage[]) message;
for(SpriteMessage spriteMessage : sprites) {
if(displayFactorWidth != 1) spriteMessage.setX(Math.round(Math.round(spriteMessage.getX() * displayFactorWidth)));
if(displayFactorHeight != 1) spriteMessage.setY(Math.round(Math.round(spriteMessage.getY() * displayFactorHeight)));
}
main.getDrawManager().setSpriteMessages(sprites);
}else
if(message instanceof InputMessage) {
switch((InputMessage) message) {
case PLAYER_MOVE_CENTER: main.getGameManager().setPlayerDirection(1, Direction.CENTER); break;
case PLAYER_MOVE_RIGHT: main.getGameManager().setPlayerDirection(1, Direction.RIGHT); break;
case PLAYER_MOVE_LEFT: main.getGameManager().setPlayerDirection(1, Direction.LEFT); break;
case PLAYER_SHOOT: main.getGameManager().shootArrow(1); break;
}
}else
if(message instanceof StatusMessage) {
switch((StatusMessage) message) {
case LEVELCHANGE_START: main.setStatus(GameStatus.MULTIPLAYER_LEVELCHANGE);
main.getGameManager().setLevel(main.getGameManager().getLevel() + 1); break;
case LEVELCHANGE_END: main.setStatus(GameStatus.MULTIPLAYER_GAME); break;
case GAME_OVER: main.setStatus(GameStatus.SCORE); break;
case GAME_RESTART: main.setStatus(GameStatus.MULTIPLAYER_GAME); break;
case CONNECTION_END: main.getCommunicationManager().closeConnection();
main.print("Partner hat Spiel verlassen, schließe Verbindung.");
main.getComponentHandler().showPopUp("Der Partner hat das Spiel verlassen."); break;
}
}else
if(message instanceof SoundNumber) {
main.getSoundHandler().playSound((SoundNumber) message);
}else
if(message instanceof PlayerScoreMessage) {
main.getGameManager().setPlayerPoints(0, ((PlayerScoreMessage) message).getFirstScore());
main.getGameManager().setPlayerPoints(1, ((PlayerScoreMessage) message).getSecondScore());
}else
if(message instanceof DisplayModeMessage) {
main.print("DisplayMode erhalten");
DisplayMode ownDisplayMode = main.getScreenHandler().getCurrentDisplayMode();
DisplayMode oppositeDisplayMode = ((DisplayModeMessage) message).getDisplayMode();
main.print(ownDisplayMode.getWidth() + " " + ownDisplayMode.getHeight());
main.print(oppositeDisplayMode.getWidth() + " " + oppositeDisplayMode.getHeight());
displayFactorWidth = (double) 1 / oppositeDisplayMode.getWidth() * ownDisplayMode.getWidth();
displayFactorHeight = (double) 1 / oppositeDisplayMode.getHeight() * ownDisplayMode.getHeight();
main.print("DisplayFactorWidth: " + displayFactorWidth);
main.print("DisplayFactorHeight: " + displayFactorHeight);
}
}
}[/code]
SpriteMessage:
[JAVA=5]public class SpriteMessage implements Serializable {
private static final long serialVersionUID = -7914187131101524916L;
private final int imageNumber;
private int x;
private int y;
public SpriteMessage(int imageNumber, double x, double y) {
this.imageNumber = imageNumber;
this.x = Math.round(Math.round(x));
this.y = Math.round(Math.round(y));
}
public int getImageNumber() {
return imageNumber;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}[/code]
ich versuche gerade ein 2D-Spiel von mir netzwerkfähig zu machen. Ich versende verschiedene Klassen über einen ObjecOutputStream, für Sounds, Statusänderungen, Positionen usw.
Mit Abstand am öftesten versendet wird ein Array aus SpriteMessage, die lediglich drei Integer-Werte speichert.
Allerdings bekomme ich früher oder später jedes Mal eine ArrayStore- oder StreamCorruptedException. Mal läuft es nur einige Sekunden, mal eine Minute.
Code:
Exception in thread "Thread-8" java.lang.ArrayStoreException
Alle Exceptions treten beim Lesen auf:
[JAVA=37]message = inputStream.readObject();[/code]
Sehr merkwürdig: Schreibe ich für jedes empfangene Objekt eine Nachricht in System.out (s. Senden Z. 37) funktioniert alles, läuft nur langsamer...
Verbindung herstellen:
[JAVA=83]//Stellt eine Verbindung zum angegebenen Socket her und gibt den Erfolg zurück
public boolean connect(Socket socket, boolean toHost) {
this.socket = socket;
try {
outputStream = new ObjectOutputStream(socket.getOutputStream());
inputStream = new ObjectInputStream(socket.getInputStream());
gameListener = new GameListener(main, inputStream);
gameListener.start();
if(toHost) main.setProgrammeStatus(ProgrammeStatus.NETWORK_CLIENT);
else {
main.setProgrammeStatus(ProgrammeStatus.NETWORK_HOST);
sendDisplayMode();
}
main.setStatus(GameStatus.MULTIPLAYER_GAME);
} catch (IOException e) {e.printStackTrace(); return false;}
return true;
}[/code]
Senden:
[JAVA=35]public void sendObject(Object object) {
//Löscht man die print-Befehle klappt gar nichts mehr. Warum weiß niemand.
//main.print("Sende " + object);
if(isConnected()) {
try {
outputStream.writeObject(object);
//main.print("Übertragung erfolgreich.");
} catch(SocketException e) {
if(e.getLocalizedMessage().equals("Connection reset")) {
main.getCommunicationManager().closeConnection();
main.getComponentHandler().showPopUp("Verbindung unterbrochen!");
}else e.printStackTrace();
}
catch (IOException e) {e.printStackTrace();}
}
}[/code]
Empfangene Nachrichten auswerten:
[JAVA=29]@Override
public void listen() {
Object message = null;
try {
message = inputStream.readObject();
} catch(SocketException e) {
if(e.getLocalizedMessage().equals("Connection reset") || e.getLocalizedMessage().equals("socket closed")) {
main.getCommunicationManager().closeConnection();
main.getComponentHandler().showPopUp("Verbindung unterbrochen!");
}else e.printStackTrace();
}
catch (IOException e) {e.printStackTrace();}
catch (ClassNotFoundException e) {e.printStackTrace();}
if(message != null) {
//main.print("Objekt erhalten: " + message);
if(message instanceof SpriteMessage[]) {
SpriteMessage[] sprites = (SpriteMessage[]) message;
for(SpriteMessage spriteMessage : sprites) {
if(displayFactorWidth != 1) spriteMessage.setX(Math.round(Math.round(spriteMessage.getX() * displayFactorWidth)));
if(displayFactorHeight != 1) spriteMessage.setY(Math.round(Math.round(spriteMessage.getY() * displayFactorHeight)));
}
main.getDrawManager().setSpriteMessages(sprites);
}else
if(message instanceof InputMessage) {
switch((InputMessage) message) {
case PLAYER_MOVE_CENTER: main.getGameManager().setPlayerDirection(1, Direction.CENTER); break;
case PLAYER_MOVE_RIGHT: main.getGameManager().setPlayerDirection(1, Direction.RIGHT); break;
case PLAYER_MOVE_LEFT: main.getGameManager().setPlayerDirection(1, Direction.LEFT); break;
case PLAYER_SHOOT: main.getGameManager().shootArrow(1); break;
}
}else
if(message instanceof StatusMessage) {
switch((StatusMessage) message) {
case LEVELCHANGE_START: main.setStatus(GameStatus.MULTIPLAYER_LEVELCHANGE);
main.getGameManager().setLevel(main.getGameManager().getLevel() + 1); break;
case LEVELCHANGE_END: main.setStatus(GameStatus.MULTIPLAYER_GAME); break;
case GAME_OVER: main.setStatus(GameStatus.SCORE); break;
case GAME_RESTART: main.setStatus(GameStatus.MULTIPLAYER_GAME); break;
case CONNECTION_END: main.getCommunicationManager().closeConnection();
main.print("Partner hat Spiel verlassen, schließe Verbindung.");
main.getComponentHandler().showPopUp("Der Partner hat das Spiel verlassen."); break;
}
}else
if(message instanceof SoundNumber) {
main.getSoundHandler().playSound((SoundNumber) message);
}else
if(message instanceof PlayerScoreMessage) {
main.getGameManager().setPlayerPoints(0, ((PlayerScoreMessage) message).getFirstScore());
main.getGameManager().setPlayerPoints(1, ((PlayerScoreMessage) message).getSecondScore());
}else
if(message instanceof DisplayModeMessage) {
main.print("DisplayMode erhalten");
DisplayMode ownDisplayMode = main.getScreenHandler().getCurrentDisplayMode();
DisplayMode oppositeDisplayMode = ((DisplayModeMessage) message).getDisplayMode();
main.print(ownDisplayMode.getWidth() + " " + ownDisplayMode.getHeight());
main.print(oppositeDisplayMode.getWidth() + " " + oppositeDisplayMode.getHeight());
displayFactorWidth = (double) 1 / oppositeDisplayMode.getWidth() * ownDisplayMode.getWidth();
displayFactorHeight = (double) 1 / oppositeDisplayMode.getHeight() * ownDisplayMode.getHeight();
main.print("DisplayFactorWidth: " + displayFactorWidth);
main.print("DisplayFactorHeight: " + displayFactorHeight);
}
}
}[/code]
SpriteMessage:
[JAVA=5]public class SpriteMessage implements Serializable {
private static final long serialVersionUID = -7914187131101524916L;
private final int imageNumber;
private int x;
private int y;
public SpriteMessage(int imageNumber, double x, double y) {
this.imageNumber = imageNumber;
this.x = Math.round(Math.round(x));
this.y = Math.round(Math.round(y));
}
public int getImageNumber() {
return imageNumber;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}[/code]