Að spila Rust á 24 klukkustundum: reynslu af persónulegri þróun

Að spila Rust á 24 klukkustundum: reynslu af persónulegri þróun

Í þessari grein mun ég tala um persónulega reynslu mína af því að þróa lítinn leik í Rust. Það tók um 24 tíma að búa til virka útgáfu (ég vann aðallega á kvöldin eða um helgar). Leiknum er langt frá því að vera lokið en ég held að reynslan verði gefandi. Ég mun deila því sem ég lærði og nokkrum athugunum sem ég gerði þegar ég byggði leikinn frá grunni.

Skillbox mælir með: Tveggja ára verklegt nám „Ég er PRO vefhönnuður“.

Við minnum á: fyrir alla Habr lesendur - 10 rúblur afsláttur þegar þú skráir þig á hvaða Skillbox námskeið sem er með því að nota Habr kynningarkóðann.

Af hverju Ryð?

Ég valdi þetta tungumál vegna þess að ég hef heyrt margt gott um það og ég sé það verða sífellt vinsælli í leikjaþróun. Áður en ég skrifaði leikinn hafði ég litla reynslu af því að þróa einföld forrit í Rust. Þetta var bara nóg til að gefa mér tilfinningu fyrir frelsi á meðan ég skrifaði leikinn.

Hvers vegna leikurinn og hvers konar leikur?

Það er gaman að búa til leiki! Ég vildi að það væru fleiri ástæður, en fyrir „heima“ verkefni vel ég efni sem eru ekki of nátengd venjulegu starfi mínu. Hvaða leikur er þetta? Mig langaði að búa til eitthvað eins og tennishermi sem sameinar Cities Skylines, Zoo Tycoon, Prison Architect og tennis sjálft. Almennt séð reyndist þetta vera leikur um tennisakademíu þar sem fólk kemur til að spila.

Tækniþjálfun

Mig langaði að nota Rust, en ég vissi ekki nákvæmlega hversu mikla grunnvinnu það myndi taka til að byrja. Ég vildi ekki skrifa pixlaskyggingar og nota drag-n-drop, svo ég var að leita að sveigjanlegustu lausnunum.

Ég fann gagnleg úrræði sem ég deili með þér:

Ég skoðaði nokkrar Rust leikjavélar og valdi að lokum Piston og ggez. Ég rakst á þá þegar ég var að vinna að fyrra verkefni. Að lokum valdi ég ggez vegna þess að það virtist hentugra til að útfæra lítinn 2D leik. Einingauppbygging Piston er of flókin fyrir nýliði (eða einhvern sem er að vinna með Rust í fyrsta skipti).

Uppbygging leiksins

Ég eyddi tíma í að hugsa um arkitektúr verkefnisins. Fyrsta skrefið er að búa til „land“, fólk og tennisvelli. Menn verða að fara um vellina og bíða. Leikmenn verða að hafa færni sem batnar með tímanum. Auk þess ætti að vera ritstjóri sem gerir þér kleift að bæta við nýju fólki og dómstólum, en þetta er ekki lengur ókeypis.

Eftir að hafa hugsað allt til enda fór ég að vinna.

Leikjagerð

Upphaf: Hringir og abstrakt

Ég tók dæmi frá ggez og fékk hring á skjáinn. Dásamlegt! Nú eru smá abstrakt. Ég hélt að það væri gaman að draga í burtu frá hugmyndinni um leikhlut. Hver hlutur verður að vera framleiddur og uppfærður eins og segir hér:

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

Þetta stykki af kóða gaf mér fallegan lista yfir hluti sem ég gat uppfært og skilað í jafn fallegri lykkju.

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 er nauðsynlegt vegna þess að það inniheldur allar kóðalínur. Ég eyddi smá tíma í að aðskilja skrárnar og fínstilla möppuskipulagið. Svona leit þetta út eftir það:
auðlindir -> þetta er þar sem allar eignir eru (myndir)
src
- einingar
— game_object.rs
— hring.rs
— aðal.rs -> aðallykkja

Fólk, gólf og myndir

Næsta skref er að búa til Person leikhlut og hlaða myndum. Allt ætti að vera byggt á grundvelli 32*32 flísar.

Að spila Rust á 24 klukkustundum: reynslu af persónulegri þróun

Tennisvellir

Eftir að hafa kynnt mér hvernig tennisvellir líta út ákvað ég að gera þá úr 4*2 flísum. Upphaflega var hægt að gera mynd af þessari stærð, eða setja saman 8 aðskildar flísar. En svo áttaði ég mig á því að það vantaði aðeins tvær einstakar flísar og hér er ástæðan.

Alls höfum við tvær slíkar flísar: 1 og 2.

Hver hluti vallarins samanstendur af flísum 1 eða flísum 2. Hægt er að leggja þær út eins og venjulega eða snúa 180 gráður.

Að spila Rust á 24 klukkustundum: reynslu af persónulegri þróun

Grunnbygging (samsetning) háttur

Eftir að mér tókst að ná fram endurgerð vefsvæða, fólks og korta, áttaði ég mig á því að grunnsamsetningarhamur var líka nauðsynlegur. Ég útfærði það svona: þegar ýtt er á hnappinn er hluturinn valinn og smellurinn setur hann á viðkomandi stað. Svo, hnappur 1 gerir þér kleift að velja völl og hnappur 2 gerir þér kleift að velja leikmann.

