# Java Tetris



## Utopia (27. Jan 2012)

Guten Abend,

ich bin gerade dabei, Tetris in Java zu programmieren oder zumindest es zu versuchen, was wohl nicht funktioniert. In meiner Grafischen Oberfläche wird das Feld mit den Steinen nicht angezeigt und ich kann den Fehler einfach nicht finden, weil es sogar läuft, nur eben nichts anzeigt. Hoffe mir kann jemand weiterhelfen. Es sind insgesamt vier Dateien:


```
package tetris;

public class Spielstein {
  
  public int farbcode;
  public int x1;
  public int y1;
  public int x2;
  public int y2;
  public int x3;
  public int y3;
  public int x4;
  public int y4;

  /**
   * 
   */
  public Spielstein(int i) {
            switch (i) {
                case 1:
                    //Rechtes L
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 1;
                    x3 = 7; y3 = 3;
                    x4 = 8; y4 = 3;
                    farbcode = 1;
                break;
                case 2:
                    //Linkes L
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 1;
                    x3 = 7; y3 = 3;
                    x4 = 6; y4 = 3;
                    farbcode = 2;
                break;
                case 3:
                    //Quadrat
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 3;
                    x3 = 8; y3 = 2;
                    x4 = 8; y3 = 3;
                    farbcode = 3;
                break;
                case 4:
                    //Dreieck
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 1;
                    x3 = 6; y3 = 2;
                    x4 = 8; y4 = 2;
                    farbcode = 4;
                break;
                case 5:
                    //Reihe
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 1;
                    x3 = 7; y3 = 3;
                    x4 = 7; y4 = 4;
                    farbcode = 5;
                break;
                case 6:
                    //Rechtes Parallelogramm
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 1;
                    x3 = 8; y3 = 1;
                    x4 = 6; y4 = 2;
                    farbcode = 6;
                break;
                case 7:
                    //Linkes Parallelogramm
                    x1 = 7; y1 = 2;
                    x2 = 7; y2 = 1;
                    x3 = 8; y3 = 2;
                    y4 = 6; y4 = 1;
                    farbcode = 7;
                break;   
            }        
  }
  
  public void verschieben(int x, int y){
            x1 = x1+x;
            y1 = y1+y;
            x2 = x2+x;
            y2 = y2+y;
            x3 = x3+x;
            y3 = y3+y;
            x4 = x4+x;
            y4 = y4+y;
  }
  
  int xKoordDrehen(int y){
            return x1 + y - y1;
  }
  
  int yKoordDrehen(int x){
            return y1 - x + x1;
  }
  
  public void drehen(){
            int x,y;
            x = xKoordDrehen(y2);
            y = yKoordDrehen(x2);
            x2 = x;
            y2 = y;
            x = xKoordDrehen(y1);
            y = yKoordDrehen(x1);
            x1 = x;
            y1 = y;
            x = xKoordDrehen(y3);
            y = yKoordDrehen(x3);
            x3 = x;
            y3 = y;
            x = xKoordDrehen(y4);
            y = yKoordDrehen(x4);
            x4 = x;
            y4 = y;
  }
        
        public Spielstein kopie(){
            Spielstein KlonSpielstein = new Spielstein(farbcode);
            return KlonSpielstein;
        }

}
```


