Hranie Rusta za 24 hodín: skúsenosť s osobným rozvojom

Hranie Rusta za 24 hodín: skúsenosť s osobným rozvojom

V tomto článku budem hovoriť o mojej osobnej skúsenosti s vývojom malej hry v Ruste. Vytvorenie pracovnej verzie trvalo približne 24 hodín (väčšinou som pracoval po večeroch alebo cez víkendy). Hra nie je ani zďaleka dokončená, ale myslím si, že zážitok bude obohacujúci. Podelím sa o to, čo som sa naučil, a o niektoré postrehy, ktoré som urobil pri budovaní hry od začiatku.

Skillbox odporúča: Dvojročný praktický kurz "Som PRO web developer".

Pripomíname vám: pre všetkých čitateľov „Habr“ - zľava 10 000 rubľov pri registrácii do akéhokoľvek kurzu Skillbox pomocou propagačného kódu „Habr“.

Prečo práve Rust?

Vybral som si tento jazyk, pretože som o ňom počul veľa dobrých vecí a vidím, že sa pri vývoji hier stáva čoraz populárnejším. Pred napísaním hry som mal málo skúseností s vývojom jednoduchých aplikácií v Ruste. To stačilo na to, aby som mal pri písaní hry pocit slobody.

Prečo hra a aký druh hry?

Vytváranie hier je zábava! Prial by som si, aby bolo viac dôvodov, ale pre „domáce“ projekty si vyberám témy, ktoré s mojou bežnou prácou príliš nesúvisia. Čo je to za hru? Chcel som urobiť niečo ako tenisový simulátor, ktorý kombinuje Cities Skylines, Zoo Tycoon, Prison Architect a samotný tenis. Vo všeobecnosti sa ukázalo, že ide o hru o tenisovej akadémii, kam ľudia chodia hrať.

Technický tréning

Chcel som použiť Rust, ale nevedel som presne, koľko základov by to vyžadovalo začať. Nechcel som písať pixel shadery a používať drag-n-drop, tak som hľadal čo najflexibilnejšie riešenia.

Našiel som užitočné zdroje, o ktoré sa s vami podelím:

Preskúmal som niekoľko herných motorov Rust, nakoniec som si vybral Piston a ggez. Narazil som na ne pri práci na predchádzajúcom projekte. Nakoniec som si vybral ggez, pretože sa mi zdal vhodnejší na implementáciu malej 2D hry. Modulárna štruktúra piestu je príliš zložitá pre začínajúceho vývojára (alebo niekoho, kto pracuje s Rustom po prvýkrát).

Štruktúra hry

Strávil som nejaký čas premýšľaním o architektúre projektu. Prvým krokom je urobiť „pozemok“, ľudí a tenisové kurty. Ľudia sa musia pohybovať po kurtoch a čakať. Hráči musia mať zručnosti, ktoré sa časom zlepšujú. Navyše by mal existovať editor, ktorý vám umožní pridávať nových ľudí a súdy, ale to už nie je zadarmo.

Keď som si všetko dobre premyslel, pustil som sa do práce.

Tvorba hry

Začiatok: Kruhy a abstrakcie

Vzal som si príklad z ggez a dostal som na obrazovku kruh. Podivuhodný! Teraz niekoľko abstrakcií. Myslel som, že by bolo pekné abstrahovať od myšlienky herného objektu. Každý objekt musí byť vykreslený a aktualizovaný, ako je uvedené tu:

// the game object trait
trait GameObject {
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()>;
    fn draw(&mut self, ctx: &mut Context) -> GameResult<()>;
}
 
// a specific game object - Circle
struct Circle {
    position: Point2,
}
 
 impl Circle {
    fn new(position: Point2) -> Circle {
        Circle { position }
    }
}
impl GameObject for Circle {
    fn update(&mut self, _ctx: &mut Context) -> GameResult<()> {
        Ok(())
    }
    fn draw(&mut self, ctx: &mut Context) -> GameResult<()> {
        let circle =
            graphics::Mesh::new_circle(ctx, graphics::DrawMode::Fill, self.position, 100.0, 2.0)?;
 
         graphics::draw(ctx, &circle, na::Point2::new(0.0, 0.0), 0.0)?;
        Ok(())
    }
}

