Witam napisalem aplikacje w Javie. Mozna sie polaczyc do serwera i poruszac sie kwadratem razem z innymi graczami. Jesli sam sobie to testuje to dziala swietnie, bezproblemowo. Jednak problem zaczyna sie gdy ktos podlaczy sie ze mna z innego komputera i jednoczesnie bedzie poruszac kwadratami (jesli tylko 1 osoba bedzie sie poruszala a druga nic nie robila to wszystko bedzie w porzadku). Wtedy nie da sie normalnie sterowac kwadratem. Np. klikam strzalke w prawo by isc w prawo i nic sie nie dzieje, a jak wciskam jednoczesnie gore i prawo to np. idzie tylko w prawo. Wklejam kod serwera i klienta. (caly na wszelki wypadek jakby ktos chcial u siebie przetestowac). Sporo kodu ale na uwage zasluguje tylko pierwsza klasa bo problem lezy raczej po stronie serwera. Moze po prostu nie nadaza i powininem dodac sleep() w watku gracza? A moze cos innego?
SERWER
public class SquaresServer {
public static void main(String[] args) {
try {
ServerSocket so = new ServerSocket(8189);
final List<PrintWriter> writers = new LinkedList<>();
final int[] nextId = {0};
while (true) {
Socket incoming = so.accept();
final Scanner in = new Scanner(incoming.getInputStream());
final PrintWriter out = new PrintWriter(incoming.getOutputStream(), true);
//Nadanie graczowi id
final int playerId = nextId[0]++;
out.println(playerId);
//Powiadomienie wszystkich graczy o nowym graczu
writers.add(out);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
for (PrintWriter writer : writers) {
writer.println("new|0:0:" + red + ":" + green + ":" + blue + ":" +
playerId + ":false:false:false:false");
}
new Thread(new Runnable() {
@Override
public void run() {
try {
//Pobranie pozycji graczy od innego gracza
if (writers.size() > 1) {
PrintWriter writer;
do {
writer = writers.get((int) (Math.random() * writers.size()));
} while (writer == out);
writer.println("get|update");
}
while (in.hasNextLine()) {
String line = in.nextLine();
//Pierwsza nadeslana linia jest pusta (nie wiem dlaczego tak sie dzieje ale to teraz nieistotne)
if (line.equals("")) {
continue;
}
String[] split = line.split("\\|");
String type = split[0];
String message = split[1];
switch (type) {
case "move":
for (PrintWriter writer : writers) {
writer.println(line);
}
break;
case "update":
String[] squares = message.split("/");
for (String square : squares) {
for (PrintWriter writer : writers) {
writer.println("new|" + square);
}
}
break;
}
}
} finally {
writers.remove(out);
for (PrintWriter writer : writers) {
writer.println("remove|" + playerId);
}
}
}
}).start();
}
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
KLIENT
public class Squares {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame();
}
});
}
}
public class MainFrame extends JFrame {
public MainFrame() {
final MainPanel mainPanel = new MainPanel();
add(mainPanel);
addWindowListener(new WindowAdapter() {
@Override
public void windowDeactivated(WindowEvent ev) {
//Zeby nie stracic kontroli nad kwadratem
mainPanel.stopSquare();
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setResizable(false);
pack();
setVisible(true);
}
}
public class MainPanel extends JPanel {
private final int WIDTH = 600;
private final int HEIGHT = 400;
private List<Square> squares = new LinkedList<>();
private int id;
private Scanner in;
private PrintWriter out;
public MainPanel() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
addKeyListener(new KeyHandler());
try {
Socket so = new Socket("xxx.xxx.xxx.xxx", 8189);
in = new Scanner(so.getInputStream());
out = new PrintWriter(so.getOutputStream(), true);
id = in.nextInt();
new Thread(new Runnable() {
@Override
public void run() {
while (in.hasNextLine()) {
String line = in.nextLine();
//Pierwsza nadeslana linia jest pusta (nie wiem dlaczego tak sie dzieje ale to teraz nieistotne)
if (line.equals("")) {
continue;
}
String[] split = line.split("\\|");
String type = split[0];
String message = split[1];
switch (type) {
case "new":
String[] info = message.split(":");
int x = Integer.parseInt(info[0]);
int y = Integer.parseInt(info[1]);
int red = Integer.parseInt(info[2]);
int green = Integer.parseInt(info[3]);
int blue = Integer.parseInt(info[4]);
int id = Integer.parseInt(info[5]);
boolean up = Boolean.parseBoolean(info[6]);
boolean right = Boolean.parseBoolean(info[7]);
boolean down = Boolean.parseBoolean(info[8]);
boolean left = Boolean.parseBoolean(info[9]);
//Dodajemy kwadrat jesli jeszcze nie istnieje zaden o takim id
if (getSquareFromId(id) == null) {
squares.add(new Square(x, y, new Color(red, green, blue),
id, up, right, down, left));
}
break;
case "get":
switch (message) {
case "update":
StringBuilder sb = new StringBuilder();
for (Square square : squares) {
sb.append(square.toString());
sb.append("/");
}
sb.delete(sb.length() - 1, sb.length());
out.println("update|" + sb.toString());
break;
}
break;
case "move":
info = message.split(":");
int squareId = Integer.parseInt(info[0]);
Square square = getSquareFromId(squareId);
String dir = info[1];
boolean state = (info[2].equals("on")) ? true : false;
switch (dir) {
case "up":
square.setUp(state);
break;
case "right":
square.setRight(state);
break;
case "down":
square.setDown(state);
break;
case "left":
square.setLeft(state);
break;
}
break;
case "remove":
squareId = Integer.parseInt(message);
squares.remove(getSquareFromId(squareId));
break;
}
}
}
}).start();
} catch (IOException ex) {
ex.printStackTrace();
JOptionPane.showMessageDialog(this, ex.getMessage(), "Error",
JOptionPane.ERROR_MESSAGE);
}
new Thread(new MoveRnn()).start();
}
public void stopSquare() {
out.println("move|" + id + ":up:off");
out.println("move|" + id + ":right:off");
out.println("move|" + id + ":down:off");
out.println("move|" + id + ":left:off");
}
private Square getSquareFromId(int id) {
for (Square square : squares) {
if (square.getId() == id) {
return square;
}
}
return null;
}
@Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.DARK_GRAY);
g2.fillRect(0, 0, WIDTH, HEIGHT);
for (Square square : squares) {
g2.setColor(square.getColor());
g2.fillRect(square.getX(), square.getY(), Square.SIZE, Square.SIZE);
}
}
private class MoveRnn implements Runnable {
@Override
public void run() {
try {
while (true) {
for (Square square : squares) {
int oldX = square.getX();
int oldY = square.getY();
square.move();
if (square.getX() < 0 || square.getX() > WIDTH - Square.SIZE) {
square.setX(oldX);
}
if (square.getY() < 0 || square.getY() > HEIGHT - Square.SIZE) {
square.setY(oldY);
}
}
repaint();
Thread.sleep(10);
}
} catch (InterruptedException ex) {
}
}
}
private class KeyHandler extends KeyAdapter {
@Override
public void keyPressed(KeyEvent ev) {
switch (ev.getKeyCode()) {
case KeyEvent.VK_UP:
out.println("move|" + id + ":up:on");
break;
case KeyEvent.VK_RIGHT:
out.println("move|" + id + ":right:on");
break;
case KeyEvent.VK_DOWN:
out.println("move|" + id + ":down:on");
break;
case KeyEvent.VK_LEFT:
out.println("move|" + id + ":left:on");
break;
}
}
@Override
public void keyReleased(KeyEvent ev) {
switch (ev.getKeyCode()) {
case KeyEvent.VK_UP:
out.println("move|" + id + ":up:off");
break;
case KeyEvent.VK_RIGHT:
out.println("move|" + id + ":right:off");
break;
case KeyEvent.VK_DOWN:
out.println("move|" + id + ":down:off");
break;
case KeyEvent.VK_LEFT:
out.println("move|" + id + ":left:off");
break;
}
}
}
}
public class Square {
private int x;
private int y;
private Color color;
private int id;
private boolean up;
private boolean right;
private boolean down;
private boolean left;
public static final int SIZE = 30;
public Square(int x, int y, Color color, int id,
boolean up, boolean right, boolean down, boolean left) {
this.x = x;
this.y = y;
this.color = color;
this.id = id;
this.up = up;
this.right = right;
this.down = down;
this.left = left;
}
public void setUp(boolean up) {
this.up = up;
}
public void setRight(boolean right) {
this.right = right;
}
public void setDown(boolean down) {
this.down = down;
}
public void setLeft(boolean left) {
this.left = left;
}
public void move() {
if (up) {
y--;
}
if (right) {
x++;
}
if (down) {
y++;
}
if (left) {
x--;
}
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Color getColor() {
return color;
}
public int getId() {
return id;
}
@Override
public String toString() {
return x + ":" + y + ":" + color.getRed() + ":" + color.getGreen()
+ ":" + color.getBlue() + ":" + id + ":" + up + ":" + right
+ ":" + down + ":" + left;
}
}