Igranje Rusta za 24 sata: iskustvo ličnog razvoja

Igranje Rusta za 24 sata: iskustvo ličnog razvoja

U ovom članku ću govoriti o svom ličnom iskustvu razvoja male igre u Rustu. Za izradu radne verzije trebalo je oko 24 sata (uglavnom sam radio uveče ili vikendom). Igra je daleko od završene, ali mislim da će iskustvo biti isplativo. Podijelit ću ono što sam naučio i neka zapažanja koja sam napravio dok sam pravio igru ​​od nule.

Skillbox preporučuje: Dvogodišnji praktični kurs "Ja sam PRO web developer".

Podsećamo: za sve čitaoce "Habra" - popust od 10 rubalja pri upisu na bilo koji Skillbox kurs koristeći "Habr" promotivni kod.

Zašto Rust?

Odabrao sam ovaj jezik jer sam čuo puno dobrih stvari o njemu i vidim da postaje sve popularniji u razvoju igara. Prije pisanja igre, imao sam malo iskustva u razvoju jednostavnih aplikacija u Rustu. Ovo je bilo dovoljno da mi pruži osjećaj slobode dok pišem igru.

Zašto igra i kakva igra?

Pravljenje igrica je zabavno! Volio bih da ima više razloga, ali za “kućne” projekte biram teme koje nisu previše usko vezane za moj redovni posao. Koja je ovo igra? Želeo sam da napravim nešto poput teniskog simulatora koji kombinuje Cities Skylines, Zoo Tycoon, Prison Architect i sam tenis. Generalno, ispalo je da je to igra o teniskoj akademiji u koju ljudi dolaze da igraju.

Tehnička obuka

Hteo sam da koristim Rust, ali nisam tačno znao koliko će temelja biti potrebno za početak. Nisam želio pisati pikselne shadere i koristiti drag-n-drop, pa sam tražio najfleksibilnija rješenja.

Našao sam korisne resurse koje dijelim s vama:

Istražio sam nekoliko Rust igrica, na kraju sam izabrao Piston i ggez. Naišao sam na njih dok sam radio na prethodnom projektu. Na kraju sam izabrao ggez jer mi se činio prikladnijim za implementaciju male 2D igre. Piston-ova modularna struktura je previše složena za početnika (ili nekoga ko prvi put radi sa Rustom).

Struktura igre

Proveo sam neko vrijeme razmišljajući o arhitekturi projekta. Prvi korak je da se napravi "zemlja", ljudi i teniski tereni. Ljudi se moraju kretati po sudovima i čekati. Igrači moraju imati vještine koje se vremenom poboljšavaju. Osim toga, trebao bi postojati uređivač koji vam omogućava da dodajete nove ljude i sudove, ali to više nije besplatno.

Pošto sam sve dobro razmislio, krenuo sam na posao.

Kreiranje igre

Početak: Krugovi i apstrakcije

Uzeo sam primjer iz ggez-a i dobio sam krug na ekranu. Divno! Sada neke apstrakcije. Mislio sam da bi bilo lijepo apstrahirati se od ideje o objektu igre. Svaki objekat mora biti prikazan i ažuriran kako je ovdje navedeno:

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

Ovaj dio koda mi je dao lijepu listu objekata koje sam mogao ažurirati i prikazati u jednako lijepoj petlji.

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 neophodan jer sadrži sve linije koda. Proveo sam malo vremena razdvajajući datoteke i optimizirajući strukturu direktorija. Ovako je to izgledalo nakon toga:
resursi -> ovdje su sva sredstva (slike)
src
- entiteti
— game_object.rs
— krug.rs
— main.rs -> glavna petlja

Ljudi, podovi i slike

Sljedeći korak je kreiranje objekta igre Person i učitavanje slika. Sve bi trebalo graditi na bazi pločica 32*32.

Igranje Rusta za 24 sata: iskustvo ličnog razvoja

Teniski tereni

Nakon što sam proučio kako izgledaju teniski tereni, odlučio sam da ih napravim od 4*2 pločica. U početku je bilo moguće napraviti sliku ove veličine ili sastaviti 8 zasebnih pločica. Ali onda sam shvatio da su potrebne samo dvije jedinstvene pločice, a evo i zašto.

Ukupno imamo dvije takve pločice: 1 i 2.

Svaki dio terena se sastoji od pločice 1 ili pločice 2. Mogu se postaviti kao normalno ili okrenuti za 180 stepeni.

Igranje Rusta za 24 sata: iskustvo ličnog razvoja

Osnovni način izgradnje (montaže).

Nakon što sam uspio postići renderiranje lokacija, ljudi i mapa, shvatio sam da je potreban i osnovni način sastavljanja. Ja sam to implementirao ovako: kada se pritisne dugme, objekat se selektuje, a klik ga postavlja na željeno mesto. Dakle, dugme 1 vam omogućava da izaberete teren, a dugme 2 vam omogućava da izaberete igrača.

