Žaisti Rust per 24 valandas: asmeninio tobulėjimo patirtis

Žaisti Rust per 24 valandas: asmeninio tobulėjimo patirtis

Šiame straipsnyje papasakosiu apie savo asmeninę patirtį kuriant nedidelį žaidimą „Rust“. Sukurti darbinę versiją užtruko apie 24 valandas (daugiausia dirbau vakarais arba savaitgaliais). Žaidimas toli gražu nebaigtas, bet manau, kad patirtis bus naudinga. Pasidalinsiu tuo, ką sužinojau ir kai kuriais pastebėjimais, kuriuos padariau kurdamas žaidimą nuo nulio.

„Skillbox“ rekomenduoja: Dvejų metų praktinis kursas "Aš esu PRO žiniatinklio kūrėjas".

Primename: visiems „Habr“ skaitytojams – 10 000 rublių nuolaida užsiregistravus į bet kurį „Skillbox“ kursą naudojant „Habr“ reklamos kodą.

Kodėl Rust?

Pasirinkau šią kalbą, nes apie ją girdėjau daug gerų dalykų ir matau, kad ji tampa vis populiaresnė žaidimų kūrimo srityje. Prieš rašydamas žaidimą, turėjau mažai patirties kuriant paprastas programas „Rust“. To pakako, kad rašant žaidimą pajusčiau laisvės pojūtį.

Kodėl žaidimas ir koks žaidimas?

Kurti žaidimus yra smagu! Norėčiau, kad priežasčių būtų daugiau, bet „namų“ projektams renkuosi temas, kurios nėra pernelyg glaudžiai susijusios su mano įprastu darbu. Kas tai per žaidimas? Norėjau sukurti kažką panašaus į teniso treniruoklį, kuris apjungtų „Cities Skylines“, „Zoo Tycoon“, „Prison Architect“ ir patį tenisą. Apskritai, tai buvo žaidimas apie teniso akademiją, kur žmonės ateina žaisti.

Techninis mokymas

Norėjau naudoti Rust, bet tiksliai nežinojau, kiek reikės paruošti parengiamąjį darbą. Nenorėjau rašyti pikselių šešėlių ir naudoti drag-n-drop, todėl ieškojau kuo lankstesnių sprendimų.

Radau naudingų išteklių, kuriais dalinuosi su jumis:

Ištyriau keletą „Rust“ žaidimų variklių, galiausiai pasirinkdamas „Piston“ ir „ggez“. Su jais susidūriau dirbdamas prie ankstesnio projekto. Galiausiai pasirinkau ggez, nes jis atrodė labiau tinkamas mažam 2D ​​žaidimui įgyvendinti. Stūmoklio modulinė struktūra yra per sudėtinga pradedantiesiems kūrėjams (arba tiems, kurie pirmą kartą dirba su Rust).

Žaidimo struktūra

Kurį laiką galvojau apie projekto architektūrą. Pirmas žingsnis – padaryti „žemę“, žmones ir teniso kortus. Žmonės turi judėti po teismus ir laukti. Žaidėjai turi turėti įgūdžių, kurie laikui bėgant tobulėja. Be to, turėtų būti redaktorius, leidžiantis pridėti naujų žmonių ir teismų, tačiau tai nebėra nemokama.

Viską gerai apgalvojęs ėmiausi darbo.

Žaidimo kūrimas

Pradžia: apskritimai ir abstrakcijos

Paėmiau pavyzdį iš ggez ir ekrane gavau apskritimą. Nuostabu! Dabar šiek tiek abstrakcijų. Maniau, kad būtų malonu abstrahuotis nuo žaidimo objekto idėjos. Kiekvienas objektas turi būti pateiktas ir atnaujintas, kaip nurodyta čia:

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

Ši kodo dalis suteikė man puikų objektų sąrašą, kurį galėčiau atnaujinti ir pateikti taip pat gražiai.

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 yra būtinas, nes jame yra visos kodo eilutės. Aš praleidau šiek tiek laiko atskirdamas failus ir optimizuodamas katalogų struktūrą. Štai kaip atrodė po to:
ištekliai -> čia yra visas turtas (vaizdai)
src
- subjektai
- game_object.rs
— ratas.rs
— main.rs -> pagrindinė kilpa

Žmonės, grindys ir vaizdai

Kitas žingsnis – sukurti žaidimo „Person“ objektą ir įkelti vaizdus. Viskas turėtų būti pastatyta 32*32 plytelių pagrindu.

Žaisti Rust per 24 valandas: asmeninio tobulėjimo patirtis

Teniso kortai

Išstudijavus kaip atrodo teniso kortai, nusprendžiau juos pagaminti iš 4*2 plytelių. Iš pradžių buvo galima padaryti tokio dydžio atvaizdą, arba sudėti 8 atskiras plyteles. Bet tada supratau, kad reikia tik dviejų unikalių plytelių, ir štai kodėl.

Iš viso turime dvi tokias plyteles: 1 ir 2.

Kiekviena aikštės dalis susideda iš 1 arba 2 plytelės. Jie gali būti išdėstyti įprastai arba apversti 180 laipsnių kampu.

Žaisti Rust per 24 valandas: asmeninio tobulėjimo patirtis

Pagrindinis konstravimo (surinkimo) režimas

Kai man pavyko pasiekti svetainių, žmonių ir žemėlapių atvaizdavimą, supratau, kad taip pat reikalingas pagrindinis surinkimo režimas. Įgyvendinau taip: paspaudus mygtuką, objektas pasirenkamas, o spustelėjimas jį pastato į norimą vietą. Taigi, mygtukas 1 leidžia pasirinkti aikštę, o mygtukas 2 leidžia pasirinkti žaidėją.

