Send and process x-y-coordinates as UDP data from other application - best way to do it?

Hi,



I’d like to send UDP messages containing X/Y coordinates (something like this: “45:231”) of a controller app (Processing PApplet running in a JFrame) via the network and have jMonkeyEngine process the coordinates as fired shots (rays).



What would be the best way to implement this?

I have tried several approaches bt was not able to get it working.



Option 1:

  • create a SpiderMonkey server, connect the game to the server (already have a working example)
  • send UDP Packets to the SpiderMonkey server and have the messages releayed to the game using JME messaging API?



    The problem I have:

    I can not extend SimpleApp in my controller app that sends the coordinates, as this will be a Swing app based on Processing and disturb or block the graphics update threads and raise exceptions in Processing.



    If you have Processing, you can try this code:





    [java]

    int xmpos = -1;

    int ympos = -1;



    DatagramSocket dsocket;

    int port = 9001;

    InetAddress IPAddress;



    void setup () {

    size (512, 384);

    frameRate (25);



    // setup networking

    try {

    IPAddress = InetAddress.getByName(“localhost”);

    dsocket = new DatagramSocket();

    } catch (SocketException e) {

    e.printStackTrace();

    } catch (UnknownHostException u) {

    u.printStackTrace();

    }





    }







    void draw () {



    if (mousePressed) {

    // to filter if mouse did not move

    if (xmpos != mouseX || ympos != mouseY) {

    xmpos = mouseX;

    ympos = mouseY;



    println(“CLICK:t” + xmpos + “t” + ympos);

    sendShot(xmpos2, ympos2);

    fill(255,0,0);

    ellipse(xmpos, ympos, 9, 9);

    }



    }



    }



    // this sends the created shot coordinates via UDP

    // maybe better to send serialzed objects?



    void sendShot(int x, int y) {

    String message = x + “:” + y + “n”;

    println(message);

    byte[] packet = message.getBytes();

    println(“Sending datagram with " + packet.length + " bytes”);

    try {

    dsocket.send(new DatagramPacket(packet, packet.length, IPAddress, port));

    }



    catch (Exception e) {

    e.printStackTrace();

    }

    }



    [/java]







    Option 2:



    Send my Coordinates directly to the game, that runs a simple UDP listener Thread. I got this working, however after the first message received, it looks like it’s no longer receiving other messages. Threading problems?



    Looks like this:



    [java]

    public void simpleInitApp() {

    ulisten = new UDPListener();

    Thread ShotInput = new Thread(ulisten);

    ShotInput.start();

    }





    private class UDPListener implements Runnable {

    int clientPort = 9001;

    int buffer_size = 1024;

    byte buffer[] = new byte[buffer_size];

    DatagramPacket p;

    DatagramSocket ds;



    public UDPListener() {

    try {

    ds = new DatagramSocket(clientPort);

    } catch (Exception e) {

    e.printStackTrace();

    }



    System.out.println(“Starting UDPListener”);



    }



    public void run() {

    try {

    p = new DatagramPacket(buffer, buffer.length);

    ds.receive§;



    System.out.println(new String(p.getData(), 0, p.getLength()));



    } catch (Exception e) {

    e.printStackTrace();

    }



    }



    }





    [/java]



    Option 3:

    Trying to integrate the SpiderMonkeyserver directly into the controller app as a seperate thread and send SM messages to the game? Only blocked the drawing of the graphic updates in my Processing app.



    I have already done a lot of tests, but could not make it work.

    Hmm, it lookes that I just don’t understand some concepts yet and need some help og more experienced programmers.



    I really would appreciate your help or some hints on this and maybe some comments on which would be the best approach.



    Many thanks!

    Marc

I’m not sure why you wouldn’t just use SpiderMonkey on the client. You don’t need to use SimpleApplication or any of that stuff if you don’t want to. Just connect to the server, register a listener for your messages, and then do what you need to do in that listener.



The listeners are already on a separate thread so you will have to handle the thread safe access if you are sharing your game data between different threads. But I don’t know how you’ve architected your client application. Usually, there would be a separate game thread and swing would just be a viewer of the game state somehow.



Note: by sending your messages as UDP that they might not get to the other end. UDP is good for sending state that goes stale but TCP (or setReliable(true) in SpiderMonkey messages) is better for messages that must arrive.

Hi pspeed,



Many thanks! I got it working now using your proposed approach. Works very smoothly.

My controller app connects to the server and the server just broadcasts the arrived message to the JME game. The errors produced in Processing draw() function are gone completely.



Now working on the code that makes the game react on the incoming coordinates.



Again, many thanks!

Marc