Kucheza Rust katika masaa 24: uzoefu wa maendeleo ya kibinafsi

Kucheza Rust katika masaa 24: uzoefu wa maendeleo ya kibinafsi

Katika nakala hii nitazungumza juu ya uzoefu wangu wa kibinafsi wa kukuza mchezo mdogo huko Rust. Ilichukua kama masaa 24 kuunda toleo la kufanya kazi (mara nyingi nilifanya kazi jioni au wikendi). Mchezo haujakamilika, lakini nadhani uzoefu utakuwa wa kuridhisha. Nitashiriki nilichojifunza na baadhi ya uchunguzi niliofanya nilipokuwa nikitengeneza mchezo kuanzia mwanzo.

Skillbox inapendekeza: Kozi ya vitendo ya miaka miwili "Mimi ni msanidi programu wa wavuti".

Tunakukumbusha: kwa wasomaji wote wa "Habr" - punguzo la rubles 10 wakati wa kujiandikisha katika kozi yoyote ya Skillbox kwa kutumia msimbo wa uendelezaji wa "Habr".

Kwa nini Kutu?

Nilichagua lugha hii kwa sababu nimesikia mambo mengi mazuri kuihusu na ninaiona inazidi kuwa maarufu katika ukuzaji wa mchezo. Kabla ya kuandika mchezo, nilikuwa na uzoefu mdogo wa kuunda programu rahisi katika Rust. Hii ilitosha kunipa hisia ya uhuru wakati wa kuandika mchezo.

Kwa nini mchezo na aina gani ya mchezo?

Kufanya michezo ni furaha! Natamani kungekuwa na sababu zaidi, lakini kwa miradi ya "nyumbani" ninachagua mada ambazo hazihusiani sana na kazi yangu ya kawaida. Huu ni mchezo gani? Nilitaka kutengeneza kitu kama kiigaji cha tenisi kinachochanganya Cities Skylines, Zoo Tycoon, Mbunifu wa Magereza na tenisi yenyewe. Kwa ujumla, iligeuka kuwa mchezo kuhusu chuo cha tenisi ambapo watu huja kucheza.

Mafunzo ya kiufundi

Nilitaka kutumia Rust, lakini sikujua ni msingi kiasi gani ungechukua ili kuanza. Sikutaka kuandika vivuli vya pixel na kutumia buruta-n-tone, kwa hivyo nilikuwa nikitafuta suluhisho rahisi zaidi.

Nimepata nyenzo muhimu ambazo ninashiriki nawe:

Niligundua injini kadhaa za mchezo wa Rust, hatimaye nikachagua Piston na ggez. Nilikutana nao wakati nikifanya kazi kwenye mradi uliopita. Mwishowe, nilichagua ggez kwa sababu ilionekana inafaa zaidi kwa kutekeleza mchezo mdogo wa 2D. Muundo wa moduli wa Piston ni ngumu sana kwa msanidi programu anayeanza (au mtu ambaye anafanya kazi na Rust kwa mara ya kwanza).

Muundo wa mchezo

Nilitumia muda kufikiria juu ya usanifu wa mradi huo. Hatua ya kwanza ni kutengeneza "ardhi", watu na mahakama za tenisi. Watu wanapaswa kuzunguka mahakama na kusubiri. Wachezaji lazima wawe na ujuzi unaoboreka kwa muda. Zaidi ya hayo, kunapaswa kuwa na kihariri kinachokuruhusu kuongeza watu wapya na mahakama, lakini hii si bure tena.

Baada ya kufikiria kila kitu, nilienda kufanya kazi.

Uumbaji wa mchezo

Mwanzo: Miduara na Vifupisho

Nilichukua mfano kutoka kwa ggez na nikapata mduara kwenye skrini. Ajabu! Sasa baadhi ya vifupisho. Nilidhani itakuwa nzuri kujiondoa kutoka kwa wazo la kitu cha mchezo. Kila kitu lazima kitolewe na kusasishwa kama ilivyoelezwa hapa:

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

