始めに
今回初めてQiitaに投稿してみました。「ちゃんと調べりゃわかるだろ!」とかはあるとは思うんですけど、Rustに関してはいかんせん日本語の記事が少ないし、自分用のメモとしても経験としてもこうして書いてみようと思いました。
では本題入ります。
古い記事が多い
現在pistonを利用したゲームを作りたいとちまちま勉強しています。
Rustに関する記事で、piston_windowクレートを利用しているものはいくつもあったのに、その内容が古かったり、そもそもこれで動いていたのか?というものがいくつかあり、その中でもなんとか動くように書き直して使いたいというものがありました。
pistonを用いたゲーム製作について調べていると、描画と更新の処理をmatchで分岐させる書き方を以下のブログなどで見かけました。が、コピペしても動かず、また似たような書き方を探しても見つからなかったため、今風?の書き方を調べてみました。(英弱にはツラかった。。。
A RUST/PISTON GAME DEVELOPING TUTORIAL
Getting started with Piston, a game library for Rust
じゃあコード書いてみます
バージョンは1.24.0(stable)です。
// クレートのインポート
extern crate piston_window;
use piston_window::*;
// ウィンドウの作成
let window: PistonWindow = WindowSettings::new("title", [640, 480])
.build().unwrap();
ここまでは大体どこも一緒です。
ちなみにこの後メインループの処理に入るのですが、だいぶ前から更新されていないようなサイトでは以下のように書いてあるものがあるので注意です。~~(例えば、意外にもcrates.ioのpiston_windowのページとか)~~こちらは古いページでした。最新のページではちゃんとSome(e)
を使った書き方になっていました。
// 古い書き方
for e in window {
// 中の処理
}
// 現在の書き方
while let Some(e) = window.next() {
// 中の処理
}
そしてここからが今回記事を書くに至った処理方法です。
// 以下を追加
use piston_window::Event::*; // Event::Loop()用
use piston_window::Loop::*; // Loop::Render(), Loop::Update()用
while let Some(e) = window.next() {
// ここ
match e {
Loop(Render(_)) => {
// レンダリング(描画)に関するフレームで入るブロック
// draw_2d()なんかはここで呼ぶ
}
Loop(Update(_)) => {
// アップデート(更新)に関するフレームで入るブロック
// 例えば移動するボールの座標更新なんかはここで行う
}
_ => { }
}
}
追加のuseは無くてもいいのですが、その場合はEvent::Loop(Loop::Render(_))
などとそれぞれを書き直してください。
大学の授業の方針でProcessingを触っていた自分としては、描画と更新は同時にやればいいんじゃないの?と思ったんですけど、実はLoop(Update(_))
に入るときは描画処理は一切行われないようです。描画とはこういうものなのだろうか...
(Loop(Render(_))
を空にして、Loop(update(_))
に描画処理と、確認のprintln!
などを用意しておくとわかります)
ちなみに、Render()
やUpdate()
に引数を与えると、ブロック内で引数に情報を付加させて利用できます。
Loop(Render(r)) => {
// r: RenderArgs
}
Loop(Update(upd)) => {
// upd: UpdateArgs
}
例えば、upd.dtでデルタタイムが取得できます。
詳しくはリファレンスを見てもらえればわかると思います。
終わりに
リファレンスが英語しかないのはしょうがないですが、もう少しわかりやすいといいですね...。自分の力不足をひしひしと感じました。
他にももうすこし日本語の記事が増えるといいですね。
あとこういう書き方の方がいいよ、など意見がありましたらぜひご教授ください。よろしくお願いします。