【问题标题】:Implement Drag and Drop in Java game在 Java 游戏中实现拖放
【发布时间】:2012-04-02 19:24:21
【问题描述】:

我正在开发一个棋盘游戏,它是一个 8x8 网格,有 5 个不同颜色的图像。只要对象在一行或一列中彼此相邻,它们就可以交换。如果切换导致 3 个或更多对象在一行或一列中相同,它们将被删除。如果切换不导致匹配,则切换不会发生。当物体被移除时,板子会塌陷,因此位于移除物体上方的物体会掉下来代替它们的位置,而新的物体会从顶部落入以填充空间。

我想知道一个很好的方法来实现拖动操作和对象的下落。我应该使用分层窗格吗?

任何想法都会帮助我。

【问题讨论】:

标签: java swing user-interface drag-and-drop jlayeredpane


【解决方案1】:
  1. 拖动操作: 创建一个哈希图,它报告一个颜色索引(比如 8x8 网格中总共 5 种不同的颜色)和一个矩形对象。 Rect 和 color 分别代表键和值。您每次分别在 2 个相邻的块(矩形)上单击两次,得到这两种适当的颜色并交换它们。然后再次检查你的颜色分布,如果现在至少有一个块在一条线上相邻有 3 种或 3 种以上的相同颜色。如果没有,请换回颜色。

  2. 跌倒: 找到至少一个块集后(超过3个甚至在同一行相邻),将删除矩形上方的所有色块减去每个矩形的高度 * 删除的矩形数在当前列中。然后反复检查当前的颜色分布,直到一行上没有超过 3 个相同颜色的块集。

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

计时器将是一个不错的选择。找到至少一个block set(超过3个甚至在同一行相邻)后调用Timer的schedule(TimerTask task, long delay, long period),需要在其中定义TimerTask run(),它什么都不做,只会调用 main 中定义的 JComponent/JFrame 的 repaint(int x, int y, int width, int height)线程绘制下降的部分。在您的 JComponent/JFrame 的 paint(Graphics g) 中,您需要绘制下落部分的不同阶段。您还需要在 TimerTask 的 run() 中使用一个循环,以便每次在 period 毫秒之后,另一个 JComponent/JFrame 的 repaint(x, y, width, height) 将被调用。如果你想循环它5次,那么只需在第5次循环中使用TimerTask的cancel(),定时器就会结束。如果您不太关心闪烁效果,只需使用 repaint() 代替,并且每次在 paint(Graphics g) 中绘制一个完整的 8x8 网格图像。我使用 JComponent/JFrame 的原因是你可以直接在 JFrame 上绘制,也可以基于 JFrame 在 JComponent 上绘制。

谢谢。我有一些想法来实现下降和拖动效果。现在我被困在我的程序中,找不到我的出路。如果我能得到一些帮助,我将不胜感激。到目前为止,我的程序是我在一个框架中创建了一个带有 8x8 网格布局的面板。我创建了一个带有 ImageID(行号和列号的字符串)、Image(JLabel)、行和列的类。我创建了一个存储在 GridLayout 中的二维数组中的 64 个对象。每个对象都附加了一个 mouselistener 和 mousemotionlistener。当用户单击网格时,我获取图像对象,然后获取单击的图像的行和列 – newjav昨天
我被卡住的问题是当鼠标按下、拖动和释放时。当鼠标释放或鼠标拖动时我得到的对象是被按下的对象。所以我没有得到释放鼠标的网格的行和列。如何计算释放鼠标的网格位置。我被困在这里,无法继续前进

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

【讨论】:

  • 非常感谢。我能够使用 Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), container); 从父坐标中获取行和列
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-14
  • 1970-01-01
相关资源
最近更新 更多