step1 初期化とクリーンアップ
C、Nimに続き、RustでもSDL2を試してみました。Rustではsdl2クレートを使わせてもらいました。使った実感としましては、ところどころ違いがあり、ソースコードを結構読みましたが、大体同じ知識で使えるという感じでした。C、Nimと同様step1~7まで作ったものはGitHubに置いておきましたが、一応解説ということで記事にしました。
まずは動作確認としてstep1の初期化とクリーンアップのコードです。
extern crate sdl2;
use sdl2;
fn main() {
let sdl_ctx = sdl2::init();
match sdl_ctx {
Ok(_) => println!("Success"),
Err(e) => eprintln!("{}", e),
}
}
SDL_Init
にあたるものはsdl2::init()
となっています。本来は初期化成功の場合は0、失敗の場合は負のエラーコードを返してきますが、Rustのsdl2はResult<Sdl, String>
を返してきます。上記のように少ないコードなら何の問題もなくmatch式を使えばよいのですが、戻り値がResultというものは結構、いやむしろほとんどなので、毎回match式にするとごちゃごちゃしたコードになってしまいます。したがって、以下のような形に変更します。
extern crate sdl2;
use sdl2;
fn main() -> Result<(), String> {
let sdl_ctx = sdl2::init()?;
Ok(())
}
さて本来必須であるSDL_Quit
でありますが、RustではSdl
にDrop
トレイトが実装されているので、終了の際には自動で行ってくれます。安心安全。step2 ウィンドウの作成
次にstep2のウィンドウ作成をやります。コードは以下のようなものになりました。
use sdl2;
use sdl2::event::Event;
use sdl2::keyboard::Keycode;
use sdl2::pixels::Color;
use std::time::Duration;
use std::thread;
const TITLE: &'static str = "My SDL Window";
const WINDOW_WIDTH: u32 = 640;
const WINDOW_HEIGHT: u32 = 480;
fn main() -> Result<(), String> {
let sdl_ctx = sdl2::init()?;
let video_subsys = sdl_ctx.video()?;
let window = video_subsys.window(TITLE, WINDOW_WIDTH, WINDOW_HEIGHT)
.position_centered()
.build()
.map_err(|e| e.to_string())?;
let mut canvas = window.into_canvas()
.build()
.map_err(|e| e.to_string())?;
let mut event_pump = sdl_ctx.event_pump()?;
'running: loop {
canvas.set_draw_color(Color::RGB(0, 255, 0));
canvas.clear();
canvas.present();
for ev in event_pump.poll_iter() {
match ev {
Event::Quit {..} |
Event::KeyDown {keycode: Some(Keycode::Escape), ..} =>
break 'running,
_ => {}
}
}
thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
}
Ok(())
}
CやNimではSDL_Init(SDL_INIT_VIDEO)
といった感じで同時に行っていた処理ですが、Rustでは分けて行うようです。そしてSDL_Renderer
に相当するものがCanvas
になります。このあたりはソースコードを結構読みました。また上記のコードではウィンドウのxボタンでウィンドウを消すことができるようにしていますが、そのためにはevent_pump
とループが必要でした。例えば自動で消えるようにするだけならば、この部分は必要なく、thread::sleep(Duration::new(5, 0)
といった感じでうまく行きます。しかし、今後どうせ使うことになりますので、この時点で書いておくのもありかと思います。