Tačiau vis tiek turime atsiminti, ką reiškia 1 ir 2, todėl pridėjau vielinį rėmą, kad būtų aišku, kuris objektas buvo pasirinktas. Štai kaip atrodo.

Žaisti Rust per 24 valandas: asmeninio tobulėjimo patirtis

Architektūros ir pertvarkymo klausimai

Dabar turiu kelis žaidimo objektus: žmones, aikšteles ir grindis. Tačiau tam, kad vieliniai rėmeliai veiktų, kiekvienam objekto objektui reikia pasakyti, ar patys objektai yra demonstravimo režimu, ar kadras tiesiog nupieštas. Tai nėra labai patogu.

Man atrodė, kad architektūrą reikia permąstyti taip, kad būtų atskleisti tam tikri apribojimai:

  • Turėti objektą, kuris atvaizduoja ir atnaujina save, yra problema, nes tas subjektas negalės „žinoti“, ką jis turi pateikti – vaizdo ir rėmelio;
  • nėra įrankio, skirto keistis savybėmis ir elgesiu tarp atskirų objektų (pavyzdžiui, is_build_mode ypatybės arba elgsenos atvaizdavimas). Galima būtų naudoti paveldėjimą, nors nėra tinkamo būdo tai įgyvendinti Rust. Man tikrai reikėjo maketo;
  • prireikė subjektų sąveikos įrankio priskiriant žmones į teismus;
  • patys subjektai buvo duomenų ir logikos mišinys, kuris greitai tapo nekontroliuojamas.

Dar šiek tiek tyrinėjau ir atradau architektūrą ECS – Entity Component System, kuris dažniausiai naudojamas žaidimuose. Štai ECS pranašumai:

  • duomenys atskirti nuo logikos;
  • kompozicija vietoj paveldėjimo;
  • į duomenis orientuota architektūra.

ECS apibūdina trys pagrindinės sąvokos:

  • subjektai – objekto, į kurį nurodo identifikatorius, tipas (tai gali būti žaidėjas, kamuolys ar kažkas kita);
  • komponentai – iš jų susideda esybės. Pavyzdys – atvaizdavimo komponentas, vietos ir kt. Tai duomenų saugyklos;
  • sistemos – jos naudoja ir objektus, ir komponentus, taip pat turi elgseną ir logiką, pagrįstą šiais duomenimis. Pavyzdys yra atvaizdavimo sistema, kuri kartoja visus objektus su atvaizdavimo komponentais ir atlieka atvaizdavimą.

Išstudijavus tapo aišku, kad ECS išsprendžia šias problemas:

  • naudojant išdėstymą vietoj paveldėjimo objektams sistemiškai organizuoti;
  • atsikratyti kodų maišaties per valdymo sistemas;
  • naudojant tokius metodus kaip is_build_mode, kad vielos rėmo logika būtų toje pačioje vietoje – atvaizdavimo sistemoje.

Taip atsitiko įdiegus ECS.

ištekliai -> čia yra visas turtas (vaizdai)
src
- komponentai
—pozicija.rs
— asmuo.rs
- teniso_court.rs
— aukštas.rs
- wireframe.rs
- mouse_tracked.rs
- ištekliai
-pelė.rs
- sistemos
- atvaizdavimas.rs
— konstantos.rs
- utils.rs
- world_factory.rs -> pasaulio gamyklos funkcijos
— main.rs -> pagrindinė kilpa

Priskiriame žmones į teismus

ECS palengvino gyvenimą. Dabar turėjau sistemingą būdą pridėti duomenis prie objektų ir pridėti logiką, pagrįstą tais duomenimis. O tai savo ruožtu leido organizuoti žmonių pasiskirstymą tarp teismų.

Ką aš padariau:

  • papildė Asmeniui duomenis apie priskirtus teismus;
  • pridėjo duomenis apie paskirstytus žmones į Teniso kortą;
  • pridėta CourtChoosingSystem, kuri leidžia analizuoti žmones ir teismus, aptikti turimus aikšteles ir paskirstyti jiems žaidėjus;
  • pridėjo PersonMovementSystem, kuri ieško teismams priskirtų žmonių, o jei jų nėra, tada siunčia žmones ten, kur reikia.

Žaisti Rust per 24 valandas: asmeninio tobulėjimo patirtis

Sumavimas

Man labai patiko dirbti su šiuo paprastu žaidimu. Be to, džiaugiuosi, kad parašiau Rustą, nes:

  • Rūdys suteikia jums tai, ko jums reikia;
  • ji turi puikią dokumentaciją, Rust yra gana elegantiška;
  • konsistencija šalta;
  • jums nereikia griebtis klonavimo, kopijavimo ar kitų panašių veiksmų, kuriuos dažnai darydavau C++;
  • Parinktys yra labai paprastos naudoti ir puikiai susidoroja su klaidomis;
  • jei projektą pavyko sudaryti, tai 99% laiko jis veikia ir tiksliai taip, kaip turėtų. Manau, kad kompiliatoriaus klaidų pranešimai yra geriausi, kuriuos aš mačiau.

Žaidimo kūrimas „Rust“ dar tik prasideda. Tačiau jau yra stabili ir gana didelė bendruomenė, kuri stengiasi atverti Rustą visiems. Todėl į kalbos ateitį žvelgiu optimistiškai, laukiu mūsų bendro darbo rezultatų.

„Skillbox“ rekomenduoja:

Šaltinis: www.habr.com

Добавить комментарий