Sehemu hii ya nambari ilinipa orodha nzuri ya vitu ambavyo ningeweza kusasisha na kutoa kwa kitanzi kizuri sawa.

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 ni muhimu kwa sababu ina mistari yote ya msimbo. Nilitumia muda kidogo kutenganisha faili na kuboresha muundo wa saraka. Hivi ndivyo ilivyokuwa baada ya hapo:
rasilimali -> hapa ndipo mali zote ziko (picha)
src
- vyombo
- mchezo_object.rs
- mduara.rs
β€” main.rs -> kitanzi kikuu

Watu, sakafu na picha

Hatua inayofuata ni kuunda kitu cha mchezo wa Mtu na kupakia picha. Kila kitu kinapaswa kujengwa kwa misingi ya tiles 32 * 32.

Kucheza Rust katika masaa 24: uzoefu wa maendeleo ya kibinafsi

Korti za tenisi

Baada ya kusoma jinsi mahakama za tenisi zinavyoonekana, niliamua kuzifanya kutoka kwa vigae 4*2. Hapo awali, iliwezekana kutengeneza picha ya saizi hii, au kuweka pamoja tiles 8 tofauti. Lakini basi niligundua kuwa tiles mbili tu za kipekee zilihitajika, na hii ndio sababu.

Kwa jumla tunayo tiles mbili kama hizo: 1 na 2.

Kila sehemu ya mahakama ina tile 1 au tile 2. Wanaweza kuwekwa kama kawaida au kupindua digrii 180.

Kucheza Rust katika masaa 24: uzoefu wa maendeleo ya kibinafsi

Ujenzi wa msingi (mkusanyiko) mode

Baada ya kufaulu kufikia utoaji wa tovuti, watu na ramani, niligundua kuwa hali ya msingi ya mkusanyiko pia ilihitajika. Niliitekeleza kama hii: wakati kifungo kinaposisitizwa, kitu kinachaguliwa, na kubofya huiweka mahali unayotaka. Kwa hiyo, kifungo cha 1 kinakuwezesha kuchagua mahakama, na kifungo cha 2 kinakuwezesha kuchagua mchezaji.

Lakini bado tunahitaji kukumbuka 1 na 2 inamaanisha nini, kwa hivyo niliongeza wireframe ili iwe wazi ni kitu gani kilichaguliwa. Hivi ndivyo inavyoonekana.

Kucheza Rust katika masaa 24: uzoefu wa maendeleo ya kibinafsi

Maswali ya usanifu na refactoring

Sasa nina vitu kadhaa vya mchezo: watu, mahakama na sakafu. Lakini ili fremu za waya zifanye kazi, kila chombo kinahitaji kuambiwa ikiwa vitu vyenyewe viko katika hali ya onyesho, au ikiwa fremu imechorwa tu. Hii si rahisi sana.

Ilionekana kwangu kuwa usanifu ulihitaji kufikiria tena kwa njia ambayo ilifunua mapungufu kadhaa:

  • Kuwa na huluki inayojitolea na kujisasisha yenyewe ni tatizo kwa sababu huluki hiyo haitaweza "kujua" kile inachopaswa kutoa - picha na wireframe;
  • ukosefu wa zana ya kubadilishana sifa na tabia kati ya vyombo binafsi (kwa mfano, is_build_mode mali au utoaji wa tabia). Itawezekana kutumia urithi, ingawa hakuna njia sahihi ya kuitekeleza katika Rust. Nilichohitaji sana ni mpangilio;
  • chombo cha mwingiliano kati ya vyombo kilihitajika ili kuwapa watu mahakama;
  • vyombo vyenyewe vilikuwa mchanganyiko wa data na mantiki ambayo ilitoka nje ya udhibiti haraka.

Nilifanya utafiti zaidi na kugundua usanifu ECS - Mfumo wa Kipengele cha Huluki, ambayo hutumiwa kwa kawaida katika michezo. Hapa kuna faida za ECS:

  • data imetenganishwa na mantiki;
  • utungaji badala ya urithi;
  • usanifu wa data-centric.

