# Java 2d translation() fehler



## Derok (2. Apr 2009)

Hey, also hab folgendes Problem, bei einem Projekt mit 3weiteren Personen ein mmorpg zu programmieren bin ich nun doch mal auf ein hinderniss gestoßen.
Der Fehler liegt in der Klasse Player, in der methode paintp die alle 40ms von einem Thread aufgerufen wird, allerdings wird vor paintp die methode move aufgerufen.
Die methoden kup, kleft usw werden von der Main klasse mit einem Tastaturlistener aufgerufen.
So das zum Programm.



```
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.*;
import javax.imageio.ImageIO;

/**
 *
 * @author Derok
 */
public class Player
{
    private int id, richtung=1, ypos, xpos, hpmax, hpmom, ts1, ts2;
    private int xschritt, xschritt2;
    private int yschritt, yschritt2;
    private boolean windows=false, collside = false, collside2 = false;
    private boolean left = false, right = false, up = false, down = false, aktive=false;
    private Main client;
    private Interface face;
    private WeltThread welt;
    private House1 house1;
    private MobThread mobs;
    private collision collis;
    private Image Spieler1, Spieler2, Spieler3, Spieler4, 
            Spieler5, Spieler6, Spieler7, Spieler8;
    private BufferedImage collpic;
    private int collpixel;
    Player(WeltThread welt, Interface face, MobThread mobs, House1 house, Main client)
    {
        collis = new collision();
        this.client = client;
        this.welt = welt;
        this.face = face;
        this.house1 = house;
        this.mobs = mobs;
        try {
            collpic = ImageIO.read(new File("./build/Bilder/wasser1.bmp"));
        } catch (IOException ex) {
            Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
        }
        Spieler1 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler.png");
        Spieler2 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler1.png");
        Spieler3 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler2.png");
        Spieler4 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler3.png");
        Spieler5 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler4.png");
        Spieler6 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler5.png");
        Spieler7 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler6.png");
        Spieler8 = Toolkit.getDefaultToolkit().getImage("./build/Bilder/Spieler7.png");
    }
    void position(int x, int y, boolean aktive)
    {
        xpos = x;
        ypos = y;
        this.aktive = aktive;
    }
    void setid(int i)
    {
        id = i;
    }
    void kleft(boolean a)
    {
        left = a;
    }
    void kright(boolean a)
    {
        right = a;
    }
    void kup(boolean a)
    {
        up = a;
    }
    void kdown(boolean a)
    {
        down = a;
    }
    void move()
    {
        if(left==true)
        {
            xschritt=-4;
            xschritt2=4;
            richtung=7;           
            
        }
        if(right==true)
        {
            xschritt= 4;
            xschritt2=-4;
            richtung=3;
        }
        if(up==true)
        {
            yschritt =-4;
            yschritt2= 4;
            richtung=1;
        }
        if(down==true)
        {
            yschritt= 4;
            yschritt2=-4;
            richtung=5;
        } 
        if(left==true&up==true)
        {
            xschritt=-3;
            yschritt=-3;
            xschritt2=3;
            yschritt2=3;
            richtung=8;
        }
        if(left==true&down==true)
        {
            xschritt=-3;
            yschritt=3;
            xschritt2=3;
            yschritt2=-3;
            richtung=6;
        }  
        if(right==true&up==true)
        {
            xschritt=3;
            yschritt=-3;
            xschritt2=-3;
            yschritt2=3;
            richtung=2;
        }  
        if(right==true&down==true)
        {
            xschritt=3;
            yschritt=3;
            xschritt2=-3;
            yschritt2=-3;
            richtung=4;
        }
        
        collpixel = collpic.getRGB(xpos+xschritt+550, ypos+yschritt+420);
        if(collpixel<-1)
        {
            collside=true;
        }
        if(collside==false)
        {
            collside = collis.collisiontestobejct(xpos+xschritt, ypos+yschritt, 30, 30, house1.getxpos(), 
                house1.getypos(), house1.getbreite(), house1.gethoehe());
        }
        if(collside==false)
        {
            collside = collis.collisiontestobejct(xpos+xschritt, ypos+yschritt, 30, 30, mobs.getxpos(), 
                mobs.getypos(), mobs.getbreite(), mobs.gethoehe());
        }
        if(collside==true)
        {
            if(collis.collisiontestobejct(xpos+xschritt, ypos, 30, 30, house1.getxpos(), 
                house1.getypos(), house1.getbreite(), house1.gethoehe())==true)
            {
                ypos += yschritt;
                ts1 = 1;
            }
            if(collis.collisiontestobejct(xpos, ypos+yschritt, 30, 30, house1.getxpos(), 
                house1.getypos(), house1.getbreite(), house1.gethoehe())==true)
            {
                xpos += xschritt;
                ts2 = 1;
            }
            
        }
        else
        {
            xpos += xschritt;
            ypos += yschritt;
            ts1 = 0;
            ts2 = 0;
            
        }
        face.setpos(xpos, ypos);
        welt.setpos(xpos, ypos, richtung, aktive);
        xschritt=0;
        yschritt=0;
        collside2 = collside;
        collside = false;
    }
    void windows()
    {
        windows=true;
    }

    int positionx()
    {
        return xpos;
    }
    void paintp(Graphics g)
    {
        Graphics2D g2 = (Graphics2D) g;
        if(aktive==true)
        {
        if(windows==true)
        {
            g2translate(-xpos, -ypos);
            g2.translate(512, 384);
            windows=false;
        }

            if(collside2==true)
            {
                if(ts1==1)
                {
                    g2.translate(0, yschritt2);
                    
                }
                if(ts2==1)
                {
                    g2.translate(xschritt2, 0);
                }
            }
            else
            {
                g2.translate(xschritt2, yschritt2);
            }
            xschritt2=0;
            yschritt2=0;
            collside2=false;
        g2.setColor(Color.black);
        switch(richtung)
        {
                case 1:
                g2.drawImage(Spieler1, xpos-5, ypos-5, client); break;
                case 2:
                g2.drawImage(Spieler2, xpos-5, ypos-5, client); break;
                case 3:
                g2.drawImage(Spieler3, xpos-5, ypos-5, client); break; 
                case 4:
                g2.drawImage(Spieler4, xpos-5, ypos-5, client); break; 
                case 5:
                g2.drawImage(Spieler5, xpos-5, ypos-5, client); break; 
                case 6:
                g2.drawImage(Spieler6, xpos-5, ypos-5, client); break; 
                case 7:
                g2.drawImage(Spieler7, xpos-5, ypos-5, client); break; 
                case 8:
                g2.drawImage(Spieler8, xpos-5, ypos-5, client); break; 
        }
        }
    }
}
```
Mein genaues Problem liegt im folgenden bereich:

