# Darstellungsproblem?



## JLF Entwickler (9. Nov 2009)

Guten Abend

Ich habe wieder einmal Probleme beim Programmieren. Eigentlich sollte eine über das Netzwerk spielbare Java Version von "Little Fighter" entstehen. Nun habe ich zwei Probleme: Wenn ich einen dritten oder weitere Clients starte funktioniert das nicht, ich erhalte eine "Index out of Bounds Exception" bei meiner Array-List im Client.
Das zweite Problem: Bei zwei Clients funktioniert die Datenübertragung korrekt, d.h. das System.out.println bei Zeile 266 im Client gibt die richtigen Daten des jeweils anderen Clients aus, doch das Bild des Anderen wird nicht angezeigt. Ich sehe nur die Grafik des Spielers, diese jedoch korrekt und ohne Fehler.

Ich wäre sehr dankbar, wenn mir jemand weiterhelfen könnte. Auch sonstige kleinere Ansätze zum verbessern des Codes sind willkommen.

Hier der Code des Clients:
EDIT: Lest lieber den Code im vierten Post, ich habe versucht das für die Probleme Wichtige auszuwählen. Damit man hier etwas nachlesen kann, lasse ich den Gesamtcode noch da.


```
package Client;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import java.awt.image.BufferStrategy;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.util.ArrayList;
import java.util.HashMap;
import javax.imageio.ImageIO;
import javax.swing.JPanel;



public class JLF extends Canvas implements KeyListener {
    //Position des Charakters
    int posX, posY;

    //Tastaturbelegung
    int down, up, left, right, attack, jump, defend;

    //Anzeigevariabeln
    final int BREITE=1000;
    final int HOEHE=800;
    public BufferStrategy bf;
    
    //Schrittzählvariabeln
    int sUp = 0, sDown = 0, sRight = 0, sLeft = 0;

    //Bildwiederholungsrate in ms
    private final int SPEED = 20;

    //Bild-Zwischenspeicher
    public HashMap sprites;

    //Charaktervariabeln
    public String chara;
    public String action = "stand";
    public String lastAction;
    boolean moving = false;
    boolean dRight = true;
    boolean attacking = false;
    boolean sAtk = false;

    //Abbruchvariabeln
    private boolean breakUp, breakDown, breakLeft, breakRight;

    //Kommunikation mit Server
    final String SERVER = "localhost";
    final int PORT = 1991;
    Socket s;
    PrintWriter writer;
    BufferedReader reader;
    StringBuffer ServerMessage;

    //Variabeln für Gegenspieler
    int numberOfPlayers=0;
    int oldNumberOfPlayers;
    ArrayList players = new ArrayList();


    //Konstruktor
    public JLF(){
        //Serverkommunikation
        try {
            s = new Socket(SERVER, PORT);
        } catch (UnknownHostException ex) {
            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
        } catch (IOException ex) {
            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
        }
        try {
            writer = new PrintWriter(s.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
        } catch (IOException ex) {
            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
        }
        //Login
        writer.println("LOGIN Test Testpw");
        writer.flush();
        try {

            if (!reader.readLine().equals("accepted")) {
                //erneutes Login
            }
        } catch (IOException ex) {
            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
        }

        down = KeyEvent.VK_X;
        up = KeyEvent.VK_W;
        left = KeyEvent.VK_A;
        right = KeyEvent.VK_D;
        attack = KeyEvent.VK_S;
        jump = KeyEvent.VK_TAB;
        defend = KeyEvent.VK_BACK_SLASH;

        sprites = new HashMap();
        JFrame window = new JFrame("Java Little Fighter");
        JPanel panel = (JPanel)window.getContentPane();
        setBounds(0,0,BREITE,HOEHE);
        window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        panel.setPreferredSize(new Dimension(WIDTH,HOEHE));
        panel.add(this);
        window.setBounds(0,0,BREITE,HOEHE);
        window.setResizable(false);
        window.setVisible(true);
        this.setBackground(Color.BLUE);
        createBufferStrategy(2);
        bf = getBufferStrategy();
        chara = "deep";
        action = "stand";
        this.addKeyListener(this);
        //Threads starten
        breakLeft = true;
        breakRight = true;
        breakUp = true;
        breakDown = true;
        moveUpThread mUT = new moveUpThread();
        mUT.start();
        moveDownThread mDT = new moveDownThread();
        mDT.start();
        moveLeftThread mLT = new moveLeftThread();
        mLT.start();
        moveRightThread mRT = new moveRightThread();
        mRT.start();
        sAttackThread sAtkT = new sAttackThread();
        sAtkT.start();
        requestFocus();
        game();
        System.out.println("fertig");
    }

//Hauptloop des Spiels
    public void game(){
        String input="";
        while(true){
            //Serverausgabe
            if(dRight){
                writer.println(posX + "," + posY + "," + action + ",1");
            }else{
                writer.println(posX + "," + posY + "," + action + ",0");
            }
            writer.flush();

            //Servereingabe
            try {
                input = reader.readLine();
                oldNumberOfPlayers = numberOfPlayers;
                numberOfPlayers = Integer.parseInt(input);
                if(numberOfPlayers > oldNumberOfPlayers){
                    Object[] pl = new Object[4];
                    players.add(pl);
                }
                int k = 0;
                String[] playerMessages = new String[numberOfPlayers-1];
                while(k < numberOfPlayers-1){
                    playerMessages[k] = reader.readLine();
                    String[] splitted = playerMessages[k].split(",");
                    Object[] pl = (Object[]) players.get(k);
                    pl[0] = Integer.parseInt(splitted[0]);
                    pl[1] = Integer.parseInt(splitted[1]);
                    pl[2] = splitted[2];
                    pl[3] = Integer.parseInt(splitted[3]);
                    k++;
                }

            } catch (IOException ex) {
                Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
            }

            draw();


            try {
                Thread.sleep(SPEED);
            } catch (InterruptedException ex) {
                Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
    }

    //Stellt die Umgebung dar
    private void draw(){
        Graphics g = bf.getDrawGraphics();
        g.clearRect(0, 0, BREITE, HOEHE);
        BufferedImage img = null;
        try{
            img = getSprite(chara, action, dRight);
        }catch(Exception ex){
                System.out.println("Grafik konnte nicht geladen werden: "+ ex);
        }
        
        try{
            g.drawImage(img, posX+(img.getWidth()/2), posY+(img.getHeight()/2),null);
        }catch(Exception ex){
            System.out.println("Fehler beim erstellen des Grafikobjekts: " + ex);
        }
        finally{
            g.dispose();
        }

        drawPlayers(g);

        bf.show();

        Toolkit.getDefaultToolkit().sync();
    }

    //Lädt das Bild
    public BufferedImage loadImage(String name) {
        BufferedImage image;
        try {
             image = ImageIO.read(new File(name));
             return image;
        } catch (Exception e) {
            System.out.println(name +" konnte nicht geoeffnet werden.");
            System.out.println("Fehler: "+e.getClass().getName()+" "+e.getMessage());
            return null;
        }
     }

    //Gibt das benötigte Bild zurück
    //Wenn das Bild noch nicht geladen wurde, wird es geladen und zwischengespeichert
    public BufferedImage getSprite(String ch, String act, Boolean directionRight){
         BufferedImage img;
         if(directionRight){
             img = (BufferedImage)sprites.get(ch+"."+act);
             if (img == null) {
                 img = loadImage(ch+"."+act+".gif");
                 sprites.put(ch+"."+act,img);
             }
         }else{
             img = (BufferedImage)sprites.get(ch+"."+act+".left");
             if(img == null){
                 img = loadImage(ch+"."+act+".left.gif");
                 sprites.put(ch+"."+act+".left", img);
             }
         }
         return img;
     }

    private void drawPlayers(Graphics g) {
        for(int i = 0; i<numberOfPlayers-1; i++){
            BufferedImage img = null;
            Object[] plArr = (Object[]) players.get(i);
            Integer X = (Integer) plArr[0];
            Integer Y = (Integer) plArr[1];
            System.out.println(X + ", " + Y + ", " + plArr[2]);
            try{
                if(plArr[3].equals(1)){
                    img = getSprite(chara, (String) plArr[2], true);
                }else{
                    img = getSprite(chara, (String) plArr[2], false);
                }

            }catch(Exception ex){
                    System.out.println("Grafik konnte nicht geladen werden: "+ ex);
            }

            try{
                g.drawImage(img, X+(img.getWidth()/2), Y+(img.getHeight()/2),null);
            }catch(Exception ex){
                System.out.println("Fehler beim erstellen des Grafikobjekts: " + ex);
            }
            finally{
                g.dispose();
            }
        }
    }

    //Threads für die verschiedenen Bewegungen der Spielfigur

    private class moveUpThread extends Thread {

        @Override
        public void run(){
            while(true){
                if(!breakUp){
                    lastAction = action;
                    action = "move1";
                    while(sUp<5){
                        posY = posY-2;
                        sUp++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sUp = 0;
                }

                if(!breakUp){
                    action = "move2";
                    while(sUp<5){
                       posY = posY-2;
                       sUp++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sUp = 0;
                }
                if(!breakUp){
                    action = "move3";
                    while(sUp<5){
                       posY = posY-2;
                       sUp++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sUp = 0;
                }
                if(!breakUp){
                    action = "stand";
                    while(sUp<5){
                      posY = posY-2;
                      sUp++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sUp = 0;
                }
                try{
                    Thread.sleep(SPEED);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    private class moveDownThread extends Thread{
        @Override
        public void run(){
            while(true){
                if(!breakDown){
                    lastAction = action;
                    action = "move1";
                    while(sDown<5){
                        posY = posY+2;
                        sDown++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sDown = 0;
                }

                if(!breakDown){
                    action = "move2";
                    while(sDown<5){
                       posY = posY+2;
                       sDown++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sDown = 0;
                }
                    
                if(!breakDown){
                    action = "move3";
                    while(sDown<5){
                       posY = posY+2;
                       sDown++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sDown = 0;
                }
                   
                if(!breakDown){
                    action = "stand";
                    while(sDown<5){
                      posY = posY+2;
                      sDown++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sDown = 0;
                }
                try {
                    Thread.sleep(SPEED);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                }
            
            }
        }
    }   

    private class moveRightThread extends Thread{
        @Override
        public void run(){
            
            while(true){
                if(!breakRight){
                    lastAction = action;
                    action = "move1";
                    while(sRight<5){
                        posX = posX+2;
                        sRight++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sRight = 0;
                }

                if(!breakRight){
                    action = "move2";
                    while(sRight<5){
                       posX = posX+2;
                       sRight++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sRight = 0;
                }
                if(!breakRight){
                    action = "move3";
                    while(sRight<5){
                       posX = posX+2;
                       sRight++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sRight = 0;
                }
                if(!breakRight){
                    action = "stand";
                    while(sRight<5){
                      posX = posX+2;
                      sRight++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sRight = 0;
                }
                try {
                    Thread.sleep(SPEED);
                } catch (InterruptedException ex) {
                    Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        }
    }

    private class moveLeftThread extends Thread{
        @Override
        public void run(){
            while(true){
                if(!breakLeft){
                    lastAction = action;
                    action = "move1";
                    while(sLeft<5){
                        posX = posX-2;
                        sLeft++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sLeft = 0;
                }

                if(!breakLeft){
                    action = "move2";
                    while(sLeft<5){
                       posX = posX-2;
                       sLeft++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sLeft = 0;
                }
                if(!breakLeft){
                    action = "move3";
                    while(sLeft<5){
                       posX = posX-2;
                       sLeft++;
                        try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sLeft = 0;
                }
                if(!breakLeft){
                    action = "stand";
                    while(sLeft<5){
                      posX = posX-2;
                      sLeft++;
                      try {
                            Thread.sleep(SPEED);
                        } catch (InterruptedException ex) {
                            Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                        }
                    }
                    sLeft = 0;
                }
                try {
                        Thread.sleep(SPEED);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
            
        }
    }

    private class sAttackThread extends Thread{
        public void run(){
            while(true){
                if(sAtk){
                    lastAction = action;
                    for(int i = 1; i<=3; i++){
                        action= "sAttack"+i;
                        try {
                                Thread.sleep(4*SPEED);
                            } catch (InterruptedException ex) {
                                Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                            }
                    }
                    action = "stand";
                    attacking = false;
                    sAtk = false;
                }
                try {
                        Thread.sleep(10*SPEED);
                    } catch (InterruptedException ex) {
                        Logger.getLogger(JLF.class.getName()).log(Level.SEVERE, null, ex);
                }
            }



        }
    }

    public void breakAll() {
        breakUp = true;
        breakDown = true;
        breakLeft = true;
        breakRight = true;
    }
    //Erforderliche Methoden zur Tastatursteuerung
    public void keyTyped(KeyEvent e) {
    }

    public void keyPressed(KeyEvent e) {
        if(!moving&&!attacking){
            if(e.getKeyCode()== up){
                breakUp = false;
                moving = true;
            }

            if(e.getKeyCode()== down){
                breakDown = false;
                moving = true;
            }

            if(e.getKeyCode()== right){
                breakRight = false;
                dRight = true;
                moving = true;
            }

            if(e.getKeyCode()== left){
                breakLeft = false;
                dRight = false;
                moving = true;
            }
        }
        if(e.getKeyCode()==attack){
            breakAll();
            attacking = true;
            sAtk = true;
        }
    }

    public void keyReleased(KeyEvent e) {
        if(e.getKeyCode()==up){
            action = "stand";
            moving = false;
            breakUp = true;

        }
        if(e.getKeyCode()==down){
            action = "stand";
            moving = false;
            breakDown = true;

        }
        if(e.getKeyCode()==left){
            action = "stand";
            moving = false;
            breakLeft = true;
        }
        if(e.getKeyCode()==right){
            action = "stand";
            moving = false;
            breakRight = true;
        }

    }

   public static void main(String[] args){
        new JLF();
    }
}
```

