WxLua GUI 2d mappinp

时间:2018-07-29 02:59:39

标签: lua textures wxlua

好的,我想为我的GUI制作2d地图(游戏的文字地图)。在游戏中,我将地形数据导出到一个外部lua文件中,该文件如下所示:Info = {{1 = {颜色=“蓝色”,x = 0,y = 0},等等...}大数组。我的gui读取此文件并wxDrawcircle并将像素大小的彩色点放置在坐标上。这一切都可以,并且创建了一个漂亮的地图,但是问题是当我单击或执行任何操作时,它都冻结了,看起来GUI无法处理所有这些点。几乎就像我每次单击GUI一样,刷新并重新渲染所有这些点。因此,我的问题是我应该制作纹理,还是我的GUI有一种方法可以一次又一次地渲染地图,而不是像刷新自身一样一遍又一遍?

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

我的GUI。更新

    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 个答案:

答案 0 :(得分:0)

您可以改进几件事:

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

所以我的问题是我应该改用一个纹理,还是我的GUI有一种方法可以一次渲染地图,而不是像刷新自身一样一遍又一遍地渲染地图?

是的,您可以将要绘制的内容保存到位图,然后绘制位图本身,而无需花费时间绘制其组件。您的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()