Reputation: 499
Ok, so I am making a monopoly game. I so far have a JFrame
, with a JPanel
acting as a board. I have loaded all necessary images. I create a Player
object which extends JLabel
, to represent the player on the board.
I am trying to set the location of (in hopes of moving pieces around the board) Player
object (which is a JLabel
), on the board (which is a JPanel
). I tried the .setLocation
method, .setBounds
method.
For some reason, no matter what i do the Player
object only shows up on the top middle of the JPanel
. I was wondering how I could move the Player
object on my board.
JFrame
code (I attempt to move the JLabel
in the bottom of the constructor):
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
Code:
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
Object Code:
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);
}
}
Upvotes: 0
Views: 2607
Reputation: 347204
There are a couple of ways you can achieve this, personally, the simplest would be to use custom painting directly and not bother with using Swing based components for the players.
The basic problem you have is JPanel
uses a FlowLayout
by default, which means that you will always be fighting layout manager. In this case you might consider using a custom layout manager, for example...
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;
}
}
}
}
}
}
As you can see, this becomes real complicated real quick. This example currently only allows 4 players per cell, so if you want more, then you're going to have to create your own algorithim
Upvotes: 5