(Server im nächsten Post)


----------



## JLF Entwickler (9. Nov 2009)

```
package Server;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.RandomAccessFile;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

public class JLFServer {
    private final int PORT = 1991;
    private boolean stop = false;
    final int SPEED = 20;
    int numberOfClients = 0;
    RandomAccessFile file = null;
    //Speichert die Daten jedes Clients, pro Feld in der Array-List ein Client
    ArrayList clients = new ArrayList();


    //Konstruktor
    public JLFServer() throws IOException{
        try{
            file = new RandomAccessFile("users.txt", "r");
        }catch(FileNotFoundException ex){
            System.out.println("Fehler beim öffnen der Datein users.txt: " + ex);
        }
        ServerSocket server = new ServerSocket(PORT);
        System.out.println("Server service started.");
        //Endlosschleife
        while(!stop){
            /*Akzeptieren des Clients und erstellen eines Threads, um den Hauptthread freizuhalten zum
            Annehmen weiterer Clients.*/
            Socket cl = server.accept();
            numberOfClients++;
            //Object[] wird in die Array-List gespeichert
            Object[] pl = new Object[5];
            pl[0] = cl;
            clients.add(pl);
            System.out.println(cl.getInetAddress()+" nimmt Verbindung zum Server auf.");
            Thread cT = new ClientThread(cl, numberOfClients-1);
            cT.start();
        }
        System.exit(0);
    }

    public class ClientThread extends Thread{
        private Socket client;
        public String character;
        public int pX;
        public int pY;
        public boolean dRight;
        public String action;
        public String name;
        public int range;
        public int maxLife;
        public int dmg;
        public int defense;
        private String pw;
        private int number;

        public ClientThread(Socket c, int n){
            this.client = c;
            this.number = n;
        }

        @Override
        public void run(){
            Object[] pl = (Object[]) clients.get(number);
            /*pl[1] = pX;
            pl[2] = pY;
            pl[3] = action;
            pl[4] = dRight;*/
            String message;
            try {
                PrintWriter writer = new PrintWriter(client.getOutputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                message = reader.readLine();
                System.out.println("User: " + message);
                if(message.startsWith("LOGIN")){
                    String[] splittedMessage = message.split(" ");
                    name = splittedMessage[1];

                    pw = splittedMessage[2];
                    if (isUser(splittedMessage[1])&&correctPW(splittedMessage[2],splittedMessage[1])) {
                        writer.println("accepted");
                        System.out.println("accepted");
                        writer.flush();
                    }else{
                        writer.println("refused");
                        writer.flush();
                    }
                }else if (message.startsWith("CREATE_USER")){

                }else{
                }
                try{
                    getData();
                }catch(Exception ex){
                    System.out.println("Fehler beim Einlesen der Userdaten von " + name + ": " + ex);
                }
                
                while((message = reader.readLine())!=null){
                    String[] sarr = message.split(",");
                    pX = Integer.parseInt(sarr[0]);
                    pY = Integer.parseInt(sarr[1]);
                    action = sarr[2];
                    if(sarr[3].equals("1")){
                        dRight = true;
                    }else{
                        dRight = false;
                    }
                    pl[1] = pX;
                    pl[2] = pY;
                    pl[3] = action;
                    pl[4] = dRight;
                    sendPlayerpos(writer);
                }
                Thread.yield();
                numberOfClients--;

            } catch (IOException ex) {
                Logger.getLogger(JLFServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }
        
        private void getData() throws IOException{
            RandomAccessFile file = null;
            String line;
            try{
                file = new RandomAccessFile("users.txt", "r");
            }catch(FileNotFoundException ex){
                System.out.println("Fehler beim Oeffnen der Datei users.txt: " + ex);
            }

            while ((line=file.readLine())!=null){
                String[] splittedLine = line.split(" ");
                if(splittedLine[0].equals(name)&&splittedLine[1].equals(pw)){
                    range = Integer.parseInt(splittedLine[2]);
                    maxLife = Integer.parseInt(splittedLine[3]);
                    dmg = Integer.parseInt(splittedLine[4]);
                    defense = Integer.parseInt(splittedLine[5]);
                    break;
                }
            }
        }

        private void sendPlayerpos(PrintWriter w) {
            w.println(numberOfClients);
            w.flush();
            for(int i = 0; i < numberOfClients; i++){
                if(i!=number){
                    Object[] plArr = (Object[]) clients.get(i);
                    if(plArr[4].equals(true)){
                        w.println(plArr[1] + "," + plArr[2] + "," + plArr[3] + ",1");
                    }else{
                        w.println(plArr[1] + "," + plArr[2] + "," + plArr[3] + ",0");
                    }
                    w.flush();
                }
            }
        }

        private boolean correctPW(String pw,String username) throws IOException {
                RandomAccessFile file = null;
                String line;
                try{
                    file = new RandomAccessFile("users.txt", "r");
                }catch(FileNotFoundException ex){
                    System.out.println("Fehler beim öffnen der Datein users.txt: " + ex);
                }
                //line = file.readLine();
                boolean rtn = false;
                while ((line=file.readLine())!=null){
                    String[] splittedLine = line.split(" ");
                    if(splittedLine[0].equals(username)&&splittedLine[1].equals(pw)){
                        rtn = true;
                        break;
                    }
                }
                return rtn;
        }

        private boolean isUser(String username) throws IOException{
                RandomAccessFile file = null;
                String line;
                try{
                    file = new RandomAccessFile("users.txt", "r");
                }catch(FileNotFoundException ex){
                    System.out.println("Fehler beim öffnen der Datein users.txt: " + ex);
                }
                //line = file.readLine();
                boolean rtn = false;
                while ((line=file.readLine())!=null){
                    String[] splittedLine = line.split(" ");
                    if(splittedLine[0].equals(username)){
                        rtn = true;
                        break;
                    }
                }
                return rtn;
            }

    }




    public static void main(String[] args){
        try {
            new JLFServer();
        } catch (IOException ex) {
            Logger.getLogger(JLFServer.class.getName()).log(Level.SEVERE, null, ex);
        }
    }
}
```

