LifeLike – Interfejs Użytkownika

Witam w następnej części dotyczącej LifeLike. Poprzednio pisałem o zaznaczaniu postaci i dodawaniu przeciwników oraz przełączaniu się między nimi. Dzisiaj, przejdę do UI!

Manager UI w LifeLike

Jak można było zobaczyć, z UI można było spotkać się w menu głównym i w mini grze The Ball, które znajdują się pod linkiem poniżej. Link
W UI Managerze zawarte są metody do kontrolowania komponentów UI, jak np. okno z logami oraz z szczegółami. UI Manager jest podpięty do GameManagera.

Ekran Logów

PIerwszym elementem dla rasowych Rogue Like i Oldschoolowych RPG jest ekran logów. Czyli pole tekstowe z logiem – ile zadaliśmy, co znaleźliśmy i ewentualnie, co, kto do nas powiedział.
Jednak ekran logów trzeba było ograniczyć do określonej liczby linijek – tzn. czyścić te pierwsze, aby cały czas nie było więcej niż wybrana liczba linijek – u mnie 10. Logi dodaje się przez metodę AddLog(treść), a edytor przyjmuje podstawowe tagi html jak „b”, „i” oraz \t i \n dla nowej linii.
Cały kod zobaczycie na GitHubie, a fragment o którym mówię, zobaczycie poniżej.

[csharp]
public void AddLog(string log)
{
ClearFirstLine();

_stringLog.AppendLine(log);
GameLog.text = _stringLog.ToString();
}
[/csharp]

Zaznaczony Przeciwnik

W poprzedniej części nauczyliśmy się, jak zaznaczać przeciwnika i przełączać się pomiędzy nimi, dlatego też, aby to rozszerzyć, stworzyłem panel do wyświetlania danych wybranego wroga.
Obecnie wyświetlane jest jego imię, lvl oraz coś, co poruszę w następnym punkcie, do którego potrzebny jest…

[csharp]
private void SelectedEnemyPanel()
{
if (EnemyUtils.SelectedEnemy==null) return;
if (SelectedEnemyStatistic != null)
{
SelectedEnemyStatistic.text = string.Format("<b>Name</b>: {0} \n<b>Class Name</b>: {1}",
EnemyUtils.SelectedEnemy.EnemyCharacter.Name,
EnemyUtils.SelectedEnemy.ClassName);
}
if (SelectedEnemyDetail != null)
{
SelectedEnemyDetail.text = string.Format("<b>Distance:</b>{0}",
EnemyUtils.SelectedEnemy.Distance);
}

}
[/csharp]

Dystans

Tak, dobrze wiedzieć, jak daleko jesteśmy od przeciwnika, nie tylko, aby był to nowy wodotrysk do wyświetlania, ale także jest to przydatne do systemu walki dystansowego oraz jako informacja, czy jesteśmy na tyle blisko, aby zaatakować bezpośrednio.
Tu by się przydała trochę wiedza z uczelni oraz wzór na odległość między 2 wektorami … ale Unity dostarcza nam Vector.Distance pomiędzy graczem a wrogiem.

Dystans dodałem do klasy Enemy. Pomaga to także posortować przeciwników ze względu na dystans od gracza.

[csharp]
public int Distance {
get {
if (GameManager.Instance.PlayerObject != null)
return (int) Vector2.Distance(GameManager.Instance.PlayerObject.transform.position,
transform.position);
Debug.Log(GameManager.Instance.PlayerObject);
return 0;
//Matematyka jednak cos daje!
// return (int) Mathf.Sqrt(Mathf.Pow(Player.transform.position.x – SelectedEnemy.transform.position.x, 2) +
// Mathf.Pow(Player.transform.position.y – SelectedEnemy.transform.position.y, 2));
}
}
[/csharp]

LifeLIke
1 wersja UI

Podsumowanie

To tyle na temat UI. Temat będzie jeszcze poruszony przy okienku tworzenia postaci oraz dodawania szczegółów dotyczących gracza.
Kod jak zwykle można znaleźć na GitHub https://github.com/aluspl/RogueLikeDSP.
Chciałem dodać player, ale Unity upiera się, że klasy Enemy nie ma … mimo że jest .

Pozdrawiam!

LifeLike – Walka Bezpośrednia – na serio!

