代码之家  ›  专栏  ›  技术社区  ›  snowllama

Java麻将游戏-帮助实现手部重组,将JLabels从我拖动所选棋子的位置移开

  •  0
  • snowllama  · 技术社区  · 9 年前

    我目前正在制作一个java麻将游戏,我正在开发GUI。我有一个JPanel,它包含一个JLabel数组,每个JLabel都有一个自定义的鼠标监听器。

    我想要的是用某种方式重新组织你的手。例如,你刚刚画了一个瓷砖,你想把它放在最左边,以保持你手中的组织。

    我已经可以拖动平铺,但我希望它能够 卡入到位 当你释放它,然后 每隔一个平铺向下移动 。所以如果我把它放在最左边,每个瓷砖都会向右移动一个。因此,程序需要某种方式 识别瓦片已被移动并确定其处于什么位置。 我希望得到一些关于如何实施这一点的指导,或者我需要更改/添加/研究的内容。

    这是我的鼠标监听器类,如果需要任何其他信息,请告诉我。

    package mahjongCode;
    
    import java.awt.Component;
    import java.awt.Cursor;
    import java.awt.Point;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.SwingUtilities;
    
    public class DragAndDropListener extends MouseAdapter{
        private Point startPoint;
        private Component draggedObject;
        private JPanel panel;
        private JLabel[] handTiles;
    
        public DragAndDropListener(JPanel panel, JLabel[] handTiles){
            this.panel = panel;
            this.handTiles = handTiles;
        }
        @Override
        public void mousePressed(MouseEvent e){
            panel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            draggedObject = (Component) e.getSource();
            startPoint = SwingUtilities.convertPoint(draggedObject, e.getPoint(), 
                                                        draggedObject.getParent());
        }
    
        @Override
        public void mouseDragged(MouseEvent e){
            Point location = SwingUtilities.convertPoint(draggedObject, e.getPoint(), 
                                                            draggedObject.getParent());
            Point locTrans = location.getLocation();
            locTrans.translate(draggedObject.getParent().getX(), draggedObject.getParent().getY());
            if(draggedObject.getParent().getBounds().contains(locTrans)){
                Point newLocation = draggedObject.getLocation();
                newLocation.translate(location.x - startPoint.x, location.y - startPoint.y);
                newLocation.x = Math.max(newLocation.x, 0);
                newLocation.x = Math.min(newLocation.x, draggedObject.getParent().getWidth() - draggedObject.getWidth());
                newLocation.y = Math.max(newLocation.y, 0);
                newLocation.y = Math.min(newLocation.y, draggedObject.getParent().getHeight() - draggedObject.getHeight());
                draggedObject.setLocation(newLocation);
                panel.repaint();
                startPoint = location;
            }
        }
    
        @Override 
        public void mouseReleased(MouseEvent e){
            panel.setCursor(null);
            startPoint = null;
            draggedObject = null;
        }
    
        public void makeDraggable(Component component){
            component.addMouseListener(this);
            component.addMouseMotionListener(this);
        }
    
    }
    
    1 回复  |  直到 9 年前
        1
  •  2
  •   Community dbr    7 年前

    既然您有一个JLabel数组,那么您的解决方案已经完成了一半!我实际上回答了一个 similar question 就在最近。

    你可能会发现这是有益的。

    至于“捕捉到位”,如果你是根据阵列标记绘制瓷砖的手,捕捉是为你完成的,因为它们将在捕捉后被绘制到位。

    我对麻将不太了解,但我认为麻将牌与Uno手中的牌相似,因为你不受设定值的限制。如果是这种情况,ArrayList可能非常有益。你可以阅读一些关于 ArrayList vs Array here .


    编辑:

    enter image description here

    我认为有几种方法可以解决这个问题,可能还有更多: 如果每个平铺都获得了框架/屏幕/窗格的相对部分,那么您可以获得它的x坐标值(平铺上的红线),当您向左拖动鼠标(蓝色箭头,红色圆点),越过绿色箭头时,会自动将该平铺向左移动。

    如果在本例中,当鼠标移动超过固定宽度时,有最大数量的平铺(例如4),则可以基于该预定值直接交换平铺。

    也许我能看到的最简单的方法是:

    enter image description here

    当他们释放拖放时(我假设是点击和拖动),获取鼠标最后一个已知位置的坐标,然后系统地将位置与每个索引进行比较,直到找到位置,然后以这种方式处理。

    由于本例中的X值小于所有其他值,因此将其放置在数组列表的前面。阵列列表位置决定每个平铺的绘制位置。当您在此处释放鼠标时,选定的平铺将保存在一个局部变量中,然后将所有平铺移动到右侧的一个插槽以适应新的更改,最后,根据数组索引0,将选定的平铺位置设置为(150100)。