LoginSignup
1
1

More than 3 years have passed since last update.

Rustでconrodを使って赤い円をアニメーションさせる

Posted at

はじめに

前回: RustでWindowに円を描く からの続きです。今回は、簡単なアニメーションをさせようと思います。

コード全体はこちらになります。

Rustでconrodを使って赤い円をアニメーションさせる

Waitを入れながらUI Eventを処理する

アニメーションさせるポイントの一つは、Main Loopの中でWaitを入れつつUI系Eventも処理することです。
元のサンプルにそういう処理があったので、似たような感じで下記のようにしています。

event.rs
    pub fn next(&mut self, events_loop: &mut glium::glutin::EventsLoop, interval_ms: u64) -> Vec<glium::glutin::Event> {
        let last_update = self.last_update;
        let frame_interval_ms = std::time::Duration::from_millis(interval_ms);
        let duration_since_last_update = std::time::Instant::now().duration_since(last_update);
        if duration_since_last_update < frame_interval_ms {
            std::thread::sleep(frame_interval_ms - duration_since_last_update);
        }

        // Collect all pending events.
        let mut events = Vec::new();
        events_loop.poll_events(|event| events.push(event));

        self.last_update = std::time::Instant::now();
        events
    }

これを使って、

main.rs
    let mut animation_loop = event::AnimationLoop::new();

    'render: loop {
        for event in animation_loop.next(&mut events_loop, 
                                         1000 / constants::FPS as u64) {
            ...

という感じでWaitを入れつつ、そのWaitしている間に発生した events を取り出すようになっています。

アニメーション処理を切り出しておく

今後、色々なアニメーションをやりたいので、おまじないだらけの main.rs と分離しておくと気分が良さそうです。

animation.rs
use conrod_core;
use conrod_core::{widget, Positionable, Colorable, Widget};

widget_ids! {
    struct Ids {
        circle,
    }
}

pub struct Animation {
    n_frame: u64,
    ids: Ids,
}

impl Animation {
    pub fn new(ui: &mut conrod_core::Ui) -> Self {
        Animation {
            n_frame: 0,
            ids: Ids::new(ui.widget_id_generator()),
        }
    }

    pub fn next_frame(&mut self, ref mut ui: conrod_core::UiCell) {
        self.n_frame += 1;

        widget::Circle::fill(10.)
            // 単に左から右に赤い円が動く
            .xy([(((self.n_frame as i64) % 400)-200) as f64, 0.])
            .color(conrod_core::color::RED)
            .set(self.ids.circle, ui);
    }
}

として、

main.rs
    let mut anim = animation::Animation::new(&mut ui);
    ...

        anim.next_frame(ui.set_widgets());

と使うようにしました。
今後アニメーション系の処理を変えたい場合は、 animation.rs を変更するだけで良くなります(たぶん...)。

さいごに

大したことしてないですが、新しいものに触れるのは楽しいですね。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1