Jump to content

Вопрос по отображению окон инвентаря игрока.


photo

Recommended Posts

Всем привет!

Уважаемые разработчики и те кто знает, подскажите  пожалуйста)

Делаю простенький инвентарь игрока. Добавлять, выбрасывать предметы - без проблем. Но неожиданно столкнулся 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_... безрезультатно.

Ну а теперь вопрос. Как мне сделать так, что бы иконки предметов инвентаря полностью заполняли окно инвентаря произвольного размера?

Спасибо!

 

quest_0.jpg

quest_1.jpg

quest_2.jpg

Link to comment

Добрый день!

Можете, пожалуйста, показать, как Вы в коде создаете виджет Inv и задаете ему размеры? И как добавляете элементы в Inv_grid?

Также для начала можете попробовать убрать дублирование следующей строки:

Inv.AddChild(Inv_grid, Gui.ALIGN_LEFT | Gui.ALIGN_EXPAND | Gui.ALIGN_OVERLAP); 

и посмотреть, как Ваш инвентарь будет себя вести, если из этой же строки убрать Gui.ALIGN_OVERLAP.

Link to comment

Спасибо за ответ! Да действительно, скопировал два раза строчку:

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();        
    }
}

 

  • Like 1
Link to comment

Большое спасибо за код! Удалось выяснить, в чем была проблема.

В 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.

  • Like 2
Link to comment

Большое Вам спасибо за столь развёрнутый ответ!  Да, я уже догадался что проблема просто не решится и вместо WidgetWindow перешел на WidgetHBox. Он прекрасно работает.  Скрин прилагаю)

3 hours ago, moody_pooch said:

Вы можете вызвать один раз в Init() сразу после создания Inv_grid, все дальнейшие изменения с Inv_grid (добавление дочерних элементов итп) уже сами будут отображаться в Inv.

Спасибо за совет! Непременно учту в дальнейшей работе)

Ну и собственно результат. Осталось нарисовать сетку. Вертикальную полосу прокрутки добавил (появится, когда окно полностью заполнится предметами). Контекстное меню на каждую иконку добавил.  Сейчас буду пытаться сохранить/загрузить всё это дело в файл. 

inv.thumb.jpg.242e92891d403220211eeb2e4c34354a.jpg

Спасибо! Поддержка на 5!

  • Like 3
Link to comment
×
×
  • Create New...