Przesyłanie tablicy Socket

0

Witam pisze grę w statki i posiadam w niej 3 klasy (Statki-cala gra, Serwer, Client), i napotkałem pewien problem ponieważ rozmieszczenie statków mam w tablicy 10 x 10 w klasie Statki a jak wiadomo gracze musza się tym wymieniać do gry, a nie wiem jak przesyłać między sobą te tablice. Jakbym mógł prosić o jakieś porady i przykładowy kod jak to zrobić był bym bardzo wdzięczny.

0

Możesz przesyłać obiekty z klas, które implementują interfejs Serializable. Stwórz klasę opakowującą tablicę, którą chcesz przesyłać. Coś takiego

import java.io.*;

public class SerializedArray implements Serializable 
{
    private Klasa[] array=null;
    //-------------------------
    public void setArray(Klasa[] array)
    {
        this.array=array;
    }
    //-------------------------
    public Klasa[] getArray()
    {
        return array;
    }
}
0

@bogdans:
A nie lepiej coś w stylu:

public class Holder<T> implements Serializable {
  private T value = null;
  public void set(T value) {
    this.value = value;
  }
  public T get() {
    return value;
  }
}

Holder<Klasa[]> holder = new Holder<Klasa[]>();

Poza tym tablice w Javie dziedziczą po java.lang.Object, więc chyba można je bez problemu przesyłać za pomocą ObjectInputStream/ ObjectOutputStream.

0

Udało mi się wymienić tablicami za pomocą ObjectInputStream/ObjectOutputStream, ale teraz napotkałem na inny problem ponieważ po każdym kliknięciu myszą w dane pole muszę wymienić się tablicami znów i przemalować pola do gry. Wszystko było by dobrze gdyby nie to że po kliknięciu i w pole i zmianie jego wartości wywołuje repaint(); ,a następnie chce wysłać tą tablice. I tu jest problem, tablica zostaje wysłana i client odbiera ja i przemalowuje swoje pola natomiast na Serverze pole nie zostaje przemalowane choc wywolana zostaje funkcja repaint() jeszcze przed wysłaniem tablicy, pole przemalowuje się dopiero po odebraniu tablicy od clienta. Macie jakiej pomysły co z tym może być nie tak?

0

Narobisz sobie problemów projektowych jeżeli będziesz uważał, że masz jednego klienta i jednego serwera. W istocie masz jednego serwera oraz dwóch klientów z których jeden jest na tej samej maszynie. Dopiero wtedy Twoje problemy z synchronizacją staną się łatwo rozwiązywalne. To co postrzegasz w różnych grach (sieciowych) jako gospodarza gry (bądź serwer gry), to jest taki skrót myślowy. Choć jest on dla graczy jest zupełnie wystarczający, nie jest stanem rzeczywistym i nie jest wystarczający dla kogoś kto grę projektuje.
W takiej grze jak ta, którą opisujesz każdy z klientów powinien w swoim ruchu modyfikować stan gry poprzez komunikację z serwerem, a w celu wyświetlenia stanu gry odbierać potrzebne dane również za pomocą komunikacji z serwerem - lecz w odwrotną stronę. Klient sam nie powinien wyrysowywać niczego czego nie otrzymał zwrotnie od serwera. Nawet jeżeli serwer siedzi w pamięci "tuż obok". Różnić się będzie jedynie warstwa komunikacyjna - jednak z punktu widzenia abstrakcji klienta gry komunikacja powinna być identyczna czy serwer będzie znajdować się na tym samym komputerze, na innym komputerze z klientem gry, na zupełnie innym serwerze dedykowanym, czy wręcz na serwerze, którego fizyczne umiejscowienie będzie dla klienta gry nieznane (w tzw. chmurze).

0

Trochę zrozumiałem trochę nie :D za to ujmę teraz temat delikatnie inaczej. Wykonuje ruch (strzelam w pole ile chce strzałów, pole to narysowana szachownica na panelu ,a każde klikniecie w dany kwadrat zmienia odpowiednia wartość w tablicy 10x10) po każdym ruchu zmieniam kolor pola na szachownicy na odpowiedni funkcja repaint() i wysyłam tablice ,a klient ja odbiera po czym powinien przemalować swoje pola na szachownicy (odbiór odbywa się w nieskończonej pętli). I teraz chodzi mi o to że klient nie chce przemalować swojej szachownicy a gdy po prostu serwer zostaje zamknięty i połączenie zerwane klient spokojnie ja przemalowuje. o co może tu chodzić?

wysyłanie tablicy:

 public void shootOut() throws ClassNotFoundException, IOException{
          
                        ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
                        t1 = so.getTab1();
                        oos.writeObject(t1); 
        }
public int[][] getTab(){
 
           return tab;
         
}

Odbieranie:

public int[][] shootIn() throws IOException, ClassNotFoundException{
         
                        ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
                        Object o;
                        o = ois.readObject();
                        t = (int[][]) o;
                        return t;
        }

Wywołanie funkcji odbierającej i przemalowującej pole:

while(true){
                            tab = c.shootIn();
                            repaint();
                            }
0

Kilka pytań pomocniczych:

  1. Uważasz, że ta przesyłana dwuwymiarowa tablica intów zawiera całą informację o stanie rozgrywki?
  2. Czym u Ciebie różni się klient od serwera? Co każdy z nich robi?
  3. Wywołanie repaint() powoduje przemalowanie przez wywołanie ze Swinga metody paint komponentu, do którego odwoływał się this.repaint(). Co tak naprawdę odrysowuje paint()?
  4. Co się stanie jeżeli okienko z grą zostanie przykryte przez inne okno, a następnie odkryte? Podaj oba przypadki, czyli kiedy jest ruch własnej strony i strony przeciwnej.
1

Zapewne to odbieranie danych z serwera masz w tym samym wątku, który obsługuje GUI aplikacji. Problem polega na tym, że tak długo jak wątek nie będzie miał kiedy obsłużyć GUI to nie zobaczysz efektu odrysowywania, a że z tej pętli wyjdzie Ci dopiero jak coś jest nie tak z komunikacją to efekt widzisz dopiero po zamknięciu serwera.

Odbieranie pakietów musisz zrobić w innym wątku.

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