# Tetris: Rotation der Tetrominos



## Exterminas (24. Okt 2010)

hey ho,
ich bin gerade dabei für die schule tetris zu basteln. das programm ist soweit fast fertig und funktioniert auch wunderbar bis auf die rotation der tetrominos. so bald ich die pfeiltaste nach oben drücke, welche die methode zum rotieren ausführt bleibt das tetromino stehen und reagiert auf keine taste mehr. ich vermute irgend einen simplen denk- bzw. schreibfehler aber ich finde ihn einfach nicht. der übeltäter ist vermutlich die methode "public int[][] rotateTetromino(int a[][])" in der tetromino klasse.

schon mal ein herzliches danke an alle die sich gedanken darüber machen.

hier mal der code des applets:


```
import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class frmMain extends Applet implements Runnable, KeyListener
{
    int iRadius,iYspeed,i,iYspeedCounter,j;
    clsTetromino Tetromino;
    int iArea[][] =
        {
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,0,0,0,0,0,0,0,0,0,0,10,10},
            {10,10,10,10,10,10,10,10,10,10,10,10,10,10},
            {10,10,10,10,10,10,10,10,10,10,10,10,10,10},
        };
    
    Image dbImage;
    Graphics dbg;
    Thread th;

    public void init()
    {
        this.setBackground(Color.black);
        this.addKeyListener(this);
        Tetromino = new clsTetromino();
        iRadius = 10;
        iYspeed = 1;
        iYspeedCounter = 0;
        
        Tetromino.createTetromino();
                //y1...4                      x1...4
        iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = Tetromino.getCurTetromino();
        iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = Tetromino.getCurTetromino();
        iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = Tetromino.getCurTetromino();
        iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = Tetromino.getCurTetromino();
    }

    public void start()
    {
        th = new Thread(this);
        th.start();
    }

    public void stop()
    {
    }

    public void keyTyped(KeyEvent e)
    {
    }

    public void keyPressed(KeyEvent e)
    {
        switch(e.getKeyCode())
        {
            case KeyEvent.VK_LEFT : iArea = Tetromino.moveLeft(iArea);
                                    repaint();
                                    break;
            case KeyEvent.VK_RIGHT : iArea = Tetromino.moveRight(iArea);
                                     repaint();
                                     break;
            case KeyEvent.VK_DOWN : if(iArea[Tetromino.getPos(1,0) + 1][Tetromino.getPos(0,0)] < 10 &&
                                       iArea[Tetromino.getPos(1,1) + 1][Tetromino.getPos(0,1)] < 10 &&
                                       iArea[Tetromino.getPos(1,2) + 1][Tetromino.getPos(0,2)] < 10 &&
                                       iArea[Tetromino.getPos(1,3) + 1][Tetromino.getPos(0,3)] < 10)
                                    {
                                        iArea = Tetromino.moveDown(iArea);
                                    }
                                    else
                                    {                                        
                                        iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] + 10;
                                        iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] + 10;
                                        iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] + 10;
                                        iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] + 10;
                                        
                                        Tetromino.createTetromino();
                                        
                                        iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = Tetromino.getCurTetromino();
                                        iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = Tetromino.getCurTetromino();
                                        iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = Tetromino.getCurTetromino();
                                        iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = Tetromino.getCurTetromino();
                                    }
                                    repaint();
                                    break;
            case KeyEvent.VK_UP : iArea = Tetromino.rotateTetromino(iArea);
                                  repaint();
        }
    }
    
    public void keyReleased(KeyEvent e)
    {
    }
    
    public void destroy()
    {
    }

    public void run()
    {
        while(true)
        {            
            iYspeedCounter = iYspeedCounter + iYspeed;
            
            if(iYspeedCounter % 10 == 0)
            {
                if(iArea[Tetromino.getPos(1,0) + 1][Tetromino.getPos(0,0)] < 10 &&
                   iArea[Tetromino.getPos(1,1) + 1][Tetromino.getPos(0,1)] < 10 &&
                   iArea[Tetromino.getPos(1,2) + 1][Tetromino.getPos(0,2)] < 10 &&
                   iArea[Tetromino.getPos(1,3) + 1][Tetromino.getPos(0,3)] < 10)
                {
                    iArea = Tetromino.moveDown(iArea);
                }
                else
                {
                    iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] + 10;
                    iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] + 10;
                    iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] + 10;
                    iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] + 10;
                                        
                    Tetromino.createTetromino();
                                        
                    iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = Tetromino.getCurTetromino();
                    iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = Tetromino.getCurTetromino();
                    iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = Tetromino.getCurTetromino();
                    iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = Tetromino.getCurTetromino();
                }
                repaint();
            }

            try
            {
                Thread.sleep(100);
            }
            catch(InterruptedException e)
            {
            }
        }
    }

    //////////////////////////////////////////////////////////////////////////////////////////
    public void update(Graphics g)                                                          //
    {                                                                                       //
        if (dbImage == null)                                                                //
        {                                                                                   //
            dbImage = createImage(this.getSize().width, this.getSize().height);             //
            dbg = dbImage.getGraphics();                                                    //
        }                                                                                   //
                                                                                            //
        dbg.setColor(getBackground());                                                      //Doppelpufferung
        dbg.fillRect(0, 0,this.getSize().width, this.getSize().height);                     //
                                                                                            //
        dbg.setColor(getForeground());                                                      //
        paint (dbg);                                                                        //
                                                                                            //
        g.drawImage(dbImage,0,0,this);                                                      //
    }                                                                                       //
    //////////////////////////////////////////////////////////////////////////////////////////

    public void paint(Graphics g)
    {
        g.setColor(new Color(90,90,90));            //zeichnet graues Gitter
        for(i = 0;i < 11;i++)
        {
            g.drawLine(100 + i * 20,0,100 + i * 20,400);
        }
        for(i = 0;i < 21;i++)
        {
            g.drawLine(100,i * 20,300,i * 20);
        }


        for(i = 2;i < 12;i++)                       //zeichnet die einzelnen Blöcke in den gewünschten Farben
        {
            for(j = 0;j < 20;j++)
            {
                switch(iArea[j][i])
                {
                    case 2 : g.setColor(Color.magenta);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 3 : g.setColor(Color.cyan);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 4 : g.setColor(Color.blue);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 5 : g.setColor(Color.orange);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 6 : g.setColor(Color.yellow);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 7 : g.setColor(Color.red);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 8 : g.setColor(Color.green);
                             g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                             break;
                    case 12 : g.setColor(Color.magenta);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                    case 13 : g.setColor(Color.cyan);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                    case 14 : g.setColor(Color.blue);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                    case 15 : g.setColor(Color.orange);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                    case 16 : g.setColor(Color.yellow);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                    case 17 : g.setColor(Color.red);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                    case 18 : g.setColor(Color.green);
                              g.fillRect(60 + i * 20 + 1,j * 20 + 1, 2 * iRadius - 1,2 * iRadius - 1);
                              break;
                }
            }
        }
    }
}
```

