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

2024-04-24

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

一切都很顺利,但我对让程序在第一个停止移动时向框架添加新的方块形状背后的逻辑感到困惑。到目前为止,我使用随机数生成器随机创建四边形,并将其添加到框架中。我只是不知道如何循环它,以便一旦该形状停止移动,它就会在屏幕顶部添加另一个形状。

这是一个 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();
    }


}

预先感谢您的任何帮助。我相信,一旦解决了这个问题,我就可以实现程序的其余部分,因为我似乎不知道如何让形状继续下降。


我只是不知道如何循环它,以便一旦该形状停止移动,它就会在屏幕顶部添加另一个形状。

在你的计时器逻辑中你有:

component.moveRectangleBy(dx,dy);

因此,这假设您始终有一个“活动”组件。您需要能够确定组件何时位于底部,以便可以重置组件。

因此,您可以重构您的侦听器代码,使其看起来像这样:

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. 删除整行

基本设计分为 4 类:

  1. TetrisIcon - 绘制一个带边框的正方形
  2. TetrisPiece - 俄罗斯方块的 4x4 数组表示。值为 1 表示应绘制 TetricIcon。
  3. TetrisBoard - 包含要绘制的俄罗斯方块图标列表以及当前在棋盘上移动的俄罗斯方块。当俄罗斯方块到达底部时,其各个俄罗斯方块图标将被移动到棋盘上。
  4. 俄罗斯方块 - 构建框架并开始游戏。

如果你想玩它,那就玩得开心:

Tetris:

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();
            }
        });
*/
    }
}

俄罗斯方块板:

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;
        }
    }
}

俄罗斯方块块:

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;
    }

}

俄罗斯方块图标:

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);
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

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

