24 ordutan Rust jolasten: garapen pertsonaleko esperientzia

24 ordutan Rust jolasten: garapen pertsonaleko esperientzia

Artikulu honetan Rust-en joko txiki bat garatzeko nire esperientzia pertsonalari buruz hitz egingo dut. 24 ordu inguru behar izan zituen lan bertsio bat sortzeko (batez ere arratsaldez edo asteburuetan lan egiten nuen). Partida amaitzetik urrun dago, baina esperientzia aberasgarria izango dela uste dut. Jokoa hutsetik eraikitzean ikasitakoa eta egindako ohar batzuk partekatuko ditut.

Skillbox-ek gomendatzen du: Bi urteko ikastaro praktikoa "PRO web garatzailea naiz".

Gogoratzen dugu: "Habr" irakurle guztientzat - 10 errubloko deskontua "Habr" promozio-kodea erabiliz Skillbox-eko edozein ikastarotan izena ematean.

Zergatik Herdoila?

Hizkuntza hau aukeratu dut gauza on asko entzun ditudalako eta jokoen garapenean gero eta ezagunagoa dela ikusten dudalako. Jokoa idatzi aurretik, esperientzia gutxi nuen Rust-en aplikazio sinpleak garatzen. Hau nahikoa izan zen jokoa idaztean askatasun sentsazioa emateko.

Zergatik jokoa eta zer nolako jokoa?

Jolasak egitea dibertigarria da! Arrazoi gehiago egotea nahiko nuke, baina “etxeko” proiektuetarako nire ohiko lanarekin oso lotuta ez dauden gaiak aukeratzen ditut. Zein joko da hau? Cities Skylines, Zoo Tycoon, Prison Architect eta tenisa bera konbinatzen dituen tenis-simulagailu baten antzeko zerbait egin nahi nuen. Oro har, jendea jokatzera etortzen den tenis-akademia bati buruzko joko bat izan zen.

Prestakuntza teknikoa

Rust erabili nahi nuen, baina ez nekien zehazki zenbat oinarri beharko zen hasteko. Ez nuen pixel shaders idatzi eta arrastatu eta jaregin erabili nahi, beraz, irtenbide malguenak bilatzen ari nintzen.

Zurekin partekatzen ditudan baliabide erabilgarriak aurkitu ditut:

Rust-eko hainbat joko-motor arakatu nituen, azkenean Piston eta ggez aukeratuz. Aurreko proiektu batean lanean ari nintzela egin nuen topo. Azkenean, ggez aukeratu nuen 2D joko txiki bat ezartzeko egokiagoa iruditu zitzaidalako. Piston-en egitura modularra konplexuegia da garatzaile hasiberri batentzat (edo Rust-ekin lehen aldiz lan egiten duenarentzat).

Jolasaren egitura

Denbora pixka bat eman nuen proiektuaren arkitekturan pentsatzen. Lehen urratsa “lurra”, jendea eta tenis pistak egitea da. Jendeak epaitegietatik mugitu eta itxaron behar du. Jokalariek denborarekin hobetzen diren trebetasunak izan behar dituzte. Gainera, pertsona eta auzitegi berriak gehitzeko aukera ematen duen editore bat egon beharko litzateke, baina hau jada ez da doakoa.

Dena ondo pentsatuta, lanari ekin nion.

Jokoen sorrera

Hasiera: zirkuluak eta abstrakzioak

ggezen adibide bat hartu nuen eta pantailan zirkulu bat lortu nuen. Zoragarria! Orain abstrakzio batzuk. Jolas-objektu baten ideiatik urruntzea ona izango zela pentsatu nuen. Objektu bakoitza errendatu eta eguneratu behar da hemen adierazi bezala:

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

Kode zati honek begizta berdin batean eguneratu eta errendatu nezakeen objektuen zerrenda polita eman zidan.

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 beharrezkoa da kode lerro guztiak dituelako. Denbora pixka bat eman nuen fitxategiak bereizten eta direktorioen egitura optimizatzen. Hauxe izan zen ondoren:
baliabideak -> hemen daude aktibo guztiak (irudiak)
src
- entitateak
- game_object.rs
— zirkulua.rs
— main.rs -> begizta nagusia

Pertsonak, solairuak eta irudiak

Hurrengo urratsa Pertsona jokoaren objektu bat sortzea eta irudiak kargatzea da. Dena 32 * 32 fitxan oinarrituta eraiki behar da.

24 ordutan Rust jolasten: garapen pertsonaleko esperientzia

Tenis pistak

Tenis pistak nolakoak diren aztertu ondoren, 4*2 fitxak egitea erabaki nuen. Hasieran, posible zen tamaina horretako irudi bat egitea, edo 8 fitxa bereizi elkartzea. Baina orduan konturatu nintzen bi fitxa bakar bakarrik behar zirela, eta hona hemen zergatik.

Guztira, horrelako bi fitxa ditugu: 1 eta 2.

Kantxako atal bakoitza 1. edo 2. fitxaz osatuta dago. Normal moduan jarri daitezke edo 180 gradu irauli daitezke.

24 ordutan Rust jolasten: garapen pertsonaleko esperientzia

Oinarrizko eraikuntza (muntaia) modua

Guneak, pertsonak eta mapak errendatzea lortu ondoren, oinarrizko muntaketa modua ere beharrezkoa zela konturatu nintzen. Honela inplementatu nuen: botoia sakatzean, objektua hautatzen da, eta klik egiteak nahi duzun lekuan jartzen du. Beraz, 1. botoiak kantxa bat hautatzeko aukera ematen du, eta 2. botoiak jokalari bat hautatzeko.

