Hra - Vrstvy na postavě – .NET – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Hra - Vrstvy na postavě – .NET – Fórum – Programujte.comHra - Vrstvy na postavě – .NET – Fórum – Programujte.com

 

Mutagen
~ Anonymní uživatel
549 příspěvků
7. 11. 2017   #1
-
0
-

Zdravím,

po delší době sem si chtěl trošku oživit C# tak jsem si vymyslel menší projekt (základní systém tahového rpg), všechno se zatím vyvyjí kladně, ale až na jednu věc. Tou jsou vrstvy (layers) na postavě (hlava, hrud, ruce, nohy). Jako první mě napadlo to udělat jednoduše, normální pole/list objektu (IDLayeru, Item) s tím, že každá část je předem definovaná. Tam jsem problém ještě neviděl, fungovalo to jak mělo až do chvíle, kdy jsem chtěl udělat  Item, který musel mít i předem definovaný na jaký layer jde nasadit (což u hlavy, těla a nohou nevadí), ale problém nastal tehdy, když to měla být zbraň, která se dá nasadit do rukou. Jelikož jsem musel při vytváření definovat kam ten item pujde nasadit tak jsem měl navýběr pravá nebo levá ruka (napevno) a nemohl si člověk vybírat do jaké ruky to dá.

Tak jsem to předělal (do aktuální podoby), že Layers je objekt který drží objekty Torso, Head, Legs a Hands (Hands je rozšířen o Hand(Left/Right) a Hand má v sobě objekty Ring, Bracelet, Hand).

Což ve výsledku funguje přesně jak potřebuju, ale to nastavování a práci s těmi objekty mě příjde strašně krkolomná až otřesná. Přes switch/case rozlišuju podle LayerTypu jaký objekt mám naplnit/přepsat/vymazat, což se mi zdá nepraktické, když do rukou můžu nasadit typ Weapon či Armory (štít) a další rozšíření o šperky a další věci co by mohli být na layeru v rukách).

Tím bych se rád zeptat jaké zkušenosti máte Vy, jak vyřešit tento problém, či jestli neuchyluju náhodou špatným směrem.

PS. Kdyby náhodou byl zájem vidět aktuální kod, dodatečně dodám.

Děkuji za pomoc :)

Nahlásit jako SPAM
IP: 193.138.154.–
MilanL+1
Grafoman
7. 11. 2017   #2
-
0
-

#1 Mutagen
asi bych to dělal přes množiny/kolekce v jedný kolekci budeš mít inventář v dalších kolekcích věci podle typů hlava/tělo/nohy/boty/ozdoby na těle(náhrdelník/medaile apod)/paže/ruce-zbraně(1r/2r)/štíty, prsteny/náramky

pak při doplnování na dané místo uděláš průnik množiny inventář-hlava a pokud v invu něco je tak bud nasadíš neo nabídne výběr k nasazení u rukou pak už jen rozlišíš jestli je zbraň 1- nebo obou ruční, případně další možné kombinace zbraň+štít nebo 2 zbraně.

Nahlásit jako SPAM
IP: 185.112.167.–
Mutagen
~ Anonymní uživatel
549 příspěvků
7. 11. 2017   #3
-
0
-

#2 MilanL
Díky za odpověd, ale tomuhle co řikáš jsem se právě chtěl kompletně vyhnout, abych to měl v kolekcích podle typu. Mám čistě 1 kolekci (batoh) kde mám všechny itemy. To co jsi napsal je klasický systém RPG. Napsal jsi kombinace rozlišování (to při aktuálním kodu je snadno providitelný) ovšem to není to co jsme přesně chtěl vědět. Ptal jsem se na systém Layeru a né systém jak nasadit itemy. Šlo mě ovšem o mechanismus abych nemusel psát zdlouhavé switch/case pro každý layerID a následně u ruk by to bylo o další 2 urovně Left.Hand a Right.Hand ... Což jsem eliminoval právě zmíněným kódem dolejc.

