3
\$\begingroup\$

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!

\$\endgroup\$
  • 1
    \$\begingroup\$ Welcome to the site. Your quest seems fine, but it also seems like almost none of your posted code is relevant to your problem. Posting your exception or error message might be useful, in case you've misdiagnosed the problem. Anyway, it seems like the core of your question is about how to initiate an asynchronous process in Slick. Is that correct? \$\endgroup\$ – Seth Battin Dec 27 '15 at 6:38
1
\$\begingroup\$

Thanks for reading, turns out I just needed to spend a bit more time on my problem. For those who find this in the future, I used Kryonet to run my network code in a separate process.

\$\endgroup\$
  • \$\begingroup\$ Mark your answer as correcr \$\endgroup\$ – Bálint Nov 11 '16 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.