und hier der code der tetromino klasse:


```
import java.lang.Math;

public class clsTetromino
{
    private int iCurTetromino,i,j,k,iMaxX,iMinX,iMaxY,iMinY;
    double cx,cy;
    private int iPos[][] = 
                {
                    {0,0,0,0},      //x
                    {0,0,0,0},      //y
                };
    private int iTmp[][] = 
                {
                    {0,0,0,0},
                    {0,0,0,0},
                };
    private int iArea[][] =
                {
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                    {0,0,0,0,0,0,0,0,0,0,0,0,0,0},
                };

    public clsTetromino()
    {
    }
    
    public void createTetromino()
    {
        iCurTetromino = (int)(Math.random()* ((8 - 2) + 1) + 2);
        switch(iCurTetromino)
        {             //x1...4          y1...4
            case 2 : iPos[0][0] = 6; iPos[1][0] = 0;        //  2
                     iPos[0][1] = 5; iPos[1][1] = 1;        //2 2 2
                     iPos[0][2] = 6; iPos[1][2] = 1;
                     iPos[0][3] = 7; iPos[1][3] = 1;
                     break;
            case 3 : iPos[0][0] = 6; iPos[1][0] = 0;        //3
                     iPos[0][1] = 6; iPos[1][1] = 1;        //3
                     iPos[0][2] = 6; iPos[1][2] = 2;        //3
                     iPos[0][3] = 6; iPos[1][3] = 3;        //3
                     break;
            case 4 : iPos[0][0] = 7; iPos[1][0] = 0;        //  4
                     iPos[0][1] = 7; iPos[1][1] = 1;        //  4
                     iPos[0][2] = 7; iPos[1][2] = 2;        //4 4
                     iPos[0][3] = 6; iPos[1][3] = 2;
                     break;
            case 5 : iPos[0][0] = 6; iPos[1][0] = 0;        //5
                     iPos[0][1] = 6; iPos[1][1] = 1;        //5
                     iPos[0][2] = 6; iPos[1][2] = 2;        //5 5
                     iPos[0][3] = 7; iPos[1][3] = 2;
                     break;
            case 6 : iPos[0][0] = 6; iPos[1][0] = 0;        //6 6
                     iPos[0][1] = 7; iPos[1][1] = 0;        //6 6
                     iPos[0][2] = 6; iPos[1][2] = 1;
                     iPos[0][3] = 7; iPos[1][3] = 1;
                     break;
            case 7 : iPos[0][0] = 5; iPos[1][0] = 0;        //7 7
                     iPos[0][1] = 6; iPos[1][1] = 0;        //  7 7
                     iPos[0][2] = 6; iPos[1][2] = 1;
                     iPos[0][3] = 7; iPos[1][3] = 1;
                     break;
            case 8 : iPos[0][0] = 7; iPos[1][0] = 0;        //  8 8
                     iPos[0][1] = 8; iPos[1][1] = 0;        //8 8
                     iPos[0][2] = 6; iPos[1][2] = 1;
                     iPos[0][3] = 7; iPos[1][3] = 1;
        }
    }
    
    public int getCurTetromino()
    {
        return iCurTetromino;
    }
    
    public int getPos(int a, int b)
    {
        j = a;
        k = b;
        return iPos[j][k];
    }
    
    public int[][] moveLeft(int a[][])
    {
        iArea = a;
        if(iArea[iPos[1][0]][iPos[0][0] - 1] < 10 &&
           iArea[iPos[1][1]][iPos[0][1] - 1] < 10 &&
           iArea[iPos[1][2]][iPos[0][2] - 1] < 10 &&
           iArea[iPos[1][3]][iPos[0][3] - 1] < 10)
        {
            iArea[iPos[1][0]][iPos[0][0]] = 0;
            iArea[iPos[1][1]][iPos[0][1]] = 0;
            iArea[iPos[1][2]][iPos[0][2]] = 0;
            iArea[iPos[1][3]][iPos[0][3]] = 0;
            iPos[0][0] = iPos[0][0] - 1;
            iPos[0][1] = iPos[0][1] - 1;
            iPos[0][2] = iPos[0][2] - 1;
            iPos[0][3] = iPos[0][3] - 1;
            iArea[iPos[1][0]][iPos[0][0]] = iCurTetromino;
            iArea[iPos[1][1]][iPos[0][1]] = iCurTetromino;
            iArea[iPos[1][2]][iPos[0][2]] = iCurTetromino;
            iArea[iPos[1][3]][iPos[0][3]] = iCurTetromino;
        }
        return iArea;
    }
    
    public int[][] moveRight(int a[][])
    {
        iArea = a;
        if(iArea[iPos[1][0]][iPos[0][0] + 1] < 10 &&
           iArea[iPos[1][1]][iPos[0][1] + 1] < 10 &&
           iArea[iPos[1][2]][iPos[0][2] + 1] < 10 &&
           iArea[iPos[1][3]][iPos[0][3] + 1] < 10)
        {
            iArea[iPos[1][0]][iPos[0][0]] = 0;
            iArea[iPos[1][1]][iPos[0][1]] = 0;
            iArea[iPos[1][2]][iPos[0][2]] = 0;
            iArea[iPos[1][3]][iPos[0][3]] = 0;
            iPos[0][0] = iPos[0][0] + 1;
            iPos[0][1] = iPos[0][1] + 1;
            iPos[0][2] = iPos[0][2] + 1;
            iPos[0][3] = iPos[0][3] + 1;
            iArea[iPos[1][0]][iPos[0][0]] = iCurTetromino;
            iArea[iPos[1][1]][iPos[0][1]] = iCurTetromino;
            iArea[iPos[1][2]][iPos[0][2]] = iCurTetromino;
            iArea[iPos[1][3]][iPos[0][3]] = iCurTetromino;
        }
        return iArea;
    }
    
    public int[][] moveDown(int a[][])
    {
        iArea = a;
        iArea[iPos[1][0]][iPos[0][0]] = 0;
        iArea[iPos[1][1]][iPos[0][1]] = 0;
        iArea[iPos[1][2]][iPos[0][2]] = 0;
        iArea[iPos[1][3]][iPos[0][3]] = 0;
        iPos[1][0] = iPos[1][0] + 1;
        iPos[1][1] = iPos[1][1] + 1;
        iPos[1][2] = iPos[1][2] + 1;
        iPos[1][3] = iPos[1][3] + 1;
        iArea[iPos[1][0]][iPos[0][0]] = iCurTetromino;
        iArea[iPos[1][1]][iPos[0][1]] = iCurTetromino;
        iArea[iPos[1][2]][iPos[0][2]] = iCurTetromino;
        iArea[iPos[1][3]][iPos[0][3]] = iCurTetromino;
        return iArea;
    }
    
    public int[][] rotateTetromino(int a[][])
    {
        iArea = a;
        iArea[iPos[1][0]][iPos[0][0]] = 0;
        iArea[iPos[1][1]][iPos[0][1]] = 0;
        iArea[iPos[1][2]][iPos[0][2]] = 0;
        iArea[iPos[1][3]][iPos[0][3]] = 0;
        iTmp = iPos;
        
        iMinX = iPos[0][0];                  //ermitteln von cx und cy (koordinaten der Mittelpunktes)
        for(i = 0;i < 4;i++)
        {
            if(iPos[0][i] < iMinX)
            {
                iMinX = iPos[0][i];
            }
        }
        
        iMaxX = iPos[0][0];
        for(i = 0;i < 4;i++)
        {
            if(iPos[0][i] > iMaxX)
            {
                iMaxX = iPos[0][i];
            }
        }
        
        cx = (iMinX + iMaxX) / 2;
        
        iMinX = iPos[1][0];
        for(i = 0;i < 4;i++)
        {
            if(iPos[1][i] < iMinX)
            {
                iMinX = iPos[1][i];
            }
        }
        
        iMaxX = iPos[1][0];
        for(i = 0;i < 4;i++)
        {
            if(iPos[1][i] > iMaxX)
            {
                iMaxX = iPos[1][i];
            }
        }
        
        cy = (iMinY + iMaxY) / 2;
        
        //neue x1...4         alte y1...4
        iPos[0][0] = (int) (iTmp[1][0] + cx - cy); 
        iPos[0][1] = (int) (iTmp[1][1] + cx - cy); 
        iPos[0][2] = (int) (iTmp[1][2] + cx - cy); 
        iPos[0][3] = (int) (iTmp[1][3] + cx - cy); 
        //neue y1...4         alte x1...4
        iPos[1][0] = (int) (cx - cy - iTmp[0][0]);
        iPos[1][1] = (int) (cx - cy - iTmp[0][1]);
        iPos[1][2] = (int) (cx - cy - iTmp[0][2]);
        iPos[1][3] = (int) (cx - cy - iTmp[0][3]);
        
        iArea[iPos[1][0]][iPos[0][0]] = iCurTetromino;
        iArea[iPos[1][1]][iPos[0][1]] = iCurTetromino;
        iArea[iPos[1][2]][iPos[0][2]] = iCurTetromino;
        iArea[iPos[1][3]][iPos[0][3]] = iCurTetromino;
        return iArea;
    }
}
```


