我正在尝试创建一个 requestAnimationFrame 循环,它将调用game.render()
每一帧。我正在关注本教程 - https://rustwasm.github.io/wasm-bindgen/examples/request-animation-frame.html
struct Game {
state: GameState,
ctx: web_sys::CanvasRenderingContext2d
}
impl Game {
fn render(self: Game) {
self.ctx.begin_path();
self.ctx.arc(self.state.x, 50.0, 40.0, 0.0, 2.0 * std::f64::consts::PI);
self.ctx.stroke();
}
}
#[wasm_bindgen(start)]
pub fn run() -> Result<(), JsValue> {
let game = init();
let f = Rc::new(RefCell::new(None));
let g = f.clone();
*g.borrow_mut() = Some(Closure::wrap(Box::new(move || {
game.render();
request_animation_frame(f.borrow().as_ref().unwrap());
}) as Box<dyn FnMut()>));
request_animation_frame(g.borrow().as_ref().unwrap());
Ok(())
}
fn init() -> Game {
let doc = document();
let canvas = doc.create_element("canvas").unwrap();
canvas.set_attribute("width", "800px").unwrap();
canvas.set_attribute("height", "800px").unwrap();
canvas.set_id("fp-canvas");
body().append_child(&canvas).expect("Could not attach canvas");
Game {
ctx: context(),
state: GameState {
x: 3.0
}
}
}
但它给出了以下错误 -
error[E0277]: expected a `std::ops::FnMut<()>` closure, found `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]`
--> src/lib.rs:89:42
|
89 | *g.borrow_mut() = Some(Closure::wrap(Box::new(move || {
| __________________________________________^
90 | | game.render();
91 | | request_animation_frame(f.borrow().as_ref().unwrap());
92 | | }) as Box<dyn FnMut()>));
| |______^ expected an `FnMut<()>` closure, found `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]`
|
= help: the trait `std::ops::FnMut<()>` is not implemented for `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]`
= note: wrap the `[closure@src/lib.rs:89:51: 92:6 game:Game, f:std::rc::Rc<std::cell::RefCell<std::option::Option<wasm_bindgen::closure::Closure<dyn std::ops::FnMut()>>>>]` in a closure with no arguments: `|| { /* code */ }
= note: required for the cast to the object type `dyn std::ops::FnMut()`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.
error: could not compile `fighting-pixel`.
To learn more, run the command again with --verbose.
如果我注释掉game.render()
它会编译。但我想保持一个将被更新以创建动画的状态。我做错了什么?为什么闭包不允许调用结构方法?
在此先感谢您的帮助。