Jugant a Rust en 24 hores: experiència de desenvolupament personal

Jugant a Rust en 24 hores: experiència de desenvolupament personal

En aquest article parlaré de la meva experiència personal de desenvolupar un petit joc a Rust. Va trigar unes 24 hores a crear una versió de treball (vaig treballar sobretot a la nit o els caps de setmana). El joc està lluny d'haver acabat, però crec que l'experiència serà gratificant. Compartiré el que he après i algunes observacions que he fet mentre construïm el joc des de zero.

Skillbox recomana: Curs pràctic de dos anys "Sóc un desenvolupador web PRO".

Recordem: per a tots els lectors de "Habr": un descompte de 10 rubles en inscriure's a qualsevol curs de Skillbox amb el codi promocional "Habr".

Per què Rust?

He escollit aquest llenguatge perquè n'he sentit moltes coses bones i veig que cada cop es fa més popular en el desenvolupament de jocs. Abans d'escriure el joc, tenia poca experiència desenvolupant aplicacions senzilles a Rust. Això va ser suficient per donar-me una sensació de llibertat mentre escrivia el joc.

Per què el joc i quin tipus de joc?

Fer jocs és divertit! Tant de bo hi hagués més motius, però per als projectes “a casa” trio temes que no estiguin massa relacionats amb la meva feina habitual. Quin joc és aquest? Volia fer una cosa així com un simulador de tennis que combina Cities Skylines, Zoo Tycoon, Prison Architect i el propi tennis. En general, va resultar ser un joc sobre una acadèmia de tennis on la gent ve a jugar.

Formació tècnica

Volia utilitzar Rust, però no sabia exactament quanta feina faria falta per començar. No volia escriure shaders de píxels i utilitzar arrossegar i deixar anar, així que buscava les solucions més flexibles.

He trobat recursos útils que comparteixo amb vosaltres:

Vaig explorar diversos motors de joc Rust i, finalment, vaig triar Piston i ggez. Els vaig trobar mentre treballava en un projecte anterior. Al final, vaig triar ggez perquè em semblava més adequat per implementar un petit joc en 2D. L'estructura modular de Piston és massa complexa per a un desenvolupador novell (o algú que treballa amb Rust per primera vegada).

Estructura del joc

Vaig estar una estona pensant en l'arquitectura del projecte. El primer pas és fer “terra”, gent i pistes de tennis. La gent s'ha de moure pels jutjats i esperar. Els jugadors han de tenir habilitats que millorin amb el temps. A més, hi hauria d'haver un editor que permeti afegir noves persones i tribunals, però això ja no és gratuït.

Després d'haver-ho pensat tot, em vaig posar a treballar.

Creació de jocs

Inici: Cercles i abstraccions

Vaig prendre un exemple de ggez i vaig obtenir un cercle a la pantalla. Meravellós! Ara algunes abstraccions. Vaig pensar que seria bo abstraure's de la idea d'un objecte de joc. Cada objecte s'ha de representar i actualitzar tal com s'indica aquí:

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

Aquest fragment de codi em va donar una bona llista d'objectes que podria actualitzar i representar en un bucle igualment agradable.

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 és necessari perquè conté totes les línies de codi. Vaig passar una mica de temps separant els fitxers i optimitzant l'estructura de directoris. Aquest és el que semblava després d'això:
recursos -> aquí és on es troben tots els actius (imatges)
src
- entitats
— game_object.rs
— cercle.rs
— main.rs -> bucle principal

Persones, pisos i imatges

El següent pas és crear un objecte de joc Persona i carregar imatges. Tot s'ha de construir sobre la base de rajoles de 32 * 32.

Jugant a Rust en 24 hores: experiència de desenvolupament personal

Pistes de tennis

Després d'estudiar com són les pistes de tennis, vaig decidir fer-les a partir de fitxes de 4*2. Inicialment, era possible fer una imatge d'aquesta mida o reunir 8 fitxes separades. Però aleshores em vaig adonar que només es necessitaven dues fitxes úniques, i aquí teniu el perquè.

En total tenim dues fitxes d'aquest tipus: 1 i 2.

Cada secció de la pista consta de rajola 1 o rajola 2. Es poden disposar de manera normal o girar-se 180 graus.

Jugant a Rust en 24 hores: experiència de desenvolupament personal

Mode de construcció bàsica (muntatge).

Després d'aconseguir la representació de llocs, persones i mapes, em vaig adonar que també calia un mode de muntatge bàsic. Ho vaig implementar així: quan es prem el botó, l'objecte es selecciona i el clic el col·loca al lloc desitjat. Per tant, el botó 1 us permet seleccionar una pista i el botó 2 us permet seleccionar un jugador.