```
if(windows==true)
        {
            g2.translate(-xpos, -ypos);
            g2.translate(512, 384);
            windows=false;
        }
```
Dies soll dafür sein, das, sobald sich der spieler eingeloggt hat und die xpos und ypos vom server erhalten hat, sich der spieler immer zentral vom fenster befindet.
Funktioniert soweit alles, debugger sagt auch immer das gleiche bei jedem start nur was ich nicht verstehe und woran ich seit 4 Tagen hänge, ist das es eine ca 50% chance gibt das dieser translate befehl nicht mein fenster versetzt, obwohl der debugger sagt das er es macht (ausprobiert durch an gleicher position stehen und client öfters starten und debugger spuckt immer das gleiche aus).

Weiß jemand was da sein könnte? wie gesagt ich bin ratlos und weiß nichtmehr weiter. Im internet habe ich dazu leider auch nichts gefunden 
Bei anderen PCs ist es genau das gleiche



MFG Stefan


----------



## 0x7F800000 (3. Apr 2009)

Derok hat gesagt.:


> Hey, also hab folgendes Problem, bei einem Projekt mit 3weiteren Personen ein mmorpg zu programmieren bin ich nun doch mal auf ein hinderniss gestoßen.


ihr leute müsst ja wohl echt hard druf sein... 4 Leute die ohne jegliche Konventionen ein MMORPG proggen? na da bin ich mal auf das Ergebnis gespannt...
Also ehrlich, wie kommt man auf die Idee im gemischen Englisch-Denglisch ("kleft","yshritt2","MobThread") mit Rechtschreibfehlern ("obejct") ohne CamelCase ("collisiontestobejct") mit gröbsten Missachtungen von Groß-Kleinschreibung ("class collision"), und auch noch dermaßen gemeingefährlichen Klassennamen wie "Interface" zuviert ein Spiel zu programmieren? ;noe:
Guten Tipp: wirft mal eure IDE's an, und refactort erstmal 2-3 Tage... :autsch:

