在俄罗斯方块项目中添加其他形状。循环逻辑辅助

时间:2017-02-28 19:49:58

标签: java swing tetris

我正在创建一个俄罗斯方块克隆作为个人项目,以帮助我更好地绘制图像,移动它们,并学习碰撞检测。

一切都很顺利但我很难理解当第一个停止移动时让程序在框架中添加新的tetrimino形状的逻辑。到目前为止,我使用随机数生成器随机创建tetrimino,并可以将其添加到帧中。我只是无法弄清楚如何循环它,以便一旦该形状停止移动,它会在屏幕顶部添加另一个形状。

这是一个pre alpha版本,在目前的实现中,我还没有添加碰撞检测,任何评分,背景,旋转形状的能力等等。我只是无法超越这个逻辑障碍。请帮忙!

一些代码:

    public class tetrisGame extends JFrame
{
    //Frame dimensions
    private static final int FRAME_WIDTH = 600;
    private static final int FRAME_HEIGHT = 600;

    private final int MAX_VALUE = 7; //RNG MAX VALUE
    private final int MIN_VALUE = 1; //RNG MIN VALUE
    private static int dy = 10;
    private static int dx = 0;

    private JLabel welcomeLabel, imageLabel, blankLabel, blankLabel2, creditsLabel1, creditsLabel2, creditsLabel3;
    private JButton startButton, creditsButton, exitButton, returnButton, leftButton, rightButton;
    private Shapes component; //Tetrimino Shape

    private JPanel totalGUI, buttonPanel, startPanel, creditsPanel, gamePanel, movePanel;

    public tetrisGame()
    {
        createComponents();
        setSize(FRAME_WIDTH, FRAME_HEIGHT);
        setTitle("Tetris");
    }

