4

I have recently downloaded some simple game code off a online tutorial. I am currently trying to make it multiplayer. However in my portion of the program where the coordinates are written to a socket the variables don't update. I have searched all over the internet looking fro an answer but I have found none. I have tested the code and the Ints get sent successfully.

My Client.java

import java.net.*;
import java.util.Scanner;
import java.io.*;

import javax.swing.SwingUtilities;



public class Client implements Runnable{

   public void run() {

       Craft crObj = new Craft();
       int playerX = 3001;
    int playerY = 300;
       String serverName = "127.0.0.1";
       int port = 6789;
       int port1 = 6788;
       Socket client = null, client1 = null;
       System.out.println("Connecting to " + serverName + " on port " + port);
       OutputStream outsetup = null, out1setup = null;


       try {
       client = new Socket(serverName, port);
       client1 = new Socket(serverName, port1);
       } catch (IOException e) {
           System.out.println(e);
       }
       System.out.println("Connected");

       Scanner test = new Scanner(System.in);
       try {
            outsetup = client.getOutputStream();
            out1setup = client1.getOutputStream();
       } catch(IOException e) {
           System.out.println(e);
       }
       DataOutputStream out = new DataOutputStream(outsetup);
       DataOutputStream out1 = new DataOutputStream(out1setup);


       while(true) {
           try {
//Doesn't Update Here
               playerX = crObj.getX();
               playerY = crObj.getY();
               out.writeInt(playerX);
               out.flush();
               out1.writeInt(playerY);
               out1.flush();

           } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
           }

      }

   }
}

My Craft.java

import java.awt.Image;
import java.awt.event.KeyEvent;

import javax.swing.ImageIcon;

public class Craft {

    private String craft = "craft.png";
    Client clObj = new Client();
    public int dx;
    public int dy;
    public int x;
    public int y;
    private Image image;
    public ImageIcon ii;

    public Craft() {
        ImageIcon ii = new ImageIcon(this.getClass().getResource(craft));
        image = ii.getImage();
        x = 40;
        y = 60;
    }


    public void move() {
        x += dx;
        y += dy;
    }

    public int getX() {
        return x;
    }

    public int getY() {
        return y;
    }

    public Image getImage() {
        return image;
    }
    public void keyPressed(KeyEvent e) {

        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = -2;
            ii = new ImageIcon(this.getClass().getResource("craftBACK.png"));
            image = ii.getImage();
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 2;
            ii = new ImageIcon(this.getClass().getResource("craft.png"));
            image = ii.getImage();
        }

        if (key == KeyEvent.VK_UP) {
            dy = -2;
            ii = new ImageIcon(this.getClass().getResource("craftUP.png"));
            image = ii.getImage();
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 2;
            ii = new ImageIcon(this.getClass().getResource("craftDOWN.png"));
            image = ii.getImage();
        }
    }

    public void keyReleased(KeyEvent e) {
        int key = e.getKeyCode();

        if (key == KeyEvent.VK_LEFT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_RIGHT) {
            dx = 0;
        }

        if (key == KeyEvent.VK_UP) {
            dy = 0;
        }

        if (key == KeyEvent.VK_DOWN) {
            dy = 0;
        }

    }
}

Board.java

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

import javax.swing.JPanel;
import javax.swing.Timer;


public class Board extends JPanel implements ActionListener {
    public int xMain = 0;
    Client clObj = new Client();
    private Timer timer;
    private Craft craft;

    public Board() {

        addKeyListener(new TAdapter());
        setFocusable(true);
        setBackground(Color.BLACK);
        setDoubleBuffered(true);

        craft = new Craft();

        timer = new Timer(5, this);
        timer.start();
    }


    public void paint(Graphics g) {
        super.paint(g);

        Graphics2D g2d = (Graphics2D)g;
        g2d.drawImage(craft.getImage(), craft.getX(), craft.getY(), this);

        Toolkit.getDefaultToolkit().sync();
        g.dispose();
    }


    public void actionPerformed(ActionEvent e) {
        craft.move();
        xMain = craft.getX();
        System.out.println(xMain);
        repaint();
    }


    private class TAdapter extends KeyAdapter {

        public void keyReleased(KeyEvent e) {
            craft.keyReleased(e);
        }

        public void keyPressed(KeyEvent e) {
            craft.keyPressed(e);
        }
    }

}

RType.java

import javax.swing.JFrame;

public class RType extends JFrame {

    public RType() {

        add(new Board());

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(400, 300);
        setLocationRelativeTo(null);
        setTitle("R - Type");
        setResizable(false);
        setVisible(true);
        (new Thread(new Client())).start();
    }

    public static void main(String[] args) {
        new RType();
    }
}
IslaStewart
  • 311
  • 2
  • 11

2 Answers2

2

Since you are accessing values from different thread making them volatile should help.

Replace

public int dx;
public int dy;
public int x;
public int y;

with

public volatile int dx;
public volatile int dy;
public volatile int x;
public volatile int y;

You might also need to set some delay in your while(true) loop

playerX = crObj.getX();
playerY = crObj.getY();

Getting these values after some delay (Thread.sleep(100))

Tala
  • 8,888
  • 5
  • 34
  • 38
-1

Make variable static that's work for me

Replace

public int dx;
public int dy;
public int x;
public int y;

With

public static volatile int dx;
public static volatile int dy;
public static volatile int x;
public static volatile int y;

Here volatile qualifier is not recommended. But for fresh value, it should be used.

Chayan Mistry
  • 396
  • 3
  • 14
  • 1
    Why is the `volatile` qualifier not recommended? – hostingutilities.com Apr 06 '19 at 04:42
  • Mainly `volatile` is used in the interrupt routine where it needs to update the variable status every time. And I have also tested my code **with** and **without** `volatile` it's working for both. But without `static` it not worked. – Chayan Mistry Apr 06 '19 at 12:44