Tak, tym razem na serio, będę kontynuował walkę bezpośrednią. Zauważyłem, że jeśli skupię się na kodzie i robię wpis “Code First”, a nie “Theory First” – jak to miało miejsce w poprzednim wpisie, to powstaje dużo kodu, a zostaje mało czasu na jego opis. Będę więc się trochę streszczał. 🙂

Refactoring LifeLike

Z racji wkurzających żółtych podpowiedzi w nowym Rider oraz paru pomysłów związanych z przeciwnikami, postanowiłem zrobić lekką refaktoryzację – w tym zmiany namespace i foldery plików + parę narzędzi do zarządzania przeciwnikami.

Wróg… jest czerwony!

W poprzednim wpisie wspominałem o inspiracji Superhot, w tym postanowiłem słowa zamienić w czyny i stworzyć tego wroga. Jest to, lekka modyfikacja naszego playera, który swoją drogą, również zmienił grafikę. W przyszłości, każdy zasłuży na swój własny wygląd.W tym, będzie po prostu Red Manem ..i wygląda tak:

Jesteśmy Zieloni … Ci dobrzy
Oni są Czerwoni … są Be

Przeciwniku, pojaw się na mapie!

A przy okazji dodaj się do listy Przeciwników, aby łatwo Cię było potem wybrać … i zabić.

[csharp]
private void AddEnemy(MapElement[,] map, int x, int y)
{
if (MaxEnemies &lt;= 0) return;
var chance = _random.Next(100)==1;
if (chance) return;
if (map[x,y]!=MapElement.Floor) return;

var enemy=Instantiate(Enemies.FirstOrDefault(), GetPosition(x, y), Quaternion.identity , EnemiesCollection);
GameManager.Instance.AddEnemy(enemy);

MaxEnemies–;
}
[/csharp]

Założyłem sobie, że przeciwnik musi pojawić się na podłodze, a nie w ścianie. A i musi być w ograniczonej liczbie. 🙂 Póki co, generator działa ze zbyt dużą częstotliwością, więc szansa na pojawienie się przeciwnika jest bardzo duża – za duża.
Ale cóż, ważne, że takim oto sposobem, nasz czerwony wróg pojawił się na mapie !

Luke ! I am Your Enemy

Przeciwniku, bądź Oznaczony!

Kolejnym kluczowym elementem, jest wiedza … kogo zaatakowaliśmy. 🙂

Przeciwnik dostał ten sam shader, co podłoga, więc nie jest widoczny w nocy, ale dodałem mu jakiś element oznaczenia. Małą lampkę, która oznacza, że przeciwnik jest zaznaczony. Zaznaczenia zmieniamy, przez kliknięcie TAB (lub innego przypisanego klawisza)

[csharp]
private void SelectEnemy()
{
if (Enemies.Count < = 0) return;
if (EnemyUtils.EnemyIndex == Enemies.Count) EnemyUtils.EnemyIndex = 0;
foreach (var enemy in Enemies)
{
enemy.IsSelected = false;
}
Debug.Log("Selected Enemy: "+EnemyUtils.SelectedEnemy.EnemyCharacter.Name + "Current Index: "+ EnemyUtils.EnemyIndex);
Enemies[EnemyUtils.EnemyIndex].IsSelected = true;
EnemyUtils.EnemyIndex++;
}
[/csharp]

Podsumowanie

To tyle w dzisiejszym odcinku. Temat kontynuowany będzie też w następny wpisie. Jak widać, nie jest to wcale mało rozbudowany system, a gdy będziemy chcieli do tego dodać jeszcze walkę dystansową i mierzenie, czy dany przeciwnik faktycznie jest w zasięgu bezpośredniego czy dalekiego ataku, to system będzie naprawdę sporo rozbudowany. Nie zapominajmy też, że będzie UI, szansa trafienia oraz okno z logiem naszych ataków.

Link do gry i aktualnej wersji jak zwykle na githubie

LifeLike – Walka Bezpośrednia

A w przyszłości i dystansowa 🙂

Tematem dzisiejszego wieczorno-sobotniego wpisu jest kolejna część dotycząca walki. Byłem świadkiem wpisów na blogach, które mają maksymalnie po 2-3 zdania, 2 razy w tygodniu i to totalnie o niczym. Nie chcę iść tą drogą, ale niestety skutkuje to tym, że ciężko mi czasami wrzucić 2 posty tygodniowo. Dzisiaj przechodzimy do kolejnej części na temat walki, czyli to, czym roguelike żyją .. lub nie 🙂

Czytaj dalej LifeLike – Walka Bezpośrednia