yurickon Posted January 22, 2023 Posted January 22, 2023 Всем привет! Уважаемые разработчики и те кто знает, подскажите пожалуйста) Делаю простенький инвентарь игрока. Добавлять, выбрасывать предметы - без проблем. Но неожиданно столкнулся c тем что показано на скриншоте №1. На окне инвентаря 300*300 добавляю 6 иконок предметов. Для этого использую такую конструкцию (код C#): 1.Создаю конструкторы виджетов нужных окон с заданными параметрами 2. Добавляю виджеты в качестве детей с помощью метода AddChild 3. Вывожу на экран Inv_grid = new WidgetGridBox(6, 4, 4); Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_EXPAND | Gui.ALIGN_OVERLAP); Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_EXPAND | Gui.ALIGN_OVERLAP); Icon_inv[0].AddCallback(Gui.CALLBACK_INDEX.LEAVE, leave_menu_icon_inv_0); Icon_inv[0].AddCallback(Gui.CALLBACK_INDEX.CLICKED, create_menu_icon_inv_0); Icon_inv_menu[0].AddCallback(Gui.CALLBACK_INDEX.CLICKED, menu_icon_use_0); Inv_item[0].AddChild(Icon_label[0], Gui.ALIGN_BOTTOM | Gui.ALIGN_RIGHT | Gui.ALIGN_OVERLAP); WindowManager.MainWindow.AddChild(Inv, Gui.ALIGN_CENTER | Gui.ALIGN_OVERLAP); Как видно на скриншоте №1, последние две иконки накладываются на предыдущие две. Хотя установлено 6 столбцов и они должны (как я думал) распределиться до правого края окна. Но этого не происходит! Далее. Я просто увеличил ширину окна 400*300, как показано на скриншоте №2, и картина поменялась. Такое ощущение что правая область окна начиная примерно с середины, запрещает размещать там объекты grid. Ну и на третьем скриншоте показан результат уменьшения количество столбцов (первая цифра) Inv_grid = new WidgetGridBox(4, 4, 4); до 4-х. Теперь всё корректно отображается. Перепробовал все Gui.ALIGN_... безрезультатно. Ну а теперь вопрос. Как мне сделать так, что бы иконки предметов инвентаря полностью заполняли окно инвентаря произвольного размера? Спасибо!
moody_pooch Posted January 23, 2023 Posted January 23, 2023 Добрый день! Можете, пожалуйста, показать, как Вы в коде создаете виджет Inv и задаете ему размеры? И как добавляете элементы в Inv_grid? Также для начала можете попробовать убрать дублирование следующей строки: Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_EXPAND | Gui.ALIGN_OVERLAP); и посмотреть, как Ваш инвентарь будет себя вести, если из этой же строки убрать Gui.ALIGN_OVERLAP.
yurickon Posted January 23, 2023 Author Posted January 23, 2023 Спасибо за ответ! Да действительно, скопировал два раза строчку: Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_EXPAND | Gui.ALIGN_OVERLAP); Но в коде эта строчка используется один раз. Убрал по Вашему совету Gui.ALIGN_OVERLAP, однако в результате иконки добавляются в центр с увеличением окна инвентаря... Вот собственно сам код. Там много лишнего, не относящегося к проблеме (ссылки на иконки и т.д.) но он показывает всю картину. public class inv : Component { public WidgetWindow Inv; public WidgetWindow[] Inv_item; public WidgetScrollBox Inv_scroll; public WidgetGridBox Inv_grid; public WidgetSprite[] Icon_inv; public WidgetMenuBox[] Icon_inv_menu; public WidgetLabel [] Icon_label; public int [] Icon_label_inv; float[] z_add; public int Inv_active; Node _fps; WidgetIcon close_icon; private void Init() { Inv = new WidgetWindow("Инвентарь", 350, 350); Inv.Moveable = false; //неподвижное окно Inv.BackgroundColor = vec4.GREY;//цвет фона Inv_item = new WidgetWindow[6]; Icon_inv = new WidgetSprite[6]; Icon_inv_menu = new WidgetMenuBox[6]; Icon_label = new WidgetLabel[6]; Icon_label_inv = new int [6]; z_add = new float[6]; Inv_grid = new WidgetGridBox(6, 10, 10); for(int i = 0; i < 6; i ++) { Icon_inv_menu[i] = new WidgetMenuBox(5, 5); Icon_label[i] = new WidgetLabel("0"); } //--------разводной ключ-------------- Inv_item[0] = new WidgetWindow("Ключ"); Icon_inv[0] = new WidgetSprite("gui/Adjustable_wrench_inv.png"); //--------будильник------------------- Inv_item[1] = new WidgetWindow("Часы"); Icon_inv[1] = new WidgetSprite("gui/Alarm_inv.png"); //--------альбом--------------------- Inv_item[2] = new WidgetWindow("Альбом"); Icon_inv[2] = new WidgetSprite("gui/Albom_surovin_inv.png"); //--------хворост------------------- Inv_item[3] = new WidgetWindow("Хворост"); Icon_inv[3] = new WidgetSprite("gui/Brushwood_inv.png"); //--------вода------------------- Inv_item[4] = new WidgetWindow("Вода"); Icon_inv[4] = new WidgetSprite("gui/Water_inv.png"); //--------тушенка------------------- Inv_item[5] = new WidgetWindow("Тушенка"); Icon_inv[5] = new WidgetSprite("gui/Meat_bank_inv.png"); //кнопка закрытия инвентаря close_icon = new WidgetIcon( "Inv_close.png"); close_icon.SetPosition(10, -24); close_icon.SetToolTip("Закрыть инвентарь"); close_icon.AddCallback(Gui.CALLBACK_INDEX.CLICKED, inv_close); Inv.AddChild(close_icon, Gui.ALIGN_RIGHT | Gui.ALIGN_TOP | Gui.ALIGN_OVERLAP); } void inventory_add() { //открываем инвентарь if(Input.IsKeyDown(Input.KEY.I)) { Inv_active += 1; if(Inv_active == 1) { ControlsApp.MouseHandle = Input.MOUSE_HANDLE.USER; Input.MouseCursorSystem = true; Game.Scale = 0; WindowManager.MainWindow.AddChild(Inv, Gui.ALIGN_CENTER | Gui.ALIGN_OVERLAP); } if(Inv_active == 2) { ControlsApp.MouseHandle = Input.MOUSE_HANDLE.GRAB; Input.MouseCursorSystem = true; WindowManager.MainWindow.RemoveChild(Inv); Game.Scale = 1f; for(int i = 0; i < z_add.Length; i ++) z_add[i] = 0; Inv_active = 0; } } //Добавление предметов (тестирование) if(Input.IsKeyDown(Input.KEY.NUMPAD_DIGIT_0)) Inv_add_item(0, "Разводной ключ. Нужен при ремонтах."); if(Input.IsKeyDown(Input.KEY.NUMPAD_DIGIT_1)) Inv_add_item(1, "Сломанные часы. Требуется починка."); if(Input.IsKeyDown(Input.KEY.NUMPAD_DIGIT_2)) Inv_add_item(2, "Альбом Суровина!"); if(Input.IsKeyDown(Input.KEY.NUMPAD_DIGIT_3)) Inv_add_item(3, "Хворост. Можно расжечь костёр."); if(Input.IsKeyDown(Input.KEY.NUMPAD_DIGIT_4)) Inv_add_item(4, "Питьевая вода."); if(Input.IsKeyDown(Input.KEY.NUMPAD_DIGIT_5)) Inv_add_item(5, "Тушеное мясо."); } public void Inv_add_item(int i, string _tooltip) { Icon_label_inv[i] += 1; Icon_label[i].Text = Icon_label_inv[i].ToString("0"); Inv_item[i].SetToolTip(_tooltip); //подсказка Inv_item[i].AddChild(Icon_inv[i], Gui.ALIGN_LEFT | Gui.ALIGN_TOP); //добавляем иконку инвентаря Inv_item[i].AddChild(Icon_label[i], Gui.ALIGN_RIGHT | Gui.ALIGN_TOP |Gui.ALIGN_OVERLAP); //добавляем количество предметов в слоте Inv_grid.AddChild(Inv_item[i], Gui.ALIGN_FIXED); //добавляем слоты в сетку инвентаря Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_TOP | Gui.ALIGN_OVERLAP); //сетку добавляес в основное окно инвентаря } void inv_close() { ControlsApp.MouseHandle = Input.MOUSE_HANDLE.GRAB; Input.MouseCursorSystem = true; WindowManager.MainWindow.RemoveChild(Inv); Inv_active = 0; Game.Scale = 1f; for(int i = 0; i < z_add.Length; i ++) z_add[i] = 0; } private void Update() { inventory_add(); } } 1
moody_pooch Posted January 24, 2023 Posted January 24, 2023 Большое спасибо за код! Удалось выяснить, в чем была проблема. В WidgetGridBox Вы добавляете элементы Inv_item типа WidgetWindow. С тем, как Вы их добавляете, нет проблем, но по какой-то причине WidgetWindow внутри WidgetGridBox ведет себя так, как Вы наблюдали в своём примере. К сожалению, на данный момент могу только порекомендовать Вам заменить тип Inv_item на какой-нибудь другой виджет, например, WidgetGroupBox, WidgetVBox и др. Стоит заметить, что тут могут возникнуть проблемы с tooltip, так как хоть Вы и можете виджету типа WidgetGroupBox вызвать метод SetToolTip(), отображаться он не будет. Вместо это можно будет задать tooltip элементам внутри Inv_item, например, Icon_inv. По поводу увеличения окна инвентаря: Quote Но в коде эта строчка используется один раз. Убрал по Вашему совету Gui.ALIGN_OVERLAP, однако в результате иконки добавляются в центр с увеличением окна инвентаря... Когда Вы создаете окно этой строкой: Inv = new WidgetWindow("Инвентарь", 350, 350); параметры конструктора x и y - это не размеры окна, а отступы внутри окна до его элементов и между его элементами. Поэтому, когда вы убираете Gui.ALIGN_OVERLAP, Inv_grid выставляется, как ему указано в левой верхней части окна Inv, но из-за внутренних отступов равных 350, кажется будто Inv_grid смещается в центр, а окно расширяется. Уберите Gui.ALIGN_OVERLAP и попробуйте выставите границы меньшего размера, и всё придет в норму. Задать размеры окна инвентаря можно следующим образом: Inv.Width = 350; Inv.Height = 350; Также могу добавить небольшой совет, который, возможно, будет полезен. Вам необязательно каждый раз добалять заново дочерние элементы в виджет, если эти элементы изменились. Достаточно на этапе инициализации сделать это один раз. Например, эту строку: Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_EXPAND | Gui.ALIGN_OVERLAP); Вы можете вызвать один раз в Init() сразу после создания Inv_grid, все дальнейшие изменения с Inv_grid (добавление дочерних элементов итп) уже сами будут отображаться в Inv. 2
yurickon Posted January 24, 2023 Author Posted January 24, 2023 Большое Вам спасибо за столь развёрнутый ответ! Да, я уже догадался что проблема просто не решится и вместо WidgetWindow перешел на WidgetHBox. Он прекрасно работает. Скрин прилагаю) 3 hours ago, moody_pooch said: Вы можете вызвать один раз в Init() сразу после создания Inv_grid, все дальнейшие изменения с Inv_grid (добавление дочерних элементов итп) уже сами будут отображаться в Inv. Спасибо за совет! Непременно учту в дальнейшей работе) Ну и собственно результат. Осталось нарисовать сетку. Вертикальную полосу прокрутки добавил (появится, когда окно полностью заполнится предметами). Контекстное меню на каждую иконку добавил. Сейчас буду пытаться сохранить/загрузить всё это дело в файл. Спасибо! Поддержка на 5! 3
Recommended Posts