Ali još uvijek moramo zapamtiti šta znače 1 i 2, pa sam dodao žičani okvir da bude jasno koji je objekt odabran. Ovako to izgleda.

Igranje Rusta za 24 sata: iskustvo ličnog razvoja

Pitanja o arhitekturi i refaktoriranju

Sada imam nekoliko objekata za igru: ljude, terene i podove. Ali da bi žičani okviri funkcionirali, svakom objektnom entitetu treba biti rečeno da li su sami objekti u demonstracijskom modu ili je okvir jednostavno nacrtan. Ovo nije baš zgodno.

Činilo mi se da arhitekturu treba preispitati na način koji otkriva neka ograničenja:

  • Imati entitet koji sam sebe renderuje i ažurira je problem jer taj entitet neće moći da „zna” šta bi trebalo da renderuje – sliku i žičani okvir;
  • nedostatak alata za razmjenu svojstava i ponašanja između pojedinačnih entiteta (na primjer, svojstvo is_build_mode ili renderiranje ponašanja). Bilo bi moguće koristiti nasljeđivanje, iako ne postoji odgovarajući način da se to implementira u Rustu. Ono što mi je zaista trebalo je izgled;
  • alat za interakciju između entiteta bio je potreban za raspoređivanje ljudi u sudove;
  • sami entiteti su bili mješavina podataka i logike koja je brzo izmakla kontroli.

Još sam istraživao i otkrio arhitekturu ECS - Sistem komponenti entiteta, koji se obično koristi u igricama. Evo prednosti ECS-a:

  • podaci su odvojeni od logike;
  • sastav umjesto nasljeđivanja;
  • data-centric arhitektura.

ECS karakteriziraju tri osnovna koncepta:

  • entiteti - tip objekta na koji se identifikator odnosi (može biti igrač, lopta ili nešto drugo);
  • komponente - od njih se sastoje entiteti. Primjer - komponenta renderiranja, lokacija i ostalo. To su skladišta podataka;
  • sistemi - koriste i objekte i komponente, plus sadrže ponašanje i logiku koji su zasnovani na ovim podacima. Primjer je sistem za renderiranje koji se ponavlja kroz sve entitete sa komponentama za renderiranje i vrši renderiranje.

Nakon proučavanja, postalo je jasno da ECS rješava sljedeće probleme:

  • korištenje rasporeda umjesto nasljeđivanja za sistemsko organizovanje entiteta;
  • otklanjanje zbrke koda kroz kontrolne sisteme;
  • koristeći metode kao što je is_build_mode kako bi se logika žičanog okvira zadržala na istom mjestu - u sistemu renderiranja.

To se dogodilo nakon implementacije ECS-a.

resursi -> ovdje su sva sredstva (slike)
src
- komponente
—position.rs
— person.rs
— tennis_court.rs
— floor.rs
- wireframe.rs
— mouse_tracked.rs
- resursi
—mouse.rs
- sistemi
— rendering.rs
— konstante.rs
— utils.rs
— world_factory.rs -> world factory funkcije
— main.rs -> glavna petlja

Mi raspoređujemo ljude u sudove

ECS je olakšao život. Sada sam imao sistematski način dodavanja podataka entitetima i dodavanja logike na osnovu tih podataka. A to je zauzvrat omogućilo organiziranje raspodjele ljudi po sudovima.

sta sam uradio:

  • dodani podaci o dodijeljenim sudovima osobi;
  • dodao podatke o raspoređenim ljudima u TennisCourt;
  • dodat je CourtChoosingSystem, koji vam omogućava da analizirate ljude i terene, otkrijete dostupne terene i distribuirate igrače na njih;
  • dodao je PersonMovementSystem, koji traži ljude dodijeljene sudovima, a ako nisu tamo, šalje ljude tamo gdje trebaju biti.

Igranje Rusta za 24 sata: iskustvo ličnog razvoja

Sumiranje

Zaista sam uživao radeći na ovoj jednostavnoj igrici. Štaviše, drago mi je da sam koristio Rust da to napišem, jer:

  • Rust vam daje ono što vam treba;
  • ima odličnu dokumentaciju, Rust je prilično elegantan;
  • konzistencija je hladna;
  • ne morate pribjeći kloniranju, kopiranju ili drugim sličnim radnjama, što sam često radio u C++;
  • Opcije su vrlo jednostavne za korištenje i vrlo dobro obrađuju greške;
  • ako je projekat bio u mogućnosti da se kompajlira, onda 99% vremena radi, i tačno kako treba. Mislim da su poruke o grešci kompajlera najbolje što sam vidio.

Razvoj igara u Rustu tek počinje. Ali već postoji stabilna i prilično velika zajednica koja radi na otvaranju Rusta za sve. Stoga na budućnost jezika gledam s optimizmom, radujući se rezultatima našeg zajedničkog rada.

Skillbox preporučuje:

izvor: www.habr.com

Dodajte komentar