Baina oraindik gogoratu behar dugu zer esan nahi duten 1 eta 2, beraz, alanbre bat gehitu dut zein objektu hautatu zen argitzeko. Honela dirudi.

24 ordutan Rust jolasten: garapen pertsonaleko esperientzia

Arkitektura eta refactoring galderak

Orain hainbat joko-objektu ditut: pertsonak, kantxak eta solairuak. Baina wireframes funtziona dezan, objektu-entitate bakoitzari esan behar zaio objektuak beraiek erakustaldi moduan dauden ala marko bat besterik gabe marrazten den. Hau ez da oso erosoa.

Iruditu zitzaidan arkitektura birpentsatu behar zela, muga batzuk agerian utzi zituen moduan:

  • Bere burua errendatzen eta eguneratzen duen entitate bat izatea arazo bat da, entitate horrek ezingo baitu "jakin" zer errendatu behar duen -irudi bat eta alanbre bat;
  • entitate indibidualen artean propietateak eta portaera trukatzeko tresnarik eza (adibidez, is_build_mode propietatea edo portaera errendatzea). Herentzia erabiltzea posible izango litzateke, Rust-en ezartzeko modu egokirik ez dagoen arren. Benetan behar nuena diseinua zen;
  • entitateen arteko elkarrekintzarako tresna bat behar zen pertsonak epaitegietara esleitzeko;
  • entitateak beraiek datuen eta logikaren nahasketa bat ziren, azkar kontroletik kanpo geratu zirenak.

Ikerketa gehiago egin nuen eta arkitektura deskubritu nuen ECS - Entitate Osagaien Sistema, jokoetan erabili ohi dena. Hona hemen ECSren abantailak:

  • datuak logikatik bereizten dira;
  • konposizioa herentziaren ordez;
  • datuetan oinarritutako arkitektura.

ECS oinarrizko hiru kontzeptuk bereizten dute:

  • entitateak - identifikatzaileak aipatzen duen objektu mota (jokalari bat, pilota bat edo beste zerbait izan daiteke);
  • osagaiak - entitateak haiez osatuta daude. Adibidea - errendatzeko osagaia, kokapenak eta beste batzuk. Hauek datu biltegiak dira;
  • sistemak - objektuak eta osagaiak erabiltzen dituzte, eta datu horietan oinarritutako portaera eta logika dute. Adibide bat errendatze-sistema bat da, errendatzeko osagaiak dituzten entitate guztietan zehar errepikatzen duena eta errendatzea egiten duena.

Hori aztertu ondoren, argi geratu zen ECS-k arazo hauek konpontzen dituela:

  • diseinua erabiltzea herentziaren ordez entitateak sistematikoki antolatzeko;
  • kontrol-sistemen bidez kodea nahastea kentzea;
  • is_build_mode bezalako metodoak erabiliz wireframe logika leku berean mantentzeko - errendatze sisteman.

Hau da ECS ezarri ondoren gertatu zena.

baliabideak -> hemen daude aktibo guztiak (irudiak)
src
- osagaiak
—posizioa.rs
— pertsona.rs
— tenis_pista.rs
- solairua.rs
- wireframe.rs
— mouse_tracked.rs
- baliabideak
—sagua.rs
- sistemak
— errendatzea.rs
— konstanteak.rs
- utils.rs
— world_factory.rs -> munduko fabrikaren funtzioak
— main.rs -> begizta nagusia

Epaitegietara jendea esleitzen dugu

ECS-k bizitza erraztu du. Orain entitateei datuak gehitzeko eta datu horietan oinarritutako logika gehitzeko modu sistematiko bat nuen. Eta honek, epaitegien artean jendearen banaketa antolatzea ahalbidetu zuen.

Zer egin dut:

  • esleitutako epaitegiei buruzko datuak gehitu zizkion Pertsonari;
  • banatutako pertsonei buruzko datuak gehitu ditu TennisCourt-era;
  • gehitu du CourtChoosingSystem, zeinak pertsonak eta kantxak aztertzeko, erabilgarri dauden kantxak detektatzeko eta haietara jokalariak banatzeko;
  • PersonMovementSystem bat gehitu du, epaitegietara esleitutako pertsonak bilatzen dituena, eta ez badaude, jendea behar duten tokira bidaltzen duena.

24 ordutan Rust jolasten: garapen pertsonaleko esperientzia

Laburbilduz

Asko gustatu zait joko sinple honetan lan egitea. Gainera, pozten naiz idazteko Rust erabili nuelako, zeren eta:

  • Herdoilak behar duzuna ematen dizu;
  • dokumentazio bikaina du, Rust nahiko dotorea da;
  • koherentzia freskoa da;
  • ez duzu klonaziora, kopiatzera edo antzeko beste ekintzetara jo beharrik, askotan C++-n egiten nuena;
  • Aukerak erabiltzeko oso errazak dira eta akatsak oso ondo kudeatzen dituzte;
  • proiektua osatu ahal izan bazen, denboraren %99an funtzionatzen du, eta behar den moduan. Uste dut konpiladorearen errore-mezuak ikusi ditudan onenak direla.

Rust-en jokoen garapena hasi besterik ez da egin. Baina dagoeneko komunitate egonkor eta nahiko handi bat dago Rust guztientzako irekitzeko lanean. Horregatik, baikortasunez begiratzen diot hizkuntzaren etorkizunari, gure lan komunaren emaitzei begira.

Skillbox-ek gomendatzen du:

Iturria: www.habr.com

Gehitu iruzkin berria