0

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

    }  
} 
c0der
  • 18,467
  • 6
  • 33
  • 65
BramV
  • 59
  • 1
  • 8
  • For the board game consider using standard a layout manager (for example `GridLayout`) and add to it components (like `JLabel`). See the `BoardPanel` [here](https://stackoverflow.com/a/51751213/3992939). Also please stick to the site policy of one focused question per post. – c0der Dec 03 '18 at 11:58

2 Answers2

2

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.

c0der
  • 18,467
  • 6
  • 33
  • 65
  • any idea how to replace the random move with a user-defined move ? (I mean, specifically how to replace the model.setPlayerX(rnd.nextInt(100)) by e.g. move with 1 gridcell in the X direction ? ) – BramV Dec 08 '18 at 16:59
  • `private void movePlayerX(int distance) { model.setPlayerX(distance); }` is the easy part. You need to define `distance`. – c0der Dec 08 '18 at 17:30
  • Yes, I have for example defined distance as int 50, as combined with the code you provided. But there happens nothing. What I don't understand is that, while rnd.NextInt(100) works fine while you can't do an easy x+50 or y+50 ?. (Of course, the final purpose is to move with one gridcel and that should be- in my code- 50, so a simple method to move the player from the current position to x+50 and y+50 (and x-50 and y-50 is OK ). (It also works also to set the player at a specified position, it is really the PLUS and MINUS from the current position that fails ) – BramV Dec 08 '18 at 18:06
  • `while you can't do an easy x+50 or y+50 ?` you can – c0der Dec 08 '18 at 18:10
  • yes probably, but how? I have tried a range of variations in code, but none of them works (e.g. model.setPlayerX(distance); , model.setPlayerX(PlayerX+distance), model.setPlayerX(+50), model.SetPlayerX(+distance), ... – BramV Dec 08 '18 at 18:38
  • Post a question with mcve of your attempt and leave me a message here – c0der Dec 09 '18 at 05:05
  • new question: https://stackoverflow.com/questions/53690759/move-object-added-to-grid-over-specified-number-of-gridcells-in-user-specified – BramV Dec 09 '18 at 08:59
0

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.

daniu
  • 14,137
  • 4
  • 32
  • 53
  • Thanks, I already have a separate Class 'Board.Java' with a matrix representation of the board game including coordinates (matrix printed in the console as numbers), but I have no idea how I can couple - with a sperate class GUI - transform this board into a GUI representation with a player that can move and objects on the board. What I actually not understand and I have totally no idea how to do (that's why i created a new board in the GUI class), is how to make the coupling between the 'Board Class'/Player Class and the GUI. Is it possible to explain this simply with sample code? – BramV Dec 03 '18 at 12:40