【问题标题】:RTS style of drag and select systemRTS风格的拖拽选择系统
【发布时间】:2015-03-11 17:14:03
【问题描述】:

我正在尝试用 C++ 和 SDL2 制作一个点击和拖动选择系统,就像实时战略游戏中使用的那种系统。您单击鼠标并将其拖动到要选择的内容上。我该怎么做呢?

编辑:我知道如何处理鼠标输入。我使用了一个 Rect 结构来跟踪选择区域的大小。然而,当区域正确绘制时,区域内的对象根本没有反应。但是每次单独单击它们都可以正常工作。

我想我的问题是检查组选择与单个对象选择的最佳方法是什么?

【问题讨论】:

标签: c++ sdl drag-to-select


【解决方案1】:

您必须检查要拖动的矩形内的内容(测试取决于包含的形状)并拖动这些形状

【讨论】:

    【解决方案2】:

    我可以描述一下我是如何实现的。

    在事件处理例程中,执行类似于以下代码的操作。我认为方法名称很好地解释了正在发生的事情以及我的想法(这是从我基于 SDL2 的 hobby-hack-RTS-engine 复制的):

            case SDL_MOUSEBUTTONDOWN:
            {
                // Calculate index, x and y for the tile that was clicked in the map.
                int iClick = m_Map.getTileIndex(event.button.x, event.button.y);
                if(iClick >= 0)
                {
                    int xClick = m_Map.getTileX(iClick);
                    int yClick = m_Map.getTileY(iClick);
    
                    if((int)event.button.button == 1)
                    {
    
                        // Unmark all MO..
                        for(std::list<MGMovingObject>::iterator it = m_MO.begin(); it != m_MO.end(); it++)
                        {
                            it->unMark();
                        }
    
                        activateFraming(event.button.x, event.button.y);
                   }
                   else
                   {
                        ...
                   }
               }
               break;
           }
    
    
    
            case SDL_MOUSEBUTTONUP:
            {
                if((int)event.button.button == 1)
                {
                    int endClickX = m_Map.getTileX(m_Map.getTileIndex(getFrameEndX(), getFrameEndY()));
                    int endClickY = m_Map.getTileY(m_Map.getTileIndex(getFrameEndX(), getFrameEndY()));
                    int startClickX = m_Map.getTileX(m_Map.getTileIndex(getFrameStartX(), getFrameStartY()));
                    int startClickY = m_Map.getTileY(m_Map.getTileIndex(getFrameStartX(), getFrameStartY()));
                    if(endClickX > 0 && endClickY > 0 && startClickX > 0 && startClickY > 0)
                    {
                        for(int x = std::min(startClickX, endClickX); x <= std::max(startClickX, endClickX); x++)
                        {
                            for(int y = std::min(startClickY, endClickY); y <= std::max(startClickY, endClickY); y++)
                            {
                                for(std::list<MGMovingObject>::iterator it = m_MO.begin(); it != m_MO.end(); it++)
                                {
                                    if(it->getTileX() == x && it->getTileY() == y)
                                    {
                                        it->mark();
                                    }
                                }
                            }
                        }
                    }
                    deactivateFraming();
                }
                else
                {
                     ...
                }
                break;
           }
    

    我的可选对象在m_MO 中存储为std::list&lt;MGMovingObject&gt;

    这个想法是我保存选择框开始和选择框结束的平铺坐标。然后我遍历可选对象并检测选择框架内的对象。我选择了这些(mark()),当我在稍后阶段迭代对象时,比如在渲染期间,我可以读出它们是否被选中(isMarked())。

    如果你想窃取代码或想法,这里是我复制的实际源文件:https://github.com/qmargyl/mgframework/blob/master/src/mgframework/mgframework.cpp

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多