Rusti mängimine 24 tunniga: isikliku arengu kogemus

Rusti mängimine 24 tunniga: isikliku arengu kogemus

Selles artiklis räägin oma isiklikust kogemusest väikese mängu arendamisel Rustis. Tööversiooni loomiseks kulus umbes 24 tundi (töötasin enamasti õhtuti või nädalavahetustel). Mäng pole veel kaugeltki lõppenud, kuid arvan, et kogemus on rahuldust pakkuv. Jagan õpitut ja mõningaid tähelepanekuid, mida tegin mängu nullist ülesehitamisel.

Skillbox soovitab: Kaheaastane praktiline kursus "Ma olen PRO veebiarendaja".

Tuletame meelde: kõigile "Habr" lugejatele - allahindlus 10 000 rubla, kui registreerute mis tahes Skillboxi kursusele, kasutades sooduskoodi "Habr".

Miks Rust?

Valisin selle keele, kuna olen selle kohta palju head kuulnud ja näen, et see muutub mänguarenduses aina populaarsemaks. Enne mängu kirjutamist oli mul vähe kogemusi Rustis lihtsate rakenduste arendamisel. Sellest piisas, et anda mulle mängu kirjutamise ajal vabadustunne.

Miks mäng ja millist mängu?

Mängude tegemine on lõbus! Soovin, et põhjuseid oleks rohkem, aga “koduprojektide” jaoks valin teemad, mis pole minu tavatööga liiga tihedalt seotud. Mis mäng see on? Tahtsin teha midagi tennise simulaatori sarnast, mis ühendaks Cities Skylinesi, Zoo Tycooni, Prison Architecti ja tennise enda. Üldiselt kujunes see mänguks tenniseakadeemiast, kuhu tullakse mängima.

Tehniline koolitus

Tahtsin kasutada Rustit, kuid ma ei teadnud täpselt, kui palju eeltööd selle käivitamine nõuab. Ma ei tahtnud kirjutada pikslivarjureid ja kasutada drag-n-drop-i, seega otsisin kõige paindlikumaid lahendusi.

Leidsin kasulikke ressursse, mida teiega jagan:

Uurisin mitmeid Rusti mängumootoreid, valides lõpuks Pistoni ja Ggezi. Sattusin nendega kokku eelmise projekti kallal töötades. Lõpuks valisin ggezi, sest see tundus sobivam väikese 2D mängu realiseerimiseks. Kolvi moodulstruktuur on liiga keeruline algajale arendajale (või inimesele, kes töötab Rustiga esimest korda).

Mängu struktuur

Mõtisklesin mõnda aega projekti arhitektuuri üle. Esimene samm on teha "maa", inimesed ja tenniseväljakud. Inimesed peavad kohtutes ringi liikuma ja ootama. Mängijatel peavad olema oskused, mis aja jooksul paranevad. Lisaks peaks olema redaktor, mis võimaldab teil lisada uusi inimesi ja kohtuid, kuid see pole enam tasuta.

Olles kõik läbi mõelnud, asusin tööle.

Mängu loomine

Algus: ringid ja abstraktsioonid

Võtsin näite ggezist ja sain ekraanile ringi. Imeline! Nüüd mõned abstraktsioonid. Arvasin, et oleks tore mänguobjekti ideest eemalduda. Iga objekt tuleb renderdada ja värskendada, nagu siin on kirjeldatud:

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

See kooditükk andis mulle kena loendi objektidest, mida saaksin värskendada ja sama kena tsüklina renderdada.

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 on vajalik, kuna see sisaldab kõiki koodiridu. Kulutasin veidi aega failide eraldamisele ja kataloogistruktuuri optimeerimisele. Pärast seda nägi see välja selline:
ressursid -> siin on kõik varad (pildid)
src
- üksused
- game_object.rs
— ring.rs
— main.rs -> põhisilmus

Inimesed, põrandad ja pildid

Järgmise sammuna tuleb luua Person mänguobjekt ja laadida pilte. Kõik tuleks ehitada 32*32 plaatide baasil.

Rusti mängimine 24 tunniga: isikliku arengu kogemus

Tenniseväljakud

Olles uurinud, millised tenniseväljakud välja näevad, otsustasin teha need 4*2 plaatidest. Esialgu oli võimalik teha sellises mõõdus pilt ehk siis kokku panna 8 eraldi plaati. Kuid siis sain aru, et vaja on ainult kahte ainulaadset plaati ja siin on põhjus.

Kokku on meil kaks sellist plaati: 1 ja 2.

Iga väljaku sektsioon koosneb plaadist 1 või plaadist 2. Neid saab paigutada tavapäraselt või pöörata 180 kraadi.

Rusti mängimine 24 tunniga: isikliku arengu kogemus

Ehitamise (montaaži) põhirežiim

Pärast seda, kui mul õnnestus saavutada saitide, inimeste ja kaartide renderdamine, mõistsin, et vaja on ka elementaarset montaažirežiimi. Tegin selle nii: nupule vajutades valitakse objekt välja ja klõps asetab selle soovitud kohta. Niisiis, nupp 1 võimaldab valida väljaku ja nupp 2 võimaldab valida mängija.