En við þurfum samt að muna hvað 1 og 2 þýða, svo ég bætti við vírramma til að gera það ljóst hvaða hlutur var valinn. Svona lítur þetta út.

Að spila Rust á 24 klukkustundum: reynslu af persónulegri þróun

Arkitektúr og endurnýjunarspurningar

Nú á ég nokkra leikjahluti: fólk, velli og gólf. En til þess að vírrammar virki þarf að segja hverjum hluteiningu hvort hlutirnir sjálfir séu í sýnistillingu eða hvort rammi sé einfaldlega teiknaður. Þetta er ekki mjög þægilegt.

Mér virtist sem það þyrfti að endurhugsa arkitektúrinn á þann hátt sem leiddi í ljós nokkrar takmarkanir:

  • Það er vandamál að hafa einingu sem myndar og uppfærir sjálfa sig vegna þess að þessi eining mun ekki geta "vitað" hvað hann á að gera - mynd og vírramma;
  • skortur á tæki til að skiptast á eiginleikum og hegðun á milli einstakra eininga (til dæmis is_build_mode eignin eða hegðun rendering). Það væri hægt að nota arf, þó að það sé engin almennileg leið til að útfæra það í Rust. Það sem ég virkilega þurfti var skipulagið;
  • tól fyrir samskipti milli aðila þurfti til að úthluta fólki fyrir dómstóla;
  • einingarnar sjálfar voru blanda af gögnum og rökfræði sem fór fljótt úr böndunum.

Ég gerði nokkrar frekari rannsóknir og uppgötvaði arkitektúrinn ECS - Entity Component System, sem er almennt notað í leikjum. Hér eru kostir ECS:

  • gögn eru aðskilin frá rökfræði;
  • samsetning í stað arfs;
  • gagnamiðuð arkitektúr.

ECS einkennist af þremur grunnhugtökum:

  • entities - tegund hlutar sem auðkennið vísar til (það gæti verið leikmaður, bolti eða eitthvað annað);
  • íhlutir - einingar eru gerðar úr þeim. Dæmi - flutningsþáttur, staðsetningar og annað. Þetta eru gagnageymslur;
  • kerfi - þau nota bæði hluti og íhluti, auk þess innihalda hegðun og rökfræði sem eru byggð á þessum gögnum. Dæmi er flutningskerfi sem endurtekur sig í gegnum allar einingar með flutningshlutum og framkvæmir flutninginn.

Eftir að hafa rannsakað það varð ljóst að ECS leysir eftirfarandi vandamál:

  • að nota skipulag í stað arfs til að skipuleggja einingar kerfisbundið;
  • losa sig við kóðarugl í gegnum stjórnkerfi;
  • nota aðferðir eins og is_build_mode til að halda wireframe rökfræðinni á sama stað - í flutningskerfinu.

Þetta er það sem gerðist eftir innleiðingu ECS.

auðlindir -> þetta er þar sem allar eignir eru (myndir)
src
- íhlutir
—staða.rs
— manneskja.rs
— tennisvöllur.rs
— hæð.rs
- wireframe.rs
— mouse_tracked.rs
- auðlindir
— mús.rs
- kerfi
— flutningur.rs
— fastar.rs
— utils.rs
— world_factory.rs -> heimsverksmiðjuaðgerðir
— aðal.rs -> aðallykkja

Við skipum fólk í dómstóla

ECS hefur gert lífið auðveldara. Nú hafði ég kerfisbundna leið til að bæta gögnum við einingar og bæta við rökfræði út frá þeim gögnum. Og þetta gerði það aftur á móti mögulegt að skipuleggja dreifingu fólks á milli dómstóla.

Hvað hef ég gert:

  • bætt við gögnum um úthlutaða dómstóla við Persónu;
  • bætti við gögnum um dreift fólk til TennisCourt;
  • bætt við CourtChoosingSystem, sem gerir þér kleift að greina fólk og velli, greina tiltæka velli og dreifa leikmönnum til þeirra;
  • bætt við PersonMovementSystem, sem leitar að fólki sem er úthlutað til dómstóla, og ef það er ekki þar, sendir það fólk þangað sem það þarf að vera.

Að spila Rust á 24 klukkustundum: reynslu af persónulegri þróun

Toppur upp

Mér fannst mjög gaman að vinna í þessum einfalda leik. Þar að auki er ég ánægður með að ég notaði Rust til að skrifa það, vegna þess að:

  • Ryð gefur þér það sem þú þarft;
  • það hefur framúrskarandi skjöl, Rust er alveg glæsilegt;
  • samkvæmni er flott;
  • þú þarft ekki að grípa til klónunar, afritunar eða annarra svipaðra aðgerða, sem ég gerði oft í C++;
  • Valkostir eru mjög auðveldir í notkun og meðhöndla villur mjög vel;
  • ef hægt var að setja verkefnið saman, þá virkar það 99% af tímanum og nákvæmlega eins og það á að gera. Ég held að þýðanda villuboðin séu þau bestu sem ég hef séð.

Leikjaþróun í Rust er rétt að hefjast. En það er nú þegar stöðugt og nokkuð stórt samfélag sem vinnur að því að opna Rust fyrir alla. Því horfi ég bjartsýn á framtíð tungumálsins og hlakka til árangurs af sameiginlegu starfi okkar.

Skillbox mælir með:

Heimild: www.habr.com

Bæta við athugasemd