public object this[LayerID _layer]
        {
            get
            {
                switch(_layer)
                {
                    case LayerID.Head:
                        return FHead;
                    case LayerID.Torso:
                        return FTorso;
                    case LayerID.Hands:
                        return FHands;
                    case LayerID.Legs:
                        return FLegs;
                }
                return null;
            }

            set
            {
                switch (_layer)
                {
                    case LayerID.Head:
                        FHead = (LayerItem)value;
                        break;
                    case LayerID.Torso:
                        FTorso = (LayerItem)value;
                        break;
                    case LayerID.Hands:
                        FHands = (HandsLayer)value;
                        break;
                    case LayerID.Legs:
                        FLegs = (LayerItem)value;
                        break;
                }
            }
        }
public HandLayer this[HandsLayerID _layer]
        {
            get 
            {
                if (_layer == HandsLayerID.Left)
                    return this.Left;
                else 
                    return this.Right;
            }
        }

        public LayerItem this[HandsLayerID _layer, HandLayerID _layer2]
        {
            get
            {
                if (_layer == HandsLayerID.Left)
                    return this.Left[_layer2];
                else
                    return this.Right[_layer2];
            }
        }
public LayerItem this[HandLayerID _layer]
        {
            get
            {
                switch(_layer)
                {
                    case HandLayerID.Bracelet:
                        return this.FBracelet;
                    case HandLayerID.Hand:
                        return this.FHand;
                    case HandLayerID.Ring:
                        return this.Ring;
                }
                return null;
            }

            set
            {
                switch(_layer)
                {
                    case HandLayerID.Bracelet:
                        FBracelet = value;
                        break;
                    case HandLayerID.Hand:
                        FHand = value;
                        break;
                    case HandLayerID.Ring:
                        FRing = value;
                        break;
                }
            }
        }

A pak k tomu přistupuju

this.property[LayerID.Head/Torso/Legs] = Item2Equip

a u ruk

this.property[LayerID.Hands][HandsLayerID.Left/Right][HandLayerID.Hand/Ring/Bracelet] = Item2Equip

Popřípadě kdybych chtěl kompletně celou postavu svlíknout tak stačí čistě tohle

foreach (LayerID lLayerID in Enum.GetValues(typeof(LayerID)))
            {
                if (lLayerID == LayerID.Hands)
                {
                    foreach (HandsLayerID lHandsLayerID in Enum.GetValues(typeof(HandsLayerID)))
                        foreach (HandLayerID lHandLayerID in Enum.GetValues(typeof(HandLayerID)))
                            ((HandsLayer)player.LayerItems[lLayerID])[lHandsLayerID][lHandLayerID] = null;
                }
                else
                    player.LayerItems[lLayerID] = null;
            }

Ale přesto díky aspon za odpověd :)

Nahlásit jako SPAM
IP: 89.190.90.–
gna
~ Anonymní uživatel
1891 příspěvků
8. 11. 2017   #4
-
0
-

   

Dictionary<ID, Item> veci = new Dictionary<ID, Item>();
veci[id] = item;
item = veci[id];
Nahlásit jako SPAM
IP: 213.211.51.–
Mutagen
~ Anonymní uživatel
549 příspěvků
8. 11. 2017   #5
-
0
-

#4 gna
Též by se dalo použít, ale už není třeba. Možná v budoucnu použiju na rozšíření. Ty layery by se tím daly též využít, to neřikám, ale předělával jsem to na 2x a teď to funguje jak potřebuju, i práce s tím je minimální oproti tomu switch/case jak jsem to měl předtím a přehlednější.

Nahlásit jako SPAM
IP: 193.138.154.–
Ovrscout
~ Anonymní uživatel
113 příspěvků
8. 11. 2017   #6
-
0
-

nemám radu ale dotaz, obouruční a jedenapůlruční zbraně také podporuješ? :)

Nahlásit jako SPAM
IP: 193.165.79.–
peter
~ Anonymní uživatel
4016 příspěvků
8. 11. 2017   #7
-
0
-