```
package tetris;

public class Spielfeld {

  public int xmax = 16;
  public int ymax = 30;
  public int[][] feld = new int[xmax+2][ymax+2];
  public int punkte;
  public Spielstein aktSpielstein = new Spielstein((int)(Math.random()*6+1));
  public SpielfeldCanvas einSpielfeldCanvas = new SpielfeldCanvas(this);
  
  /**
   * 
   */
  public Spielfeld() {

  }
  
  private void loeschen(Spielstein einSpielstein){
            feld[einSpielstein.x1][einSpielstein.y1] = 0;
            feld[einSpielstein.x2][einSpielstein.y2] = 0;
            feld[einSpielstein.x3][einSpielstein.y3] = 0;
            feld[einSpielstein.x4][einSpielstein.y4] = 0;
            einSpielfeldCanvas.zeichneSpielstein(einSpielstein, 0);
  }
  
  private void setzen(Spielstein einSpielstein){
            feld[einSpielstein.x1][einSpielstein.y1] = einSpielstein.farbcode;
            feld[einSpielstein.x2][einSpielstein.y2] = einSpielstein.farbcode;
            feld[einSpielstein.x3][einSpielstein.y3] = einSpielstein.farbcode;
            feld[einSpielstein.x4][einSpielstein.y4] = einSpielstein.farbcode;
            einSpielfeldCanvas.zeichneSpielstein(einSpielstein, einSpielstein.farbcode);
  }
  
  private void verschieben(Spielstein einSpielstein, int x, int y){
            if(verschiebbar(einSpielstein, x, y) == true){
                loeschen(einSpielstein);
                einSpielstein.verschieben(x, y);
                setzen(einSpielstein);
            }  
  }
  
  private void ablegen(Spielstein einSpielstein){
            einSpielstein.farbcode = einSpielstein.farbcode + 8;
            setzen(einSpielstein);
  }
  
  private boolean verschiebbar(Spielstein einSpielstein, int x, int y){
            Spielstein verschobenerSpielstein = einSpielstein.kopie();
            verschobenerSpielstein.verschieben(x, y);
            return setzbar(verschobenerSpielstein);
  }
  
  private boolean drehbar(Spielstein einSpielstein){
            Spielstein verschobenerSpielstein = einSpielstein.kopie();
            verschobenerSpielstein.drehen();
            return setzbar(verschobenerSpielstein);
  }
  
  private void drehen(Spielstein einSpielstein, int x, int y){
            if(drehbar(einSpielstein) == true){
                loeschen(einSpielstein);
                einSpielstein.drehen();
                setzen(einSpielstein);
            }  
  }
  
  private boolean setzbar(Spielstein s){
            int f = aktSpielstein.farbcode;
            return (feld[s.x1][s.y1] == f || feld[s.x1][s.y1] == 0) &&
                   (feld[s.x2][s.y2] == f || feld[s.x2][s.y2] == 0) &&
                   (feld[s.x3][s.y3] == f || feld[s.x3][s.y3] == 0) &&
                   (feld[s.x4][s.y4] == f || feld[s.x4][s.y4] == 0);
  }
  
  private void neuerSpielstein(){
            this.aktSpielstein = new Spielstein((int)(Math.random()*6+1));
  }
  
  public void nach_unten(){
            if (verschiebbar(aktSpielstein, 0, 1)) {
                verschieben(aktSpielstein, 0, 1);
            }
  }
  
  public void fallen(){
            while(verschiebbar(aktSpielstein, 0, 1)){
                nach_unten();
            }
  }
  
  public void nach_links(){
            if (verschiebbar(aktSpielstein, -1, 0)) {
                verschieben(aktSpielstein, -1, 0);
            }
  }
  
  public void nach_rechts(){
            if (verschiebbar(aktSpielstein, 1, 0)) {
                verschieben(aktSpielstein, 1, 0);
            }
  }
  
  public void drehen_public(){
            if(drehbar(aktSpielstein) == true){
                loeschen(aktSpielstein);
                aktSpielstein.drehen();
                setzen(aktSpielstein);
            }  
  }
  
  public void neuerStein(){
            this.aktSpielstein = new Spielstein((int)(Math.random()*6+1));
  }

}
```


