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 ответ
Есть несколько вещей, которые вы можете улучшить:
- Вы создаете
dc
за каждую точку. Это крайне неэффективно, так как вам нужно создать его только один раз перед циклами (на самом деле вы делаете это, но не используете его). - То же самое для удаления
dc
; делать это только один раз после цикла - Вы продолжаете перезагружать файлы несколько раз; загрузите их и сохраните результаты в таблице, затем используйте их по мере необходимости.
- Вы сбрасываете ручку и кисть, даже когда цвета не меняются; чтобы свести к минимуму изменения, вы можете сгруппировать их по цвету.
- Вы рисуете круг с радиусом 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()
,