Tento kúsok kódu mi dal pekný zoznam objektov, ktoré som mohol aktualizovať a vykresliť v rovnako peknej slučke.

mpl event::EventHandler for MainState {
    fn update(&mut self, context: &mut Context) -> GameResult<()> {
        // Update all objects
        for object in self.objects.iter_mut() {
            object.update(context)?;
        }
 
        Ok(())
    }
 
    fn draw(&mut self, context: &mut Context) -> GameResult<()> {
        graphics::clear(context);
 
        // Draw all objects
        for object in self.objects.iter_mut() {
            object.draw(context)?;
        }
 
        graphics::present(context);
 
        Ok(())
    }
}

main.rs je potrebný, pretože obsahuje všetky riadky kódu. Strávil som trochu času oddelením súborov a optimalizáciou adresárovej štruktúry. Takto to potom vyzeralo:
zdroje -> tu sú všetky aktíva (obrázky)
src
- entity
— game_object.rs
— kruh.rs
— main.rs -> hlavná slučka

Ľudia, podlahy a obrazy

Ďalším krokom je vytvorenie herného objektu Person a načítanie obrázkov. Všetko by malo byť postavené na základe 32*32 dlaždíc.

Hranie Rusta za 24 hodín: skúsenosť s osobným rozvojom

Tenisové kurty

Po naštudovaní ako vyzerajú tenisové kurty som sa rozhodol vyrobiť ich z dlaždíc 4*2. Spočiatku bolo možné vyrobiť obraz tejto veľkosti, alebo poskladať 8 samostatných dlaždíc. Ale potom som si uvedomil, že sú potrebné iba dve jedinečné dlaždice a tu je dôvod.

Celkovo máme dve takéto dlaždice: 1 a 2.

Každá časť ihriska pozostáva z dlaždice 1 alebo dlaždice 2. Môžu byť usporiadané ako normálne alebo otočené o 180 stupňov.

Hranie Rusta za 24 hodín: skúsenosť s osobným rozvojom

Základný konštrukčný (montážny) režim

Potom, čo sa mi podarilo dosiahnuť vykreslenie stránok, ľudí a máp, som si uvedomil, že je potrebný aj základný režim zostavy. Implementoval som to takto: po stlačení tlačidla sa objekt vyberie a kliknutím ho umiestnite na požadované miesto. Takže tlačidlo 1 vám umožňuje vybrať ihrisko a tlačidlo 2 vám umožní vybrať hráča.

Stále si však musíme pamätať, čo znamenajú 1 a 2, preto som pridal drôtený model, aby bolo jasné, ktorý objekt bol vybraný. Takto to vyzerá.

Hranie Rusta za 24 hodín: skúsenosť s osobným rozvojom

Otázky architektúry a refaktoringu

Teraz mám niekoľko herných objektov: ľudí, kurty a podlahy. Aby však drôtové modely fungovali, každej objektovej entite je potrebné povedať, či sú samotné objekty v demonštračnom režime, alebo či je rám jednoducho nakreslený. To nie je veľmi pohodlné.

Zdalo sa mi, že architektúru je potrebné prehodnotiť spôsobom, ktorý odhalí určité obmedzenia:

  • Mať entitu, ktorá sa vykresľuje a aktualizuje, je problém, pretože táto entita nebude schopná „vedieť“, čo má vykresľovať – obrázok a drôtový model;
  • chýbajúci nástroj na výmenu vlastností a správania medzi jednotlivými entitami (napríklad vlastnosť is_build_mode alebo vykresľovanie správania). Bolo by možné použiť dedičnosť, hoci v Ruste neexistuje správny spôsob, ako ju implementovať. Čo som skutočne potreboval, bolo rozloženie;
  • bol potrebný nástroj na interakciu medzi subjektmi na prideľovanie osôb na súdy;
  • samotné entity boli zmesou dát a logiky, ktorá sa rýchlo vymkla spod kontroly.