```
package tetris;

import java.awt.*;

public class SpielfeldCanvas extends Canvas{
    
        private int kbreite;
        private Spielfeld dasSpielfeld;

  /**
   * 
   */
  public SpielfeldCanvas(Spielfeld einSpielfeld) {
            dasSpielfeld = einSpielfeld;
            dasSpielfeld.einSpielfeldCanvas = this;
  }
        
        private Color codeToColor(int farbcode){
            Color farbe;
            if (farbcode > 7) {
                farbcode = farbcode - 8;
            }
            switch (farbcode) {
                case 0: farbe = Color.black;
                    break;
                case 1: farbe = new Color(230, 10, 0);
                    break;
                case 2: farbe = new Color(255, 235, 0);
                    break;
                case 3: farbe = new Color(10, 170, 10);
                    break;
                case 4: farbe = new Color(20, 140, 180);
                    break;
                case 5: farbe = new Color(255, 250, 210);
                    break;
                case 6: farbe = new Color(210, 50, 130);
                    break;
                case 7: farbe = Color.orange;
                    break;
                default:
                    farbe = Color.red;
            }
            return farbe;
        }
        
        public void paint(Graphics g){
            g.setColor(Color.red);
            for (int i = 0; i <= dasSpielfeld.xmax; i++) {
                g.drawLine(i * kbreite, 0, i * kbreite, dasSpielfeld.ymax * kbreite);
            }
            for (int j = 0; j <= dasSpielfeld.ymax; j++) {
                g.drawLine(0, j * kbreite, dasSpielfeld.xmax * kbreite, j * kbreite);
            }
            for (int i = 0; i < dasSpielfeld.xmax; i++ ) {
                for (int j = 0; j < dasSpielfeld.ymax; j++ ) {
                    Color farbe = codeToColor(dasSpielfeld.feld[i + 1][j + 1]);
                    g.setColor(farbe);
                    zeichneKaestchen(g, i, j);
                }
            }
        }
        
        private void zeichneKaestchen(Graphics g, int x, int y) {
            g.fillRect(x * kbreite + 1, y * kbreite + 1, kbreite - 1, kbreite - 1);
        }
        
        public void zeichneSpielstein(Spielstein einSpielstein, int farbcode) {
            Graphics g = getGraphics();
            g.setColor(codeToColor(farbcode));
            zeichneKaestchen(g, einSpielstein.x1 - 1, einSpielstein.y1 - 1);
            zeichneKaestchen(g, einSpielstein.x2 - 1, einSpielstein.y2 - 1);
            zeichneKaestchen(g, einSpielstein.x3 - 1, einSpielstein.y3 - 1);
            zeichneKaestchen(g, einSpielstein.x4 - 1, einSpielstein.y4 - 1);
        }
}
```