Zkus uvazovat databazove a programove. Co potrebujes? Potrebujes, kdyz manik zasahne ruku, aby bylo mozne poskodit prsten, zbran, ruku, pripadne kryt ruky, rukavice, ...

Odbocka. Treba nektere kordy maji kolem cele ruky kovovy obal. Takze nemusis mit rukavice a mas v podstate celou ruku chranenou. Kordem propichnes kde co. Ma velky dosah a obvykle utok na krk je fatalni. Ale machnutim neznicis brneni. Ale utok kordem si treba tezko vsimnes v helme, protoze je to jen tenoucka tycka. Takze i u takove obycejne zbrane jsou ruzne vlastnosti, ktere zavisi na druhu brneni nepritele.
Zpet...

Takze, protoze chci s vecmi blize pracovat, tak na layery ted uplne zapomen. Postava ma sloty (kolonky, ctverecky), pro kazdy typ jeden. Kazdy slot ma id. Kazdy slot patri pod kategorii (layer). Kazda kategorie spada pod dalsi kategorii. Proste mas jakysi strom. Kategorie maji ruzne vlastnosti.
slot prsten
- kategorie ruka
- level 1
slot rukavice
- kategorie ruka
- level 2
slot ocelove drapy
- kategorie ruka
- level 3
Treba na zachycovani mece dlani. Nebo kolem zapesti, utocne drapy / noze
Kdyz nekdo zautoci na ruku, pokud ma postava drapy, tak je pravdepodobne, ze ocel vykryje vetsinu a nedojde k poskozeni rukavic ani prstene.
Kdyz ma postava jen rukavice (kozene), tak je sance, ze se prsten poskodi i narazem nebo zpusobi zachyceni zbrane zbrane, vetsi poskozeni rukaci a soucasne prstene. Kdyz ma kovove rukavice, tak nejspis neposkodi ani prsten.
Cili, umisteni do lvl 3 od tela chrani predmety bliz telu.

Mno, a pak muzes mit dalsi kategorii provazani, ktera urcuje, ze jsou nejake veci provazane a pri pouziti je treba zkontrolovat podle nejakych podminek i dalsi sloty. Treba nasazeni mece, kdyz mas v jedne ruce zbran, zda muzes mit i druhe. Nebo stit. A muzes mit dva stity? Proc ne, ze jo? Proc to vetsina rpg neumoznuje? Muzes stity zpusobovat dmg? Proc ne, treba efekt omraceni jako uder kladiva, odstrceni, nebo s ostny na stitu i rezne rany. Ale proti platovemu brneni to nebude mit efekt. Takze mu stit neda skoro zadne dmg. Leda by tam nemel 10 ostnu, ale jen jeden. A pak je ale sance, ze to v kovu uvizne. Ale muzes mit stit upevneny k ruce, tak o nej asi neprijdes a asi se ti podari jej vypacit.

Pak tam muzes mit vlastnost vaha. Omezeni kategorie na vahu. Omezeni kategorie telo na vahu.
slot brneni
- kat lvl 1 postava
- kat lvl 2 telo
- max vaha
slot/kat postava
- kat lvl 1 -zadna- / cili je to root slot
- max vaha
Jakoze je treba kontrolovat treba vahu napric vsemi kategoriemi. Ruka to mozna unese, ale telo celkove bude pretizene.

Nahlásit jako SPAM
IP: 2001:718:2601:258:f017:74...–
MilanL+1
Grafoman
8. 11. 2017   #8
-
0
-

#3 Mutagen

Co takhle polymorfismus ten by na to nešel použít, nebo se chceš vyhnout i tomu?

Uděláš si Abstraktního rodiče layer z něj pak odvodíš všechny zbývající layery a v procházení postavy už se ti to rozliší samo. Při vytváření postavy si založíš pole nebo kolekci layers, kam si nacpeš jednotlivý layery a pak v programu už jen procházíš a pak se ke každé položce pole použijí metody odpovídající typu layeru.

