Lojë në Rust brenda 24 orëve: përvoja ime personale e zhvillimit

Lojë në Rust brenda 24 orëve: përvoja ime personale e zhvillimit

Në këtë artikull, do të flas për përvojën time personale në zhvillimin e një loje të vogël me Rust. Ndërsa krijova versionin funksional, më mori rreth 24 orë (kryesisht punova në mbrëmje ose gjatë fundjavës). Loja është ende larg përfundimit, por mendoj se përvoja do të jetë e dobishme. Do të tregoj se çfarë kam mësuar dhe disa vëzhgime të bëra gjatë ndërtimit të lojës nga zero.

Skillbox rekomandon: Kurs praktik dyvjeçar Unë jam zhvillues web PRO.

KujtojmĂ«: pĂ«r tĂ« gjithĂ« lexuesit e "Habra" — zbritje prej 10,000 rublej pĂ«r regjistrimin nĂ« çdo kurs Skillbox me kodin promocional "Habr".

Pse Rust?

Zgjodha këtë gjuhë sepse kam dëgjuar shumë të mira për të dhe shoh se po bëhet gjithnjë e më popullore në fushën e zhvillimit të lojërave. Para se të shkruaja lojën, kisha një përvojë të vogël në zhvillimin e aplikacioneve të thjeshta me Rust. Kjo ishte pikërisht e mjaftueshme për të ndjerë një liri të caktuar gjatë shkruarjes së lojës.

Pse loja dhe çfarë loje?

Krijimi i lojĂ«rave Ă«shtĂ« argĂ«tues! Do doja tĂ« kishte mĂ« shumĂ« arsye, por pĂ«r projektet «shtĂ«piake», zgjedh tema qĂ« nuk janĂ« shumĂ« tĂ« lidhura me punĂ«n time tĂ« zakonshme. ÇfarĂ« loje? DĂ«shiroja tĂ« bĂ«ja diçka si njĂ« simulues tenisi, ku kombinohen Cities Skylines, Zoo Tycoon, Prison Architect dhe vetĂ« tenisi. NĂ« pĂ«rgjithĂ«si, ndihesha se kisha krijuar njĂ« lojĂ« pĂ«r njĂ« akademi tenisi, ku njerĂ«zit vijnĂ« pĂ«r tĂ« luajtur.

Përgatitja teknike

Dëshiroja të përdor Rust, por nuk e dija saktësisht se sa «nga zero» do të duhej të filloja punën. Nuk doja të shkruaja shader pikselësh dhe të përdorja drag-and-drop, prandaj kërkoja zgjidhje sa më fleksibile.

Gjeta disa burime të dobishme që po i ndaj me ju:

Studova disa motorë lojërash Rust, duke e zgjedhur përfundimisht Piston dhe ggez. I takova këto ndërsa punoja në projektin e mëparshëm. Në fund, zgjodha ggez, pasi më dukej më e përshtatshme për realizimin e një loje të vogël 2D. Strukturimi modular i Piston është shumë i komplikuar për një zhvillues fillestar (apo për dikë që punon për herë të parë me Rust).

Struktura e lojës

Kaluova pak kohĂ« duke menduar pĂ«r arkitekturĂ«n e projektit. Hapi i parĂ« — tĂ« krijoja «tokat», njerĂ«zit dhe kortet e tenisit. NjerĂ«zit duhet tĂ« lĂ«vizin nĂ«pĂ«r kurte dhe tĂ« presin. LojtarĂ«t duhet tĂ« kenĂ« aftĂ«si qĂ« pĂ«rmirĂ«sohen me kalimin e kohĂ«s. Gjithashtu, duhet tĂ« ketĂ« njĂ« redaktor qĂ« lejon shtimin e njerĂ«zve dhe korteve, por kjo tashmĂ« nuk Ă«shtĂ« falas.

Pasi mendova gjithçka, fillova punën.

Krijimi i një loje

Fillimi: rrethana dhe abstraksione

Mora njĂ« shembull nga ggez dhe arrita njĂ« rreth nĂ« ekran. Ma çudit! Tani disa abstraksione. MĂ« dukej e dobishme tĂ« shkĂ«putesha nga ideja e objektit tĂ« lojĂ«s. Çdo objekt duhet tĂ« jetĂ« i renderuar dhe i pĂ«rditĂ«suar, siç Ă«shtĂ« parashikuar kĂ«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(())
    }
}

Ky pjesë kodi më lejon të kem një listë të shkëlqyer objektesh, të cilat mund t'i përditësoj dhe t'i renderoj në një cikël po aq të shkëlqyer.

mpl event::EventHandler për MainState {
    fn update(&mut self, context: &mut Context) -> GameResult<()> {
        // Përditëso të gjitha objektet
        për objekt në self.objects.iter_mut() {
            objekt.update(context)?;
        }
 
        Ok(())
    }
 
    fn draw(&mut self, context: &mut Context) -> GameResult<()> {
        graphics::clear(context);
 
        // Vizato të gjitha objektet
        për objekt në self.objects.iter_mut() {
            objekt.draw(context)?;
        }
 
        graphics::present(context);
 
        Ok(())
    }
}

