我正在尝试创建一个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()
,它将进行编译。但是我想保持一个状态,该状态将被更新以创建动画。我做错了什么?为什么Closure不允许调用struct方法?
感谢您的帮助。
我发现了问题。游戏结构就像-
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();
}
}
[忘记为&
加上self
符号。感谢Discord频道#wg-wasm的Pauan#6666指出了这一点。