Rust 24 саатта ойноо: жеке өнүгүү тажрыйбасы

Rust 24 саатта ойноо: жеке өнүгүү тажрыйбасы

Бул макалада мен Рустта кичинекей оюнду иштеп чыгуу боюнча жеке тажрыйбам жөнүндө сүйлөшөм. Жумушчу версиясын түзүү үчүн 24 саатка жакын убакыт кетти (мен көбүнчө кечинде же дем алыш күндөрү иштечүмүн). Оюн бүтө элек, бирок тажрыйба пайдалуу болот деп ойлойм. Мен үйрөнгөндөрүм менен бөлүшөм жана оюнду нөлдөн баштап түзүүдө жасаган кээ бир байкоолорумду бөлүшөм.

Skillbox сунуштайт: Эки жылдык практикалык курс "Мен PRO веб-иштеп чыгуучумун".

Биз эсиңизге салабыз: "Хабрдын" бардык окурмандары үчүн - "Habr" промо-кодун колдонуу менен каалаган Skillbox курсуна катталганда 10 000 рубль арзандатуу.

Эмне үчүн Rust?

Мен бул тилди тандадым, анткени мен ал жөнүндө көп жакшы нерселерди укканмын жана анын оюн өнүктүрүүдө барган сайын популярдуу болуп баратканын көрүп жатам. Оюнду жазганга чейин мен Rust'та жөнөкөй тиркемелерди иштеп чыгууда аз тажрыйбага ээ болчумун. Бул оюнду жазып жатканда мага эркиндик сезимин берүү үчүн жетиштүү болду.

Эмне үчүн оюн жана кандай оюн?

Оюндарды жасоо кызыктуу! Мен дагы көп себептерди каалайм, бирок "үй" долбоорлору үчүн мен кадимки ишим менен өтө тыгыз байланышпаган темаларды тандайм. Бул кандай оюн? Мен Cities Skylines, Zoo Tycoon, Prison Architect жана теннистин өзүн бириктирген теннис симулятору сыяктуу нерсени жасагым келди. Жалпысынан алганда, бул теннис академиясы жөнүндө оюн болуп чыкты, ал жерде адамдар ойношот.

Техникалык окуу

Мен Rustту колдонгум келди, бирок аны баштоо үчүн канча негиз талап кыларын так билген эмесмин. Мен пикселдик шейдерлерди жазгым келген жок жана сүйрөп түшүрүүнү колдонгум келген жок, ошондуктан мен эң ийкемдүү чечимдерди издеп жүрдүм.

Мен сиз менен бөлүшө турган пайдалуу ресурстарды таптым:

Мен бир нече Rust оюн кыймылдаткычтарын изилдеп, акыры Piston жана ggez тандадым. Мурунку долбоордо иштеп жүрүп аларга жолугуп калдым. Акыр-аягы, мен ggezди тандадым, анткени ал кичинекей 2D оюнун ишке ашыруу үчүн ылайыктуураак көрүндү. Поршендин модулдук түзүлүшү жаңыдан иштеп чыгуучу (же Rust менен биринчи жолу иштеп жаткан адам) үчүн өтө татаал.

Оюн структурасы

Мен долбоордун архитектурасы жөнүндө ойлонуп бир аз убакыт өткөрдүм. Биринчи кадам - ​​"жер", адамдар жана теннис корттору. Эл сотторду айланып, күтүшү керек. Оюнчулар убакыттын өтүшү менен жакшыра турган жөндөмгө ээ болушу керек. Мындан тышкары, жаңы адамдарды жана сотторду кошууга мүмкүндүк берген редактор болушу керек, бирок бул мындан ары бекер.

Баарын жакшылап ойлонуп, ишке кириштим.

Оюн түзүү

Башталыш: Айланалар жана абстракциялар

Мен ггезден мисал алып, экранда тегерекче алдым. Керемет! Эми кээ бир абстракциялар. Мен оюн объектисинин идеясынан абстракциялоону жакшы деп ойлогом. Ар бир объект бул жерде айтылгандай көрсөтүлүшү жана жаңыртылышы керек:

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