----------



## Quaxli (25. Okt 2010)

Exterminas hat gesagt.:


> hey ho,
> ich bin gerade dabei für die schule tetris zu basteln. das programm ist soweit fast fertig und funktioniert auch wunderbar bis auf die rotation der tetrominos....



Nö, funktioniert nicht, zumindest nicht bei mir.  
Ich werde mal versuchen genauer drauf zu sehen, aber was mir schon auf aufgefallen ist, ist folgendes:


```
public void keyPressed(KeyEvent e)
    {
        switch(e.getKeyCode())
        {
            case KeyEvent.VK_LEFT : iArea = Tetromino.moveLeft(iArea);
                                    repaint();
                                    break;
            case KeyEvent.VK_RIGHT : iArea = Tetromino.moveRight(iArea);
                                     repaint();
                                     break;
            case KeyEvent.VK_DOWN : if(iArea[Tetromino.getPos(1,0) + 1][Tetromino.getPos(0,0)] < 10 &&
                                       iArea[Tetromino.getPos(1,1) + 1][Tetromino.getPos(0,1)] < 10 &&
                                       iArea[Tetromino.getPos(1,2) + 1][Tetromino.getPos(0,2)] < 10 &&
                                       iArea[Tetromino.getPos(1,3) + 1][Tetromino.getPos(0,3)] < 10)
                                    {
                                        iArea = Tetromino.moveDown(iArea);
                                    }
                                    else
                                    {                                        
                                        iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] + 10;
                                        iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] + 10;
                                        iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] + 10;
                                        iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] + 10;
                                        
                                        Tetromino.createTetromino();
                                        
                                        iArea[Tetromino.getPos(1,0)][Tetromino.getPos(0,0)] = Tetromino.getCurTetromino();
                                        iArea[Tetromino.getPos(1,1)][Tetromino.getPos(0,1)] = Tetromino.getCurTetromino();
                                        iArea[Tetromino.getPos(1,2)][Tetromino.getPos(0,2)] = Tetromino.getCurTetromino();
                                        iArea[Tetromino.getPos(1,3)][Tetromino.getPos(0,3)] = Tetromino.getCurTetromino();
                                    }
                                    repaint();
                                    break;
            case KeyEvent.VK_UP : iArea = Tetromino.rotateTetromino(iArea);
                                  repaint();
        }
    }
```

Wenn Dir an einer flüssig laufenden Animation gelegen ist, haben weder größere Code-Blöcke, noch repaint-Aufrufe im Key-Listener etwas verloren.
Das repaint() sollte in der run-Methode Deines Threads periodisch aufgerufen werden - und zwar immer, d. h. außerhalb irgendwelcher if-Bedingungen.
Und was das Bewegen der Steine betrifft: Üblicherweise beschränkt man sich im KeyListener auf das Setzen von Boolean-Werten (left = true) und fragt diese dann im GameLoop ab (die run-Methode Deines Threads).


----------



## Quaxli (25. Okt 2010)

Dein Programm wirft übrigens eine Exception:

Exception in thread "AWT-EventQueue-1" java.lang.ArrayIndexOutOfBoundsException: -4
	at clsTetromino.rotateTetromino(clsTetromino.java:231)
	at frmMain.keyPressed(frmMain.java:104)
	at java.awt.Component.processKeyEvent(Component.java:6092)
	at java.awt.Component.processEvent(Component.java:5911)
	at java.awt.Container.processEvent(Container.java:2023)
	at java.awt.Component.dispatchEventImpl(Component.java:4501)
	at java.awt.Container.dispatchEventImpl(Container.java:2081)
	at java.awt.Component.dispatchEvent(Component.java:4331)
	at java.awt.KeyboardFocusManager.redispatchEvent(KeyboardFocusManager.java:1848)
	at java.awt.DefaultKeyboardFocusManager.dispatchKeyEvent(DefaultKeyboardFocusManager.java:704)
	at java.awt.DefaultKeyboardFocusManager.preDispatchKeyEvent(DefaultKeyboardFocusManager.java:969)
	at java.awt.DefaultKeyboardFocusManager.typeAheadAssertions(DefaultKeyboardFocusManager.java:841)
	at java.awt.DefaultKeyboardFocusManager.dispatchEvent(DefaultKeyboardFocusManager.java:668)
	at java.awt.Component.dispatchEventImpl(Component.java:4373)
	at java.awt.Container.dispatchEventImpl(Container.java:2081)
	at java.awt.Component.dispatchEvent(Component.java:4331)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:599)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:269)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:184)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:174)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:169)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:161)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:122)