随机推荐

  • 为什么没有用户代理为视频元素实现 CSS 光标样式

    我想知道是否可以更改 CSS 属性cursor在默认 HTML5 上video元素 到目前为止 我的测试已经得出结论 没有用户代理 浏览器 实现cursor pointer默认情况下 所以你只剩下正常的操作系统箭头 控制指示器 当您尝试设置
  • “未捕获的引用错误:窗口未定义”p5.js Web Worker

    我有一个 javascript 代码 我将网络工作者与 p5 js 库一起使用 它不允许我使用 p5 的任何功能 所以我必须使用importScripts p5 js 在使用 p5 的任何函数之前导入 p5 js 库的函数 onmessag
  • Swift 泛型类作为委托

    我在 swift 中使用泛型类作为委托时遇到了问题 例如我尝试使用通用 NSFetchedResultsDelegate 定义为 class FetchedTableController
  • 使用 React 和 webpack 4 拆分项目; html 标签是意外的标记

    背景 我正在使用 React babel webpack4 和 es6 或者可能是 es7 我有一些模块被多个反应项目重用 因此 我创建了一个包含这些模块的 标准 文件夹 以便它们与任何特定项目分开 Problem 在我的 React 项目
  • 为 WinSocks 和 *nix 制作非阻塞套接字

    在 C C 中 如何将 WinSocks 和 nix 中的阻塞套接字转换为非阻塞套接字 这样 select 就能正常工作 您可以将预处理器用于特定于平台的代码 在Linux上 fcntl fd F SETFL O NONBLOCK Wind
  • Java 中的合成字段是什么? [复制]

    这个问题在这里已经有答案了 有人可以用一种易于理解的方式解释 Java 中合成字段的重要性吗 我记得在非静态内部类的上下文中阅读它 其中每个此类内部类实例都维护对封闭类的引用 为什么这样的引用 字段被称为合成字段 合成字段是编译器创建的字段
  • Xcode 永远快速索引

    我目前正在使用 swift 和 Xcode 6 Beta 3 开发一个 iOS 应用程序 到目前为止一切都很顺利 但现在随着我的项目的增长 Xcode 突然开始索引 并且一次又一次地这样做 使得 Xcode 几乎无法使用 我在网上搜索了类似
  • aws CLI 比使用 boto3 更快吗?

    我有存储在 s3 存储桶中的包 我需要读取每个包的元数据文件并将元数据传递给程序 我用了boto3 resource s3 在 python 中读取这些文件 该代码需要几分钟才能运行 如果我使用 aws clisync 它下载这些图元文件的
  • 更好的 boost asio Deadline_timer 示例

    我正在寻找一个更好的例子boost asio deadline timer 给出的例子总是会超时并调用close方法 我尝试打电话cancel 在计时器上但这会导致函数传递到async wait立即被呼叫 在异步 tcp 客户端中使用计时器
  • 使用 Ant 遍历目录

    假设我有一个包含以下路径的 PDF 文件集合 some path pdfs birds duck pdf some path pdfs birds goose pdf some path pdfs insects fly pdf some
  • 异步 REST API 生成警告

    我正在使用 Spring boot 应用程序 我有一个返回 Callable 的休息控制器 GetMapping fb roles Timed public Callable
  • 在 UIView 子类中调用drawRect

    我已经对 UIView 进行了子类化 并且实现了一个 drawRect 我基本上希望在设置 CGPoint 这是此 UIView 的一个属性 之后调用此 drawRect 我该怎么做呢 这是我的代码 id initWithCoder NSC
  • 根据请求创建 Hibernate-Session

    我刚刚启动了一个简单的 Java 测试项目 它使用 Hibernate 管理一些实体 并提供 REST 接口来操作这些对象并提供一些额外的业务逻辑 REST 接口是使用 RESTEasy 和 Jetty 创建的 到目前为止 一切工作正常 但
  • 如何在不循环的情况下找到小于一个数的最大二的幂? [关闭]

    这个问题不太可能对任何未来的访客有帮助 它只与一个较小的地理区域 一个特定的时间点或一个非常狭窄的情况相关 通常不适用于全世界的互联网受众 为了帮助使这个问题更广泛地适用 访问帮助中心 help reopen questions 如何在不循
  • Python Sci-Kit 学习:多标签分类 ValueError:无法将字符串转换为浮点数:

    我正在尝试使用 scikit learn 0 17 进行多标签分类 我的数据看起来像 training Col1 Col2 asd dfgfg 1 2 3 poioi oiopiop 4 test Col1 asdas gwergwger
  • Android 版 Eclipse 中的“调试为...”

    我是一名 Android 菜鸟 正在 Eclipse Galileo 3 52 环境中自学调试 我有一个小的 hello world 应用程序 可以在模拟器中正常运行 所以现在我想通过设置断点 查看变量等来练习调试 但是 运行 gt 调试为
  • MATLAB:让audioplayer()在函数结束后继续播放

    我正在使用使用以下子函数的代码 function playTone duration toneFreq Generate a tone samplesPerSecond 44100 the bit rate of the tone y si
  • 未安装分发证书/私钥

    使用 Xcode 9 1 构建 iOS 应用程序后 我想将其存档并将其上传到 appStore 进行 beta 测试 但点击按钮后出现以下问题Upload to the App Store 并选择Automatically manage s
  • 在 mvc3 中公开实体或 DTO 以查看的最佳实践是什么?

    我创建了自己定制的大量架构 包括针对不同技术的 n 层 目前正在使用 asp net mvc 框架进行 n 层架构 问题是我在数据访问层有实体框架 由于实体将拥有所有关系元数据和导航属性 因此它变得更重 我觉得直接通过 mvc 视图公开这些
  • 在俄罗斯方块项目中添加其他形状。循环逻辑辅助

    我正在创建一个俄罗斯方块克隆作为个人项目 以帮助我更好地绘制图像 移动图像以及学习碰撞检测 一切都很顺利 但我对让程序在第一个停止移动时向框架添加新的方块形状背后的逻辑感到困惑 到目前为止 我使用随机数生成器随机创建四边形 并将其添加到框架