Closed. This question needs
details or clarity。它当前不接受答案。
想改善这个问题吗?添加详细信息并通过
editing this post阐明问题。
3个月前关闭。
所以我的任务是在Java中使用gui创建游戏。游戏描述如下:
游戏发生在大小为n×m的区域中,其中m和n小于50。
每个单元格从一组中包含单个颜色或字符或数字(您的选择)
可能的值。该程序由三个参数n,m,k定义。该程序
在二维字段上随机放置字符/颜色/数字。首先
颜色/字符/数字属于玩家。游戏的目的是
玩家用自己的颜色绘制整个比赛场地。着色通过
选择源字段和目标字段。
如果它们是相同的颜色,则游戏将所有相邻字段替换为目标颜色
作为源字段颜色中的目标字段。
游戏向用户显示颜色/字符/数字的列表。
当用户绘制整个字段时,游戏结束,移动次数为
所选字段的数量。
我创建了gui:
公众GGGame {
Butt0nz();
theFrame();
}
public void Butt0nz() {
colors.add(Color.RED);
colors.add(Color.GREEN);
colors.add(Color.BLUE);
colors.add(Color.YELLOW);
colors.add(Color.ORANGE);
b1 = new JButton("Restart");
b1.addActionListener(this);
b2 = new JButton("Moves: "+ "0");
b3 = new JButton("Is continuation possible: ");
menubar = new JMenuBar();
file = new JMenu("File");
open = new JMenuItem("Open");
save = new JMenuItem("Save");
close = new JMenuItem("Exit");
save.addActionListener(this);
open.addActionListener(this);
close.addActionListener(this);
menubar.add(file);
file.add(open);
file.add(save);
file.add(close);
}
public Color randomColor() {
return colors.get(new Random().nextInt(colors.size()));
}
public void theFrame() {
JPanel panel = new JPanel();
setLayout(new BorderLayout());
panel.setLayout(new GridLayout(n, m));
for (int i = 0; i < n; i++)
{
for (int j = 0; j < m; j++)
{
button[i][j] = new JButton();
button[i][j].setOpaque(true);
button[i][j].setBackground(randomColor());
panel.add(button[i][j]);
}
}
JPanel butt0n = new JPanel();
butt0n.add(b1);
butt0n.add(b2);
butt0n.add(b3);
setJMenuBar(menubar);
setTitle("Color Game");
add(butt0n, BorderLayout.NORTH);
add(panel, BorderLayout.CENTER);
setSize(1000, 1000);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
'''
我只想要一些有关如何开始游戏逻辑的建议。我读了一些东西,我知道游戏的逻辑就像扫雷器一样,我知道应该执行FloodFill算法使它正常工作,但是我只想更清楚地了解如何开始。
我认为您可以从JButton
中的GridLayout(n, m)
开始,因为与将鼠标侦听器添加到带有自定义绘画的大面板上相比,它可以更清晰地处理事件。
我建议将网格(即带有JPanel
的GridLayout
的JButton
)放入JScrollPane
,以便具有更大的按钮。例如,如果不使用JScrollPane
,并且该程序旨在在分辨率为1366x768的屏幕中运行,并且在50x50的游戏中,您最多使用1200x700像素(以便为窗口边框留一些余量),表示每个按钮24x14(宽度乘以高度)像素。如果您认为可以,那么依靠屏幕的分辨率可能不好。而是将网格放在JScrollPane
中。我并不是建议使用明显的300x300之类的按钮(因为这可能不必要地大),但例如30x30甚至更大的按钮,并不是很难点击。
另一个想法是让用户即时设置每个按钮的大小,即通过程序中的设置,例如,它可以是两个滑块(一个用于宽度,一个用于高度)。
我建议不要使用数字或字符选项,因为这比设置背景颜色更难注意到。
出于明显的原因,我建议为每个按钮的背景使用不强烈的颜色。例如,考虑使用您指定的颜色填充整个区域...这可能使某人(至少我自己哈哈)失明。例如,您可以使用这些颜色的darker()
版本。如果那行不通,我测试了另一个选择:添加一些透明度(即alpha颜色分量),以使按钮的原始颜色显示出来,据我所知,这些颜色并不是盲目的。
这是用透明的红色绘制一些按钮的示例代码:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.GridLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(final String[] args) {
final int rows = 10, cols = 10;
final JPanel panel = new JPanel(new GridLayout(0, cols));
for (int i = 0; i < rows; ++i)
for (int j = 0; j < cols; ++j) {
final JButton button = new JButton() {
@Override
protected void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(new Color(255, 0, 0, 50));
g.fillRect(0, 0, getWidth(), getHeight());
}
};
button.setPreferredSize(new Dimension(30, 30));
panel.add(button);
}
final JFrame frame = new JFrame("ColorGame.");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
我认为结果不会使任何人盲目(尽管它几乎是红色的):
我认为
Flood Fill algorithm in Wikipedia解释得很好。因此,除了那里的材料之外,您不需要其他东西来实现它。它还提供了一些递归伪代码来解决该问题。
为了轻松检查结束条件,您可以使用背景数量等于玩家所选择颜色的按钮数量的计数器/
int
。当该数字等于N乘以M时,则结束游戏。但是不要忘了每次更新按钮背景都会更新您的计数器。如果您不想使用此计数器,例如,因为它可能使代码不那么干净且更容易出错,那么您最简单的操作可能是在每次移动后遍历每个按钮,并计算哪些按钮具有用户的颜色作为背景,但效率不高,尽管在我看来,对于这种特定情况,解决尺寸问题最多为50x50(即2500个颜色相等性检查)的效率不是很大。
为了便于调整,我建议使用子类(例如
JButton
类),并重写
getPreferredSize()
方法以返回类型为
Dimension
的共享库,该共享库将包含由用户的设置滑块选择的值。然后,每次更新此共享的可变对象时,只需在
revalidate()
的
JScrollPane
视图(即包含按钮的面板)上调用
Viewport
,它将更新
JScrollPane
。
由于您将
JButton
子类化,您可能需要添加按钮在网格中对应的行数和列数,因此,当调用
ActionListener
时,您将知道用户单击的位置(并使用相同的
ActionListener
所有来源/按钮的对象)。在这种情况下,您可能不必忘记检查
ActionEvent
的source属性(具有行和列ID的按钮),而不是其他任何按钮。
我认为比
JButton
更合适的是使用
JToggleButton
。因此,以这种方式,您可以让用户知道哪个是源目标按钮对中他们选择的第一个按钮,如果再次单击同一按钮,则撤消其初始选择。当然,当选择一个切换按钮时,您将需要保持对第一个切换按钮的引用,以使其与第二个切换按钮匹配并知道从何处开始。
到目前为止,这就是我所拥有的,只是让您入门而已。如果您需要更多信息或说明,请在评论中告诉我。