2048 WASM ou jogue no Rust em 2 dias

Este artigo é um experimento com o Rust com sua compilação subsequente no WASM. Foi interessante sentir essas tecnologias em algo mais difícil do que calcular o fatorial, então a escolha recaiu sobre o conhecido jogo 2048 .















Descrição do jogo



O jogo original é um campo quadrado de 4 por 4. Cada quadrado pode estar vazio ou ocupado por uma peça

com uma potência de dois. O estado inicial do campo possui 2 células preenchidas.















4 : , , ,

. . 90%

10%.







, , :















, , .







, , .







:















, .







: 2048.









Rust, .







Rust.

Yew — , React', ,

.







:







cargo new --lib rust-2048 && cd rust-2048
      
      





, Cargo.toml :







[dependencies]
yew = "0.17"
wasm-bindgen = "0.2.67"
      
      





, src/lib.rs



:







use wasm_bindgen::prelude::*;
use yew::prelude::*;
struct Model {
    link: ComponentLink<Self>,
    value: i64,
}
enum Msg {
    AddOne,
}
impl Component for Model {
    type Message = Msg;
    type Properties = ();
    fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
        Self {
            link,
            value: 0,
        }
    }
    fn update(&mut self, msg: Self::Message) -> ShouldRender {
        match msg {
            Msg::AddOne => self.value += 1
        }
        true
    }
    fn change(&mut self, _props: Self::Properties) -> ShouldRender {
        // Should only return "true" if new properties are different to
        // previously received properties.
        // This component has no properties so we will always return "false".
        false
    }
    fn view(&self) -> Html {
        html! {
            <div>
                <button onclick=self.link.callback(|_| Msg::AddOne)>{ "+1" }</button>
                <p>{ self.value }</p>
            </div>
        }
    }
}
#[wasm_bindgen(start)]
pub fn run_app() {
    App::<Model>::new().mount_to_body();
}
      
      





:







mkdir static
      
      





index.html :







<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <title>Yew Sample App</title>
    <script type="module">
      import init from "./wasm.js";
      init();
    </script>
  </head>
  <body></body>
</html>
      
      





wasm-pack ( cargo install wasm-pack



):







wasm-pack build --target web --out-name wasm --out-dir ./static
      
      





:







Error: crate-type must be cdylib to compile to wasm32-unknown-unknown. Add the following to your Cargo.toml file:
[lib]
crate-type = ["cdylib", "rlib"]
      
      





, . Cargo.toml :







[lib]
crate-type = ["cdylib", "rlib"]
      
      





( miniserve, ):







cd static
python -m SimpleHTTPServer
      
      





http://127.0.0.1:8000 . , .









: https://github.com/dev-family/wasm-2048/commit/6bc015fbc88c1633f4605944fd920b2780e261c1







.

.







:







2, 4, 0, 0
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





, . :







0, 0, 2, 4
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





, .

:







  1. => .


         /--------  , 
2, 4, 0, 0
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





2.







      /--------  , 
2, 4, 0, 0
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





3.







    /--------   
2, 4, 0, 0
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





4.







       /-------- 
2, 0, 4, 0
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





5.







         /--------   ,        
2, 0, 0, 4
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





6.







 /--------  
2, 0, 0, 4
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





7.







    /-------- 
0, 2, 0, 4
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





8.







       /--------      
0, 0, 2, 4
0, 0, 0, 0
0, 0, 0, 0
0, 0, 0, 0
      
      





, , — .







Direction#build_traversal



( ),

Grid#traverse_from



( ) Grid#move_in



— , .









: https://github.com/dev-family/wasm-2048/commit/7e08b5af6008e6f9d716d7c9a41b0810e869df9e







: ,

.. 4 , 2

. , ,

.







, TestCase, .. .









: https://github.com/dev-family/wasm-2048/commit/6082409412f6c19943c453c5d706d57bbcef538b







rand, WASM

wasm-bindgen



feature.







, ,

Grid



enable_new_tiles



.







(.. ),

traverse_from



. , , .







UI



: https://github.com/dev-family/wasm-2048/commit/356e0889a84d7fc2582662e76238f94fc69bfed7







UI , React / JSX. html!



Yew ,

. React - .







Não havia documentação sobre como trabalhar com o teclado, e, em princípio, os serviços não são documentados de forma alguma, você precisa ler as fontes, ver exemplos.







Animações



Commit: https://github.com/dev-family/wasm-2048/commit/e258748ab114ec5f930dbeb77d674bdbc5e63b1a .







Para tornar a interface mais viva, você precisa adicionar animações.







Eles são implementados em cima de transições CSS regulares. Ensinamos os ladrilhos a lembrar sua posição anterior e, ao renderizar, exibimos o ladrilho imediatamente na posição antiga e no próximo tique - na nova.








All Articles