Java [1242]

Zapisz się
Dodaj kartkę Dodaj bana
Powód wlepienia kartki
Wybierz wątek docelowy z listy lub wpisz jego ID
  • Jarek

    witam,

    spotkal sie juz moze ktos z takim problemem??? mam aplikacje client - server, ktora wysyla w czasie rzeczywistym dane z klawiatury. Nie moze byc opoznien, bo to jest gra arkanoid i dane musza byc na bierzaco aktualizowane.
    Doszedlem tylko do takiego momentu, w ktorym dane sa wysylane za wolno i zle dziala, albo pojawia mi sie wyjatek tak jak w temacie.

    wie moze ktos jak ten problem rozwiazac???

    pozdrawiam
  • mystery

    wklej kod
  • Jarek

    glowna petla gry

    public void run(){

    Thread myThread = Thread.currentThread();
    Graphics g = getGraphics();
    while (t == myThread){
    startTime = System.currentTimeMillis();
    if(paused){

    try{

    Thread.sleep(500);
    }
    catch(InterruptedException e){}
    lastFrame = System.currentTimeMillis();
    }
    else{

    g.setColor(0);
    g.fillRect(0,0,getWidth(), getHeight());
    g.setColor(0xffffff);

    player.paint(g);
    player2.paint(g);
    myBall.paint(g);
    flushGraphics();

    keyState = getKeyStates();

    this.keyboard(); / /czyta zdarzenia z klawiatury i uruchamia dalsze metody
    if(player.collision(myBall) || player2.collision(myBall));
    myBall.collision(true);
    myBall.cycle((int)(System.curr entTimeMillis() - lastFrame));/ /ruch pilki
    lastFrame = System.currentTimeMillis();
    int timeSoFar = (int) (System.currentTimeMillis()-st artTime);
    if ( timeSoFar < MS_PER_FRAME){

    try{

    Thread.sleep(MS_PER_FRAME - timeSoFar);

    }
    catch(InterruptedException e){}
    }

    }
    }
    }


  • Jarek

    petla klienta

    public void run() {

    try{
    locDevice = LocalDevice.getLocalDevice();
    browser = locDevice.getDiscoveryAgent();

    }catch(Exception e){
    e.printStackTrace();
    }

    while(true){
    try {
    mDateConnect = browser.selectService(SERVER_U UID,
    ServiceRecord.NOAUTHENTICATE_N OENCRYPT, false);

    if(mDateConnect != null){
    con = (StreamConnection) Connector.open(mDateConnect);
    game.go(con);

    dos = con.openDataOutputStream();
    dos.writeInt(game.getKeyState( ));
    dos.flush();
    dos.close();

    dis = con.openDataInputStream();
    game.movePlayer2(dis.readInt() );
    dis.close();

    thread.sleep(50);
    }
    }catch(Exception e){}
    }

    }
  • KosciaK

    }catch(Exception e){}

    I to prawdopodobnie jest odpowiedź. Program może wywalać masę wyjątków, o których nawet nie masz pojęcia. A jako, że wszystkie streamy zamykasz w bloku try to przy pojawieniu się wyjątku nie zostaną zamknięte!
  • Jarek

    hmmm.... ten kod co wkleilem to dziala ale chodzi o to ze nie wszystkie informacje sa przesylane o ruchu, np jak zrobilem 3 szybkie ruchy to zostaje wyslany tylko 1.

    czyli po prostu jakby ta glowna petla byla za szybka, ale jak zwolnie to dziala beznadziejnie i tez nie ma takie rezultatu jakbym chcial.

    inna opcja jest taka, ze w glownej petli moge wywolywac dodatkowa metode

    public void sendMovement(int x, StreamConnection con){

    try {
    dos = con.openDataOutputStream();

    dos.writeInt(x);
    dos.flush();
    dos.close();
    } catch (IOException ex) {
    ex.printStackTrace();
    }

    }

    ale wtedy wywala mi wyjatek no output streams.
    Pierwsze przejscie przez glowna petle jest wyslane, ale potem prawdopodobnie polaczenie nie daje rady sie tak szybko zamknac i nie wysyla.

    nie wiem jak rozwiazac ten problem :(
  • KosciaK

    Dodaj ex.printStackTrace(); w obu pętlach i zobacz czy (i jakie) wyjątki ci zwraca. A najlepiej to przyrzyj się temu w debugerze
  • KosciaK

    no i jeszcze dość ważne pytanie to w którym miejscu pojawia ci się ten wyjątek "no more output streams".
  • Jarek

    public void sendMovement(int x, StreamConnection con){

    try {

    //w tym momencie
    dos = con.openDataOutputStream();
    //
    dos.writeInt(x);
    dos.flush();
    dos.close();
    } catch (IOException ex) {
    ex.printStackTrace();
    }

    }
  • mystery

    A nie lepiej zamiast tej petli zrobic jakiegos KeyListenera, ktory bedzie wysylal wartosc wcisnietego klawisza?
  • mystery

    albo jeszcze sproboj zrobic tak:

    otworz strumien
    while(true){
    wysylaj wcisniety klawisz
    sleep(50)
    }
    zamknij strumien
  • Eric Wu

    Arkanoid klient-serwer?
    Ciekawy pomysł...

    Ja bym to zrobił inaczej:
    Key listener który by reagował na zdarzenie wciśnięcia klawisza. I teraz jedna z 2 rzeczy:
    Wersja 1: zapis do tablicy klawiszy (bufor), wywołanie synchronizowane oczywiście, w pętli run co np. 100 ms również w synchronizowanym bloku zczytywany jest ten bufor, zamieniany na ciąg znaków, przesyłany do serwera i czyszczony, serwer analizuje ciąg, odtwarza sekwencję i reaguje.
    Wersja 2: w momencie wciśnięcia klawisza w samym listenerze wywoływana metoda wysłania znaku do serwera

    Moim zdaniem to problemem jest jedna z 2 rzeczy:

    1. zrzuca Ci jakieś wyjątki tam gdzie nie wypisujesz co się stało w catch (czyli brak printStackTrace) i nie zamyka pootwieranych strumieni, robi Ci się ich dużo nie pozamykanych i w końcu program dociera do ograniczenia ich ilości
    O tym już wspominali przedmówcy.

    2. może zbyt często i za dużo strumieni otwierasz, zamknięcie strumienia przez close nie koniecznie musi oznaczać, że został on już do końca zamknięty i nie zajmuje miejsca w jakiejś ograniczonej puli, możliwe, że jak otwiera się i zamyka ich kilkadziesiąt na sekundę to można jakieś wewnętrzne ograniczenie JVM lub systemu operacyjnego po pewnym czasie przekroczyć

    Moim zdaniem powinieneś otworzyć jeden strumień przy połączeniu (ewentualnie dwa strumienie jeden do komunikacji klient->serwer i drugi w drugą stronę) i wysyłać oraz odbierać w nich po jednym znaku, a nie otwierać oddzielny strumień dla każdego znaku.
    Zresztą przedmówca już o tym pisał.
  • Ja nie istnieje (FURBY)

    Ja bym wysyłał komunikaty, ale w Javie jest CORBA i RMI może warto z nich skorzystać w końcu po coś są. :)