    //Moves tetrimino's down using a timer
    class TimerListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            component.moveRectangleBy(dx,dy);
        }
    }

    //Moves the tetrimino to the right 
    class moveRightListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            dy = 0;
            component.moveRectangleBy(dx+10,dy);
            dy = 10;
        }
    }

    //Moves the tetrimino to the left.
    class moveLeftListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            dy = 0;
            component.moveRectangleBy(dx-10,dy);
            dy = 10;
        }
    }

    //Executed when a new game is started.  The heart of the program.
    class newGameListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            int  randomNum = createRNG(MAX_VALUE, MIN_VALUE);

            if (randomNum == 1)
            {
                component = new SquareShape();
            }
            else if (randomNum == 2)
            {
                component = new RectangleShape();
            }
            else if (randomNum == 3)
            {
                component = new JShape();
            }
            else if (randomNum == 4)
            {
                component = new SShape();
            }
            else if (randomNum == 5)
            {
                component = new TShape();
            }
            else if (randomNum == 6)
            {
                component = new LShape();
            }
            else
            {
                component = new ZShape();
            }

            //Creates and starts timer that moves shapes
            int delay = 1000;
            ActionListener timerListener = new TimerListener();
            javax.swing.Timer t = new javax.swing.Timer(delay, timerListener);
            t.start();

            remove(totalGUI);
            add(component, BorderLayout.CENTER);
            add(movePanel, BorderLayout.SOUTH);
            repaint();
            revalidate();

        }   
    }

    //Adds components of the credit screen when button is pressed
    class creditsListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            totalGUI.remove(startPanel);
            totalGUI.add(creditsPanel);
            repaint();
            revalidate();
        }
    }

    //Exits the program
    class exitListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            System.exit(0);
        }
    }

    //returns to the main menu screen. 
    class returnListener implements ActionListener
    {
        public void actionPerformed(ActionEvent e)
        {
            totalGUI.remove(creditsPanel);
            totalGUI.add(startPanel);
            repaint();
        }
    }

    //Creates all components of the GUI
    private void createComponents()
    {
        //Imports Tetris image
        try
        {
            String path = "http://static3.gamespot.com/uploads/screen_kubrick/1179/11799911/2550560-tetris.jpg";
            URL url = new URL(path);
            BufferedImage image = ImageIO.read(url);
            Image newImage = image.getScaledInstance(300,120,java.awt.Image.SCALE_SMOOTH);
            imageLabel = new JLabel(new ImageIcon(newImage));
        } catch(Exception e){}
        //Creates welcome prompt and new game buttons
        welcomeLabel = new JLabel("                                Welcome to Tetris!");
        Font boldFont = welcomeLabel.getFont();
        welcomeLabel.setFont(boldFont.deriveFont(boldFont.getStyle() ^ Font.BOLD));
        welcomeLabel.setForeground(Color.orange);
        blankLabel = new JLabel("");
        blankLabel2 = new JLabel("");
        startButton = new JButton("New Game");
        creditsButton = new JButton("Credits");
        exitButton = new JButton("Exit");

        //Adds action listeners to new game buttons
        ActionListener newGameListener = new newGameListener();
        startButton.addActionListener(newGameListener);
        ActionListener creditsListener = new creditsListener();
        creditsButton.addActionListener(creditsListener);
        ActionListener exitListener = new exitListener();
        exitButton.addActionListener(exitListener);

        //Adds new game buttons to panel
        buttonPanel = new JPanel();
        buttonPanel.setLayout(new GridLayout(6,1));
        buttonPanel.setBackground(Color.black);
        buttonPanel.add(blankLabel);
        buttonPanel.add(blankLabel2);
        buttonPanel.add(welcomeLabel);
        buttonPanel.add(startButton);
        buttonPanel.add(creditsButton);
        buttonPanel.add(exitButton);

        //Buttons that move the tetrimino's
        leftButton = new JButton("<--");
        ActionListener leftListener = new moveLeftListener();
        leftButton.addActionListener(leftListener);
        rightButton = new JButton("-->");
        ActionListener rightListener = new moveRightListener();
        rightButton.addActionListener(rightListener);
        //Panel that contains movement buttons
        movePanel = new JPanel();
        movePanel.add(leftButton);
        movePanel.add(rightButton);

        //Continue to add elements to panel
        startPanel = new JPanel();
        startPanel.setLayout(new BorderLayout());
        startPanel.add(imageLabel, BorderLayout.NORTH);
        startPanel.add(buttonPanel, BorderLayout.CENTER);

        //Create elements of credits screen
        creditsLabel1 = new JLabel("The Tetris logo, block shapes, and dimensions are registered trademarks of The Tetris Company.");
        creditsLabel1.setFont(boldFont.deriveFont(boldFont.getStyle() ^ Font.BOLD));
        creditsLabel1.setForeground(Color.orange);
        creditsLabel2 = new JLabel("                   This product is an academic work intended for individual use only.");
        creditsLabel2.setFont(boldFont.deriveFont(boldFont.getStyle() ^ Font.BOLD));
        creditsLabel2.setForeground(Color.orange);
        creditsLabel3 = new JLabel("                         All programming written in the Java language by NAME REMOVED.");
        creditsLabel3.setFont(boldFont.deriveFont(boldFont.getStyle() ^ Font.BOLD));
        creditsLabel3.setForeground(Color.orange);
        returnButton = new JButton("Return");
        ActionListener returnListener = new returnListener();
        returnButton.addActionListener(returnListener);
        creditsPanel = new JPanel();
        creditsPanel.setLayout(new GridLayout(5,1));
        creditsPanel.setBackground(Color.black);
        creditsPanel.add(creditsLabel1);
        creditsPanel.add(creditsLabel2);
        creditsPanel.add(blankLabel);
        creditsPanel.add(creditsLabel3);
        creditsPanel.add(returnButton);

        //Initial game panel
        totalGUI = new JPanel();
        totalGUI.add(startPanel);
        totalGUI.setBackground(Color.black);

        add(totalGUI, BorderLayout.CENTER);
    }

    //generates a random number.
    private int createRNG(int MAX_VALUE, int MIN_VALUE)
    {
        Random rand = new Random();
        int randomNum = rand.nextInt(MAX_VALUE - MIN_VALUE + 1) + MIN_VALUE;

        return randomNum;
    }
}

以下是其中一个形状类的代码,以防您需要引用它:

public class SquareShape extends Shapes
{
    private static final int RECTANGLE_WIDTH = 40;
    private static final int RECTANGLE_HEIGHT = 40;

    private int xLeft;
    private int yTop;
    boolean stopped = false;

    public SquareShape()
    {
        xLeft = 280;
        yTop = 0;
    }

    public void paintComponent(Graphics g)
    {
        //draws 1 large square
        g.setColor(Color.cyan);
        g.fillRect(xLeft,yTop,RECTANGLE_WIDTH,RECTANGLE_HEIGHT);

        //Divides the square into parts
        g.setColor(Color.black);
        g.drawLine(xLeft,yTop,xLeft+40,yTop);
        g.drawLine(xLeft,yTop,xLeft,yTop+40);
        g.drawLine(xLeft,yTop+40,xLeft+40,yTop+40);
        g.drawLine(xLeft+40,yTop+40,xLeft+40,yTop);
        g.drawLine(xLeft,yTop+20,xLeft+40,yTop+20);
        g.drawLine(xLeft+20,yTop,xLeft+20,yTop+40);        
    }