Code war zu lang...


----------



## hdi (10. Nov 2009)

Glaubst du echt, dass sich jemand 881 Zeilen Code ansieht? Ich drück dir die Daumen 
Wie wäre es wenn du das Problem soweit lokalisierst, dass du nur noch die nötigen Code-Ausschnitte posten musst...
zB interessiert niemanden wie hoch die Hitpoints oder die Defense von irgendeinem Spieler sind, das hat ja wohl nix mit Netzwerk zu tun.

edit:


> Auch sonstige kleinere Ansätze zum verbessern des Codes sind willkommen.


Ich hab grad deine Move- und Attack Threads gesehen... Das ganze Spiel sollte von *einem *Thread gesteuert werden.


----------



## JLF Entwickler (10. Nov 2009)

Du hast natürlich recht ich sollte das wirklich machen.

Also beim Client mache ich eigentlich folgendes 
	
	
	
	





```
//Kommunikation mit Server
    final String SERVER = "localhost";
    final int PORT = 1991;
    Socket s;
    PrintWriter writer;
    BufferedReader reader;
    StringBuffer ServerMessage;
.
.
.
    public JLF(){
//Serverkommunikation
        ...
            s = new Socket(SERVER, PORT);
        ...
        
            writer = new PrintWriter(s.getOutputStream());
            reader = new BufferedReader(new InputStreamReader(s.getInputStream()));
        ...
        //Login beim Server, um in zweiten Se
        writer.println("LOGIN Test Testpw");
        writer.flush();
}
...
//Hauptloop des Spiels
    public void game(){
        String input="";
        while(true){
            //Ausgabe
            if(dRight){
                writer.println(posX + "," + posY + "," + action + ",1");
            }else{
                writer.println(posX + "," + posY + "," + action + ",0");
            }
            writer.flush();

            //Eingabe
            try {
                input = reader.readLine();
                oldNumberOfPlayers = numberOfPlayers;
                numberOfPlayers = Integer.parseInt(input);
                if(numberOfPlayers > oldNumberOfPlayers){
                    Object[] pl = new Object[4];
                    players.add(pl);
                }
                int k = 0;
                String[] playerMessages = new String[numberOfPlayers-1];
                while(k < numberOfPlayers-1){
                    playerMessages[k] = reader.readLine();
                    String[] splitted = playerMessages[k].split(",");
                    Object[] pl = (Object[]) players.get(k);
                    pl[0] = Integer.parseInt(splitted[0]);
                    pl[1] = Integer.parseInt(splitted[1]);
                    pl[2] = splitted[2];
                    pl[3] = Integer.parseInt(splitted[3]);
                    k++;
                }

           ...

            draw();

            ...
        }
    }

//Stellt die Umgebung dar
    private void draw(){
        //bf ist die bufferStrategy, die ich benutze
        Graphics g = bf.getDrawGraphics();
        g.clearRect(0, 0, BREITE, HOEHE);
        BufferedImage img = null;
        ...
            img = getSprite(chara, action, dRight);
        ...
            g.drawImage(img, posX+(img.getWidth()/2), posY+(img.getHeight()/2),null);
        ...

        drawPlayers(g);

        bf.show();

        Toolkit.getDefaultToolkit().sync();
    }

    //Lädt das Bild
    public BufferedImage loadImage(String name) {
        BufferedImage image;
        try {
             image = ImageIO.read(new File(name));
             return image;
        } catch (Exception e) {
            System.out.println(name +" konnte nicht geoeffnet werden.");
            System.out.println("Fehler: "+e.getClass().getName()+" "+e.getMessage());
            return null;
        }
     }

    //Gibt das benötigte Bild zurück
    //Wenn das Bild noch nicht geladen wurde, wird es geladen und zwischengespeichert
    public BufferedImage getSprite(String ch, String act, Boolean directionRight){
         BufferedImage img;
         if(directionRight){
             img = (BufferedImage)sprites.get(ch+"."+act);
             if (img == null) {
                 img = loadImage(ch+"."+act+".gif");
                 sprites.put(ch+"."+act,img);
             }
         }else{
             img = (BufferedImage)sprites.get(ch+"."+act+".left");
             if(img == null){
                 img = loadImage(ch+"."+act+".left.gif");
                 sprites.put(ch+"."+act+".left", img);
             }
         }
         return img;
     }

    private void drawPlayers(Graphics g) {
        for(int i = 0; i<numberOfPlayers-1; i++){
            BufferedImage img = null;
            Object[] plArr = (Object[]) players.get(i);
            Integer X = (Integer) plArr[0];
            Integer Y = (Integer) plArr[1];
            System.out.println(X + ", " + Y + ", " + plArr[2]);
            ...
                if(plArr[3].equals(1)){
                    img = getSprite(chara, (String) plArr[2], true);
                }else{
                    img = getSprite(chara, (String) plArr[2], false);
                }

           ...
                g.drawImage(img, X+(img.getWidth()/2), Y+(img.getHeight()/2),null);
            ...
            
        }
    }
```
Da ich auch Grafikprobleme (vielleicht) habe, habe ich jetzt auch das Laden der Grafiken gepostet.

