在Java游戏中实现拖放功能

3
我正在制作一个棋盘游戏,它是一个8x8的网格,上面有五个不同颜色的图像。只要它们在一行或一列中相邻,这些对象就可以交换位置。如果交换导致一行或一列中有3个或更多相同的对象,则它们将被移除。如果交换没有结果,交换将不会发生。当对象被移除时,棋盘会坍塌,位于被移除对象上方的对象会掉下来取代它们的位置,新的对象从顶部掉落以填补空白。
我想知道实现拖动操作和对象掉落的好方法。我应该使用分层窗格吗?
任何想法都能帮助我。

请参考此示例变体 - trashgod
1个回答

0
  1. 拖动操作: 创建一个哈希表,报告颜色索引(在8x8网格中完全有5种不同的颜色)和矩形对象。矩形和颜色分别表示键和值。每次连续单击两个相邻块(矩形),获取这两个适当的颜色并交换它们。然后再次检查您的颜色分布,如果现在至少有一块设置了3个或多于3个相同颜色的相邻行上。如果没有,请将颜色交换回去。

  2. 下落: 在找到至少一个块设置(即使相邻的同一行超过3个),通过当前列中每个矩形的高度* 当前列中删除的矩形数量来减去所删除的矩形上方的所有颜色块。然后一遍又一遍地检查当前的颜色分布,直到没有更多的块集中在一条线上具有3种或更多相同的颜色。

谢谢。您如何为用户创建物体下落的感觉?我需要使用一些图形或计时器来创建这样的效果吗?

一个计时器会是一个不错的选择。在至少找到一个方块组(多于3个,甚至相邻在同一行)之后,调用计时器的schedule(TimerTask task, long delay, long period)方法,在其中需要定义TimerTaskrun()方法,该方法什么也不做,只用来调用你的JComponent/JFrame的repaint(int x, int y, int width, int height)方法,该方法在主线程中绘制下落部分。在JComponent /JFrame的paint(Graphics g)方法中,你需要绘制下落部分不同阶段的形状。此外,在你的TimerTask's run()方法中,你需要使用一个循环,以便每次经过period毫秒后,将调用另一个JComponent/JFrame的repaint(x, y, width, height)方法。如果你想要循环5次,只需在第5次循环中使用TimerTask's cancel()方法,计时器将结束。如果你不太关心闪烁效果,只需使用repaint()方法,并在paint(Graphics g)中每次绘制整个8x8网格图像。我使用JComponent/JFrame的原因是,你可以直接在JFrame上进行绘制,也可以基于JFrame在JComponent上进行绘制。

谢谢。我已经有一些想法来实现下落和拖动效果。目前我在我的程序中遇到了困难,无法自拔。如果能得到一些帮助,我将不胜感激。 我的程序目前是在框架中创建了一个8x8网格布局的面板。我创建了一个类,其中包含ImageID(字符串,包含行和列号)、Image(JLabel)、行和列。我创建了64个对象存储在2维数组中,存储在GridLayout中。每个对象都附加了一个鼠标监听器和鼠标移动监听器。当用户单击网格时,我获取图像对象,然后获取所单击图像的行和列 - newjav昨天
我卡住的问题是当鼠标按下、拖动和释放时。当鼠标释放或拖动时,我得到的对象是被按下的对象。因此,我无法获取鼠标释放的网格的行和列。如何计算鼠标释放的网格位置。我卡在这里,无法继续。

如果你只使用mousePressedListener和mouseReleasedListener而没有使用mouseMotionListener,那么你可以分别获取源网格对象和目标网格对象。但我认为你的目的是要使用MouseMotionListener。所以我有两个变体: 1. 在按下网格对象后不久,您会得到网格对象(即获取此网格对象的边界)。例如,您在第2行和列中单击了网格对象,则可以获取网格对象的成员row=1和coloum=1。假设每个网格的宽度和高度都为10(像素)。然后您可以获取此网格对象的边界:(10,10)和(20,20)。现在您想拖动到另一个网格中。因此,您需要在此网格对象的mouseReleased()函数中添加条件:如果当前释放的鼠标位置超出此网格对象的边界,则其中一个邻居现在是目标网格对象。例如,if(e.getX() > 20 && e.getY() > 10 && e.getY() < 20) {//则目标网格对象在源网格对象的右侧,其边界为(20,10),(30,10),即行=1,列=2}通过行和列,您可以从2D数组中找到目标网格对象。 2. 但如果我是你,我不会为每个网格对象分配一个mouseListener和mouseMotionListener,而只会为包括这64个网格对象的面板分配一个mouseListener和mouseMotionListener。每次单击,拖动然后释放时,您将获得适当的位置,通过该位置,您可以轻松地转换为行和列。通过行和列,您可以从2D数组中找到适当的网格对象。就是这样。希望这正是你想要的。


非常感谢。我能够使用以下代码从父组件坐标中获取行和列:Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), container); - newjav

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接