- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
好的,所以我正在制作一个垄断游戏。到目前为止,我有一个 JFrame
,其中有一个 JPanel
作为板。我已经加载了所有必要的图像。我创建了一个扩展 JLabel
的 Player
对象,以代表棋盘上的玩家。
我正在尝试设置(希望在棋盘上移动棋子)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);
}
}
玩家
对象代码:
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);
}
}
最佳答案
有几种方法可以实现这一点,就个人而言,最简单的方法是直接使用自定义绘画,而不必为播放器使用基于 Swing 的组件。
您遇到的基本问题是 JPanel
默认情况下使用 FlowLayout
,这意味着您将始终与布局管理器作斗争。在这种情况下,您可能会考虑使用自定义布局管理器,例如...
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 名玩家,因此如果您想要更多玩家,则必须创建自己的算法
关于java - 无法在 JPanel 上移动 JLabel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33883330/
我通过 spring ioc 编写了一些 Rest 应用程序。但我无法解决这个问题。这是我的异常(exception): org.springframework.beans.factory.BeanC
我对 TestNG、Spring 框架等完全陌生,我正在尝试使用注释 @Value通过 @Configuration 访问配置文件注释。 我在这里想要实现的目标是让控制台从配置文件中写出“hi”,通过
为此工作了几个小时。我完全被难住了。 这是 CS113 的实验室。 如果用户在程序(二进制计算器)结束时选择继续,我们需要使用 goto 语句来到达程序的顶部。 但是,我们还需要释放所有分配的内存。
我正在尝试使用 ffmpeg 库构建一个小的 C 程序。但是我什至无法使用 avformat_open_input() 打开音频文件设置检查错误代码的函数后,我得到以下输出: Error code:
使用 Spring Initializer 创建一个简单的 Spring boot。我只在可用选项下选择 DevTools。 创建项目后,无需对其进行任何更改,即可正常运行程序。 现在,当我尝试在项目
所以我只是在 Mac OS X 中通过 brew 安装了 qt。但是它无法链接它。当我尝试运行 brew link qt 或 brew link --overwrite qt 我得到以下信息: ton
我在提交和 pull 时遇到了问题:在提交的 IDE 中,我看到: warning not all local changes may be shown due to an error: unable
我跑 man gcc | grep "-L" 我明白了 Usage: grep [OPTION]... PATTERN [FILE]... Try `grep --help' for more inf
我有一段代码,旨在接收任何 URL 并将其从网络上撕下来。到目前为止,它运行良好,直到有人给了它这个 URL: http://www.aspensurgical.com/static/images/a
在过去的 5 个小时里,我一直在尝试在我的服务器上设置 WireGuard,但在完成所有设置后,我无法 ping IP 或解析域。 下面是服务器配置 [Interface] Address = 10.
我正在尝试在 GitLab 中 fork 我的一个私有(private)项目,但是当我按下 fork 按钮时,我会收到以下信息: No available namespaces to fork the
我这里遇到了一些问题。我是 node.js 和 Rest API 的新手,但我正在尝试自学。我制作了 REST API,使用 MongoDB 与我的数据库进行通信,我使用 Postman 来测试我的路
下面的代码在控制台中给出以下消息: Uncaught DOMException: Failed to execute 'appendChild' on 'Node': The new child el
我正在尝试调用一个新端点来显示数据,我意识到在上一组有效的数据中,它在数据周围用一对额外的“[]”括号进行控制台,我认为这就是问题是,而新端点不会以我使用数据的方式产生它! 这是 NgFor 失败的原
我正在尝试将我的 Symfony2 应用程序部署到我的 Azure Web 应用程序,但遇到了一些麻烦。 推送到远程时,我在终端中收到以下消息 remote: Updating branch 'mas
Minikube已启动并正在运行,没有任何错误,但是我无法 curl IP。我在这里遵循:https://docs.traefik.io/user-guide/kubernetes/,似乎没有提到关闭
每当我尝试docker组成任何项目时,都会出现以下错误。 我尝试过有和没有sudo 我在这台机器上只有这个问题。我可以在Mac和Amazon WorkSpace上运行相同的容器。 (myslabs)
我正在尝试 pip install stanza 并收到此消息: ERROR: No matching distribution found for torch>=1.3.0 (from stanza
DNS 解析看起来不错,但我无法 ping 我的服务。可能是什么原因? 来自集群中的另一个 Pod: $ ping backend PING backend.default.svc.cluster.l
我正在使用Hibernate 4 + Spring MVC 4当我开始 Apache Tomcat Server 8我收到此错误: Error creating bean with name 'wel
我是一名优秀的程序员,十分优秀!