ECS ina sifa ya dhana tatu za msingi:

  • vyombo - aina ya kitu ambacho kitambulisho kinarejelea (inaweza kuwa mchezaji, mpira, au kitu kingine);
  • vipengele - vyombo vinaundwa nao. Mfano - sehemu ya utoaji, maeneo na wengine. Haya ni maghala ya data;
  • mifumo - hutumia vitu na vijenzi vyote, pamoja na kuwa na tabia na mantiki ambayo inategemea data hii. Mfano ni mfumo wa uwasilishaji ambao hurudia kupitia huluki zote zilizo na vijenzi vya uwasilishaji na hufanya uwasilishaji.

Baada ya kuisoma, ikawa wazi kuwa ECS inasuluhisha shida zifuatazo:

  • kutumia mpangilio badala ya urithi kupanga vyombo kwa utaratibu;
  • kuondokana na jumble ya kanuni kupitia mifumo ya udhibiti;
  • kutumia njia kama is_build_mode kuweka mantiki ya wireframe mahali pamoja - katika mfumo wa utoaji.

Hiki ndicho kilichotokea baada ya kutekeleza ECS.

rasilimali -> hapa ndipo mali zote ziko (picha)
src
- vipengele
-nafasi.rs
- mtu.rs
- tenisi_court.rs
- sakafu.rs
- wireframe.rs
- mouse_tracked.rs
- rasilimali
-panya.rs
- mifumo
- utoaji.rs
- mara kwa mara.rs
- matumizi.rs
β€” world_factory.rs -> utendaji wa kiwanda duniani
β€” main.rs -> kitanzi kikuu

Tunapeleka watu mahakamani

ECS imerahisisha maisha. Sasa nilikuwa na njia ya kimfumo ya kuongeza data kwa vyombo na kuongeza mantiki kulingana na data hiyo. Na hii, kwa upande wake, ilifanya iwezekane kuandaa usambazaji wa watu kati ya mahakama.

Nimefanya nini:

  • aliongeza data kuhusu mahakama zilizopewa Mtu;
  • aliongeza data kuhusu watu waliosambazwa kwa TennisCourt;
  • aliongeza CourtChoosingSystem, ambayo inakuwezesha kuchambua watu na mahakama, kuchunguza mahakama zilizopo na kusambaza wachezaji kwao;
  • aliongeza PersonMovementSystem, ambayo hutafuta watu waliopewa kazi ya mahakama, na ikiwa hawapo, basi huwatuma watu wanapohitaji kuwa.

Kucheza Rust katika masaa 24: uzoefu wa maendeleo ya kibinafsi

Akihitimisha

Nilifurahiya sana kufanya kazi kwenye mchezo huu rahisi. Kwa kuongezea, ninafurahi kwamba nilitumia Rust kuiandika, kwa sababu:

  • Kutu inakupa kile unachohitaji;
  • ina nyaraka bora, Kutu ni kifahari kabisa;
  • msimamo ni baridi;
  • sio lazima ugeuke kwa cloning, kunakili au vitendo vingine sawa, ambavyo mara nyingi nilifanya katika C ++;
  • Chaguzi ni rahisi sana kutumia na kushughulikia makosa vizuri sana;
  • ikiwa mradi uliweza kukusanywa, basi 99% ya wakati unafanya kazi, na haswa kama inavyopaswa. Nadhani ujumbe wa makosa ya mkusanyaji ndio bora zaidi nimeona.

Ukuzaji wa mchezo huko Rust ndio unaanza. Lakini tayari kuna jumuiya thabiti na kubwa inayofanya kazi kufungua Rust kwa kila mtu. Kwa hivyo, ninaangalia mustakabali wa lugha kwa matumaini, nikitarajia matokeo ya kazi yetu ya kawaida.

Skillbox inapendekeza:

Chanzo: mapenzi.com

Kuongeza maoni