Kuid me peame siiski meeles pidama, mida 1 ja 2 tähendavad, seega lisasin traatraami, et oleks selge, milline objekt on valitud. See näeb välja selline.

Rusti mängimine 24 tunniga: isikliku arengu kogemus

Arhitektuuri ja ümberkujundamise küsimused

Nüüd on mul mitu mänguobjekti: inimesed, väljakud ja põrandad. Kuid selleks, et traatraamid töötaksid, tuleb igale objektiolemile öelda, kas objektid ise on demonstratsioonirežiimis või on raam lihtsalt joonistatud. See pole eriti mugav.

Mulle tundus, et arhitektuur tuleb ümber mõelda viisil, mis paljastas mõned piirangud:

  • Ennast renderdava ja värskendava olemi omamine on probleem, sest see olem ei saa "tea", mida ta peaks renderdama – pilti ja traatraami;
  • tööriista puudumine omaduste ja käitumise vahetamiseks üksikute üksuste vahel (näiteks atribuut is_build_mode või käitumise renderdamine). Pärimist oleks võimalik kasutada, kuigi Rustis seda õiget juurutada pole. Mida ma tõesti vajasin, oli paigutus;
  • inimeste kohtusse määramiseks oli vaja üksuste vahelise suhtluse vahendit;
  • olemid ise olid segu andmetest ja loogikast, mis väljusid kiiresti kontrolli alt.

Uurisin veel veidi ja avastasin arhitektuuri ECS – olemikomponentide süsteem, mida tavaliselt mängudes kasutatakse. Siin on ECS-i eelised:

  • andmed on loogikast eraldatud;
  • kompositsioon pärimise asemel;
  • andmekeskne arhitektuur.

ECS-i iseloomustavad kolm põhikontseptsiooni:

  • olemid – objekti tüüp, millele identifikaator viitab (see võib olla mängija, pall või midagi muud);
  • komponendid – olemid koosnevad neist. Näide - renderduskomponent, asukohad ja muud. Need on andmelaod;
  • süsteemid – need kasutavad nii objekte kui komponente ning sisaldavad nendel andmetel põhinevat käitumist ja loogikat. Näiteks on renderdussüsteem, mis itereerib läbi kõik renderduskomponentidega olemid ja teeb renderduse.

Pärast selle uurimist sai selgeks, et ECS lahendab järgmised probleemid:

  • olemite süsteemseks korraldamiseks pärandi asemel paigutuse kasutamine;
  • koodipuntrast vabanemine juhtimissüsteemide kaudu;
  • kasutades selliseid meetodeid nagu is_build_mode, et hoida traatraami loogikat samas kohas – renderdussüsteemis.

See juhtus pärast ECS-i rakendamist.

ressursid -> siin on kõik varad (pildid)
src
- komponendid
—positsioon.rs
— isik.rs
- tennis_court.rs
— korrus.rs
- wireframe.rs
- mouse_tracked.rs
- ressursid
-hiir.rs
- süsteemid
— renderdamine.rs
— konstandid.rs
— utils.rs
— world_factory.rs -> maailma tehase funktsioonid
— main.rs -> põhisilmus

Me määrame inimesed kohtusse

ECS on elu lihtsamaks teinud. Nüüd oli mul süstemaatiline viis üksustele andmete lisamiseks ja nende andmete põhjal loogika lisamiseks. Ja see omakorda võimaldas korraldada inimeste jaotust kohtute vahel.

Mida ma olen teinud:

  • lisanud Isikule andmed määratud kohtute kohta;
  • lisas TennisCourtile andmed hajutatud inimeste kohta;
  • lisatud CourtChoosingSystem, mis võimaldab analüüsida inimesi ja väljakuid, tuvastada saadaolevaid väljakuid ja jagada neile mängijaid;
  • lisas PersonMovementSystem, mis otsib kohtusse määratud inimesi ja kui neid seal pole, siis saadab inimesed sinna, kus nad olema peavad.

Rusti mängimine 24 tunniga: isikliku arengu kogemus

Kokkuvõtteks

Mulle väga meeldis selle lihtsa mängu kallal töötada. Lisaks on mul hea meel, et kasutasin selle kirjutamiseks Rustit, sest:

  • Rooste annab teile selle, mida vajate;
  • sellel on suurepärane dokumentatsioon, Rust on üsna elegantne;
  • konsistents on lahe;
  • te ei pea kasutama kloonimist, kopeerimist ega muid sarnaseid toiminguid, mida ma C++-s sageli tegin;
  • Valikud on väga lihtsalt kasutatavad ja vead väga hästi toime;
  • Kui projekt suudeti koostada, siis 99% ajast see toimib ja täpselt nii nagu peab. Arvan, et kompilaatori veateated on parimad, mida ma näinud olen.

Mänguarendus Rustis alles algab. Kuid juba töötab stabiilne ja üsna suur kogukond, et avada Rust kõigile. Seetõttu vaatan keele tulevikku optimistlikult, oodates meie ühise töö tulemusi.

Skillbox soovitab:

Allikas: www.habr.com

Lisa kommentaar