Nahlásit jako SPAM
IP: 91.139.9.–
Mutagen
~ Anonymní uživatel
549 příspěvků
8. 11. 2017   #9
-
0
-

#6 Ovrscout
Jedenapulruční? O tom jsem ani neslyšel, ale dvouruční ano.

#7 peter
Prej zkus myslet databázově a programově a napíšeš čistě teoretickej text a tom, jak teoreticky provázat celý tělo na ruzný kombinace, ano některé kombinace (štít + štít dokonce už reálně můžu použít, když někdo bude chtít)  ano počítám do budoucna i s váhou itemu, brnění apod (equipload), jinak až tak do detailu, že někdo bude utočit na ruku, nohu, krk apod ... Ne říkal jsem oživím a procvičím C# nedělám žádnou AAA propracovanou gamesu. Čistě základní systém RPGher.

Jinak co si myslíš, že u postavy je ten čtvereček? Ano Layer! Celý systém Layerů je strom (nebo to snad z tý ukázky kodu není poznat, že tam mám strom?) Tzv postava se rozděluje na Hlava, Krk, Hrud, Nohy, Ruce. Ruce mají další části a tak dále... Takže vlastně jsi tu napsal to co je úplně jasný. Jenom ses trošku rozvášnil a předvedl svojí vizi, což ti neberu za zlé, ale do puntíku fakt nehodlám ani jít. Zkušenosti si beru z her co jsem hrál, takže si myslím, že stačí to jen realizovat.

#8 MilanL
Polymorfismus už praktikuju... Jelikož tam v hlavním Layers vracím object (protože části mají jinou class). Ty itemy co nemají další podmnožiny jsou typu ItemLayer (item rozšířen o možnosti layeru/equipu...) a ruce jsou typu HandsLayer. Tzv s polymorfismem pracuju o uroven výš (na Playeru), kde mám vlastně metody Equip/Unequip/Use apod..

Player má v sobě Layers kde defakto mámrozložený typy layeru viz kod, kterým jsem vyřešil práci s layery...

Právě to co řikáš jsme řešil hned jako první věc pole, alenarazil jsme u rukou s tím, že to nešlo do dalších levelů (Hands.Left -> Hands.Left.Ring) ... Já věděl dopředu jak to udělat (teoreticky), ale kodově jsem s tím měl problém, protože práce s tou kolekcí byla otřesná. Nemohl jsem lehce přistupovat k danému itemu a bylo to dost krkolomný. Takhle už od začátku vím, že mám na layeru zbran a potřebuju jí snížit durabilitu ... jednoduše zavolám ((HandsLayer)layers[LayerID])[HandsID][HandID] a hned mám přímo k tomu objektu přístup. Šlo by to k tomu přistupovat i z batohu (jelikož třeba sekera je obsažena v batohu se statusem equipped) ale to bych musel rpojet celej batoh zjistit IDLayerů a podle nich najít tu sekeru a tam jí to snížit... Což dobře je oboje, ale přijde mi víc logicky, že přistoupím přímo k layeru a tam budu obsluhovat objekt, než abych ho obsluhoval z batohu (když je nasazen) ... Ze začátku jsem měl namysli právě to, že se mi to z batohu bude mazat (to by pak nebyla jiná možnost než k tomu tak přistupovat)

Nahlásit jako SPAM
IP: 193.138.154.–
peter
~ Anonymní uživatel
4016 příspěvků
9. 11. 2017   #10
-
0
-

1.5 rucni je zbran, ktera se da drzet jednou nebo dvema rukami. Pro kazdy pripad ma jine dmg. Dmg je obvykle i pri drzeni dvema mensi nez u masivni obourucni. Pri drzeni jednou dmg take neni tak dobre jako u specializovane pro jednu ruku. Vyhoda ale je, ze se da pouzivat tak i tak.

Nahlásit jako SPAM
IP: 2001:718:2601:258:a1a7:84...–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 56 hostů

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý