WxLua GUI 2d mappinp

Хорошо, ребята, поэтому я пытаюсь сделать 2D-карту (буквальную карту моей игры) для моего графического интерфейса. Когда в игре я экспортировал данные о местности во внешний файл lua, который выглядит следующим образом: Info = { 1 = {Color = “blue”, x = 0, y = 0}, ect ect...}, в основном один большой массив. Мой графический интерфейс читает этот файл и wxDrawcircle и помещает цветные точки размером с пиксель в координаты. Все это работает и создает красивую карту, но проблема в том, что когда я щелкаю или делаю что-нибудь, оно останавливается и выглядит так, будто графический интерфейс не может обработать все эти точки. Кажется, что когда я нажимаю, 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()

Это карта, которая создает немного длиннее вниз, но когда колесо прокрутки перемещается, оно исчезает

1 ответ

Решение

Есть несколько вещей, которые вы можете улучшить:

  1. Вы создаете dc за каждую точку. Это крайне неэффективно, так как вам нужно создать его только один раз перед циклами (на самом деле вы делаете это, но не используете его).
  2. То же самое для удаления dc; делать это только один раз после цикла
  3. Вы продолжаете перезагружать файлы несколько раз; загрузите их и сохраните результаты в таблице, затем используйте их по мере необходимости.
  4. Вы сбрасываете ручку и кисть, даже когда цвета не меняются; чтобы свести к минимуму изменения, вы можете сгруппировать их по цвету.
  5. Вы рисуете круг с радиусом 1 точка. Почему бы не использовать DrawPoint вместо?

Поэтому мой вопрос заключается в том, должен ли я сделать текстуру вместо этого или есть способ, которым мой графический интерфейс может отображать карту один раз, а не снова и снова, как будто она обновляется сама?

Да, вы можете сохранить то, что вы рисуете, в растровом изображении, а затем нарисовать само растровое изображение, не тратя время на рисование его компонентов. Ваш 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(),

Другие вопросы по тегам