Java游戏:根据玩家的位置限制棋盘的可见性

时间:2018-12-16 20:23:21

标签: java swing mask paintcomponent

我想将游戏板的可见性限制在玩家以外的X个单元格内(并且在玩家移动时会自动更新)。另请参见下图...

例如,我用黄线划出的区域)并在玩家移动时自动更新。

import java.io.*;
import java.lang.*;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.util.Random;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

public class Mov {

    private final MoveModel moveModel;
    private final Showvisible showvisible;

    public Mov() {
        moveModel = new MoveModel();
        showvisible = new Showvisible(moveModel);
        showvisible.getRndMoverButton().addActionListener(e-> movePlayer());
        showvisible.getMoveEastButton().addActionListener(e-> movePlayerX(50));
    }

    //move player to a random position (works fine)
    private void movePlayer() {
        final Random rnd = new Random();
        moveModel.setPlayerX(rnd.nextInt(100));
        moveModel.setPlayerY(rnd.nextInt(100));
        showvisible.refresh();
    }

    //Move player in the x direction to the East (positive) or west (negative 
    private void movePlayerX(final int distance) {
        moveModel.setPlayerX(moveModel.getPlayerX()+distance);
        showvisible.refresh();
    }

    public static void main(final String[] args) {
        new Mov();
    }
}

class Showvisible {

    private final static int GAP = 2;
    MoveModel MoveModel;
    private MainPanel mainPanel;

    Showvisible(final MoveModel MoveModel){
        this.MoveModel = MoveModel;
        createAndShowGUI();
    }

    void refresh() {
        mainPanel.repaint();
    }

    private void createAndShowGUI() {
        final JFrame board = new JFrame("Single Player Game");
        board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainPanel = new MainPanel();
        board.add(mainPanel);
        board.pack();
        board.setVisible(true);
    }

    JButton getRndMoverButton() {   return mainPanel.getRndMoverButton();   }
    JButton getMoveEastButton() { return mainPanel.getMoveEastButton(); }

    class MainPanel extends JPanel {

        private final BottomPanel bPanel;

        MainPanel() {
            setLayout(new BorderLayout(GAP,GAP));
            add(new TopPanel(), BorderLayout.PAGE_START);
            add(new BoardPanel(), BorderLayout.CENTER);
            bPanel = new BottomPanel();
            add(bPanel, BorderLayout.PAGE_START);
        }

        JButton getRndMoverButton() {   return bPanel.getRndMoverButton();  }
        JButton getMoveEastButton() { return bPanel.getMoveEastButton(); }

    }

    class TopPanel extends JPanel {
        TopPanel() {
            setLayout(new FlowLayout(FlowLayout.CENTER));
            add(new JLabel("This is an amazing game "));
        }
    }

    class BoardPanel extends JPanel {

        Player player;

        BoardPanel()   {

            setBorder(BorderFactory.createLineBorder(Color.BLACK, GAP));
            final GridLayout layout = new GridLayout(MoveModel.getBoardRows(),
                    MoveModel.getBoardCols());
            setLayout(layout);

            for (int i = 0; i <MoveModel.getBoardRows(); i++)   {

                for (int j = 0; j < MoveModel.getBoardCols(); j++)  {
                    add(new Tile());
                }
            }

            player = new Player();
            player.setBounds(new Rectangle(1000,1000, 1000,1000));
        }

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            player.paint(g);
        }
    }

    class Tile extends JLabel {

        Tile() {
            setPreferredSize(new Dimension(MoveModel.getSquareSize(), MoveModel.getSquareSize()));
            setBorder(BorderFactory.createLineBorder(Color.ORANGE, GAP));
        }
    }

    class Player extends JLabel{

        @Override
        protected void paintComponent(final Graphics g) {
            super.paintComponent(g);
            g.setColor(Color.RED);
            g.fillRect(MoveModel.getPlayerX(), MoveModel.getPlayerY(), MoveModel.getPlayerSize(),MoveModel.getPlayerSize());
        }
    }

    class BottomPanel extends JPanel {

        JButton rndMoveButton = new JButton("Random Move");
        JButton moveEastButton =new JButton("move East");


        BottomPanel(){
            add(rndMoveButton);
            add(moveEastButton);

        }

        JButton getRndMoverButton() {   return rndMoveButton;  }
        JButton getMoveEastButton() { return moveEastButton; }
    }
}

class MoveModel{

    private final int boardRows = 9, boardCols = 9, squareSize = 50;
    int playerX = 0;
    private int playerY = 0;
    private final int playerSize =25;
    int getPlayerX() {  return playerX; }

    void setPlayerX(final int playerX) {  this.playerX = playerX; }

    int getPlayerY() {return playerY;   }

    void setPlayerY(final int playerY) {  this.playerY = playerY; }

    int getPlayerSize() {return playerSize; }

    int getBoardRows() {return boardRows; }

    int getBoardCols() {return boardCols; }

    int getSquareSize() {return squareSize; }
}

输出:

output

1 个答案:

答案 0 :(得分:0)

绘画BoardPanel时,您可以用蒙版颜色(黑色)遮盖整个区域,并清除蒙版的一部分:

@Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        //mask all over
        g.setColor(Color.BLACK);
        g.fillRect(0, 0,getWidth(), getHeight());
        //clear part of mask
        Rectangle r = getVisibleBounds();
        g.clearRect(r.x, r.y, r.width, r.height); 
        player.paint(g);
    }

    private Rectangle getVisibleBounds() {
        //bounds returned may be outside painted area 
        return new Rectangle(moveModel.getPlayerX() - VISIBLE_SIZE/ 2,
                moveModel.getPlayerY() - VISIBLE_SIZE/ 2, VISIBLE_SIZE, VISIBLE_SIZE);
    }

可以从here复制粘贴完整的一文件(Mov.java)代码