1
2
3
4
5
| public void UpdateItem(int i)
{
if (i >= ViewIndex && i < ViewIndex + SlotsCount)
Slots[i - ViewIndex].SetItem(Character.Inventory[i]);
} |
HUDInventory.cs
Metoda ta będzie przydatna, gdy np. gracz zdecyduje się ubrać wybrany przedmiot - wówczas zaktualizujemy jego kwadracik.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| public void UpdateDescription()
{
if (SelectIndex != -1)
{
DescriptionLabel.Caption =
Character.Inventory[SelectIndex].DisplayName
+ "\n\n"
+ Character.Inventory[SelectIndex].Description;
SelectedPicture.Panel.MaterialName =
Character.Inventory[SelectIndex].InventoryPictureMaterial;
}
else
{
DescriptionLabel.Caption = "";
SelectedPicture.Panel.MaterialName = "QuadMaterial";
}
} |
HUDInventory.cs
Ta metoda będzie aktualizować wyświetlany opis. W przypadku gdy wybrany jest jakiś przedmiot - wyświetlamy jego obrazek, nazwę i opis. Ogre nie zapewnia nam przycinania tekstu w obiektach typu
TextArea
, więc będziemy musieli sami pilnować, by opis mieścił się w okienku. Inną opcją mogłoby być napisanie klasy kontrolki automatycznie dbającej o formatowanie tekstu i umożliwienie przewijania go użytkownikowi, jednak byłoby to bliskie tworzeniu własnego systemu GUI, czego wolelibyśmy uniknąć.
1
2
3
4
5
6
7
8
9
10
11
12
| public int ViewIndex
{
get { return _ViewIndex; }
set
{
if (value != _ViewIndex)
{
_ViewIndex = System.Math.Max(0, value);
UpdateView();
}
}
} |
HUDInventory.cs
Właściwością
ViewIndex
będziemy mogli przewijać listę przedmiotów. Każda zmiana pociąga za sobą aktualizację kwadracików.
1
2
3
4
5
6
7
8
9
10
11
12
| public int SelectIndex
{
get
{
return (_SelectIndex >= Character.Inventory.Count ? -1 : _SelectIndex);
}
set
{
if (value < 0)
value = -1;
else if (value >= Character.Inventory.Count)
value = Character.Inventory.Count - 1; |
HUDInventory.cs
Właściwość ta ma wartość -1, gdy nie jest zaznaczony żaden obiekt. Ma to miejsce w przypadku, gdy postać nie będzie posiadać żadnego przedmiotu w ekwipunku. Podczas ustawiania pilnujemy, by indeks nie wyjechał poza tablicę.
1
2
3
4
5
6
7
8
9
10
| if (_SelectIndex >= ViewIndex + SlotsCount)
ViewIndex = _SelectIndex - SlotsCount + 1;
else if (_SelectIndex < ViewIndex)
ViewIndex = _SelectIndex;
SelectQuad.Panel.Top =
SlotsSpacing + (_SelectIndex - ViewIndex) * (InventorySlot.Size + SlotsSpacing);
UpdateDescription();
}
} |
HUDInventory.cs, SelectIndex
Pilnujemy, by zaznaczony przedmiot był objęty przedziałem widoczności. W przypadku gdy zaznaczenie wyjdzie za obszar widoczności - przesuwamy zakres tak, by zaznaczony element był ostatnim widocznym. Gdy zaś zaznaczenie wyjdzie przed obszar - będzie ono pierwszym widocznym elementem. Po aktualizacji listy przesuwamy odpowiednio kwadracik podświetlający i aktualizujemy opis.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| public bool IsVisible
{
set
{
foreach (var slot in Slots) slot.IsVisible = value;
SelectQuad.IsVisible = value;
DescriptionBg.IsVisible = value;
DescriptionLabel.IsVisible = value;
SelectedPicture.IsVisible = value;
if (value)
{
UpdateView();
SelectIndex = SelectIndex;
}
}
} |
HUDInventory.cs
Właściwością
IsVisible
szybko ukryjemy i odsłonimy wszystkie elementy interfejsu. W przypadku odsłaniania aktualizujemy listę, a także indeks zaznaczenia, ponieważ ekwipunek mógł ulec zmianie i poprzedni indeks mógłby wyjść poza zakres listy ekwipunku.
Przejdźmy do klasy HumanController
:
1
2
3
4
5
6
| public enum HumanControllerState
{
FREE,
TALK,
INVENTORY
} |
HumanController.cs
Obsługę interfejsu zaimplementujemy jako nowy stan kontrolera postaci.
1
2
3
4
5
6
7
8
| ...
HUDInventory HUDInventory;
...
public HumanController()
{
...
HUDInventory = new HUDInventory();
} |
HumanController.cs
Obiekt
HUDInventory
stworzymy w konstruktorze klasy
HumanController
.
1
2
3
4
5
6
7
8
9
10
| private void HandleInventory()
{
if (Engine.Singleton.IsKeyTyped(MOIS.KeyCode.KC_DOWN))
HUDInventory.SelectIndex++;
if (Engine.Singleton.IsKeyTyped(MOIS.KeyCode.KC_UP))
HUDInventory.SelectIndex--;
if (Engine.Singleton.IsKeyTyped(MOIS.KeyCode.KC_TAB))
SwitchState(HumanControllerState.FREE);
} |
HumanController.cs
Metoda obsługująca tryb ekwipunku na ten czas będzie umożliwiać poruszanie się po liście przedmiotów. Klawiszem Tab będziemy wchodzić i wychodzić z trybu ekwipunku.
1
2
3
4
5
6
7
8
9
10
11
| if (State == HumanControllerState.FREE)
{
...
else if (newState == HumanControllerState.INVENTORY)
HUDInventory.IsVisible = true;
}
...
else if (State == HumanControllerState.INVENTORY)
if (newState == HumanControllerState.FREE)
HUDInventory.IsVisible = false;
... |
HumanController.cs, SwitchState()
Przejścia między stanami przeglądania ekwipunku a grą będą pokazywac i ukrywać interfejs.
1
2
3
4
5
| ...
if (Engine.Singleton.IsKeyTyped(MOIS.KeyCode.KC_TAB)
&& Character.CanSwitchState(Character.CharacterState.INVENTORY))
SwitchState(HumanControllerState.INVENTORY);
... |
HumanController.cs, HandleMovement()
Do trybu
INVENTORY
przejść będzie można wciskając klawisz Tab w trybie poruszania się. Musimy też dodać
stan przeglądania ekwipunku do klasy postaci, ponieważ chcemy móc określić, kiedy będzie można do niego przejść.
1
2
3
4
5
6
7
| if (Character != null)
{
...
else if (State == HumanControllerState.INVENTORY)
HandleInventory();
}
... |
HumanController.cs, Update()
Pamiętamy o wywołaniu odpowiedniej metody w stanie
INVENTORY
.
W klasie
Character
dopisujemy nowy stan i dodajemy przejście do niego z
IDLE
do mapy stanów:
1
2
3
| ...
StatesMap[CharacterState.IDLE].Add(CharacterState.INVENTORY);
... |
Character.cs, InitStatesMap()
Ten "stan" działa na takiej samej zasadzie jak
TURN
- służy tylko do określenia, czy postać może wykonać daną akcję w danym stanie.
Na koniec rozbudujemy nieco opis miecza by sprawdzić działanie interfejsu:
1
2
3
4
5
6
7
8
9
10
| ...
swordProfile.Description =
@"A sword is a long, edged piece of
forged metal, used in many civilizations
throughout the world, primarily as a
cutting or thrusting weapon and
occasionally as a clubbing or
bludgeoning weapon. The word sword
comes from the Old English sweord"; // źródło:Wikipedia ;)
swordProfile.InventoryPictureMaterial = "SpriteSword"; |
Program.cs, Main()
Interfejs powinien już działać. Możesz umieścić w grze więcej mieczy, by przetestować przewijanie listy.

Użyte materiały i tekstury

Aktualny kod źródłowy