```
package tetris;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;

public class Tetris extends JFrame {
  // Anfang Attribute
  private JButton jBAnhalten = new JButton();
  private JButton jBWeiter = new JButton();
  private JButton jBStein = new JButton();
  private JButton jBDrehen = new JButton();
  private JButton jBLinks = new JButton();
  private JButton jBRechts = new JButton();
  private JButton jBUnten = new JButton();
  private JButton jBFallen = new JButton();
  private JButton jBStarten = new JButton();
  private JButton jBBeenden = new JButton();
  private Spielfeld einSpielfeld = new Spielfeld();
  private SpielfeldCanvas canvas1 = new SpielfeldCanvas(einSpielfeld);
  // Ende Attribute

  public Tetris(String title) {
    // Frame-Initialisierung
    super(title);
    setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
    int frameWidth = 603; 
    int frameHeight = 498;
    setSize(frameWidth, frameHeight);
    Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
    int x = (d.width - getSize().width) / 2;
    int y = (d.height - getSize().height) / 2;
    setLocation(x, y);
    setResizable(false);
    Container cp = getContentPane();
    cp.setLayout(null);
    // Anfang Komponenten

    jBAnhalten.setBounds(336, 256, 81, 25);
    jBAnhalten.setText("Anhalten");
    jBAnhalten.setMargin(new Insets(2, 2, 2, 2));
    jBAnhalten.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBAnhalten_ActionPerformed(evt);
      }
    });
    cp.add(jBAnhalten);
    jBWeiter.setBounds(424, 256, 81, 25);
    jBWeiter.setText("Weiter");
    jBWeiter.setMargin(new Insets(2, 2, 2, 2));
    jBWeiter.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBWeiter_ActionPerformed(evt);
      }
    });
    cp.add(jBWeiter);
    jBStein.setBounds(336, 288, 81, 25);
    jBStein.setText("Stein");
    jBStein.setMargin(new Insets(2, 2, 2, 2));
    jBStein.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBStein_ActionPerformed(evt);
      }
    });
    cp.add(jBStein);
    jBDrehen.setBounds(424, 288, 81, 25);
    jBDrehen.setText("Drehen");
    jBDrehen.setMargin(new Insets(2, 2, 2, 2));
    jBDrehen.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBDrehen_ActionPerformed(evt);
      }
    });
    cp.add(jBDrehen);
    jBLinks.setBounds(336, 320, 81, 25);
    jBLinks.setText("Links");
    jBLinks.setMargin(new Insets(2, 2, 2, 2));
    jBLinks.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBLinks_ActionPerformed(evt);
      }
    });
    cp.add(jBLinks);
    jBRechts.setBounds(424, 320, 81, 25);
    jBRechts.setText("Rechts");
    jBRechts.setMargin(new Insets(2, 2, 2, 2));
    jBRechts.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBRechts_ActionPerformed(evt);
      }
    });
    cp.add(jBRechts);
    jBUnten.setBounds(336, 352, 81, 25);
    jBUnten.setText("Unten");
    jBUnten.setMargin(new Insets(2, 2, 2, 2));
    jBUnten.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBUnten_ActionPerformed(evt);
      }
    });
    cp.add(jBUnten);
    jBFallen.setBounds(424, 352, 81, 25);
    jBFallen.setText("Fallen");
    jBFallen.setMargin(new Insets(2, 2, 2, 2));
    jBFallen.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBFallen_ActionPerformed(evt);
      }
    });
    cp.add(jBFallen);
    jBStarten.setBounds(336, 384, 81, 25);
    jBStarten.setText("Starten");
    jBStarten.setMargin(new Insets(2, 2, 2, 2));
    jBStarten.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBStarten_ActionPerformed(evt);
      }
    });
    cp.add(jBStarten);
    jBBeenden.setBounds(424, 384, 81, 25);
    jBBeenden.setText("Beenden");
    jBBeenden.setMargin(new Insets(2, 2, 2, 2));
    jBBeenden.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
        jBBeenden_ActionPerformed(evt);
      }
    });
    cp.add(jBBeenden);
    canvas1.setBounds(16, 8, 241, 451);
    canvas1.setBackground(Color.WHITE);
    cp.add(canvas1);
    // Ende Komponenten

    setVisible(true);
  }

  // Anfang Methoden
  public void jBAnhalten_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  }

  public void jBWeiter_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  }

  public void jBStein_ActionPerformed(ActionEvent evt) {
    einSpielfeld.neuerStein();
    canvas1.repaint();
  }

  public void jBDrehen_ActionPerformed(ActionEvent evt) {
    einSpielfeld.drehen_public();
    canvas1.repaint();
  }

  public void jBLinks_ActionPerformed(ActionEvent evt) {
    einSpielfeld.nach_links();
    canvas1.repaint();
  }

  public void jBRechts_ActionPerformed(ActionEvent evt) {
    einSpielfeld.nach_rechts();
    canvas1.repaint();
  }

  public void jBUnten_ActionPerformed(ActionEvent evt) {
    einSpielfeld.nach_unten();
    canvas1.repaint();
  }

  public void jBFallen_ActionPerformed(ActionEvent evt) {
    einSpielfeld.fallen();
    canvas1.repaint();
  }

  public void jBStarten_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  }

  public void jBBeenden_ActionPerformed(ActionEvent evt) {
    // TODO hier Quelltext einfügen
  }

  // Ende Methoden

  public static void main(String[] args) {
    new Tetris("Tetris");

  }
}
```

In Tetris.java fehlen auch noch ein paar Kleinigkeiten, aber ich wollte erst einmal das Feld hinbekommen. Die erste Datei ist wahrscheinlich auch richtig. Ich denke mal der Fehler liegt wahrscheinlich entweder bei der vierten Datei oder bei der dritten, bin mir aber nicht sicher. Hoffe mir kann jemand helfen, danke.

Gruß, Utopia


----------



## Gast2 (27. Jan 2012)

Was mir beim Überfliegen aufgefallen ist:
Niemals AWT und Swing Komponenten mischen. Mach aus deinem Canvas also ein JPanel und überschreib dort die paintComponent anstatt der paint methode.

