在俄罗斯方块项目中添加其他形状.循环逻辑协助 [英] Adding additional shapes in a tetris project. loop logic assistance

查看:125
本文介绍了在俄罗斯方块项目中添加其他形状.循环逻辑协助的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am creating a tetris clone as a personal project to help me get better at drawing images, moving them, and to learn collision detection.

一切都很好,但是让我感到困惑的是,当第一个程序停止移动时,让程序向帧中添加新的tetrimino形状的逻辑背后.到目前为止,我已经使用随机数生成器随机创建了一个Tetrimino,并将其添加到框架中.我只是不知道如何循环播放,因此一旦该形状停止移动,它就会在屏幕顶部添加另一个形状.

Everything is going fine but I am stumped at the logic behind getting the program to add a new tetrimino shape to the frame when the first has stopped moving. So far I use a random number generator to create a tetrimino at random, and can add that to the frame. I just can't figure out how to loop it so that once that shape stops moving it adds another shape at the top of the screen.

这是Alpha之前的版本,在当前的实现中,我尚未添加碰撞检测,任何评分,背景,旋转形状的功能等.我只是无法克服这个逻辑障碍.请帮忙!

This is a pre alpha build and in its current implementation I have not yet added the collision detection, any scoring, backgrounds, ability to rotate shapes, etc. I just can't get past this logic roadblock. Please help!

一些代码:

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

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

And here is the code of one of the shapes classes in case you need to reference that:

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


}

在此先感谢您的帮助.我有信心,一旦解决了这个问题,我似乎可以实现该程序的其余部分,而我似乎无法弄清楚如何使形状保持下降.

Thanks in advance for any help. I'm confident I can implement the rest of the program once I get past this issue where I just can't seem to figure out how to get the shapes to keep coming down.

推荐答案

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

I just can't figure out how to loop it so that once that shape stops moving it adds another shape at the top of the screen.

在您的计时器逻辑中,您有:

Well in your Timer logic you have:

component.moveRectangleBy(dx,dy);

因此,这假定您始终有一个活动"组件.您需要具有确定组件何时位于底部的能力,以便您可以重置组件.

So this assumes you always have an "active" component. You need the ability to determine when the component is at the bottom so you can reset the component.

因此您可以重组您的侦听器代码,使其类似于:

So you might restructure your listener code to look something like:

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

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

对于它的价值,我也玩过自己的俄罗斯方块游戏.当前:

For what its worth, I have also played with my own Tetris game. It currently:

  1. 添加随机片段
  2. 将棋子向下移动
  3. 使用4个箭头键移动/旋转俄罗斯方块
  4. 删除整行

基本设计分为4类:

  1. TetrisIcon-绘制带有边框的正方形
  2. TetrisPiece-俄罗斯方块的4x4数组表示形式.值1表示应绘制TetricIcon.
  3. TetrisBoard-包含要绘制的TetrisIcons列表以及在板上向下移动的当前TetrisPiece.当TetrisPiece到达底部时,它的各个TetrisIcons将移到板上.
  4. 俄罗斯方块-构建框架并开始游戏.

如果您想玩它,那就玩得开心

If you want to play with it, have fun:

俄罗斯方块:

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:

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:

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:

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

这篇关于在俄罗斯方块项目中添加其他形状.循环逻辑协助的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