WxLua GUI 2d mappinp

WxLua GUI 2d mappinp

好的,伙计们,我正在尝试为我的图形用户界面制作一个二维地图(我的游戏的文字地图)。在游戏中,我将地形数据导出到外部 lua 文件,看起来像这样 Info = { 1 = { Color = “blue”, x = 0, y = 0 }, ect ect.. .} 基本上是一个大数组。我的图形用户界面读取这个文件和 wxDrawcircle 并在坐标处放置像素大小的彩色点。这一切都有效并创建了一个漂亮的地图,但问题是当我去点击或做任何事情时它会冻结并且看起来 GUI 无法处理所有这些点。似乎每当我单击 GUI 时都会刷新并再次重新呈现所有这些点。所以我的问题是我应该制作纹理还是我的 GUI 可以渲染地图一次而不是一遍又一遍地刷新它自己?

更新:感谢反馈,伙计们确实提高了加载速度。但我添加了 if canrun then 所以它只会 运行 一次,因为我发现每次你移动滚轮时它都会重新生成导致崩溃的整个地图。因此,如果有一种解决方法可以防止地图在您向上或向下滚动时消失,那就行得通了。

我的图形用户界面。已更新

    package.cpath = package.cpath..";./?.dll;./?.so;../lib/?.so;../lib/vc_dll/?.dll;../lib/bcc_dll/?.dll;../lib/mingw_dll/?.dll;"
require("wx")

frame = nil
canrun = true

Panle1_Send_It_Button = 100
Panle1_Static_Box_1 = 101
Panle1_Static_Box_2 = 102
Panle1_Static_Box_3 = 103
Panle1_TextCtrl_1 = 104
Panle1_TextCtrl_2 = 105

P1_SB1_Selected = -1
P1_SB2_Selected = -1
P1_SB3_Selected = -1

function HandleEvents(event)
   local name = event:GetEventObject():DynamicCast("wxWindow"):GetName()
    frame:SetStatusText(string.format("%s - You are on the %d '%s'", name, event:GetSelection(), event:GetString()), 0)
    if event:GetSelection() == 3 then canrun = true print("PRINT2") end
end


local _T = function(s) return s end
local wxT = function(s) return s end