    public void moveRectangleBy(int dx, int dy)
    { 
        if (yTop < 450)
        {
            xLeft += dx;
            yTop += dy;
            if (xLeft < 0)
            {
                xLeft = 0;
            }
            if (xLeft > 500)
            {
                xLeft = 500;
            }
        }
        repaint();
    }


}

提前感谢您的帮助。我有信心,一旦我解决了这个问题,我就可以实现其余的程序,我似乎无法弄清楚如何让形状继续下去。

1 个答案:

答案 0 :(得分:1)

  

我无法弄清楚如何将其循环以便一旦该形状停止移动,它会在屏幕顶部添加另一个形状。

你的定时器逻辑中你有:

component.moveRectangleBy(dx,dy);

所以这假设你总是有一个&#34;活跃的&#34;零件。您需要能够确定组件何时位于底部,以便您可以重置组件。

因此,您可能会将侦听器代码重构为:

if (component == null)
    component = // a new random shape
else
{
    component.moveRectangleBy(...);

    if (component.isAtBottom()) // a method you will need to write
        component == null;
}

为了它的价值,我也玩过我自己的俄罗斯方块游戏。目前:

  1. 添加随机件
  2. 将棋子移到棋盘上
  3. 使用4个箭头键移动/旋转俄罗斯方块
  4. 删除完整行
  5. 基本设计分为4个类:

    1. TetrisIcon - 绘制带边框的正方形
    2. TetrisPiece - 俄罗斯方块的4x4阵列表示。值为1表示应绘制TetricIcon。
    3. TetrisBoard - 包含要绘制的TetrisIcons列表以及向下移动的当前TetrisPiece。当TetrisPiece到达底部时,其各自的TetrisIcons将移至电路板上。
    4. 俄罗斯方块 - 构建框架并开始游戏。
    5. 如果你想玩它,玩得开心:

      方块:

      import java.awt.*;
      import java.awt.event.*;
      import java.util.ArrayList;
      import java.util.List;
      import java.util.Random;
      import javax.swing.*;
      import javax.swing.event.*;
      import javax.swing.border.*;
      import java.awt.geom.*;
      
      public class Tetris extends JPanel
      {
          private final static int TETRIS_ICON_SIZE = 20;
      
          private List<TetrisPiece> tetrisPieces = new ArrayList<TetrisPiece>();
          private TetrisBoard board;
          private Random random = new Random();
      
          public Tetris()
          {
              setLayout( new BorderLayout() );
      
              createTetrisPieces();
      
              board = new TetrisBoard(20, 10, 20);
              add(board, BorderLayout.LINE_START);
      /*
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 5, 5);
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 5, 6);
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 6, 5);
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 0, 0);
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 0, 19);
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 9, 0);
              board.setTetrisIconAt(new TetrisIcon(Color.RED, TETRIS_ICON_SIZE), 9, 19);
      
              board.setTetrisPiece( tetrisPieces.get(1) );
      */
              JButton start = new JButton( new StartAction() );
              add(start, BorderLayout.PAGE_END);
          }
      
          private void createTetrisPieces()
          {
              int[][] shape =
              {
                  {0, 1, 0, 0},
                  {0, 1, 0, 0},
                  {0, 1, 0, 0},
                  {0, 1, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.RED, TETRIS_ICON_SIZE)) );
      
              shape = new int[][]
              {
                  {0, 1, 0, 0},
                  {0, 1, 0, 0},
                  {0, 1, 1, 0},
                  {0, 0, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.YELLOW, TETRIS_ICON_SIZE)) );
      
              shape = new int[][]
              {
                  {0, 0, 1, 0},
                  {0, 0, 1, 0},
                  {0, 1, 1, 0},
                  {0, 0, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.MAGENTA, TETRIS_ICON_SIZE)) );
      
              shape = new int[][]
              {
                  {0, 0, 0, 0},
                  {0, 1, 1, 0},
                  {0, 1, 1, 0},
                  {0, 0, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.CYAN, TETRIS_ICON_SIZE)) );
      
              shape = new int[][]
              {
                  {0, 0, 0, 0},
                  {0, 1, 0, 0},
                  {1, 1, 1, 0},
                  {0, 0, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.WHITE, TETRIS_ICON_SIZE)) );
      
              shape = new int[][]
              {
                  {0, 0, 0, 0},
                  {0, 1, 1, 0},
                  {1, 1, 0, 0},
                  {0, 0, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.BLUE, TETRIS_ICON_SIZE)) );
      
              shape = new int[][]
              {
                  {0, 0, 0, 0},
                  {1, 1, 0, 0},
                  {0, 1, 1, 0},
                  {0, 0, 0, 0}
              };
      
              tetrisPieces.add( new TetrisPiece(shape, new TetrisIcon(Color.GREEN, TETRIS_ICON_SIZE)) );
          }
      
          class StartAction extends AbstractAction
          {
              public StartAction()
              {
                  super("Start Game");
              }
      
              @Override
              public void actionPerformed(ActionEvent e)
              {
                  new Timer(1000, new AbstractAction()
                  {
                      @Override
                      public void actionPerformed(ActionEvent e2)
                      {
                          if (board.getTetrisPiece() == null)
                          {
                              int piece = random.nextInt( tetrisPieces.size() );
                              board.setTetrisPiece( tetrisPieces.get( piece ) );
                          }
                          else
                          {
                              board.moveShapeDown();
                          }
                      }
                  }).start();
              }
          }
      
      
          private static void createAndShowGUI()
          {
      
              JFrame frame = new JFrame("Tetris");
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.add(new Tetris());
              frame.setLocationByPlatform( true );
              frame.pack();
              frame.setVisible( true );
          }
      
          public static void main(String[] args)
          {
              EventQueue.invokeLater( () -> createAndShowGUI() );
      /*
              EventQueue.invokeLater(new Runnable()
              {
                  public void run()
                  {
                      createAndShowGUI();
                  }
              });
      */
          }
      }
      

      TetrisBoard:

      import java.awt.*;
      import java.awt.event.*;
      import java.util.List;
      import java.util.ArrayList;
      import javax.swing.*;
      
      class TetrisBoard extends JPanel
      {
          private List<TetrisIcon[]> board;
      
          private int rows;
          private int columns;
          private int size;
      
          private TetrisPiece tetrisPiece;
      
          public TetrisBoard(int rows, int columns, int size)
          {
              this.rows = rows;
              this.columns = columns;
              this.size = size;
      
              board = new ArrayList<TetrisIcon[]>(rows);
      
              for (int i = 0; i < rows; i++)
                  board.add( new TetrisIcon[columns] );
      
              setBackground( Color.BLACK );
      
              addKeyBindings();
          }
      
          private void addKeyBindings()
          {
              InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
              ActionMap actionMap = getActionMap();
      
              String leftName = "LEFT";
              KeyStroke leftKeyStroke = KeyStroke.getKeyStroke( leftName );
              inputMap.put(leftKeyStroke, leftName);
              actionMap.put(leftName, new AbstractAction()
              {
                  @Override
                  public void actionPerformed(ActionEvent e)
                  {
                      moveShapeLeft();
                  }
              });
      
              String rightName = "RIGHT";
              KeyStroke rightKeyStroke = KeyStroke.getKeyStroke( rightName );
              inputMap.put(rightKeyStroke, rightName);
              actionMap.put(rightName, new AbstractAction()
              {
                  @Override
                  public void actionPerformed(ActionEvent e)
                  {
                      moveShapeRight();
                  }
              });
      
              String downName = "DOWN";
              KeyStroke downKeyStroke = KeyStroke.getKeyStroke( downName );
              inputMap.put(downKeyStroke, downName);
              actionMap.put(downName, new AbstractAction()
              {
                  @Override
                  public void actionPerformed(ActionEvent e)
                  {
      //              moveShapeDown();
                      dropShape();
                  }
              });
      
              String upName = "UP";
              KeyStroke upKeyStroke = KeyStroke.getKeyStroke( upName );
              inputMap.put(upKeyStroke, upName);
              actionMap.put(upName, new AbstractAction()
              {
                  @Override
                  public void actionPerformed(ActionEvent e)
                  {
                      rotateShape();
                  }
              });
          }
      
          public TetrisPiece getTetrisPiece()
          {
              return tetrisPiece;
          }
      
          public void setTetrisPiece(TetrisPiece tetrisPiece)
          {
              this.tetrisPiece = new TetrisPiece(tetrisPiece.getShape(), tetrisPiece.getIcon());
              this.tetrisPiece.setLocation( new Point(4, 0) );
              repaint();
          }
      
          public void setTetrisIconAt(TetrisIcon icon, int x, int y)
          {
              TetrisIcon[] row = board.get(y);
              row[x] = icon;
          }
      
          public TetrisIcon getTetrisIconAt(int x, int y)
          {
              TetrisIcon[] row = board.get(y);
      
              return row[x];
          }
      
          public void moveShapeLeft()
          {
              if (tetrisPiece == null) return;
      
              Point possibleLocation = new Point(tetrisPiece.getX() - 1, tetrisPiece.getY());
      
              if ( canMoveShape(possibleLocation, tetrisPiece.getShape()) )
              {
                  tetrisPiece.setLocation( possibleLocation );
                  repaint();
              }
          }
      
          public void moveShapeRight()
          {
              if (tetrisPiece == null) return;
      
              Point possibleLocation = new Point(tetrisPiece.getX() + 1, tetrisPiece.getY());
      
              if ( canMoveShape(possibleLocation, tetrisPiece.getShape()) )
              {
                  tetrisPiece.setLocation( possibleLocation );
                  repaint();
              }
          }
      
          public void dropShape()
          {
              if (tetrisPiece == null) return;
      
              Point possibleLocation = new Point(tetrisPiece.getX(), tetrisPiece.getY() + 1);
      
              while ( canMoveShape(possibleLocation, tetrisPiece.getShape()) )
              {
                  moveShapeDown();
                  possibleLocation = new Point(tetrisPiece.getX(), tetrisPiece.getY() + 1);
              }
      
      //      addTetrisPieceToBoard();
      //      tetrisPiece = null;
          }
      
          public void moveShapeDown()
          {
              if (tetrisPiece == null) return;
      
              Point possibleLocation = new Point(tetrisPiece.getX(), tetrisPiece.getY() + 1);
      
              if ( canMoveShape(possibleLocation, tetrisPiece.getShape()) )
              {
                  tetrisPiece.setLocation( possibleLocation );
                  repaint();
              }
              else
              {
                  tetrisPieceAtBottom();
              }
          }
      
          private void tetrisPieceAtBottom()
          {
              Point location = tetrisPiece.getLocation();
              int row = Math.min(rows, location.y + 4);
              row--;
      
              addTetrisPieceToBoard();
      
              int rowsRemoved = 0;
      
      
              for (; row >= location.y; row--)
              {
      //          System.out.println(row);
                  TetrisIcon[] icons = board.get(row);
      
                  if ( fullRow(row) )
                  {
                      board.remove(row);
                      rowsRemoved++;
                  }
              }
      
              for (int i = 0; i < rowsRemoved; i++)
                  board.add(0, new TetrisIcon[columns]);
      
              if (rowsRemoved > 0)
                  repaint();
          }
      
          private boolean fullRow(int row)
          {
              for (int column = 0; column < columns; column++)
              {
      //          System.out.println(row + " : " + column);
                  if ( getTetrisIconAt(column, row) == null)
                      return false;
              }
      
              return true;
          }
      
          private void addTetrisPieceToBoard()
          {
              int x = tetrisPiece.getX();
              int y = tetrisPiece.getY();
      
              for (int r = 0; r < tetrisPiece.getRows(); r++)
              {
                  for (int c = 0; c < tetrisPiece.getColumns(); c++)
                  {
                      TetrisIcon icon = tetrisPiece.getIconAt(r, c);
      
                      if (icon != null)
                      {
                          setTetrisIconAt(icon, x, y);
                      }
      
                      x++;
                  }
      
                  x = tetrisPiece.getX();
                  y++;
              }
      
              tetrisPiece = null;
          }
      
          public void rotateShape()
          {
              if (tetrisPiece == null) return;
      
              int[][] rotatedShape = tetrisPiece.getRotatedShape();
      
              if ( canMoveShape(tetrisPiece.getLocation(), rotatedShape) )
              {
                  tetrisPiece.setShape( rotatedShape );
                  repaint();
              }
          }
      
          private boolean canMoveShape(Point location, int[][] shape)
          {
              for (int r = 0; r < shape.length; r ++)
              {
                  for (int c = 0; c < shape.length; c++)
                  {
                      if (shape[r][c] == 1)
                      {
                          int x = location.x + c;
                          int y = location.y + r;
      
                          //  Past left edge
      
                          if (x < 0) return false;
      
                          //  Past right edge
      
                          if (x >= columns) return false;
      
                          //  Past bottom edge
      
                          if (y >= rows) return false;
      
                          //  Collision with TetrisIcon
      
                          if (getTetrisIconAt(x, y) != null) return false;
                      }
                  }
              }
      
              return true;
          }
      
          @Override
          public Dimension getPreferredSize()
          {
              int width = (columns * size) + columns - 1;
              int height = (rows * size) + rows - 1;
      
              return new Dimension(width, height);
          }
      
          @Override
          protected void paintComponent(Graphics g)
          {
              super.paintComponent( g );
      
              int x = 0;
              int y = 0;
              int offset = size + 1;
      
              for (int r = 0; r < rows; r++)
              {
                  TetrisIcon[] row = board.get(r);
      
                  for (int c = 0; c < row.length; c++)
                  {
                      TetrisIcon icon = row[c];
      
                      if (icon != null)
                      {
                          icon.paintIcon(this, g, x, y);
                      }
      
                      x += offset;
                  }
      
                  x = 0;
                  y += offset;
              }
      
              // paint shape
      
              if (tetrisPiece != null)
              {
                  paintShape(g, offset);
              }
          }
      
          private void paintShape(Graphics g, int offset)
          {
              int x = tetrisPiece.getX() * offset;
              int y = tetrisPiece.getY() * offset;
      
              for (int r = 0; r < tetrisPiece.getRows(); r++)
              {
                  for (int c = 0; c < tetrisPiece.getColumns(); c++)
                  {
                      TetrisIcon icon = tetrisPiece.getIconAt(r, c);
      
                      if (icon != null)
                      {
                          icon.paintIcon(this, g, x, y);
                      }
      
                      x += offset;
                  }
      
                  x = tetrisPiece.getX() * offset;
                  y += offset;
              }
          }
      }
      

      TetrisPiece:

      import java.awt.Point;
      
      public class TetrisPiece
      {
          private int[][] shape;
          private TetrisIcon icon;
          private Point location = new Point();
      
          public TetrisPiece(int[][] shape, TetrisIcon icon)
          {
              setShape(shape);
              this.icon = icon;
          }
      
          public TetrisIcon getIcon()
          {
              return icon;
          }
      
          public int[][] getShape()
          {
              return shape;
          }
      
          public void setShape(int[][] shape)
          {
              this.shape = shape;
          }
      
          public TetrisIcon getIconAt(int x, int y)
          {
              return  (shape[x][y] == 1) ? icon : null;
          }
      
          public Point getLocation()
          {
              return location;
          }
      
          public void setLocation(Point location)
          {
              this.location = location;
          }
      
          public int getX()
          {
              return location.x;
          }
      
          public int getY()
          {
              return location.y;
          }
      
          public int getRows()
          {
              return shape.length;
          }
      
          public int getColumns()
          {
              return shape[0].length;
          }
      
          public int[][] getRotatedShape()
          {
              int[][] rotatedShape = new int[shape.length][shape[0].length];
      
              int x = 0;
              int y = 0;
      
              for (int c = shape.length - 1; c >= 0; c--)
              {
                  for (int r = 0; r < shape[0].length; r++)
                  {
                      rotatedShape[x][y] = shape[r][c];
                      y++;
                  }
      
                  x++;
                  y = 0;
              }
      
              return rotatedShape;
          }
      
      }
      

      TetrisIcon:

      import java.awt.*;
      import javax.swing.*;
      
      public class TetrisIcon implements Icon
      {
          private Color color;
          private int size;
      
          public TetrisIcon(Color color, int size)
          {
              this.color = color;
              this.size = size;
          }
      
          public int getIconWidth()
          {
              return size;
          }
      
          public int getIconHeight()
          {
              return size;
          }
      
          public void paintIcon(Component c, Graphics g, int x, int y)
          {
              int width = getIconWidth() - 1;
              int height = getIconHeight() - 1;
      
              g.translate(x, y);
      
              g.setColor(color);
              g.fillRect(0, 0, width, height);
      
              g.setColor(Color.LIGHT_GRAY);
              g.drawLine(0, 0, width, 0);
              g.drawLine(0, 0, 0, height);
      
              g.setColor(Color.DARK_GRAY);
              g.drawLine(width, 0, width, height);
              g.drawLine(0, height, width, height);
      
              g.translate(-x, -y);
          }
      }