2015-11-24 47 views
0

好吧,我正在製作壟斷遊戲。我到目前爲止有JFrameJPanel充當董事會。我已經加載了所有必要的圖像。我創建了一個Player對象,它擴展了JLabel,以表示棋盤上的球員。無法移動JPLnel上的JLabel

我想設置的位置(希望在棋盤周圍移動棋子)Player對象(這是一個JLabel),在板上(這是一個JPanel)。我嘗試了.setLocation方法,.setBounds方法。

由於某種原因,不管我做什麼Player對象只顯示在JPanel的頂部中間。我想知道如何將Player物體移動到我的主板上。

JFrame代碼(我試圖在構造底部移動JLabel):

package com.Game.Monopoly; 

    import javax.imageio.ImageIO; 
    import javax.swing.ImageIcon; 
    import javax.swing.JButton; 
    import javax.swing.JFrame; 
    import javax.swing.JLabel; 
    import javax.swing.JList; 
    import javax.swing.JPanel; 
    import javax.swing.JScrollPane; 
    import javax.swing.JTextArea; 
    import javax.swing.Timer; 

    import java.awt.Color; 
    import java.awt.Dimension; 
    import java.awt.Graphics; 
    import java.awt.Image; 
    import java.awt.LayoutManager; 
    import java.awt.Point; 
    import java.awt.SystemColor; 
    import java.awt.event.ActionEvent; 
    import java.awt.event.ActionListener; 
    import java.awt.image.BufferedImage; 
    import java.io.IOException; 

    import net.miginfocom.swing.MigLayout; 

    //a class that represent the board (JFrame) and all of it components 
    public class GameFrame extends JFrame { 
     private final double SCALE; 
     // all the graphical components 
     private Board board; 
     private JLabel lblPlayerMoney; 
     private JLabel lblCurrentPlayer; 
     private JLabel lblDice1; 
     private JLabel lblDice2; 
     private JList lstPropertiesList; 
     private JButton btnEndTurn; 
     private JButton btnBuyProperty; 
     private JButton btnRollDice; 

     // all images needed 
     private ImageIcon imgDice1; 
     private ImageIcon imgDice2; 
     private ImageIcon imgDice3; 
     private ImageIcon imgDice4; 
     private ImageIcon imgDice5; 
     private ImageIcon imgDice6; 
     private ImageIcon icnAirplane; 

     // all players 
     private Player[] playerList; 
     // all properties 
     private Property[] propertiesList; 

     public GameFrame(double scale) { 
      // SCALE = scale; 
      SCALE = 1; 

      // set up the JFrame 
      setResizable(true); 
      setTitle("Monopoly"); 
      // etUndecorated(true); 
      // set size to a scale of 1080p 
      setSize((int) (1920 * SCALE), (int) (1080 * SCALE)); 
      setLayout(new MigLayout()); 
      loadImages(); 

      // add the components to the frame 
      board = new Board(SCALE); 
      board.setPreferredSize(new Dimension((int) (1024 * SCALE), 
        (int) (1024 * SCALE))); 
      board.setBackground(Color.BLACK); 
      add(board, "east, gapbefore 80"); 
      lblCurrentPlayer = new JLabel("Current Player:" + " Player 1"); 
      add(lblCurrentPlayer, "wrap"); 
      lblPlayerMoney = new JLabel("Player1's money:" + "$14000000"); 
      add(lblPlayerMoney, "wrap"); 
      lstPropertiesList = new JList(); 
      add(new JScrollPane(lstPropertiesList), 
        "span 2 2, grow, height 70:120:200"); 
      btnRollDice = new JButton("Roll Dice"); 
      add(btnRollDice, "wrap"); 
      lblDice1 = new JLabel(imgDice1); 
      add(lblDice1); 
      lblDice2 = new JLabel(imgDice1); 
      add(lblDice2, "wrap"); 
      btnBuyProperty = new JButton("Buy Property"); 
      add(btnBuyProperty, "wrap, top"); 
      btnEndTurn = new JButton("End Turn"); 
      add(btnEndTurn, "aligny bottom"); 

      setUpEventListeners(); 
      loadProperties(); 

      // load players 
      playerList = new Player[6]; 
      playerList[0] = new Player("Player 1", icnAirplane); 

      // add Players to the board 

      board.add(playerList[0]); 
      playerList[0].setLocation(new Point(500, 230)); 
     } 

     public static void main(String[] args) { 
      GameFrame board = new GameFrame(1); 
      board.setVisible(true); 

     } 

     // method to add event listeners 
     public void setUpEventListeners() { 

      // roll dice 
      btnRollDice.addActionListener(new ActionListener() { 
       // creates an object with an timers to help with rolling dice 
       class RollDice implements ActionListener { 
        private Timer time = new Timer(152, this); 
        private int count = 0; 

        public void actionPerformed(ActionEvent e) { 
         count++; 
         if (count == 21) 
          time.stop(); 

         int whatDice1 = (int) (Math.random() * 6) + 1; 
         int whatDice2 = (int) (Math.random() * 6) + 1; 

         // set the icons of the labels according to the random 
         // number 

         if (whatDice1 == 1) 
          lblDice1.setIcon(imgDice1); 
         else if (whatDice1 == 2) 
          lblDice1.setIcon(imgDice2); 
         else if (whatDice1 == 3) 
          lblDice1.setIcon(imgDice3); 
         else if (whatDice1 == 4) 
          lblDice1.setIcon(imgDice4); 
         else if (whatDice1 == 5) 
          lblDice1.setIcon(imgDice5); 
         else if (whatDice1 == 6) 
          lblDice1.setIcon(imgDice6); 

         if (whatDice2 == 1) 
          lblDice2.setIcon(imgDice1); 
         else if (whatDice2 == 2) 
          lblDice2.setIcon(imgDice2); 
         else if (whatDice2 == 3) 
          lblDice2.setIcon(imgDice3); 
         else if (whatDice2 == 4) 
          lblDice2.setIcon(imgDice4); 
         else if (whatDice2 == 5) 
          lblDice2.setIcon(imgDice5); 
         else if (whatDice2 == 6) 
          lblDice2.setIcon(imgDice6); 
        } 

        public void roll() { 
         count = 0; 
         time.start(); 
        } 
       } 

       // create a new dice roll object 
       RollDice roll = new RollDice(); 

       // if the roll dice button is clicked 
       public void actionPerformed(ActionEvent arg0) { 
        roll.roll(); 
       } 

      }); 

     } 

     // load all images to memory 
     public void loadImages() { 
      BufferedImage i = null; 
      try { 
       i = ImageIO.read((getClass().getResource("/resources/Dice 1.png"))); 
       imgDice1 = new ImageIcon(i.getScaledInstance(100, 100, 
         java.awt.Image.SCALE_SMOOTH)); 

       i = ImageIO.read((getClass().getResource("/resources/Dice 2.png"))); 
       imgDice2 = new ImageIcon(i.getScaledInstance(100, 100, 
         java.awt.Image.SCALE_SMOOTH)); 

       i = ImageIO.read((getClass().getResource("/resources/Dice 3.png"))); 
       imgDice3 = new ImageIcon(i.getScaledInstance(100, 100, 
         java.awt.Image.SCALE_SMOOTH)); 

       i = ImageIO.read((getClass().getResource("/resources/Dice 4.png"))); 
       imgDice4 = new ImageIcon(i.getScaledInstance(100, 100, 
         java.awt.Image.SCALE_SMOOTH)); 

       i = ImageIO.read((getClass().getResource("/resources/Dice 5.png"))); 
       imgDice5 = new ImageIcon(i.getScaledInstance(100, 100, 
         java.awt.Image.SCALE_SMOOTH)); 

       i = ImageIO.read((getClass().getResource("/resources/Dice 6.png"))); 
       imgDice6 = new ImageIcon(i.getScaledInstance(100, 100, 
         java.awt.Image.SCALE_SMOOTH)); 

       i = ImageIO.read((getClass() 
         .getResource("/resources/Airplane Icon.png"))); 
       icnAirplane = new ImageIcon(i.getScaledInstance(40, 40, 
         java.awt.Image.SCALE_SMOOTH)); 

      } catch (IOException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 

     // load all properties 
     public void loadProperties() { 
      propertiesList = new Property[40]; 

      // set up the properties list 
      // (name, index, isBuyable, price, initial rent) 
      propertiesList[0] = new Property("Go", 0, false, 0, 0); 
      propertiesList[1] = new Property("Jacob's Field", 1, true, 600000, 
        20000); 
      propertiesList[2] = new Property("Community Chest", 2, false, 0, 0); 
      propertiesList[3] = new Property("Texas Stadium", 3, true, 600000, 
        40000); 
      propertiesList[4] = new Property("Income Tax", 4, false, 0, 0); 
      propertiesList[5] = new Property("O'Hare International Airport", 5, 
        true, 2000000, 250000); 
      propertiesList[6] = new Property("Grand Ole Opry", 6, true, 1000000, 
        60000); 
      propertiesList[7] = new Property("Chance", 7, false, 0, 0); 

     } 
    } 

JPanel代碼:

package com.Game.Monopoly; 

import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Image; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.net.URL; 

import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JPanel; 

public class Board extends JPanel { 
    private static final long serialVersionUID = 1L; 
    private Image board; 

    public Board(double scale) { 
     this.setPreferredSize(new Dimension((int) (1024 * scale), 
       (int) (1024 * scale))); 

     BufferedImage i = null; 
     try { 
      i = ImageIO.read((getClass().getResource("/resources/monopoly-board-web.jpg"))); 

     } catch (IOException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } 
     board = i.getScaledInstance((int) (1024 * scale), (int) (1024 * scale), java.awt.Image.SCALE_SMOOTH); 

    } 

    public void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     g.drawImage(board, 0, 0, this); 
    } 

} 

Player對象代碼:

package com.Game.Monopoly; 

import javax.swing.ImageIcon; 
import javax.swing.JLabel; 

//a class representing a player with its graphical component 
public class Player extends JLabel { 

    private String playerName; 
    private int money; 
    private Property[] propertiesOwned; 

    public Player(String n, ImageIcon icon) { 
     playerName = n; 
     this.setIcon(icon); 
    } 

    // changes the amount of money available 
    public void changeMoney(int amount) { 
     money = money + amount; 
    } 

    public void movePlayer(int x, int y){ 
     this.setLocation(x, y); 
    } 

} 
+1

你正在與佈局管理器作鬥爭,我相信默認情況下使用的是「FlowLayout」 。在這裏,你最好設計一個自己的佈局管理器來支持你的Board,並允許你在虛擬座標中指定組件的位置(比如單元格或「遊戲位置」),然後將其轉換由佈局經理來實際的座標 – MadProgrammer

回答

4

有有幾種方法可以幫助你就個人而言,最簡單的就是直接使用自定義繪畫,而不用爲玩家使用基於Swing的組件。

你有的基本問題是JPanel默認情況下使用FlowLayout,這意味着你將永遠與佈局管理器搏鬥。在這種情況下,你可能會考慮使用自定義佈局管理器,例如...

Monopoly

import java.awt.Component; 
import java.awt.Container; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.LayoutManager2; 
import java.awt.Point; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.IOException; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import java.util.Random; 
import javax.imageio.ImageIO; 
import javax.swing.ImageIcon; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JPanel; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Monopoly { 

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

    public Monopoly() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new MonopolyBoard()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class MonopolyBoard extends JPanel { 

     private List<JLabel> players; 

     public MonopolyBoard() { 
      setLayout(new MonopolyBoardLayout()); 

      players = new ArrayList<>(2); 
      try { 
       players.add(makePlayer("/Dog.png")); 
       players.add(makePlayer("/Car.png")); 

       for (JLabel player : players) { 
        add(player, new Integer(0)); 
       } 
      } catch (IOException exp) { 
       exp.printStackTrace(); 
      } 

      Timer timer = new Timer(1000, new ActionListener() { 
       private int count = 0; 
       private Random rnd = new Random(); 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        int playerIndex = count % players.size(); 
        JLabel player = players.get(playerIndex); 

        MonopolyBoardLayout layout = (MonopolyBoardLayout) getLayout(); 
        int position = layout.getPosition(player); 

        position += rnd.nextInt(5) + 1; 
        if (position > 35) { 
         position -= 35; 
        } 

        layout.setPosition(player, position); 

        revalidate(); 
        repaint(); 
        count++; 
       } 
      }); 
      timer.start(); 
     } 

     protected JLabel makePlayer(String path) throws IOException { 
      JLabel label = new JLabel(new ImageIcon(ImageIO.read(getClass().getResource(path))), JLabel.CENTER); 
      return label; 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      Graphics2D g2d = (Graphics2D) g.create(); 
      int width = getWidth(); 
      int height = getHeight(); 

      for (int index = 0; index < 36; index++) { 
       Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height); 
       g2d.draw(bounds); 
      } 

      g2d.dispose(); 
     } 

    } 

    public static class MonopolyBoardLayoutHelper { 

     private static Map<Integer, Point> mapBoardCells; 

     static { 
      mapBoardCells = new HashMap<>(25); 

      mapBoardCells.put(10, new Point(0, 8)); 
      mapBoardCells.put(11, new Point(0, 7)); 
      mapBoardCells.put(12, new Point(0, 6)); 
      mapBoardCells.put(13, new Point(0, 5)); 
      mapBoardCells.put(14, new Point(0, 4)); 
      mapBoardCells.put(15, new Point(0, 3)); 
      mapBoardCells.put(16, new Point(0, 2)); 
      mapBoardCells.put(17, new Point(0, 1)); 
      mapBoardCells.put(18, new Point(0, 0)); 

      mapBoardCells.put(0, new Point(9, 9)); 
      mapBoardCells.put(1, new Point(8, 9)); 
      mapBoardCells.put(2, new Point(7, 9)); 
      mapBoardCells.put(3, new Point(6, 9)); 
      mapBoardCells.put(4, new Point(5, 9)); 
      mapBoardCells.put(5, new Point(4, 9)); 
      mapBoardCells.put(6, new Point(3, 9)); 
      mapBoardCells.put(7, new Point(2, 9)); 
      mapBoardCells.put(8, new Point(1, 9)); 
      mapBoardCells.put(9, new Point(0, 9)); 

      mapBoardCells.put(19, new Point(1, 0)); 
      mapBoardCells.put(20, new Point(2, 0)); 
      mapBoardCells.put(21, new Point(3, 0)); 
      mapBoardCells.put(22, new Point(4, 0)); 
      mapBoardCells.put(23, new Point(5, 0)); 
      mapBoardCells.put(24, new Point(6, 0)); 
      mapBoardCells.put(25, new Point(7, 0)); 
      mapBoardCells.put(26, new Point(8, 0)); 
      mapBoardCells.put(27, new Point(9, 0)); 

      mapBoardCells.put(28, new Point(9, 1)); 
      mapBoardCells.put(29, new Point(9, 2)); 
      mapBoardCells.put(30, new Point(9, 3)); 
      mapBoardCells.put(31, new Point(9, 4)); 
      mapBoardCells.put(32, new Point(9, 5)); 
      mapBoardCells.put(33, new Point(9, 6)); 
      mapBoardCells.put(34, new Point(9, 7)); 
      mapBoardCells.put(35, new Point(9, 8)); 

     } 

     public static Rectangle getCellBounds(int index, int width, int height) { 
      Rectangle bounds = new Rectangle(0, 0, 0, 0); 
      int size = Math.min(width, height); 
      int cellSize = size/10; 

      int xOffset = (width - size)/2; 
      int yOffset = (height - size)/2; 

      Point point = mapBoardCells.get(index); 
      if (point != null) { 

       int x = xOffset + (point.x * cellSize); 
       int y = yOffset + (point.y * cellSize); 
       bounds = new Rectangle(x, y, cellSize, cellSize); 

      } 

      return bounds; 

     } 

    } 

    public static class MonopolyBoardLayout implements LayoutManager2 { 

     public static final int DEFAULT_CELL_SIZE = 64; 

     private Map<Component, Integer> cellConstraints; 

     public MonopolyBoardLayout() { 
      cellConstraints = new HashMap<>(5); 
     } 

     public Integer getPosition(Component comp) { 
      return cellConstraints.get(comp); 
     } 

     public void setPosition(Component comp, int position) { 
      cellConstraints.put(comp, position); 
     } 

     @Override 
     public void addLayoutComponent(Component comp, Object constraints) { 
      if (constraints instanceof Integer) { 
       int cell = (int) constraints; 
       if (cell >= 0 && cell <= 35) { 
        cellConstraints.put(comp, cell); 
       } else { 
        throw new IllegalArgumentException(constraints + " is not within the bounds of a valid cell reference (0-35)"); 
       } 
      } else { 
       throw new IllegalArgumentException(constraints + " is not a valid cell reference (integer within 0-35)"); 
      } 
     } 

     @Override 
     public Dimension maximumLayoutSize(Container target) { 
      return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10); 
     } 

     @Override 
     public float getLayoutAlignmentX(Container target) { 
      return 0.5f; 
     } 

     @Override 
     public float getLayoutAlignmentY(Container target) { 
      return 0.5f; 
     } 

     @Override 
     public void invalidateLayout(Container target) { 
     } 

     @Override 
     public void addLayoutComponent(String name, Component comp) { 
     } 

     @Override 
     public void removeLayoutComponent(Component comp) { 
      cellConstraints.remove(comp); 
     } 

     @Override 
     public Dimension preferredLayoutSize(Container parent) { 
      return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10); 
     } 

     @Override 
     public Dimension minimumLayoutSize(Container parent) { 
      return new Dimension(DEFAULT_CELL_SIZE * 10, DEFAULT_CELL_SIZE * 10); 
     } 

     @Override 
     public void layoutContainer(Container parent) { 
      int width = parent.getWidth(); 
      int height = parent.getHeight(); 

      Map<Integer, List<Component>> components = new HashMap<>(25); 

      for (Component child : parent.getComponents()) { 
       Integer cell = cellConstraints.get(child); 
       if (cell != null) { 
        List<Component> children = components.get(cell); 
        if (children == null) { 
         children = new ArrayList<>(4); 
         components.put(cell, children); 
        } 
        children.add(child); 
       } else { 
        child.setBounds(0, 0, 0, 0); 
       } 
      } 

      for (Map.Entry<Integer, List<Component>> entry : components.entrySet()) { 
       int index = entry.getKey(); 
       Rectangle bounds = MonopolyBoardLayoutHelper.getCellBounds(index, width, height); 
       List<Component> comp = entry.getValue(); 
       int xDelta = 0; 
       int yDelta = 0; 
       int availableWidth = bounds.width; 
       int availableHeight = bounds.height; 
       switch (comp.size()) { 
        case 2: 
         availableWidth /= 2; 
         xDelta = availableWidth; 
         break; 
        case 3: 
        case 4: 
         availableWidth /= 2; 
         xDelta = availableWidth; 
         availableHeight /= 2; 
         yDelta = availableHeight; 
         break; 
       } 
       int x = bounds.x; 
       int y = bounds.y; 
       for (int count = 0; count < comp.size() && count < 4; count++) { 
        Component child = comp.get(count); 
        child.setSize(availableWidth, availableHeight); 
        child.setLocation(x, y); 

        x += xDelta; 
        if (x >= bounds.x + bounds.width) { 
         x = bounds.x; 
         y += yDelta; 
        } 
       } 
      } 

     } 

    } 

} 

正如你所看到的,這將成爲真正的複雜真正的快。這個例子目前只允許每個單元有4個玩家,所以如果你想要更多,那麼你將不得不創建自己的算法。