Коддун бул бөлүгү мага жаңырта турган жана бирдей жакшы циклде көрсөтө турган объекттердин жакшы тизмесин берди.

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 керек, анткени ал коддун бардык саптарын камтыйт. Мен файлдарды бөлүп, каталогдун структурасын оптималдаштырууга бир аз убакыт короттум. Андан кийин мындай көрүндү:
ресурстар -> бул жерде бардык активдер (сүрөттөр)
СИБ
- субъектилер
— game_object.rs
— айлана.рс
— main.rs -> негизги цикл

Адамдар, полдор жана сүрөттөр

Кийинки кадам - ​​Person оюн объектин түзүү жана сүрөттөрдү жүктөө. Бардыгы 32*32 плитканын негизинде курулууга тийиш.

Rust 24 саатта ойноо: жеке өнүгүү тажрыйбасы

Теннис корту

Теннис корттору кандай экенин изилдеп чыккандан кийин, мен аларды 4*2 плиткадан жасоону чечтим. Башында мындай өлчөмдөгү сүрөттү жасоого же 8 өзүнчө плитканы чогултууга мүмкүн болгон. Бирок кийин мен эки гана уникалдуу плитка керек экенин түшүндүм, бул жерде эмне үчүн.

Жалпысынан бизде эки плиткалар бар: 1 жана 2.

Корттун ар бир бөлүгү плитка 1 же 2 плиткадан турат. Аларды кадимкидей жайгаштырса же 180 градуска буруп койсо болот.

Rust 24 саатта ойноо: жеке өнүгүү тажрыйбасы

Негизги курулуш (монтаждоо) режими

Мен сайттарды, адамдарды жана карталарды көрсөтүүгө жетишкенден кийин, мен негизги чогултуу режими да керек экенин түшүндүм. Мен муну мындайча ишке ашырдым: баскыч басылганда объект тандалып алынат жана чыкылдатуу аны керектүү жерге жайгаштырат. Ошентип, 1 баскычы кортту, ал эми 2 баскычы оюнчуну тандоого мүмкүндүк берет.

Бирок биз дагы эле 1 жана 2 эмнени билдирерин эстешибиз керек, ошондуктан мен кайсы объект тандалганын ачыктоо үчүн телпек коштум. Бул көрүнүш мына мындай.

Rust 24 саатта ойноо: жеке өнүгүү тажрыйбасы

Архитектура жана рефакторинг суроолору

Азыр менде бир нече оюн объектилери бар: адамдар, корттор жана полдор. Бирок зым рамкалары иштеши үчүн ар бир объектиге объекттердин өзү демонстрация режиминде же кадр жөн эле тартылганбы, айтып бериш керек. Бул абдан ыңгайлуу эмес.

Мага архитектураны кээ бир чектөөлөрдү ачкан жол менен кайра карап чыгуу керектей сезилди:

  • Өзүн-өзү көрсөтүүчү жана жаңыртуучу объектке ээ болуу көйгөй жаратат, анткени ал объект эмнени көрсөтүү керек экенин - сүрөт менен телмирикти "биле албайт";
  • жеке жактардын ортосунда касиеттерди жана жүрүм-турумду алмашуу куралынын жоктугу (мисалы, is_build_mode касиети же жүрүм-турумду көрсөтүү). Рустта аны ишке ашыруунун туура жолу жок болсо да, мурасты колдонууга болот. Мага чындап керек болгон нерсе макет болчу;
  • адамдарды сотторго дайындоо үчүн субъекттердин өз ара аракеттенүү инструменти керек болгон;
  • субъекттердин өздөрү тез эле көзөмөлдөн чыгып кеткен маалыматтар менен логиканын аралашмасы болгон.

Мен дагы бир аз изилдеп, архитектураны ачтым ECS - Entity Component System, көбүнчө оюндарда колдонулат. Бул жерде ECS артыкчылыктары болуп саналат:

  • маалыматтар логикадан бөлүнгөн;
  • мурастын ордуна курамы;
  • маалымат борборлоштурулган архитектура.