function GetColor(IC,Type)
    if IC == "Green" or IC == "Black" then
            if Type == 0 then 
                --Pix = wx.wxBrush(wx.wxColour(226,204,113),wx.wxSOLID
                Pix = wx.wxGREEN_BRUSH
            else
                Pix = wx.wxGREEN_PEN
            end
        else
            if IC == "Blue" then
                if Type == 0 then 
                    Pix = wx.wxCYAN_BRUSH
                else
                    Pix = wx.wxCYAN_PEN
                end
            else
               if Type == 0 then 
                    Pix = wx.wxGREY_BRUSH
               else
                    Pix = wx.wxGREY_PEN
                end
            end
        end
    return Pix
end

function OnPaint(event)
    local dc = wx.wxPaintDC(sw)
    sw:PrepareDC( dc )
    Number = 1
    if canrun then
    canrun = false
    print("PAINT")
    for i = 22,1,-1 do 
        local FileName = string.format("PixleData%s.lua",Number)
        dofile(FileName)
        for i, GroupF in ipairs(Info) do 
            local Data = Info[i]
            local Color = Data["Color"]
            local Xpos = Data["Xp"]
            local Ypos = Data["Yp"]
            local PixColor = GetColor(Color,0)
            local PenColor = GetColor(Color,1)

            dc:SetPen( PenColor )
            dc:SetBrush( PixColor )
            dc:DrawPoint( Xpos, Ypos)
        end
        Number = Number+1
    end
    dc:delete()
    end
end

function main()
    -- create the hierarchy: frame -> notebook
    frame = wx.wxFrame(wx.NULL, wx.wxID_ANY, "DCS Support Tablet",wx.wxDefaultPosition, wx.wxSize(900, 600))
    frame:CreateStatusBar(1)
    frame:SetStatusText("", 0)
    T = frame

    local notebook = wx.wxNotebook(frame, wx.wxID_ANY,
                                   wx.wxDefaultPosition, wx.wxDefaultSize)
                                   --wx.wxNB_BOTTOM)

    -- create first panel in the notebook control
    local panel1 = wx.wxPanel(notebook, wx.wxID_ANY)
    local sizer1 = wx.wxBoxSizer(wx.wxVERTICAL)
    local choice = wx.wxChoice(panel1, Panle1_Static_Box_1,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"Al Dhafra AB", "Al Maktoum Intl", "Sharjah Intl", "Fujairah Intl"})

    local choiceBoxStaticBox = wx.wxStaticBox( panel1, wx.wxID_ANY, "Deployment From")
    local choiceBoxStaticBoxSizer = wx.wxStaticBoxSizer( choiceBoxStaticBox, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer:Add(choice, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    local choice2 = wx.wxChoice(panel1, Panle1_Static_Box_2,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"Carrier", "Al Dhafra AB", "Al Maktoum Intl", "Sharjah Intl", "Fujairah Intl", "Grid Cordinates (For FOBs Only)"})

    local choiceBoxStaticBox2 = wx.wxStaticBox( panel1, wx.wxID_ANY, "Attack Location")
    local choiceBoxStaticBoxSizer2 = wx.wxStaticBoxSizer( choiceBoxStaticBox2, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer2:Add(choice2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    local choice3 = wx.wxChoice(panel1, Panle1_Static_Box_3,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"A-10C","F/A-18C","M1A2 MBT"})

    local choiceBoxStaticBox3 = wx.wxStaticBox( panel1, wx.wxID_ANY, "Unit To Be Deployed")
    local choiceBoxStaticBoxSizer3 = wx.wxStaticBoxSizer( choiceBoxStaticBox3, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer3:Add(choice3, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    local staticText = wx.wxStaticText( panel1, wx.wxID_ANY, "North", wx.wxPoint(7,194))
    local textCtrl   = wx.wxTextCtrl( panel1, Panle1_TextCtrl_1, "000", wx.wxPoint(35,190), wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER )
    local text_w, text_h = textCtrl:GetTextExtent("00000.00000")
    textCtrl:SetInitialSize(wx.wxSize(text_w, -1))

    local staticText2 = wx.wxStaticText( panel1, wx.wxID_ANY, "East", wx.wxPoint(105,194))
    local textCtrl2   = wx.wxTextCtrl( panel1, Panle1_TextCtrl_2, "000", wx.wxPoint(128,190), wx.wxDefaultSize, wx.wxTE_PROCESS_ENTER )
    local text_w2, text_h2 = textCtrl2:GetTextExtent("00000.00000")
    textCtrl2:SetInitialSize(wx.wxSize(text_w2, -1))

    local staticText3 = wx.wxStaticText( panel1, wx.wxID_ANY, "Available Resources At Selected Base - 500/", wx.wxPoint(200,194))
    local staticText4 = wx.wxStaticText( panel1, wx.wxID_ANY, "Selected Unit Cost - 100", wx.wxPoint(415,194))
    button = wx.wxButton( panel1, Panle1_Send_It_Button, "Confirm",wx.wxPoint(245,242),wx.wxSize(50, 20),0)

    sizer1:Add(choiceBoxStaticBoxSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    sizer1:Add(choiceBoxStaticBoxSizer2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    sizer1:Add(choiceBoxStaticBoxSizer3, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    panel1:SetSizer(sizer1)
    sizer1:SetSizeHints(panel1)
    notebook:AddPage(panel1, "Deployment")

    -- create second panel in the notebook control
    local panel2 = wx.wxPanel(notebook, wx.wxID_ANY)
    local sizer2 = wx.wxBoxSizer(wx.wxVERTICAL)

    local choice = wx.wxChoice(panel2, wx.wxID_ANY,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"Al Dhafra AB", "Al Maktoum Intl", "Sharjah Intl", "Fujairah Intl"})

    local choiceBoxStaticBox = wx.wxStaticBox( panel2, wx.wxID_ANY, "Deployment From")
    local choiceBoxStaticBoxSizer = wx.wxStaticBoxSizer( choiceBoxStaticBox, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer:Add(choice, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

   local choice2 = wx.wxChoice(panel2, wx.wxID_ANY,
                               wx.wxDefaultPosition, wx.wxDefaultSize,
                               {"A-10C","F/A-18C","M1A2 MBT"})

    local choiceBoxStaticBox2 = wx.wxStaticBox( panel2, wx.wxID_ANY, "Unit To Be Deployed")
    local choiceBoxStaticBoxSizer2 = wx.wxStaticBoxSizer( choiceBoxStaticBox2, wx.wxVERTICAL );
    choiceBoxStaticBoxSizer2:Add(choice2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)

    sizer2:Add(choiceBoxStaticBoxSizer, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    sizer2:Add(choiceBoxStaticBoxSizer2, 0, wx.wxALL + wx.wxGROW + wx.wxCENTER, 5)
    panel2:SetSizer(sizer2)
    sizer2:SetSizeHints(panel2)
    notebook:AddPage(panel2, "Defense")

    local panel3 = wx.wxPanel(notebook, wx.wxID_ANY)
    notebook:AddPage(panel3, "Main H.Q.")

    panel4 = wx.wxPanel(notebook, 664)
    notebook:AddPage(panel4, "Mission Information")

    sw = wx.wxScrolledWindow( panel4, wx.wxID_ANY, wx.wxDefaultPosition, wx.wxSize(900, 600),wx.wxHSCROLL + wx.wxVSCROLL)
    sw:SetScrollbars(15, 15, 900, 600, 0, 0, false)
    sw:Connect(wx.wxEVT_PAINT, OnPaint)

     frame:SetSizeHints(notebook:GetBestSize():GetWidth(),notebook:GetBestSize():GetHeight())

    -- typically you will give a control a specific window id and connect an
    -- event handler for that id, in this case respond to any id
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, HandleEvents)

    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_RADIOBOX_SELECTED, HandleEvents)
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_LISTBOX_SELECTED, HandleEvents)

    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_COMBOBOX_SELECTED, HandleEvents)
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_CHOICE_SELECTED, HandleEvents)
    frame:Connect(wx.wxID_ANY, wx.wxEVT_COMMAND_CHECKLISTBOX_TOGGLED, HandleEvents)

    frame:Connect(Panle1_Static_Box_1, wx.wxEVT_COMMAND_CHOICE_SELECTED, 
        function(event)
            P1_SB1_Selected = event:GetSelection()
    end)

    frame:Connect(Panle1_Static_Box_2, wx.wxEVT_COMMAND_CHOICE_SELECTED, 
        function(event)
            P1_SB2_Selected = event:GetSelection()
    end)

    frame:Connect(Panle1_Static_Box_3, wx.wxEVT_COMMAND_CHOICE_SELECTED, 
        function(event)
            P1_SB3_Selected = event:GetSelection()
    end)

    frame:Connect(Panle1_Send_It_Button, wx.wxEVT_COMMAND_BUTTON_CLICKED,
        function(event)
            if P1_SB1_Selected == -1 or P1_SB2_Selected == -1 or P1_SB3_Selected == -1 then
                wx.wxMessageBox("Missing Entry\n", "Try Agian Commander", wx.wxOK + wx.wxICON_INFORMATION, frame)
            else
                local MissionVariables = string.format( "STCost = %s STSpawnFrom = %s STAttackLocation = %s STUnitType = %s STCanSpawn = true", 100,P1_SB1_Selected,P1_SB2_Selected+1,P1_SB3_Selected )
                local DataFile = io.open("Data.lua", "w")
                DataFile:write(MissionVariables)
                DataFile:close()
            end
    end)

    frame:Show(true)
end
main()
wx.wxGetApp():MainLoop()

This is the map it creates its a little longer down but when the scroll wheel is moved it disappears

您可以改进以下几点:

  1. 您正在为每个点创建 dc。这是非常低效的,因为您只需要在循环之前创建一次它(实际上您这样做了,但不要使用它)。
  2. 同样删除dc;循环后只做一次
  3. 您多次重新加载文件;加载它们并将结果保存在 table 中,然后根据需要使用它。
  4. 即使颜色没有改变,您也在重置笔和画笔;为了尽量减少更改,您可能需要按颜色对它们进行分组。
  5. 你画了一个半径为 1 点的圆。为什么不使用 DrawPoint 呢?

So my question is should I make a texture instead or is there a way my GUI can render the map once and not over and over again like it’s refreshing it’s self?

是的,您可以将正在绘制的内容保存为位图,然后绘制位图本身,而无需花时间绘制其组件。您的 OnPaint 处理程序将如下所示:

local function onPaint()
  local dc = wx.wxPaintDC(frame)
  dc:DrawBitmap(bitmap, 0, 0, true)
  dc:delete()
end

您的绘图将在需要时在 bitmap 上绘制:

mdc:SelectObject(bitmap)
mdc:SetPen(WHATEVER)
mdc:DrawPoint(x, y)
mdc:SelectObject(wx.wxNullBitmap)

其中 mdc=wx.wxMemoryDC().