Außerdem: wenn man merkt, dass man irgendwelchen quatsch wie vier gleichartige if's hintereinander schreiben muss, da muss doch einem auffallen, dass da etwas schief läuft... Tue dir selbst einen gefallen, überleg dir nochmal anders, wie du das mit collisionen regelst 



> allerdings wird vor paintp die methode move aufgerufen


click-das hört sich nach viel Ärger an...

Was das eigentliche Problem angeht:
Ich würde mal spontan vermuten, dass dieser Ausschnitt den du gepostet hast nichts mit dem Problem zu tun hat. Sieht viel mehr danach aus, dass sich die Threads irgendwo beißen, aber gerade davon ist in diesem Code-ausschnitt nichts zu sehen...


----------



## Derok (3. Apr 2009)

also naja das mit stil, liegt wohl eher daran das wir selber erst seit 1 1/2 jahre java von der schule aus programmieren und unser lehrer kein plan von nix hat... aber naja eine entschuldigung ist das nicht

ehm zum eigentlichen die move methode wird vom gleichen Thread wie die repaint methode aufgerufen, zuerst die move methode und dann repaint, von der repaint aus wird das paintg aufgerufen, was eigentlich klar sein sollte.

Daher gibt es eigentlich da nach meinen wissen keine probleme.


Aber werde mal deinen Rat befolgen und mal die klassen alle ausbessern


----------



## 0x7F800000 (3. Apr 2009)

Derok hat gesagt.:


> also naja das mit stil, liegt wohl eher daran das wir selber erst seit 1 1/2 jahre java von der schule aus programmieren und unser lehrer kein plan von nix hat... aber naja eine entschuldigung ist das nicht


Nja... Lehrer? Lieber Bücher lesen... 



> ehm zum eigentlichen die move methode wird vom gleichen Thread wie die repaint methode aufgerufen, zuerst die move methode und dann repaint, von der repaint aus wird das paintg aufgerufen, was eigentlich klar sein sollte.


Das hört sich schon etwas vernünftiger an. Aber repaint kann ja auch vom AWT-Thread aufgerufen werden, wann das passiert könnt ihr aus den anderen Threads ja nicht wirklich beeinflussen... deswegen meine ich eben, dass sich da wohl irgendwo die threads beißen... Wenn irgendetwas ohne java.util.Random() oder System.currentTimeMillis() nicht deterministisch abläuft, müssen es die Threads oder irgendwelche Informationen aus der Außenwelt sein, ansonsten kann es zu keinen scheinbar zufälligen ergebnissen kommen.



> Aber werde mal deinen Rat befolgen und mal die klassen alle ausbessern


Da merkst du selbst, dass es wesentlich leichter zu lesen sein wird... 
Aber jetzt nicht hingehen und alles per Hand umschreiben, IDE's können da schon ein bisschen mehr


----------



## Marco13 (3. Apr 2009)

Um das noch mal zu bekräftigen: Wenn der "Player" (welche Aufgabe der auch immer hat: Von Steuerung über Kollisionserkennung bis painting wohl von allem etwas :autsch: ) schon im Konstruktor zwei Dinge übergeben bekommt, die (zumindest dem Namen nach) Threads sind, dann werden im übrigen Programm mit an Sicherheit grenzenden Wahrscheinlichkeit noch einige (andere) Thread-bezogene Schnitzer drin sein...


----------

