我正在开发一个项目,开发一款名为的游戏 Don't get mad bro
我有一个JPanel
的形状(圆圈)和JLabel
组件包含图片。每当我点击&#34时,我都需要它。扔掉骰子" (在后台返回1到6之间的数字)我应该等待当前玩家点击他的一个棋子,并且该棋子应该在n个位置之后移动,其中n等于骰子返回的数字。
我的问题是,我应该创建一个我等待mouseClick
事件的新线程吗?以及如何获得mouseClick
的坐标?
这是我的类继承了面板并绘制圆圈并添加标签。
public class ImagePanel extends JPanel{
private static final long serialVersionUID = 1L;
ImageMatrix imageMatrix;
BufferedImage[] images;
public static JLabel[][] labels;
DrawGameBoard board = new DrawGameBoard();
List<GameFigure> gameCircles;
List<FinishFigure> finishCircles;
int initialHeight = 528;
int initialWidth = 596;
ThreadForPawnsClick labelsClick;
public ImagePanel(){
labels = new JLabel[4][4];
images = new BufferedImage[4];
setBackground(new Color(255,255,153));
gameCircles = new ArrayList<GameFigure>();
finishCircles = new ArrayList<FinishFigure>();
imageMatrix = new ImageMatrix(initialWidth,initialHeight);
try {
images[0] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\red.png"));
images[1] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\green.png"));
images[2] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\blue.png"));
images[3] = ImageIO.read(new File("C:\\Users\\babii\\.eclipse\\DontGetMad\\resource\\yellow.png"));
} catch (IOException e) {
e.printStackTrace();
}
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
labels[i][j] = new JLabel(new ImageIcon(images[i]));
}
setLayout(null);
board.DrawHomeBoard(imageMatrix, labels);
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
add(labels[i][j]);
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
int width = this.getWidth();
int height = this.getHeight();
imageMatrix.update(width, height);
setLayout(null);
gameCircles = board.DrawMainBoard(g, imageMatrix);
//labels = board.DrawHomeBoard(g, imageMatrix, labels);
//board.DrawHomeBoard(imageMatrix, labels);
finishCircles = board.DrawFinishBoard(g, imageMatrix);
/*for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
add(labels[i][j]);
*/
}
}
此外,即使我在imageMatrix
中调用更新矩阵,我的paintComponent()
也无法在整个屏幕上展开?
答案 0 :(得分:1)
不,绝对没有。您需要以某种方式更改GUI的状态以等待鼠标单击模式,然后根据其状态更改GUI对鼠标单击的响应行为。通常,state由类的实例字段表示。因此,当您需要等待时,您可以更改其中一个状态字段,并在单击鼠标时检查字段的状态,并根据具体情况改变发生的情况。例如,在基于回合的国际象棋游戏中,一个状态字段可以是我的问题是,我应该创建一个新的线程,在其中我等待mouseClick事件?
private boolean blackTurn
,然后根据鼠标的状态确定鼠标的作用。
如何获取mouseClick的坐标?
在MouseListener中,MouseEvent参数为您提供鼠标相对于收听组件和屏幕的x和y位置。如果您的MouseListener附加到JLabel,那么您可以通过MouseEvent的getSource()
方法获得对单击的JLabel的引用,然后通过调用{获取JLabel相对于其容器JPanel的位置(如果需要) {1}}就可以了。
旁注:在Swing GUI中,你在精灵周围移动,通常最好不要将精灵放入JLabel,而是直接在绘图JPanel的paintComponent方法中直接绘制它们。
作为我的意思的一个例子,这里有一个程序,绘制4个彩色圆圈,可拖动的圆圈,但只有在使用JRadioButton设置GUI的“状态”选择相应的JRadioButton时才可拖动。这里的状态由一个名为getLocation()
的枚举表示,它包含4种颜色和相应的文本。这是这个枚举:
ColorState
然后我们创建一个绘图JPanel,一个在Map中保存四个Ellipse2D Shape对象,
import java.awt.Color;
public enum ColorState {
RED("Red", Color.RED),
GREEN("Green", Color.GREEN),
BLUE("Blue", Color.BLUE),
ORANGE("Orange", Color.ORANGE);
private String text;
private Color color;
private ColorState(String text, Color color) {
this.text = text;
this.color = color;
}
public String getText() {
return text;
}
public Color getColor() {
return color;
}
}
在for循环中,我们创建JRadioButtons,给它们设置对象状态的ActionListeners,并使用Ellipse2D Shape对象填充Map
private Map<ColorState, Shape> colorStateMap = new EnumMap<>(ColorState.class);
我们在paintComponent中绘制省略号:
for (final ColorState state : ColorState.values()) {
// create the JRadioButton
JRadioButton radioButton = new JRadioButton(state.getText());
add(radioButton); // add to GUI
buttonGroup.add(radioButton); // add to ButtonGroup
// give it an ActionListener that changes the object's state
radioButton.addActionListener(e -> {
colorState = state;
});
// create a randomly placed Ellipse2D and place into Map:
double x = Math.random() * (W - CIRCLE_WIDTH);
double y = Math.random() * (H - CIRCLE_WIDTH);
Ellipse2D ellipse = new Ellipse2D.Double(x, y, CIRCLE_WIDTH, CIRCLE_WIDTH);
colorStateMap.put(state, ellipse);
}
最后在MouseAdapter(MouseListener和MouseMotionListener)中,如果单击鼠标左键,我们会监听鼠标按下并注册成功如果单击 ,则形状:
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// make for smooth graphics
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// iterate through the enum, extracting the ellipse and drawing it
for (ColorState state : ColorState.values()) {
Shape shape = colorStateMap.get(state);
if (shape != null) {
g2.setColor(state.getColor());
g2.fill(shape); // draw the ellipse
}
}
}
请注意,鼠标拖动代码归功于MadProgrammer的回答here。请将此答案向上投票。
整个班级看起来像这样:
private class MyMouse extends MouseAdapter {
private Shape selectedShape = null;
private Point2D offset = null;
@Override
public void mousePressed(MouseEvent e) {
// check that correct button pressed
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
// has our colorState been set yet? If not, exit
if (colorState == null) {
return;
}
// is an appropriate Shape held by the Map? If so, get it
Shape shape = colorStateMap.get(colorState);
if (shape == null) {
return;
}
// does this shape contain the point where the mouse was pressed?
if (!shape.contains(e.getPoint())) {
return;
}
// Get the selected shape, get the mouse point location relative to this shape
selectedShape = shape;
double x = e.getX() - shape.getBounds2D().getX();
double y = e.getY() - shape.getBounds2D().getY();
offset = new Point2D.Double(x, y);
}
@Override
public void mouseDragged(MouseEvent e) {
// drag shape to new location
if (selectedShape != null) {
double x = e.getX() - offset.getX();
double y = e.getY() - offset.getY();
Rectangle2D bounds = selectedShape.getBounds2D();
bounds.setFrame(new Rectangle2D.Double(x, y, bounds.getWidth(), bounds.getHeight()));
((Ellipse2D) selectedShape).setFrame(bounds);
repaint();
}
}
@Override
public void mouseReleased(MouseEvent e) {
selectedShape = null;
}
}