GUI manipulations for board game

2019-04-17 06:00发布

I am totally new to java and I want to create a single-player board game in Java.

I have already many classes that define the game, but, for my question, I will limit the question to creating a GUI board for my board game.
My very concrete questions are, based on the code below :

  1. How can I move a player on the board game ? (class Player exists)
  2. Is this the correct way to create a Java board with GUI, are there better alternatives?
  3. How can I only set a specific part of the board game as visible ? (and this needs to change when the player moves!)

Thanks in advance for decent answers. Because I am very new to java, please explain your answers in a clear way.

this is the output of the code below:

output of the code

import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;

public class SwingPaintDemo3 {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGUI(); 
            }
        });
    }

    private static void createAndShowGUI() {
        System.out.println("Created GUI on EDT? "+
        SwingUtilities.isEventDispatchThread());
        JFrame f = new JFrame("Single Player Game");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        f.add(new MyPanel());
        f.pack();
        f.setVisible(true);
    } 
}

    class MyPanel extends JPanel {


        private int squareX = 50;
        private int squareY = 50;
        private int squareW = 20;
        private int squareH = 20;

        public MyPanel() {

            setBorder(BorderFactory.createLineBorder(Color.black));


   public Dimension getPreferredSize() {
        return new Dimension(250,200);
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);       
        g.drawString("This is the game board ",10,20);
        g.setColor(Color.GREEN);
        g.fillRect(squareX,squareY,squareW,squareH);
        g.setColor(Color.BLACK);
        g.drawRect(squareX,squareY,squareW,squareH);
        g.drawRect(squareX+20,squareY,squareW,squareH);
        g.drawRect(squareX+40,squareY,squareW,squareH);
        g.drawRect(squareX+60,squareY,squareW,squareH);
        g.drawRect(squareX+60,squareY,squareW,squareH);
        g.drawRect(squareX+80,squareY,squareW,squareH);
        g.drawRect(squareX,squareY+20,squareW,squareH);
        g.drawRect(squareX+20,squareY+20,squareW,squareH);
        g.drawRect(squareX+40,squareY+20,squareW,squareH);
        g.drawRect(squareX+60,squareY+20,squareW,squareH);
        g.drawRect(squareX+80,squareY+20,squareW,squareH);
        g.drawRect(squareX,squareY+40,squareW,squareH);
        g.drawRect(squareX+20,squareY+40,squareW,squareH);
        g.drawRect(squareX+40,squareY+40,squareW,squareH);
        g.drawRect(squareX+60,squareY+40,squareW,squareH);
        g.drawRect(squareX+80,squareY+40,squareW,squareH);

    }  
} 

2条回答
我欲成王,谁敢阻挡
2楼-- · 2019-04-17 06:30

For pretty much all of these questions, you need to create a method to draw a specific place on the board. You should maintain the board separate from the graphical representation - eg as places with coordinates from (0,0) to (5,3). Those can be transformed into the actual graphics. Now you can go through each of the coordinates of the board, determine what's on it (player/free/out of visibility range) and draw it accordingly.

As for "are there better methods": I'm sure there are, but go with this. Since you're just starting off, it's as good a place as any.

查看更多
Explosion°爆炸
3楼-- · 2019-04-17 06:38

The following is an mcve demonstrating a very basic implementation of game board and player using Model-View-Controller pattern.
The model in this pattern holds all the information the view needs ("I already have a separate Class 'Board.Java' with a matrix representation of the board game including coordinates" is a model).
The view is just that, and the controller links the view and the model, and orchestrate the show:

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 GameControler {

    private Model model;
    private View view;

    public GameControler() {

        model = new Model();
        view = new View(model);
        view.getButton().addActionListener(e-> movePlayer());
    }

    //move player to a random position for demo purpose only 
    private void movePlayer() {
        final Random rnd = new Random();
        model.setPlayerX(rnd.nextInt(100));//arbitrary limit which maybe outside bounds
        model.setPlayerY(rnd.nextInt(100));//arbitrary limit which maybe outside bounds
        view.refresh();
    }

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

class View {

    private final static int GAP = 2;
    Model model;
    private MainPanel mainPanel;

    View(Model model){
        this.model = model;
        createAndShowGUI();
    }

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

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

    JButton getButton() {   return mainPanel.getButton();   }

    class MainPanel extends JPanel {

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

        JButton getButton() {   return bPanel.getButton();  }
    }

    class TopPanel extends JPanel {
        TopPanel() {
            setLayout(new FlowLayout(FlowLayout.LEADING));
            add(new JLabel("This is the game board "));
        }
    }

    class BoardPanel extends JPanel {

        Player player;

        BoardPanel()   {

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

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

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

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

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

    class Tile extends JLabel {

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

    class Player extends JLabel{

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

    class BottomPanel extends JPanel {

        JButton button = new JButton("Move Player");

        BottomPanel(){
            add(button);
        }

        JButton getButton() {   return button;  }
    }
}

class Model{

    private int boardRows = 3, boardCols = 5, squareSize = 50;
    private int playerX = 0, playerY = 0, playerSize =15;

    int getPlayerX() {  return playerX; }

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

    int getPlayerY() {return playerY;   }

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

    int getPlayerSize() {return playerSize; }

    int getBoardRows() {return boardRows; }

    int getBoardCols() {return boardCols; }

    int getSquareSize() {return squareSize; }
}

enter image description here

The code can be copy pasted into one file (GameControler.java) and run. Please review, modify to your needs and ask where you need clarifications.

查看更多
登录 后发表回答