ECS үч негизги түшүнүк менен мүнөздөлөт:

  • субъекттер - идентификатор тиешелүү объекттин түрү (ал оюнчу, топ же башка нерсе болушу мүмкүн);
  • компоненттери - субъекттер алардан турат. Мисал - рендеринг компоненти, жайгашкан жерлер жана башкалар. Бул маалымат кампалары;
  • системалар - алар объектилерди да, компоненттерди да колдонушат, ошондой эле бул маалыматтарга негизделген жүрүм-турум жана логиканы камтыйт. Мисал рендеринг компоненттери бар бардык объекттер аркылуу кайталануучу жана көрсөтүүнү аткарган рендеринг системасы.

Аны изилдегенден кийин, ECS төмөнкү көйгөйлөрдү чече тургандыгы белгилүү болду:

  • объекттерди системалуу уюштуруу үчүн мурастын ордуна макетти колдонуу;
  • башкаруу системалары аркылуу коддун башаламандыгынан арылуу;
  • is_build_mode сыяктуу ыкмаларды колдонуп, симфрайм логикасын бир жерде - рендеринг системасында сактоо.

Бул ECSти ишке ашыргандан кийин болгон.

ресурстар -> бул жерде бардык активдер (сүрөттөр)
СИБ
- компоненттер
—позиция.rs
— person.rs
— tennis_court.rs
— кабат.rs
- wireframe.rs
— mouse_tracked.rs
- ресурстар
— mouse.rs
- системалар
— rendering.rs
— константалар.rs
— utils.rs
— world_factory.rs -> дүйнөлүк фабрика функциялары
— main.rs -> негизги цикл

Сотторго адамдарды дайындап жатабыз

ECS жашоону жеңилдетти. Эми менде объекттерге маалыматтарды кошуунун жана ошол маалыматтардын негизинде логиканы кошуунун системалуу жолу бар болчу. Бул болсо соттор арасында адамдарды бөлүштүрүүнү уюштурууга шарт түздү.

Мен эмне кылдым:

  • адамга дайындалган соттор жөнүндө маалыматтарды кошкон;
  • Теннискортко бөлүштүрүлгөн адамдар тууралуу маалыматтарды кошту;
  • Кошулган CourtChoosingSystem, бул сизге адамдарды жана сотторду талдоо, жеткиликтүү сотторду табуу жана аларга оюнчуларды бөлүштүрүү;
  • Сотторго дайындалган адамдарды издеген, эгерде алар жок болсо, анда адамдарды керек болгон жерге жөнөтүүчү PersonMovementSystem кошот.

Rust 24 саатта ойноо: жеке өнүгүү тажрыйбасы

кошуу жолу менен

Бул жөнөкөй оюндун үстүндө иштөө мага абдан жакты. Анын үстүнө, мен аны жазуу үчүн Русту колдонгонума кубанычтамын, анткени:

  • Дат сизге керектүү нерсени берет;
  • ал сонун документтерге ээ, Rust абдан жарашыктуу;
  • консистенциясы салкын;
  • клондоштуруу, көчүрүү же башка ушул сыяктуу аракеттерди жасоонун кереги жок, мен муну C++ тилинде көп жасайм;
  • Параметрлер колдонууга абдан оңой жана каталарды абдан жакшы чечет;
  • эгерде долбоор түзүлө турган болсо, анда ал убакыттын 99% ы иштейт жана так ошондой. Мен компилятордун ката билдирүүлөрү мен көргөн эң жакшысы деп ойлойм.

Rust оюнун иштеп чыгуу жаңы гана башталууда. Бирок Рустту бардыгына ачуу үчүн иштеп жаткан туруктуу жана кыйла чоң коомчулук бар. Андыктан мен тилдин келечегине оптимисттик көз караш менен карайм, жалпы ишибиздин жыйынтыгын чыдамсыздык менен күтөм.

Skillbox сунуштайт:

Source: www.habr.com

Комментарий кошуу