main.rs është e nevojshme sepse aty ndodhen të gjitha rreshtat e kodit. Kalova pak kohë për të ndarë skedarët dhe optimizuar strukturën e dosjeve. Kështu dukej pas kësaj:
resources -> këtu ndodhen të gjitha asetet (imazhet)
src
— entitetet
— game_object.rs
— circle.rs
— main.rs -> cikli kryesor

Njerëzit, katet dhe imazhet

Hapi tjetĂ«r — krijimi i objektit tĂ« lojĂ«s Person dhe ngarkimi i imazheve. TĂ« gjitha duhet tĂ« ndodhin nĂ« bazĂ« tĂ« pllakatave me madhĂ«si 32*32.

Lojë në Rust brenda 24 orëve: përvoja ime personale e zhvillimit

Kortet e tenisit

Duke studiuar se si duken kortet e tenisit, vendosa t'i bëj ato nga pllakat 4*2. Fillimisht, mund të bëja një imazh të tillë ose të përbëja bashkë 8 pllaka të veçanta. Por pastaj e kuptova se nevojiten vetëm dy pllakat unike, dhe ja pse.

Kemi dy pllaka të tilla: 1 dhe 2.

Çdo seksion i kortit pĂ«rbĂ«het nga pllaka 1 ose pllaka 2. Ato mund tĂ« vendosen si zakonisht ose tĂ« kthehen 180 gradĂ«.

Lojë në Rust brenda 24 orëve: përvoja ime personale e zhvillimit

Rejimi kryesor i ndërtimit (montimit)

Pasi arrita tĂ« realizoj renderimin e fushave, njerĂ«zve dhe hartave, kuptova se nevojitej gjithashtu njĂ« rejim bazĂ« ndĂ«rtimi. E realizova kĂ«shtu: kur shtypet butoni — objekti zgjidhet, dhe klikimi e vendos atĂ« nĂ« vendin e dĂ«shiruar. Pra, butoni 1 lejon tĂ« zgjidhet korti, ndĂ«rsa butoni 2 lejon tĂ« zgjidhet lojtari.

Por duhet ta mbajtur mend se çfarë përfaqësojnë 1 dhe 2, prandaj shtova një wireframe për të qartësuar se cili objekt është i zgjedhur. Kështu duket.

Lojë në Rust brenda 24 orëve: përvoja ime personale e zhvillimit

Pyetje mbi arkitekturën dhe rifaktorizimin

Tani kam kam kam kam kam. Por të punuaren e wireframes, çdo entitet objekti duhet të informohet nëse vetë objektet janë në modin për të treguar, apo vetëm është vizatuar një kornizë. Kjo nuk është shumë e përshtatshme.

Më duket se duhet të rishqyrtohet arkitektura në mënyrë që të evidentohen disa kufizime:

  • prania e njĂ« entiteti qĂ« tregon dhe pĂ«rditĂ«son veten — Ă«shtĂ« njĂ« problem, sepse ky entitet nuk do tĂ« jetĂ« nĂ« gjendje tĂ« "kuptojĂ«" se çfarĂ« duhet tĂ« renderizojĂ« — imazhin ose wireframe-in;
  • mungesa e njĂ« instrumenti pĂ«r ndarjen e pronave dhe sjelljes midis entiteteve tĂ« veçanta (shembuj — pronĂ«sia is_build_mode ose vizatimi i sjelljes). Do tĂ« ishte e mundur tĂ« pĂ«rdorej trashĂ«gimia, megjithĂ«se nĂ« Rust nuk ka njĂ« mĂ«nyrĂ« normale pĂ«r ta realizuar atĂ«. Ajo qĂ« mĂ« duhej vĂ«rtet — ishte kompozita;
  • njĂ« instrument pĂ«r ndĂ«rveprimin e entiteteve gjithashtu ishte i nevojshĂ«m, pĂ«r tĂ« caktuar njerĂ«zit nĂ« fusha;
  • vetĂ« entitetet pĂ«rbĂ«nin njĂ« pĂ«rzierje tĂ« tĂ« dhĂ«nave dhe logjikĂ«s, gjĂ« qĂ« shumĂ« shpejt dilte jashtĂ« kontrollit.

Kam bĂ«rĂ« njĂ« studim tĂ« mĂ«tejshĂ«m dhe kam zbuluar arkitekturĂ«n ECS — Sistemi i KomponentĂ«ve tĂ« Entiteteve, i cili zakonisht pĂ«rdoret nĂ« lojĂ«ra. Ja pĂ«rfitimet e ECS:

  • tĂ« dhĂ«nat ndahen nga logjika;
  • kompozita nĂ« vend tĂ« trashĂ«gimisĂ«;
  • arkitekturĂ« e fokusuar nĂ« tĂ« dhĂ«na.