Beim zweiten überfliegen:

```
Graphics g = getGraphics();
```
NIEMALS getGraphics() auf ner Komponenten aufrufen, NIE! Gezeichnet wird immer mit dem Graphics Objekt der paintComponent() Methode. Das erreichst du ja schon durch den repaint() aufruf.


----------



## Landei (27. Jan 2012)

Der Code könnte sehr stark vereinfacht werden, z.B.:


```
private static final Color[] colorCodes = new Color[]{
     Color.black, new Color(230, 10, 0), new Color(255, 235, 0), 
     new Color(10, 170, 10), new Color(20, 140, 180), new Color(255, 250, 210),
     new Color(210, 50, 130), Color.orange, Color.red}

private Color codeToColor(int farbcode){
  return colorCodes[farbCode % colorCodes.length];
}
```


----------



## Utopia (28. Jan 2012)

Vielen Dank für die Antworten.

Leider hat es mir nur sehr wenig geholfen, da ich von meinem Lehrer ein Skript bekommen habe, in dem einige Schritte zum Programmieren von Tetris beschrieben wurde, weil komplett selbst programmieren zu schwer wäre. Also habe ich gedacht, dass der Fehler in dem Teil liegt, den ich selbst gemacht habe, aber anscheinend war wohl schon das ganze Skript fehlerhaft, weil die Fehler, die ihr genannt habt, genau so schon im Skript standen. Da ich jetzt von JPanel und paintComponents und Co. nun überhaupt keine Ahnung hatte, musste ich es wohl lassen. Aber wie gesagt, trotzdem danke für die Antworten.


Gruß Utopia


----------



## HimBromBeere (28. Jan 2012)

> Niemals AWT und Swing Komponenten mischen. Mach aus deinem Canvas also ein JPanel und überschreib dort die paintComponent anstatt der paint methode.





> NIEMALS getGraphics() auf ner Komponenten aufrufen, NIE! Gezeichnet wird immer mit dem Graphics Objekt der paintComponent() Methode. Das erreichst du ja schon durch den repaint() aufruf.


Was zum Henker bringen einem die Lehrer heutztage eigtl. bei, wenn es schon an solch trivialen obgleich essentiellen Inhalten hängt...
Also ehrlich, ich weiß schon, warum ich mir das alles selbst beibringe... kann ich wenigstens nur mich für dem Käse verantwortlich machen


----------



## Utopia (28. Jan 2012)

Ich glaube ich bringe mir in Zukunft auch alles lieber selbst bei.
Übrigens habe ich gerade erfahren, dass das Skript nicht von meinem Lehrer geschrieben wurde, sondern von irgendeinem Bildungsinstitut, das Unterrichtsmaterialien zur Verfügung stellt.


----------



## Landei (28. Jan 2012)

Blargh! Aber ist ja logisch: Leute, die faktisch eine Gelddruckmaschine rumstehen haben, achten nicht mehr auf Qualität...

Sowas gehört mit COBOL nicht unter zehn Jahren bestraft!


----------



## Kar (28. Jan 2012)

Utopia hat gesagt.:


> Übrigens habe ich gerade erfahren, dass das Skript nicht von meinem Lehrer geschrieben wurde, sondern von irgendeinem Bildungsinstitut, das Unterrichtsmaterialien zur Verfügung stellt.


http://informatik.bildung-rp.de/fil...k.bildung-rp.de/Fortbildung/pdf/J2-Tetris.pdf

Da bist du besser dran, wenn du alles selber programmierst.^^


----------



## Helgon (29. Jan 2012)

The Tetris game hilft dir vielleicht

Wenn ihr wüsstet was ich für nen Info Lehrer habe. Ich hab einfach kein nerv jetzt auszuholen und Storys über den auszupacken.. Wer Ahnung hat wird doch nicht Lehrer.. der geht in die Wirtschaft


----------



## Utopia (29. Jan 2012)

@Kar

genau das ist das, was wir bekommen haben.


@Helgon

ist zwar eigentlich schon zu spät, aber trotzdem danke für den Link. Ich werde es mir mal bei Gelegenheit ansehen


----------

