1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

🦀ひとりWASM-4とRustでゲームをつくる⚙Advent Calendar 2022

Day 21

ラストのまほう 第21話『タイトル画面とリザルト画面を作る』

Last updated at Posted at 2022-12-20

ゲームであるからには、終わりと始まりが必要です。ゲームを起動するといきなりレベル画面に放り込まれるのもダメというわけではないのですが、タイトル画面を用意するとグッとゲームらしくなったような気がします。また、ゲームをクリアしたらエンディングというかリザルト画面みたいなものを用意するとクリアした感がでて良さそうです。

シーンを定義する

ここでは、それぞれの「画面」を Scene と呼ぶことにします。この『シーン』は互いに独立しており、ゲーム内では必ずシーンがひとつだけ保持されて表示されます。たとえば、ゲームのレベル画面(プレイヤーキャラクターを実際に操作して遊ぶ画面)は次のような構造体で定義されています。

#[derive(Clone)]
pub struct GameScene {
    rng: Rng,
    frame_count: u32,
    player: Body,
    player_lookup: i32,
    fruits: std::vec::Vec<Body>,
    world: World,
    debug: bool,
    score: f32,
    vibration: i32,
}

それから、この構造体にコンストラクタみたいなのとupdateメソッドを生やしておきます。

impl GameScene {
    pub fn new() -> Self {
        ...
    }

    pub fn update(&mut self, inputs: &Inputs) -> Option<Scene> {
        ...
    }
}

ここで、update関数はOption<Scene>を返すようになっていますが、ここでSomeを返した場合はそのシーンが次のシーンとして切り替わるようにしたいと思います。

このような構造体を、タイトル画面とリザルト画面のぶんも定義します。

シーンを切り替える

TypeScriptのような言語であれば、Sceneインターフェイスを用意してstartupdateメソッドを定義し、各シーンではこのインターフェイスを実装するというような仕組みを考えます。オブジェクトはヒープに入れて常にポインタ越し(参照越し)に扱う言語であればそれでいいのですが、今回は言語がRustなのでシーンを表すオブジェクトはスタックに入れたいと思います。その場合、各シーンはenumに入れて保持することになります。

#[derive(Clone)]
pub enum Scene {
    TitleScene(TitleScene),
    GameScene(GameScene),
    EndingScene(EndingScene),
}

あとはこれをゲーム全体を表す構造体に入れて、このenumからシーンの構造体を取り出してはupdateを呼ぶということを繰り返すだけです。

pub fn update(&mut self) {

    ...

    let result = match { &mut self.scene } {
        Scene::TitleScene(t) => t.update(&inputs),
        Scene::GameScene(g) => g.update(&inputs),
        Scene::EndingScene(e) => e.update(&inputs),
    };
    match result {
        Option::None => {}
        Option::Some(next) => self.scene = next,
    }

    ...
}

画像がデカすぎる

ちなみに、この画面全体を覆うような大きい画像を使うと、2 bits * 160 pixel * 160 pixel bits = 6.4 kbytesで、なんとカートリッジサイズの1/10をタイトル画面の画像1枚が占めるということになってしまいます。画像を圧縮する手も考えたのですが、よく考えたら画像を描画するときに結局メモリ上に展開することになり、そちらも64キロバイトしかないので余計に容量を食うことになるだけです。あんまり演出に凝るな、いいからゲームの完成を優先しろ、ということですね。

次回予告

次回はちょっとしたお休み回で、他のWASM-4製ゲームを触ってみて、みんなどんなゲームを作っているのか調査してみます。

1
0
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
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?