Das Problem kann auch beim Server im ClientThread liegen.

```
public class ClientThread extends Thread{
        private Socket client;
        public String character;
        public int pX;
        public int pY;
        public boolean dRight;
        public String action;
        public String name;
        private String pw;
        private int number;

        public ClientThread(Socket c, int n){
            this.client = c;
            this.number = n;
        }

        @Override
        public void run(){
            Object[] pl = (Object[]) clients.get(number);
            String message;
            try {
                PrintWriter writer = new PrintWriter(client.getOutputStream());
                BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
                message = reader.readLine();
                System.out.println("User: " + message);
                if(message.startsWith("LOGIN")){
                    String[] splittedMessage = message.split(" ");
                    name = splittedMessage[1];

                    pw = splittedMessage[2];
                    if (isUser(splittedMessage[1])&&correctPW(splittedMessage[2],splittedMessage[1])) {
                        writer.println("accepted");
                        System.out.println("accepted");
                        writer.flush();
                    }else{
                        writer.println("refused");
                        writer.flush();
                    }
                }else if (message.startsWith("CREATE_USER")){

                }else{
                }
                try{
                    getData();
                }catch(Exception ex){
                    System.out.println("Fehler beim Einlesen der Userdaten von " + name + ": " + ex);
                }
                
                while((message = reader.readLine())!=null){
                    String[] sarr = message.split(",");
                    pX = Integer.parseInt(sarr[0]);
                    pY = Integer.parseInt(sarr[1]);
                    action = sarr[2];
                    if(sarr[3].equals("1")){
                        dRight = true;
                    }else{
                        dRight = false;
                    }
                    pl[1] = pX;
                    pl[2] = pY;
                    pl[3] = action;
                    pl[4] = dRight;
                    sendPlayerpos(writer);
                }
                Thread.yield();
                numberOfClients--;

            } catch (IOException ex) {
                Logger.getLogger(JLFServer.class.getName()).log(Level.SEVERE, null, ex);
            }
        }

private void sendPlayerpos(PrintWriter w) {
            w.println(numberOfClients);
            w.flush();
            for(int i = 0; i < numberOfClients; i++){
                if(i!=number){
                    Object[] plArr = (Object[]) clients.get(i);
                    if(plArr[4].equals(true)){
                        w.println(plArr[1] + "," + plArr[2] + "," + plArr[3] + ",1");
                    }else{
                        w.println(plArr[1] + "," + plArr[2] + "," + plArr[3] + ",0");
                    }
                    w.flush();
                }
            }
        }
```

Mein Protokoll zur Kommunikation ist so gedacht, dass zuerst ein LOGIN gesendet werden muss, danach wird vom Client immer seine Position, Aktion und Richtung (also die Richtung in die er schaut) gesendet, worauf ihm der Server mit den Positionen, Aktionen und Richtungen aller anderen Clients antwortet.
Vielleicht schreibe ich heute Abend noch mehr hier rein.


----------