Die angegebene Zeile 231 ist diese:


```
....
        iPos[1][0] = (int) (cx - cy - iTmp[0][0]);
        iPos[1][1] = (int) (cx - cy - iTmp[0][1]);
        iPos[1][2] = (int) (cx - cy - iTmp[0][2]);
        iPos[1][3] = (int) (cx - cy - iTmp[0][3]);
        
        iArea[iPos[1][0]][iPos[0][0]] = iCurTetromino;  <--- hier knallt's
        iArea[iPos[1][1]][iPos[0][1]] = iCurTetromino;
        iArea[iPos[1][2]][iPos[0][2]] = iCurTetromino;
        iArea[iPos[1][3]][iPos[0][3]] = iCurTetromino;
        return iArea;
```

Warum, wieso, weshalb ist mir noch nicht ganz klar. Du hast recht wenig Kommentare im Programm und diese ganzen IAreas verwirren mich gerade ein bißchen...


----------



## Quaxli (25. Okt 2010)

So, das ist jetzt erstmal der letzt Kommentar. So kann man die Anzahl seiner Postings auch in die Höhe treiben.....

In Deiner Rotations-Methode wird regelmäßig einer der folgenden Werte negativ:


```
//neue y1...4         alte x1...4
        iPos[1][0] = (int) (cx - cy - iTmp[0][0]);
        iPos[1][1] = (int) (cx - cy - iTmp[0][1]);
        iPos[1][2] = (int) (cx - cy - iTmp[0][2]);
        iPos[1][3] = (int) (cx - cy - iTmp[0][3]);
```