Urobil som ďalší prieskum a objavil som architektúru ECS - Entity Component System, ktorý sa bežne používa v hrách. Tu sú výhody ECS:

  • údaje sú oddelené od logiky;
  • zloženie namiesto dedičstva;
  • dátovo-centrická architektúra.

ECS sa vyznačuje tromi základnými konceptmi:

  • entity - typ objektu, na ktorý sa identifikátor vzťahuje (môže to byť hráč, lopta alebo niečo iné);
  • zložky - entity sú z nich tvorené. Príklad - komponent vykresľovania, miesta a iné. Ide o dátové sklady;
  • systémy – používajú objekty aj komponenty, navyše obsahujú správanie a logiku, ktoré sú založené na týchto údajoch. Príkladom je vykresľovací systém, ktorý iteruje cez všetky entity s vykresľovacími komponentmi a vykoná vykreslenie.

Po preštudovaní sa ukázalo, že ECS rieši nasledujúce problémy:

  • používanie rozloženia namiesto dedenia na systematické organizovanie entít;
  • zbaviť sa spleti kódu prostredníctvom riadiacich systémov;
  • pomocou metód ako is_build_mode, aby logika drôtového modelu zostala na rovnakom mieste – v systéme vykresľovania.

Stalo sa tak po implementácii ECS.

zdroje -> tu sú všetky aktíva (obrázky)
src
- komponenty
—pozícia.rs
— osoba.rs
— tennis_court.rs
— podlaha.rs
- wireframe.rs
— mouse_tracked.rs
- zdroje
—myš.rs
- systémy
— vykresľovanie.rs
— konštanty.rs
— utils.rs
— world_factory.rs -> funkcie svetovej továrne
— main.rs -> hlavná slučka

Prideľujeme ľudí na súdy

ECS uľahčil život. Teraz som mal systematický spôsob, ako pridať údaje k entitám a pridať logiku založenú na týchto údajoch. A to zase umožnilo organizovať rozdeľovanie ľudí medzi súdy.

Čo som urobil:

  • doplnené údaje o pridelených súdoch k osobe;
  • pridané údaje o distribuovaných ľuďoch do TennisCourtu;
  • pridaný CourtChoosingSystem, ktorý vám umožňuje analyzovať ľudí a súdy, zisťovať dostupné kurty a distribuovať k nim hráčov;
  • pridal PersonMovementSystem, ktorý hľadá ľudí pridelených na súdy, a ak tam nie sú, tak posiela ľudí tam, kde majú byť.

Hranie Rusta za 24 hodín: skúsenosť s osobným rozvojom

Sčítanie

Práca na tejto jednoduchej hre sa mi veľmi páčila. Navyše som rád, že som na jeho napísanie použil Rust, pretože:

  • Hrdza vám dáva to, čo potrebujete;
  • má výbornú dokumentáciu, Rust je celkom elegantný;
  • konzistencia je v pohode;
  • nemusíte sa uchyľovať ku klonovaniu, kopírovaniu alebo iným podobným akciám, ktoré som často robil v C++;
  • Možnosti sa veľmi ľahko používajú a veľmi dobre zvládajú chyby;
  • ak sa projekt podarilo zostaviť, tak na 99% funguje a presne tak, ako má. Myslím, že chybové hlásenia kompilátora sú najlepšie, aké som kedy videl.

Vývoj hry v Ruste je len na začiatku. Ale už existuje stabilná a pomerne veľká komunita, ktorá pracuje na otvorení Rustu pre každého. Preto sa na budúcnosť jazyka pozerám s optimizmom, teším sa na výsledky našej spoločnej práce.

Skillbox odporúča:

Zdroj: hab.com

Pridať komentár