This is my first post, so I apologize if it's been put in the wrong place or something. Anyways, here's my problem:
I've run into an issue with running my client-side code in one of my game-states. The game crashes because the update method isn't able to keep running. I know it's because the program waits for a connection, stalling the rest of the program. This line is responsible:
connection = new Socket(InetAddress.getByName(serverIP), port);
My game-state is a standard BasicGameState with an init(), a render(), and an update(). I don't know where to put the connection code into the game-state class. Here's the game-state code if you need it:
public class ConnectState extends BasicGameState {
private UnicodeFont ufont;
private Client client = new Client();
private final int ID;
public ConnectState(int state) {
ID = state;
}
@SuppressWarnings("unchecked")
@Override
public void init(GameContainer container, StateBasedGame game) throws SlickException {
try {
Font font = new Font("Sitka Small", Font.BOLD, 70);
ufont = new UnicodeFont(font, font.getSize(), font.isBold(), font.isItalic());
ufont.addAsciiGlyphs();
ufont.addGlyphs(400, 600);
ufont.getEffects().add(new ColorEffect(Color.WHITE));
ufont.getEffects().add(new OutlineEffect(5, Color.RED));
ufont.loadGlyphs();
} catch (SlickException e) {
e.printStackTrace();
}
}
@Override
public void render(GameContainer container, StateBasedGame game, Graphics g) throws SlickException {
g.setFont(ufont);
g.drawString(client.displayMsg, container.getWidth() / 2 - ufont.getWidth(client.displayMsg) / 2,
container.getHeight() / 2 - ufont.getHeight(client.displayMsg) / 2);
}
@Override
public void update(GameContainer container, StateBasedGame game, int delta) throws SlickException {
Input input = container.getInput();
boolean isRunning = false;
if (!isRunning) {
client.run();
isRunning = true;
}
if (input.isKeyPressed(Input.KEY_F1))
if (container.isShowingFPS())
container.setShowFPS(false);
else
container.setShowFPS(true);
if (input.isKeyPressed(Input.KEY_ESCAPE))
container.exit();
}
@Override
public int getID() {
return ID;
}}
Here's the Client code if you need it as well:
public class Client {
public String displayMsg = "";
private ObjectOutputStream output;
private ObjectInputStream input;
private String serverIP = "localhost";
private Socket connection;
private boolean shouldExit = false;
private Object recievedData;
public void run() {
try {
connect();
setupStreams();
whileConnected();
} catch (EOFException e) {
showMessage("The client closed the connection!");
} catch (IOException e) {
e.printStackTrace();
} finally {
close();
}
}
public void setShouldExit(boolean should) {
shouldExit = should;
}
private void connect() throws IOException {
System.out.println("So far...");
showMessage("Attempting to connect...");
System.out.println("...so good?");
connection = new Socket(InetAddress.getByName(serverIP), 1337);
showMessage("Connection successful! ^_^");
}
private void setupStreams() throws IOException {
output = new ObjectOutputStream(connection.getOutputStream());
output.flush();
input = new ObjectInputStream(connection.getInputStream());
showMessage("The streams have been setup! Don't cross 'em!");
}
private void whileConnected() throws IOException {
do {
try {
recievedData = input.readObject();
//send or do stuff
} catch (ClassNotFoundException e) {
showMessage("Something square was shoved through the circular tube...");
}
} while (!shouldExit);
}
private void close() {
showMessage("Closing...");
try {
output.close();
input.close();
connection.close();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendData() {
//TODO
}
private void showMessage(String message) {
displayMsg = message;
}}
In short, how do I run the aforementioned line of code in a constantly updating game-state? Also, if you know a better/easier way for tcp (I'm making a turn-based game, so tcp is fine) in slick, let me know!