Però encara hem de recordar què signifiquen 1 i 2, així que vaig afegir un marc per deixar clar quin objecte es va seleccionar. Això és el que sembla.

Jugant a Rust en 24 hores: experiència de desenvolupament personal

Qüestions d'arquitectura i refactorització

Ara tinc diversos objectes de joc: persones, pistes i pisos. Però perquè funcionin els wireframes, cal dir a cada entitat d'objecte si els mateixos objectes estan en mode de demostració o si simplement es dibuixa un marc. Això no és gaire convenient.

Em va semblar que calia repensar l'arquitectura d'una manera que revelés algunes limitacions:

  • Tenir una entitat que es renderitza i s'actualitza a si mateixa és un problema perquè aquesta entitat no podrà "saber" què se suposa que ha de representar: una imatge i un filferro;
  • manca d'una eina per intercanviar propietats i comportament entre entitats individuals (per exemple, la propietat is_build_mode o la representació del comportament). Seria possible utilitzar l'herència, tot i que no hi ha una manera adequada d'implementar-la a Rust. El que realment necessitava era el disseny;
  • calia una eina d'interacció entre entitats per assignar persones als tribunals;
  • les mateixes entitats eren una barreja de dades i lògica que ràpidament es va descontrolar.

Vaig investigar més i vaig descobrir l'arquitectura ECS - Entity Component System, que s'utilitza habitualment als jocs. Aquests són els avantatges de l'ECS:

  • les dades estan separades de la lògica;
  • composició en lloc d'herència;
  • arquitectura centrada en dades.

ECS es caracteritza per tres conceptes bàsics:

  • entitats: el tipus d'objecte al qual fa referència l'identificador (podria ser un jugador, una pilota o una altra cosa);
  • components: les entitats estan formades per ells. Exemple: component de renderització, ubicacions i altres. Aquests són magatzems de dades;
  • sistemes: utilitzen objectes i components, a més contenen un comportament i una lògica que es basen en aquestes dades. Un exemple és un sistema de renderització que itera a través de totes les entitats amb components de renderització i fa la representació.

Després d'estudiar-lo, va quedar clar que ECS resol els problemes següents:

  • utilitzar la disposició en lloc de l'herència per organitzar les entitats de manera sistèmica;
  • desfer-se del revolt de codi mitjançant sistemes de control;
  • utilitzant mètodes com is_build_mode per mantenir la lògica del filferro al mateix lloc, al sistema de representació.

Això és el que va passar després d'implementar ECS.

recursos -> aquí és on es troben tots els actius (imatges)
src
- components
—posició.rs
— persona.rs
— pista_de_tenis.rs
— pis.rs
- wireframe.rs
— mouse_tracked.rs
- recursos
—ratolí.rs
- sistemes
— rendering.rs
— constants.rs
— utils.rs
— world_factory.rs -> funcions de fàbrica mundial
— main.rs -> bucle principal

Assignem persones als jutjats

ECS ha fet la vida més fàcil. Ara tenia una manera sistemàtica d'afegir dades a les entitats i afegir lògica basada en aquestes dades. I això, al seu torn, va permetre organitzar el repartiment de persones entre els jutjats.

Què he fet:

  • dades afegides sobre els tribunals assignats a Persona;
  • ha afegit dades sobre persones distribuïdes a TennisCourt;
  • S'ha afegit CourtChoosingSystem, que permet analitzar persones i pistes, detectar pistes disponibles i distribuir-hi jugadors;
  • va afegir un PersonMovementSystem, que busca persones assignades als jutjats i, si no hi són, envia persones on han d'estar.

Jugant a Rust en 24 hores: experiència de desenvolupament personal

En resum

Em va agradar molt treballar en aquest joc senzill. A més, estic content d'haver fet servir Rust per escriure-ho, perquè:

  • Rust et dóna el que necessites;
  • té una excel·lent documentació, Rust és força elegant;
  • la consistència és fresca;
  • no cal recórrer a la clonació, la còpia o altres accions semblants, que sovint feia en C++;
  • Les opcions són molt fàcils d'utilitzar i gestionen molt bé els errors;
  • si el projecte es va poder compilar, el 99% del temps funciona, i exactament com hauria de ser. Crec que els missatges d'error del compilador són els millors que he vist.

El desenvolupament del joc a Rust tot just comença. Però ja hi ha una comunitat estable i bastant gran que treballa per obrir Rust a tothom. Per tant, miro el futur de la llengua amb optimisme, esperant els resultats del nostre treball comú.

Skillbox recomana:

Font: www.habr.com

Afegeix comentari