Për ECS, karakterizohen tre koncepte bazë:

  • entitetet — njĂ« tip objekti, ndaj tĂ« cilit referohet njĂ« identifikues (kjo mund tĂ« jetĂ« njĂ« lojtar, njĂ« top ose diçka tjetĂ«r);
  • komponentĂ«t — nga tĂ« cilĂ«t pĂ«rbĂ«hen entitetet. Shembuj — komponenti i renderimit, pozita dhe tĂ« tjera. KĂ«to janĂ« depo tĂ« dhĂ«nash;
  • sistemet — ato pĂ«rdorin si objektet ashtu edhe komponentĂ«t, pĂ«rveçse pĂ«rmbajnĂ« sjellje dhe logjikĂ« qĂ« bazohen nĂ« kĂ«to tĂ« dhĂ«na. Shembull — sistemi i renderimit, i cili shqyrton tĂ« gjithĂ« entitetet me komponentĂ« pĂ«r renderim dhe merret me vizatimin.

Pas studimit doli se ECS zgjidh këto probleme:

  • aplikaimi i kompozitĂ«s nĂ« vend tĂ« trashĂ«gimisĂ« pĂ«r organizimin sistematik tĂ« entiteteve;
  • zhbĂ«rja e kaosit tĂ« kodit pĂ«rmes sistemeve tĂ« menaxhimit;
  • pĂ«rdorimi i metodave si is_build_mode pĂ«r tĂ« mbajtur logjikĂ«n e wireframe-it nĂ« tĂ« njĂ«jtin vend — nĂ« sistemin e renderimit.

Ja çfarë u arrit pas integrimit të ECS.

resources -> këtu ndodhen të gjitha asetet (imazhet)
src
— komponentĂ«
— position.rs
— person.rs
— tennis_court.rs
— floor.rs
— wireframe.rs
— mouse_tracked.rs
— burime
— mouse.rs
— sisteme
— rendering.rs
— constants.rs
— utils.rs
— world_factory.rs -> funksionet e fabrikĂ«s sĂ« botĂ«s
— main.rs -> cikli kryesor

Caktojmë njerëzit në fusha

ECS e bëri jetën më të lehtë. Tani kisha një rrugë sistematike për të shtuar të dhëna në entitete dhe për të shtuar logjikën e bazuar në këto të dhëna. Kjo, nga ana tjetër, lehtësoi shpërndarjen e njerëzve në fusha.

Ajo që bëra:

  • shtova tĂ« dhĂ«nat pĂ«r fusha tĂ« caktuara nĂ« Person;
  • shtova tĂ« dhĂ«na pĂ«r njerĂ«zit e shpĂ«rndarĂ« nĂ« TennisCourt;
  • shtova CourtChoosingSystem, e cila lejon analizimin e njerĂ«zve dhe fushave, identifikimin e fushave tĂ« disponueshme dhe shpĂ«rndarjen e lojtarĂ«ve atje;
  • shtova sistemin PersonMovementSystem, i cili kĂ«rkon njerĂ«zit e caktuar nĂ« fusha, dhe nĂ«se ata nuk janĂ« aty, i dĂ«rgon njerĂ«zit atje ku duhet.

Lojë në Rust brenda 24 orëve: përvoja ime personale e zhvillimit

Përmbledhje

Më pëlqeu shumë të punoj mbi këtë lojë të thjeshtë. Gjithashtu, jam e kënaqur që e shkrova atë në Rust, sepse:

  • Rust ju jep atĂ« qĂ« ju nevojitet;
  • ka dokumentacion tĂ« shkĂ«lqyer, Rust Ă«shtĂ« shumĂ« elegant;
  • qĂ«ndrueshmĂ«ria — Ă«shtĂ« e shkĂ«lqyer;
  • nuk Ă«shtĂ« e nevojshme tĂ« mbĂ«shtetesha nĂ« klonim, kopjim ose veprime tĂ« tjera tĂ« ngjashme, qĂ« unĂ« shpesh bĂ«ja nĂ« C++;
  • Options janĂ« shumĂ« tĂ« dobishme pĂ«r punĂ«, gjithashtu trajtojnĂ« mjaft mirĂ« gabimet;
  • nĂ«se projekti u kompilua me sukses, nĂ« 99% ai funksionon ashtu siç duhet. Mesazhet e gabimit tĂ« kompilatorit, mendoj se janĂ« mĂ« tĂ« mirat qĂ« kam parĂ«.

Zhvillimi i lojërave në Rust sapo ka filluar. Por tashmë ekziston një komunitet i qëndrueshëm dhe mjaft i madh që punon për ta hapur Rust për të gjithë. Prandaj, shikoj me optimizëm të ardhmen e gjuhës, duke pritur me padurim rezultatet e punës sonë të përbashkët.

Skillbox rekomandon:

Burimi: habr.com

Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS đŸ”„ Bleni hostim tĂ« besueshĂ«m pĂ«r faqe me mbrojtje nga DDoS, serverĂ« VPS VDS | ProHoster