Und da Du diese anschließend nutzt, Elemente des iArea-Arrays zu verändern, wirft Dein Programm eine ArrayIndexOutOfBounds-Exception.
Inwiefern der Code oben eine Rotation darstellen soll, ist mir auch noch nicht klar. Entweder ist es für mich noch zu früh oder das klappt so nicht. cx und cy soll die Mitte des Tetronmino-Arrays sein. Warum Du dann die aber voneinander subtrahierst und dann denn zuvor in iTmp gespeicherten vorherigen Zustand ist mir so nicht ganz klar.
Das Ganze erscheint mir persönlich auch etwas umständlich. Ich hätte das Ding als 4x4-Array angelegt und einmal eine Methode geschrieben, die alle Element - ob belegt oder nicht - rotiert.

Auch dieses Hin- und Her-Übergeben von iArea ist etwas verwirrend. Meiner Ansicht nach gehört die Logik für das Spielfeld in eine eigene Klasse gepackt.
Auch sonst gäbe es noch einiges zu verbessern, aber damit will ich jetzt nicht anfangen. Du solltest auf jeden Fall mal die Rotationsmethode überarbeiten.
Und eine IDE verwenden, in der Du die Exceptions siehst und ggf. debuggen kannst.


----------



## Exterminas (25. Okt 2010)

das mit der rotation hab ich faul wie ich bin von hier:
http://informatik.bildung-rp.de/fil...k.bildung-rp.de/Fortbildung/pdf/J2-Tetris.pdf

da ich atm in der schule im info unterricht sitze kann ich jetzt nicht ausführlich antworten ich werd mich aber heute mittag zu hause noch ma hinsetzen und noch mal genauer darauf eingehen und auch das ein oder andere auskommentieren.

aber soweit schon mal thx für die antwort und die hilfestellung.

zu dem hin und her übergeben lässt sich noch sagen das ich das ganze anfangs alles nur im applet gemacht hab und es jetzt nur auf die stelle etwas ausgelagert hab damit nicht alles so unübersichtlich auf einem haufen ist.

edit:
so also das mit den ganzen int arrays is eig ganz einfach. jeder "stein" in tetris besteht aus 4 quadraten. iPos speichert insgesamt 8 werte: 4 x und 4 y werte, für jedes quadrat also einen x und y wert.
in iArea ist das spielfeld gespeichert. hier werden alle tetrominos mit ihrem farbwert eingetragen (iCurTetromino). bei abgelegten Tetrominos wird der farbwert um 10 erhöht um sie vom aktuellen tetromino bei der kollisionsabfrage unterscheiden zu können.

das ganze hin und her reichen von iArea ist nicht ganz so geschickt ich weiss aber war auf die schnelle halt die idee die mir als erstes gekommen ist. so bald ein tetromino bewegt/gedreht wird, wird iArea direkt in clsTetromino angepasst. die überarbeitete und aktuelle version von iArea wird dann wieder ans applet übergeben um in der paint methode gezeichnet zu werden.

ach ja und thx für den tipp mit dem keylistener. ich bin noch recht neu was programmieren angeht un hatte keine ahnung das der ablauf dadurch negativ beeinflusst wird.


----------

