Przerobienie gry na Sockety

0

Chciałbym przerobić grę aby działało połączenie client-server na socketach. Nie wiem za bardzo jak sie za to zabrać, w jaki sposób przesyłać informacje graczowi o tym który button został kliknięty, oraz jak to wszystko złożyć w całość wszystko dobrze działało :/

Tutaj jest kod gierki który chce przerobić.


import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.net.Socket;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;


class Memory extends JFrame implements ActionListener {

    private JButton button[][] = new JButton[4][4];
    private static int ar[][] = new int[4][4];
    private ImageIcon i[][] = new ImageIcon[4][4];
    private int clicks = 0, open = 0, pre[] = {-1, -1};
    private static String naam;
    private BufferedImage img9;
    private int cards = 0;

    public static void main(String args[]) {
        Memory ob = new Memory(); 
        ob.setVisible(true);
    }

    private void randomNum(){ 
        int temp[] = new int[16];
        for (int set = 1; set <= 8; set++) {
            for (int x = 1; x <= 2; x++) {
                int n = (int) (Math.random() * 16);
                while (temp[n] != 0) {
                    n = (int) (Math.random() * 16);
                }
                temp[n] = set;
            }
        }

        for (int x = 0; x <= 15; x++) {
            if (x <= 3) {
                ar[0][x] = temp[x];
            } else if (x <= 7) {
                ar[1][x - 4] = temp[x];
            } else if (x <= 11) {
                ar[2][x - 8] = temp[x];
            } else if (x <= 15) {
                ar[3][x - 12] = temp[x];
            }
        }
    }
    
    private boolean done() {
        for (int x = 0; x <= 3; x++) {
            for (int y = 0; y <= 3; y++) {
                if (button[x][y].isEnabled()) {
                    return false;
                }
            }
        }
        return true;
    }

    public void actionPerformed(ActionEvent evt) {
        for (int x = 0; x <= 3; x++) {
            for (int y = 0; y <= 3; y++) {
                if (evt.getSource() == button[x][y] && (open == 1 ? (!(pre[0] == x && pre[1] == y)) : true)) {
                    clicks++;
                    if (open == 0) {
                        open++;
                        showAt(x, y); 
                        pre[0] = x;
                        pre[1] = y;
                    } else if (open == 1) {
                        showAt(pre[0], pre[1], x, y); 
                        if (ar[x][y] == ar[pre[0]][pre[1]]) {
                            button[pre[0]][pre[1]].setEnabled(false);
                            button[x][y].setEnabled(false);
                            ++cards;
                            System.out.println("ilosc kart: " + cards);
                        }
                        java.util.Timer ob = new java.util.Timer(); 
                        Kaam ob1 = new Kaam(); 
                        ob1.take(x, y);
                        ob.schedule(ob1, 750); 
                        open = 0; 
                    }
                }
            }
        }
    }

    class Kaam extends TimerTask {
        int x, y;
        public void take(int a, int b) {
            x = a;
            y = b;
        }

        public void run() { 
            button[x][y].setIcon(null);
            button[pre[0]][pre[1]].setIcon(null);
        }
    }

    private void showAt(int r, int c, int ro, int co) {
        for (int x = 0; x <= 3; x++) {
            for (int y = 0; y <= 3; y++) {
                if ((x == r && y == c) || (x == ro && y == co)) {
                    button[x][y].setIcon(i[x][y]); 
                } else {
                    button[x][y].setIcon(null);
                }
            }
        }
    }

    private void showAt(int r, int c) { 
        for (int x = 0; x <= 3; x++) {
            for (int y = 0; y <= 3; y++) {
                if (x == r && y == c) {
                    button[x][y].setIcon(i[x][y]); 
                } else {
                    button[x][y].setIcon(null); 
                }
            }
        }
    }

    private void Start(){ 
        randomNum();
        setLayout(new GridLayout(4, 4)); 
        for (int x = 0; x < 4; x++) {
            for (int y = 0; y < 4; y++) {
                button[x][y] = new JButton();
                add(button[x][y]);
                button[x][y].addActionListener(this);
                String number = Integer.toString(ar[x][y]);
                ImageIcon img = new ImageIcon(getClass().getResource("img" + number + ".jpg")); 
                i[x][y] = img;
            }
        }
        setSize(700, 700); 
    }

    private Memory() {
        Start();
    }
}



2

Napisz sobie oddzielnie prosty programik wykorzystujący Sockety. Napisz server, który odbiera od klienta jakąś wiadomość, coś z nią robi, a następnie odsyła wynik klientowi. Poradników w internecie jest mnóstwo. Nie ma sensu wklejać tutaj kodu do tego.

Jak już ogarniesz jak działają sockety, to nie będziesz mial problemów z zaimplementowaniem tego w Twojej grze. Chyba, że gra nie jest Twoja :)

2

Zgadzam się z wypowiedzą wyżej. Są dostępne materiały w temacie "java network messaging". Linków z grzeczności nie wkleję.
Poza ćwiczeniem wyżej proponuję przesyłać po sieci tylko to, co jest potrzebne:

  • co się zmieniło - z jakiej wartości na jaką,
  • kto zmienił - jeśli mamy kilku uczestników, musimy mieć winnego
  • czas - to serwer rządzi czasem gry, wypadałoby mieć sędziego, więc niech porównuje czasy wysłania odpowiedzi.
    Przyjmijmy, że mamy podstawowe informacje, które chcemy przesłać po sieci:
public class Message implements Serializable {
	private static final long serialVersionUID = -2336559431992089747L;
	private long time;
	private Object sourceObject;
	private Object newValue;

	public Object getSourceObject() {
		return sourceObject;
	}

	public Object getNewValue() {
		return newValue;
	}

	public long getTime() {
		return time;
	}

}

Teraz można dziedziczyć po tej klasie zależnie od tego, co chce zrobić użytkownik. Klient (apka gracza) może sprawdzić czy nowa wartość jakiegoś pola jest poprawna. Jeśli tak, to można zaufać serwerowi i tak ustawić w GUI.

3

Jeśli drugi gracz ma się dowiedzieć o czymś, co się stało u pierwszego, to takie zdarzenie modelujesz jako event. Potem musisz mieć warstwę marshalingu / unmarshalingu gdzie obiekty eventów zamieniasz na bajty / konstruujesz obiekt z bajtów - de facto tworzysz swój własny protokół. Możesz pójść trochę na łatwiznę i użyć gotowej biblioteki do serializacji np. Kryo, Możesz użyć też np. Protocol Buffers. Na końcu musisz zaimplementować warstwę transportu, która będzie zajmowała się pisaniem/czytaniem z socketu, nawiązywaniem połączenia, reconnectem itd.

1 użytkowników online, w tym zalogowanych: 0, gości: 1